Package com.bbn.openmap.layer.location.csv

Source Code of com.bbn.openmap.layer.location.csv.CSVLinkHandler$LinkDecoder

// **********************************************************************
//
// <copyright>
//
//  BBN Technologies
//  10 Moulton Street
//  Cambridge, MA 02138
//  (617) 873-8000
//
//  Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/layer/location/csv/CSVLinkHandler.java,v $
// $RCSfile: CSVLinkHandler.java,v $
// $Revision: 1.3.2.2 $
// $Date: 2005/08/09 18:18:46 $
// $Author: dietrick $
//
// **********************************************************************

package com.bbn.openmap.layer.location.csv;

/*  Java Core  */
import java.awt.Color;
import java.awt.Component;
import java.util.Properties;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JCheckBox;

import com.bbn.openmap.layer.location.Link;
import com.bbn.openmap.omGraphics.OMGraphic;
import com.bbn.openmap.util.ColorFactory;
import com.bbn.openmap.util.DataOrganizer;
import com.bbn.openmap.util.Debug;
import com.bbn.openmap.util.PropUtils;

/**
* The CSVLinkHandler is designed to let you put data on the map based
* on information from a Comma Separated Value(CSV) file. It's assumed
* that the each row in the file refers to two locations, and that a
* link is to be shown between the two locations.
*
* <P>
* The individual fields must not have leading whitespace.
*
* <P>
* The locationFile property should contain a URL referring to the
* file. This can take the form of file:/myfile.csv for a local file
* or http://somehost.org/myfile.csv for a remote file
*
* If there is a lat1/lon1 index, and a lat2/lon2 index, then the
* links' endpoints are in the link file.
* <P>
*
* The Link CSV file has to have certain fields, and the column number
* of those fields are set in the properties:
*
* <pre>
*        
*          # latitude and longitude indexes of the link end points
*          linkMarkerName.lat1Index=column_number
*          linkMarkerName.lon1Index=column_number
*          linkMarkerName.lat2Index=column_number
*          linkMarkerName.lon2Index=column_number
*          # These are optional
*          linkMarkerName.dashIndex=column_number for true/false (false is default)
*          linkMarkerName.colorIndex=column_number for color notation
*          linkMarkerName.thicknessIndex=column_number for pixel thickness of link
*          linkMarkerName.geoStyleIndex=column_number for link rendertype (STRAIGHT, GC, RHUMB)
*         
* </pre>
*
* <p>
* TODO: update the quadtree used to instead use a
* com.bbn.openmap.geo.ExtentIndex, so that lines that bisect the map
* will appear. Right now, one of the endpoints of the line has to be
* in the map window in order for the link to be displayed, and that's
* not quite right.
*/
public class CSVLinkHandler extends CSVLocationHandler {

    // //////////////////////
    // Link Variables

    /**
     * Property to use to designate the column of the link file to use
     * as the latitude of end "1".
     */
    public static final String Lat1IndexProperty = "lat1Index";
    /**
     * Property to use to designate the column of the link file to use
     * as the longitude of end "1".
     */
    public static final String Lon1IndexProperty = "lon1Index";
    /**
     * Property to use to designate the column of the link file to use
     * as the latitude of end "2".
     */
    public static final String Lat2IndexProperty = "lat2Index";
    /**
     * Property to use to designate the column of the link file to use
     * as the longitude of end "2".
     */
    public static final String Lon2IndexProperty = "lon2Index";
    /** Not used. */
    public static final String LinkTypeIndexProperty = "linkTypeIndex";
    /**
     * Index in file for True/false property to indicate link should
     * be dashed line.
     */
    public static final String DashIndexProperty = "dashIndex";
    public static final String ColorIndexProperty = "colorIndex";
    public static final String ThicknessIndexProperty = "thicknessIndex";
    /**
     * Index in CSV file for rendertype of link - STRAIGHT, GC, RHUMB
     */
    public static final String GeoStyleIndexProperty = "geoStyleIndex";

