Ticket #1642: Color by Dilution.patch

File Color by Dilution.patch, 21.5 KB (added by xeen, 15 years ago)

Based on h-a-l-9000's patch

  • src/org/openstreetmap/josm/data/gpx/WayPoint.java

     
    1717    public final LatLon latlon;
    1818    public final EastNorth eastNorth;
    1919    public double time;
    20     public Color speedLineColor;
     20    public Color customColoring;
    2121    public boolean drawLine;
    2222    public int dir;
    2323
  • src/org/openstreetmap/josm/gui/layer/GpxLayer.java

     
    8585    private boolean computeCacheInSync;
    8686    private int computeCacheMaxLineLengthUsed;
    8787    private Color computeCacheColorUsed;
    88     private boolean computeCacheColored;
     88    private colorModes computeCacheColored;
    8989    private int computeCacheColorTracksTune;
    9090
    9191    public GpxLayer(GpxData d) {
     
    368368        {-ll0,+sl4,-sl4,+ll0},
    369369        {-ll0,-sl9,-ll0,+sl9}
    370370    };
    371 
     371   
     372    // the different color modes
     373    enum colorModes { none, velocity, dilution }
     374   
    372375    @Override public void paint(Graphics g, MapView mv) {
    373376
    374377        /****************************************************************
     
    376379         ****************************************************************/
    377380        // Long startTime = System.currentTimeMillis();
    378381        Color neutralColor = getColor(name);
    379         boolean forceLines = Main.pref.getBoolean("draw.rawgps.lines.force");                     // also draw lines between points belonging to different segments
    380         boolean direction = Main.pref.getBoolean("draw.rawgps.direction");                        // draw direction arrows on the lines
    381         int maxLineLength = Main.pref.getInteger("draw.rawgps.max-line-length", -1);
     382        // also draw lines between points belonging to different segments
     383        boolean forceLines = Main.pref.getBoolean("draw.rawgps.lines.force");   
     384        // draw direction arrows on the lines
     385        boolean direction = Main.pref.getBoolean("draw.rawgps.direction");   
    382386        // don't draw lines if longer than x meters
    383         boolean lines = Main.pref.getBoolean("draw.rawgps.lines");                                // draw line between points, global setting
     387        int maxLineLength = Main.pref.getInteger("draw.rawgps.max-line-length", -1);       
     388        // draw line between points, global setting
     389        boolean lines = Main.pref.getBoolean("draw.rawgps.lines");                               
    384390        String linesKey = "draw.rawgps.lines.layer "+name;
     391        // draw lines, per-layer setting
    385392        if (Main.pref.hasKey(linesKey))
    386             lines = Main.pref.getBoolean(linesKey);                                                 // draw lines, per-layer setting
    387         boolean large = Main.pref.getBoolean("draw.rawgps.large");                                // paint large dots for points
    388         boolean colored = Main.pref.getBoolean("draw.rawgps.colors");                             // color the lines
    389         boolean alternatedirection = Main.pref.getBoolean("draw.rawgps.alternatedirection");      // paint direction arrow with alternate math. may be faster
    390         int delta = Main.pref.getInteger("draw.rawgps.min-arrow-distance", 0);
     393            lines = Main.pref.getBoolean(linesKey);   
     394        // paint large dots for points
     395        boolean large = Main.pref.getBoolean("draw.rawgps.large");
     396        // color the lines
     397        colorModes colored = colorModes.none;
     398        try {
     399            colored = colorModes.values()[Main.pref.getInteger("draw.rawgps.colors", 0)];
     400        } catch(Exception e) { }
     401        // paint direction arrow with alternate math. may be faster
     402        boolean alternatedirection = Main.pref.getBoolean("draw.rawgps.alternatedirection");   
    391403        // don't draw arrows nearer to each other than this
    392         int colorTracksTune = Main.pref.getInteger("draw.rawgps.colorTracksTune", 45); // allows to tweak line coloring for different speed levels.
     404        int delta = Main.pref.getInteger("draw.rawgps.min-arrow-distance", 0);       
     405        // allows to tweak line coloring for different speed levels.
     406        int colorTracksTune = Main.pref.getInteger("draw.rawgps.colorTracksTune", 45);
    393407        /****************************************************************
    394408         ********** STEP 2a - CHECK CACHE VALIDITY **********************
    395409         ****************************************************************/
     
    419433                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon())) {
    420434                            continue;
    421435                        }
     436                        trkPnt.customColoring = neutralColor;
    422437                        if (oldWp != null) {
    423438                            double dist = trkPnt.latlon.greatCircleDistance(oldWp.latlon);
    424                             double dtime = trkPnt.time - oldWp.time;
    425                             double vel = dist/dtime;
    426                             double velColor = vel/colorTracksTune*255;
    427439
    428                             if (!colored) {
    429                                 trkPnt.speedLineColor = neutralColor;
    430                             } else if (dtime <= 0 || vel < 0 || velColor > 255) { // attn: bad case first
    431                                 trkPnt.speedLineColor = colors[255];
    432                             } else {
    433                                 trkPnt.speedLineColor = colors[(int) (velColor)];
     440                            switch(colored) {
     441                                case velocity:
     442                                    double dtime = trkPnt.time - oldWp.time;
     443                                    double vel = dist/dtime;
     444                                    double velColor = vel/colorTracksTune*255;
     445                                    // Bad case first
     446                                    if (dtime <= 0 || vel < 0 || velColor > 255)
     447                                        trkPnt.customColoring = colors[255];
     448                                    else
     449                                        trkPnt.customColoring = colors[(int) (velColor)];
     450                                    break;
     451                               
     452                                case dilution:
     453                                    if(trkPnt.attr.get("hdop") != null) {
     454                                        float hdop = ((Float)trkPnt.attr.get("hdop")).floatValue();
     455                                        int hdoplvl = Math.round(hdop * 25);
     456                                        // High hdop is bad, but high values in colors are green.
     457                                        // Therefore inverse the logic
     458                                        int hdopcolor = 255 - (hdoplvl > 255 ? 255 : hdoplvl);
     459                                        trkPnt.customColoring = colors[hdopcolor];
     460                                    }
     461                                    break;                               
    434462                            }
     463
    435464                            if (maxLineLength == -1 || dist <= maxLineLength) {
    436465                                trkPnt.drawLine = true;
    437466                                trkPnt.dir = (int)(Math.atan2(-trkPnt.eastNorth.north()+oldWp.eastNorth.north(), trkPnt.eastNorth.east()-oldWp.eastNorth.east()) / Math.PI * 4 + 3.5); // crude but works
     
    439468                                trkPnt.drawLine = false;
    440469                            }
    441470                        } else { // make sure we reset outdated data
    442                             trkPnt.speedLineColor = colors[255];
    443471                            trkPnt.drawLine = false;
    444472                        }
    445473                        oldWp = trkPnt;
     
    463491                        if (trkPnt.drawLine) {
    464492                            // skip points that are on the same screenposition
    465493                            if (old != null && ((old.x != screen.x) || (old.y != screen.y))) {
    466                                 g.setColor(trkPnt.speedLineColor);
     494                                g.setColor(trkPnt.customColoring);
    467495                                g.drawLine(old.x, old.y, screen.x, screen.y);
    468496                            }
    469497                        }
     
    488516                            Point screen = mv.getPoint(trkPnt.eastNorth);
    489517                            // skip points that are on the same screenposition
    490518                            if (old != null && (oldA == null || screen.x < oldA.x-delta || screen.x > oldA.x+delta || screen.y < oldA.y-delta || screen.y > oldA.y+delta)) {
    491                                 g.setColor(trkPnt.speedLineColor);
     519                                g.setColor(trkPnt.customColoring);
    492520                                double t = Math.atan2(screen.y-old.y, screen.x-old.x) + Math.PI;
    493521                                g.drawLine(screen.x,screen.y, (int)(screen.x + 10*Math.cos(t-PHI)), (int)(screen.y
    494522                                + 10*Math.sin(t-PHI)));
     
    518546                            Point screen = mv.getPoint(trkPnt.eastNorth);
    519547                            // skip points that are on the same screenposition
    520548                            if (old != null && (oldA == null || screen.x < oldA.x-delta || screen.x > oldA.x+delta || screen.y < oldA.y-delta || screen.y > oldA.y+delta)) {
    521                                 g.setColor(trkPnt.speedLineColor);
     549                                g.setColor(trkPnt.customColoring);
    522550                                g.drawLine(screen.x, screen.y, screen.x + dir[trkPnt.dir][0], screen.y + dir[trkPnt.dir][1]);
    523551                                g.drawLine(screen.x, screen.y, screen.x + dir[trkPnt.dir][2], screen.y + dir[trkPnt.dir][3]);
    524552                                oldA = screen;
     
    541569                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
    542570                            continue;
    543571                        Point screen = mv.getPoint(trkPnt.eastNorth);
    544                             g.fillRect(screen.x-1, screen.y-1, 3, 3);
     572                        g.setColor(trkPnt.customColoring);
     573                        g.fillRect(screen.x-1, screen.y-1, 3, 3);
    545574                    } // end for trkpnt
    546575                } // end for segment
    547576            } // end for trk
     
    577606                        if (Double.isNaN(trkPnt.latlon.lat()) || Double.isNaN(trkPnt.latlon.lon()))
    578607                            continue;
    579608                        Point screen = mv.getPoint(trkPnt.eastNorth);
     609                        g.setColor(trkPnt.customColoring);
    580610                        g.drawRect(screen.x, screen.y, 0, 0);
    581611                    } // end for trkpnt
    582612                } // end for segment
  • src/org/openstreetmap/josm/gui/preferences/DrawingPreference.java

     
    99import java.awt.GridBagLayout;
    1010
    1111import javax.swing.BorderFactory;
     12import javax.swing.ButtonGroup;
    1213import javax.swing.JCheckBox;
    1314import javax.swing.JComboBox;
    1415import javax.swing.JLabel;
     16import javax.swing.JRadioButton;
    1517import javax.swing.JTextField;
    1618import javax.swing.JScrollPane;
    1719import javax.swing.JPanel;
    1820import javax.swing.Box;
     21import javax.swing.event.ChangeEvent;
     22import javax.swing.event.ChangeListener;
    1923
    2024import org.openstreetmap.josm.Main;
    2125import org.openstreetmap.josm.tools.GBC;
     
    2630    private JTextField drawRawGpsMaxLineLength = new JTextField(8);
    2731    private JCheckBox forceRawGpsLines = new JCheckBox(tr("Force lines if no segments imported."));
    2832    private JCheckBox largeGpsPoints = new JCheckBox(tr("Draw large GPS points."));
    29     private JCheckBox colorTracks = new JCheckBox(tr("Color tracks by velocity."));
    30     private JComboBox colorTracksTune = new JComboBox(new String[] {tr("Car"), tr("Bicycle"), tr("Foot")});
     33    private ButtonGroup colorGroup;
     34    private JRadioButton colorTypeVelocity = new JRadioButton(tr("Velocity (red = slow, green = fast)"));
     35    private JRadioButton colorTypeDilution = new JRadioButton(tr("Dilution (red = high, green = low, if available)"));
     36    private JRadioButton colorTypeNone = new JRadioButton(tr("Single Color (can be customized in Layer Manager)"));
     37    private JComboBox colorTypeVelocityTune = new JComboBox(new String[] {tr("Car"), tr("Bicycle"), tr("Foot")});
    3138    private JCheckBox directionHint = new JCheckBox(tr("Draw Direction Arrows"));
    3239    private JCheckBox drawGpsArrows = new JCheckBox(tr("Draw Direction Arrows"));
    3340    private JCheckBox drawGpsArrowsFast = new JCheckBox(tr("Fast drawing (looks uglier)"));
     
    4855        // drawRawGpsLines
    4956        drawRawGpsLines.addActionListener(new ActionListener(){
    5057            public void actionPerformed(ActionEvent e) {
    51                             forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected());
    52                             drawRawGpsMaxLineLength.setEnabled(drawRawGpsLines.isSelected());
    53                             drawGpsArrows.setEnabled(drawRawGpsLines.isSelected());
    54                             drawGpsArrowsFast.setEnabled(drawGpsArrows.isSelected() && drawGpsArrows.isEnabled());
    55                             drawGpsArrowsMinDist.setEnabled(drawGpsArrows.isSelected() && drawGpsArrows.isEnabled());
    56                             colorTracks.setEnabled(drawRawGpsLines.isSelected());
    57                             colorTracksTune.setEnabled(colorTracks.isSelected() && drawRawGpsLines.isSelected());
     58                forceRawGpsLines.setEnabled(drawRawGpsLines.isSelected());
     59                drawRawGpsMaxLineLength.setEnabled(drawRawGpsLines.isSelected());
     60                drawGpsArrows.setEnabled(drawRawGpsLines.isSelected());
     61                drawGpsArrowsFast.setEnabled(drawGpsArrows.isSelected() && drawGpsArrows.isEnabled());
     62                drawGpsArrowsMinDist.setEnabled(drawGpsArrows.isSelected() && drawGpsArrows.isEnabled());
    5863            }
    5964        });
    6065        drawRawGpsLines.setSelected(Main.pref.getBoolean("draw.rawgps.lines"));
     
    98103        drawGpsArrowsMinDist.setEnabled(drawGpsArrows.isSelected() && drawGpsArrows.isEnabled());
    99104        panel.add(new JLabel(tr("Minimum distance (pixels)")), GBC.std().insets(60,0,0,0));
    100105        panel.add(drawGpsArrowsMinDist, GBC.eol().fill(GBC.HORIZONTAL).insets(5,0,0,5));
    101 
     106       
     107        // largeGpsPoints
     108        largeGpsPoints.setSelected(Main.pref.getBoolean("draw.rawgps.large"));
     109        largeGpsPoints.setToolTipText(tr("Draw larger dots for the GPS points."));
     110        panel.add(largeGpsPoints, GBC.eop().insets(20,0,0,0));
     111       
    102112        // colorTracks
    103         colorTracks.addActionListener(new ActionListener(){
    104             public void actionPerformed(ActionEvent e) {
    105                             colorTracksTune.setEnabled(colorTracks.isSelected() && drawRawGpsLines.isSelected());
     113        colorGroup = new ButtonGroup();
     114        colorGroup.add(colorTypeNone);
     115        colorGroup.add(colorTypeVelocity);
     116        colorGroup.add(colorTypeDilution);
     117       
     118        colorTypeVelocity.addChangeListener(new ChangeListener(){
     119            public void stateChanged(ChangeEvent e) {
     120                colorTypeVelocityTune.setEnabled(colorTypeVelocity.isSelected());
    106121            }
    107122        });
    108         colorTracks.setSelected(Main.pref.getBoolean("draw.rawgps.colors"));
    109         colorTracks.setToolTipText(tr("Choose the hue for the track color by the velocity at that point."));
    110         colorTracks.setEnabled(drawRawGpsLines.isSelected());
    111         panel.add(colorTracks, GBC.std().insets(40,0,0,0));
    112123       
     124        switch(Main.pref.getInteger("draw.rawgps.colors", 0)) {
     125            case 0:
     126                colorTypeNone.setSelected(true);
     127                break;
     128            case 1:
     129                colorTypeVelocity.setSelected(true);
     130                break;
     131            case 2:
     132                colorTypeDilution.setSelected(true);
     133                break;   
     134        }
     135               
     136        colorTypeNone.setToolTipText(tr("All points and track segments will have the same color. Can be customized in Layer Manager."));
     137        colorTypeVelocity.setToolTipText(tr("Colors points and track segments by velocity."));
     138        colorTypeDilution.setToolTipText(tr("Colors points and track segments by dilution. Your capture device needs to logs that information."));
     139
    113140        // color Tracks by Velocity Tune
    114141        int ccts = Main.pref.getInteger("draw.rawgps.colorTracksTune", 45);
    115         colorTracksTune.setSelectedIndex(ccts==10 ? 2 : (ccts==20 ? 1 : 0));
    116         colorTracksTune.setToolTipText(tr("Allows to tune the track coloring for different average speeds."));
    117         colorTracksTune.setEnabled(colorTracks.isSelected() && colorTracks.isEnabled());
    118         panel.add(colorTracksTune, GBC.eop().insets(5,0,0,5));
     142        colorTypeVelocityTune.setSelectedIndex(ccts==10 ? 2 : (ccts==20 ? 1 : 0));
     143        colorTypeVelocityTune.setToolTipText(tr("Allows to tune the track coloring for different average speeds."));
     144        colorTypeVelocityTune.setEnabled(colorTypeVelocity.isSelected() && colorTypeVelocity.isEnabled());
    119145       
    120         // largeGpsPoints
    121         largeGpsPoints.setSelected(Main.pref.getBoolean("draw.rawgps.large"));
    122         largeGpsPoints.setToolTipText(tr("Draw larger dots for the GPS points."));
    123         panel.add(largeGpsPoints, GBC.eop().insets(20,0,0,0));
    124 
     146        panel.add(Box.createVerticalGlue(), GBC.eol().insets(0, 20, 0, 0));
     147       
     148        panel.add(new JLabel(tr("Track and Point Coloring")), GBC.eol().insets(20,0,0,0));
     149        panel.add(colorTypeNone, GBC.eol().insets(40,0,0,0));
     150        panel.add(colorTypeVelocity, GBC.std().insets(40,0,0,0));
     151        panel.add(colorTypeVelocityTune, GBC.eop().insets(5,0,0,5));
     152        panel.add(colorTypeDilution, GBC.eol().insets(40,0,0,0));
     153       
    125154        panel.add(Box.createVerticalGlue(), GBC.eol().fill(GBC.BOTH));
    126155        JScrollPane scrollpane = new JScrollPane(panel);
    127156        scrollpane.setBorder(BorderFactory.createEmptyBorder( 0, 0, 0, 0 ));
     
    196225        Main.pref.put("draw.rawgps.lines.force", forceRawGpsLines.isSelected());
    197226        Main.pref.put("draw.rawgps.direction", drawGpsArrows.isSelected());
    198227        Main.pref.put("draw.rawgps.alternatedirection", drawGpsArrowsFast.isSelected());
    199         Main.pref.put("draw.rawgps.min-arrow-distance", drawGpsArrowsMinDist.getText());
    200         Main.pref.put("draw.rawgps.colors", colorTracks.isSelected());
    201         int ccti=colorTracksTune.getSelectedIndex();
     228        Main.pref.put("draw.rawgps.min-arrow-distance", drawGpsArrowsMinDist.getText());       
     229        if(colorTypeVelocity.isSelected())
     230            Main.pref.putInteger("draw.rawgps.colors", 1);
     231        else if(colorTypeDilution.isSelected())
     232            Main.pref.putInteger("draw.rawgps.colors", 2);
     233        else
     234            Main.pref.putInteger("draw.rawgps.colors", 0);
     235        int ccti=colorTypeVelocityTune.getSelectedIndex();
    202236        Main.pref.putInteger("draw.rawgps.colorTracksTune", ccti==2 ? 10 : (ccti==1 ? 20 : 45));
    203237        Main.pref.put("draw.rawgps.large", largeGpsPoints.isSelected());
    204238        Main.pref.put("draw.segment.direction", directionHint.isSelected());
  • src/org/openstreetmap/josm/io/GpxReader.java

     
    223223                }
    224224                break;
    225225            case wpt:
    226                 if (qName.equals("ele") || qName.equals("magvar")
    227                         || qName.equals("geoidheight") || qName.equals("name")
    228                         || qName.equals("sym") || qName.equals("type")) {
     226                if (qName.equals("ele")  || qName.equals("magvar") ||
     227                    qName.equals("name") || qName.equals("geoidheight") ||
     228                    qName.equals("type") || qName.equals("sym")) {
    229229                    currentWayPoint.attr.put(qName, accumulator.toString());
     230                } else if(qName.equals("hdop") /*|| qName.equals("vdop") ||
     231                        qName.equals("pdop")*/) {
     232                    try {
     233                        currentWayPoint.attr.put(qName, Float.parseFloat(accumulator.toString()));
     234                    } catch(Exception e) {
     235                        currentWayPoint.attr.put(qName, new Float(0));
     236                    }
    230237                } else if (qName.equals("time")) {
    231238                    currentWayPoint.attr.put(qName, accumulator.toString());
    232239                    currentWayPoint.setTime();
  • src/org/openstreetmap/josm/io/OsmReader.java

     
    479479      * Parse the given input source and return the dataset.
    480480      * @param ref The dataset that is search in for references first. If
    481481      *      the Reference is not found here, Main.ds is searched and a copy of the
    482       *  elemet found there is returned.
     482      *  element found there is returned.
    483483      */
    484484     public static DataSet parseDataSet(InputStream source, DataSet ref, PleaseWaitDialog pleaseWaitDlg) throws SAXException, IOException {
    485485          return parseDataSetOsm(source, ref, pleaseWaitDlg).ds;