    /** The names of the various link types on the map. Not used. */
    // public static final String LinkTypesProperty = "linkTypes";
    /** Index of column in CSV to use as latitude1 of link. */
    protected int lat1Index = -1;
    /** Index of column in CSV to use as longitude1 of link. */
    protected int lon1Index = -1;
    /** Index of column in CSV to use as latitude2 of link. */
    protected int lat2Index = -1;
    /** Index of column in CSV to use as longitude2 of link. */
    protected int lon2Index = -1;
    /** Index of column in CSV to use as the type of link. */
    // protected int linkTypeIndex = -1;
    /**
     * Index of column in CSV to use as the line-type to draw a link
     * in.
     */
    protected int geoStyleIndex = -1;

    protected int dashIndex = -1;
    protected int colorIndex = -1;
    protected int thicknessIndex = -1;

    /**
     * The default constructor for the Layer. All of the attributes
     * are set to their default values.
     */
    public CSVLinkHandler() {}

    /**
     * The properties and prefix are managed and decoded here, for the
     * standard uses of the CSVLinkHandler.
     *
     * @param prefix string prefix used in the properties file for
     *        this layer.
     * @param properties the properties set in the properties file.
     */
    public void setProperties(String prefix, java.util.Properties properties) {
        super.setProperties(prefix, properties);

        String realPrefix = PropUtils.getScopedPropertyPrefix(this);

        lat1Index = PropUtils.intFromProperties(properties, realPrefix
                + Lat1IndexProperty, lat1Index);
        lon1Index = PropUtils.intFromProperties(properties, realPrefix
                + Lon1IndexProperty, lon1Index);
        lat2Index = PropUtils.intFromProperties(properties, realPrefix
                + Lat2IndexProperty, lat2Index);
        lon2Index = PropUtils.intFromProperties(properties, realPrefix
                + Lon2IndexProperty, lon2Index);
        geoStyleIndex = PropUtils.intFromProperties(properties, realPrefix
                + GeoStyleIndexProperty, geoStyleIndex);

        // linkTypeIndex = PropUtils.intFromProperties(properties,
        // realPrefix
        // + LinkTypeIndexProperty, linkTypeIndex);

        // This will replace the three properties below it.
        // Note - I can't remember how - DFD - Oh, yeah, it's not
        // implemented.

        colorIndex = PropUtils.intFromProperties(properties, realPrefix
                + ColorIndexProperty, colorIndex);
        dashIndex = PropUtils.intFromProperties(properties, realPrefix
                + DashIndexProperty, dashIndex);
        thicknessIndex = PropUtils.intFromProperties(properties, realPrefix
                + ThicknessIndexProperty, thicknessIndex);
    }

    /**
     * PropertyConsumer method, to fill in a Properties object,
     * reflecting the current values of the layer. If the layer has a
     * propertyPrefix set, the property keys should have that prefix
     * plus a separating '.' prepended to each propery key it uses for
     * configuration.
     *
     * @param props a Properties object to load the PropertyConsumer
     *        properties into.
     * @return Properties object containing PropertyConsumer property
     *         values. If getList was not null, this should equal
     *         getList. Otherwise, it should be the Properties object
     *         created by the PropertyConsumer.
     */
    public Properties getProperties(Properties props) {
        props = super.getProperties(props);

        String prefix = PropUtils.getScopedPropertyPrefix(this);
        // Start JDJ Changes
        props.put(prefix + "class", this.getClass().getName());
        props.put(prefix + LocationFileProperty, PropUtils.unnull(locationFile));
        props.put(prefix + csvHeaderProperty,
                new Boolean(csvHasHeader).toString());
        // End JDJ Changes
        props.put(prefix + Lat1IndexProperty, Integer.toString(lat1Index));
        props.put(prefix + Lon1IndexProperty, Integer.toString(lon1Index));
        props.put(prefix + Lat2IndexProperty, Integer.toString(lat2Index));
        props.put(prefix + Lon2IndexProperty, Integer.toString(lon2Index));

        // props.put(prefix + LinkTypeIndexProperty,
        // Integer.toString(linkTypeIndex));

        props.put(prefix + DashIndexProperty, Integer.toString(dashIndex));
        props.put(prefix + ColorIndexProperty, Integer.toString(colorIndex));
        props.put(prefix + ThicknessIndexProperty,
                Integer.toString(thicknessIndex));
        props.put(prefix + GeoStyleIndexProperty,
                Integer.toString(geoStyleIndex));

        return props;
    }

    /**
     * Method to fill in a Properties object with values reflecting
     * the properties able to be set on this PropertyConsumer. The key
     * for each property should be the raw property name (without a
     * prefix) with a value that is a String that describes what the
     * property key represents, along with any other information about
     * the property that would be helpful (range, default value,
     * etc.). This method takes care of the basic LocationHandler
     * parameters, so any LocationHandlers that extend the
     * AbstractLocationHandler should call this method, too, before
     * adding any specific properties.
     *
     * @param list a Properties object to load the PropertyConsumer
     *        properties into. If getList equals null, then a new
     *        Properties object should be created.
     * @return Properties object containing PropertyConsumer property
     *         values. If getList was not null, this should equal
     *         getList. Otherwise, it should be the Properties object
     *         created by the PropertyConsumer.
     */
    public Properties getPropertyInfo(Properties list) {
        list = super.getPropertyInfo(list);

        list.remove(LatIndexProperty);
        list.remove(LonIndexProperty);

        list.put(Lat1IndexProperty,
                "The column index, in the location file, of the first node latitude.");
        list.put(Lon1IndexProperty,
                "The column index, in the location file, of the first node longitude.");
        list.put(Lat2IndexProperty,
                "The column index, in the location file, of the second node latitude.");
        list.put(Lon2IndexProperty,
                "The column index, in the location file, of the second node longitude.");

        list.put(DashIndexProperty,
                "The column index, in the location file, of the true/false dash indicator.");
        list.put(ColorIndexProperty,
                "The column index, in the location file, of the color string.");
        list.put(ThicknessIndexProperty,
                "The column index, in the location file, of the pixel thickness of the link.");
        list.put(GeoStyleIndexProperty,
                "The column index, in the location file, of the render type of the link.");
        return list;
    }

    protected boolean checkIndexSettings() {

        if (lat1Index == -1 || lon1Index == -1 || lat2Index == -1
                || lon2Index == -1) {
            Debug.error("CSVLocationHandler: createData(): Index properties for Lat/Lon/Name are not set properly! lat index:"
                    + latIndex + ", lon index:" + lonIndex);
            return false;
        }

        if (Debug.debugging("csvlocation")) {
            Debug.output("CSVLinkHandler: Reading File:" + locationFile
                    + " lat1Index: " + lat1Index + " lon1Index: " + lon1Index
                    + " lat2Index: " + lat2Index + " lon2Index: " + lon2Index
                    + " geoStyleIndex: " + geoStyleIndex
                    // + " linkTypeIndex: " + linkTypeIndex
                    + " dashIndex: " + dashIndex + " colorIndex: " + colorIndex
                    + " thicknessIndex: " + thicknessIndex);
        }

        return true;
    }

    protected TokenDecoder getTokenDecoder() {
        return new LinkDecoder();
    }

    /**
     * Provides the palette widgets to control the options of showing
     * maps, or attribute text.
     * <P>
     * In this case, the palette widget only contains one button,
     * which reloads the data files for the layer.
     * <p>
     *
     * @return Component object representing the palette widgets.
     */
    public Component getGUI() {
        JButton rereadFilesButton;
        JCheckBox showCSVLinkCheck;

        showCSVLinkCheck = new JCheckBox("Show Links", isShowLocations());
        showCSVLinkCheck.setActionCommand(showLocationsCommand);
        showCSVLinkCheck.addActionListener(this);

        rereadFilesButton = new JButton("Re-Read Data File");
        rereadFilesButton.setActionCommand(readDataCommand);
        rereadFilesButton.addActionListener(this);
        Box box = Box.createVerticalBox();
        box.add(showCSVLinkCheck);
        box.add(rereadFilesButton);
        return box;
    }

    /* Utility functions */

    /**
     * This gets a line-type from a token, and translates it into one
     * of LINETYPE_STRAIGHT, LINETYPE_GREATCIRCLE, or LINETYPE_RHUMB.
     *
     * @param token the token read from the CSV file.
     * @return one of LINETYPE_STRAIGHT, LINETYPE_GREATCIRCLE, or
     *         LINETYPE_RHUMB
     */
    protected int getLineTypeFromToken(Object token) {
        int default_lintetype = OMGraphic.LINETYPE_STRAIGHT;
        String tokstring = ((String) token).trim().toLowerCase();

        if (Debug.debugging("csvlocation")) {
            Debug.output("CSVLinkHandler:getLineTypeFromToken(" + tokstring
                    + ")");
        }

        if (tokstring.startsWith("s"))
            return OMGraphic.LINETYPE_STRAIGHT;
        else if (tokstring.startsWith("g"))
            return OMGraphic.LINETYPE_GREATCIRCLE;
        else if (tokstring.startsWith("r"))
            return OMGraphic.LINETYPE_RHUMB;
        else {
            Debug.error("Don't understand Linetype " + tokstring
                    + ", using default (STRAIGHT)");
            return default_lintetype;
        }
    }

    /**
     * This interprets a color value from a token. The color can be
     * one of the standard colors in the java.awt.Color class, or it
     * can be a hexadecimal representation of any other displayable
     * color.
     * <p>
     *
     * @param token the token read from the CSV file.
     *        <p>
     * @return the java.awt.Color described by that token, or
     *         Color.black (if the token cannot be translated into a
     *         proper color).
     */
    protected Color getColorFromToken(Object token) {
        String tokstring = (String) token;

        if (Debug.debugging("csvlocation")) {
            Debug.output("CSVLinkHandler: getColorFromToken(" + tokstring + ")");
        }

        Color c = ColorFactory.getNamedColor(tokstring, null);

        if (c == null) {
            // decode a hex color string.
            c = Color.decode(tokstring);
            if (c == null) {
                c = Color.BLACK;
            }
        }

        if (Debug.debugging("csvlocation")) {
            Debug.output("CSVLinkHandler: getColorFromToken returns (" + c
                    + ")");
        }

        return c;
    }

    public class LinkDecoder implements TokenDecoder {

        float lat1;
        float lon1;
        float lat2;
        float lon2;
        int linetype;
        Color color;
        boolean dashed;
        float thickness;

        public LinkDecoder() {
            reset();
        }

        public void reset() {
            lat1 = 0;
            lon1 = 0;
            lat2 = 0;
            lon2 = 0;
            linetype = OMGraphic.LINETYPE_GREATCIRCLE;
            color = (Color) getLocationDrawingAttributes().getLinePaint();
            dashed = false;
            thickness = 1f;
        }

        public void handleToken(Object token, int i) {
            try {
                if (i == lat1Index)
                    lat1 = ((Double) token).floatValue();
                else if (i == lon1Index)
                    lon1 = ((Double) token).floatValue();
                else if (i == lat2Index)
                    lat2 = ((Double) token).floatValue();
                else if (i == lon2Index)
                    lon2 = ((Double) token).floatValue();
                else if (i == geoStyleIndex)
                    linetype = getLineTypeFromToken(token);

                // These are going to go away...
                else if (i == colorIndex)
                    color = getColorFromToken(token);
                else if (i == thicknessIndex)
                    thickness = ((Double) token).floatValue();
                else if (i == dashIndex)
                    dashed = Boolean.valueOf((String) token).booleanValue();
            } catch (NumberFormatException nfe) {

            }
        }

        public void createAndAddObjectFromTokens(DataOrganizer organizer) {
            // Original Lines added to this else block to fix
            // reading a data file with a header in it.
            Link link = new Link(lat1, lon1, lat2, lon2, "No details", color, dashed, thickness, linetype);
            link.setLocationHandler(CSVLinkHandler.this);

            // What we really want to do is get the
            // locationDrawingAttributes and set them on the link.

            Debug.message("csvlocation", "CSVLinkHandler: " + link.getDetails());

            organizer.put(lat1, lon1, link);
            organizer.put(lat2, lon2, link);
            reset();
        }
    }
}
TOP

Related Classes of com.bbn.openmap.layer.location.csv.CSVLinkHandler$LinkDecoder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.