Changeset 7319 in josm for trunk/src/org


Ignore:
Timestamp:
2014-07-20T20:43:53+02:00 (10 years ago)
Author:
akks
Message:

Add colorbar for active GPX layer, big GpxLayer class refactoring, see #5662
new classes GpxDrawHelper and ColorScale responsible for GPX drawing and coloring
move data-related methods to GpxData
remove WayPoint.customColoringTransparent from memory, calculate it at paint-time

Location:
trunk/src/org/openstreetmap/josm
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/gpx/GpxData.java

    r7020 r7319  
    44import java.io.File;
    55import java.util.Collection;
     6import java.util.Date;
    67import java.util.Iterator;
    78import java.util.LinkedList;
     
    8283     *
    8384     * FIXME might perhaps use visitor pattern?
     85     * @return the bounds
    8486     */
    8587    public Bounds recalculateBounds() {
     
    116118    /**
    117119     * calculates the sum of the lengths of all track segments
     120     * @return the length in meters
    118121     */
    119122    public double length(){
     
    125128
    126129        return result;
     130    }
     131   
     132    /**
     133     * returns minimum and maximum timestamps in the track
     134     * @param trk track to analyze
     135     * @return  minimum and maximum dates in array of 2 elements
     136     */
     137    public static Date[] getMinMaxTimeForTrack(GpxTrack trk) {
     138        WayPoint earliest = null, latest = null;
     139
     140        for (GpxTrackSegment seg : trk.getSegments()) {
     141            for (WayPoint pnt : seg.getWayPoints()) {
     142                if (latest == null) {
     143                    latest = earliest = pnt;
     144                } else {
     145                    if (pnt.compareTo(earliest) < 0) {
     146                        earliest = pnt;
     147                    } else {
     148                        latest = pnt;
     149                    }
     150                }
     151            }
     152        }
     153        if (earliest==null || latest==null) return null;
     154        return new Date[]{earliest.getTime(), latest.getTime()};
     155    }
     156
     157    /**
     158    * Returns minimum and maximum timestamps for all tracks
     159    * Warning: there are lot of track with broken timestamps,
     160    * so we just ingore points from future and from year before 1970 in this method
     161    * works correctly @since 5815
     162     * @return minimum and maximum dates in array of 2 elements
     163    */
     164    public Date[] getMinMaxTimeForAllTracks() {
     165        double min=1e100, max=-1e100, t;
     166        double now = System.currentTimeMillis()/1000.0;
     167        for (GpxTrack trk: tracks) {
     168            for (GpxTrackSegment seg : trk.getSegments()) {
     169                for (WayPoint pnt : seg.getWayPoints()) {
     170                    t = pnt.time;
     171                    if (t>0 && t<=now) {
     172                        if (t>max) max=t;
     173                        if (t<min) min=t;
     174                    }
     175                }
     176            }
     177        }
     178        if (min==1e100 || max==-1e100) return null;
     179        return new Date[]{new Date((long) (min * 1000)), new Date((long) (max * 1000)), };
    127180    }
    128181
     
    258311    }
    259312
     313    public void resetEastNorthCache() {
     314        if (waypoints != null) {
     315            for (WayPoint wp : waypoints){
     316                wp.invalidateEastNorthCache();
     317            }
     318        }
     319        if (tracks != null){
     320            for (GpxTrack track: tracks) {
     321                for (GpxTrackSegment segment: track.getSegments()) {
     322                    for (WayPoint wp: segment.getWayPoints()) {
     323                        wp.invalidateEastNorthCache();
     324                    }
     325                }
     326            }
     327        }
     328        if (routes != null) {
     329            for (GpxRoute route: routes) {
     330                if (route.routePoints == null) {
     331                    continue;
     332                }
     333                for (WayPoint wp: route.routePoints) {
     334                    wp.invalidateEastNorthCache();
     335                }
     336            }
     337        }
     338    }
     339
    260340    /**
    261341     * Iterates over all track segments and then over all routes.
     
    266346        private int idxTracks;
    267347        private Iterator<GpxTrackSegment> itTrackSegments;
    268         private Iterator<GpxRoute> itRoutes;
     348        private final Iterator<GpxRoute> itRoutes;
    269349
    270350        private Collection<WayPoint> next;
    271         private boolean[] trackVisibility;
     351        private final boolean[] trackVisibility;
    272352
    273353        public LinesIterator(GpxData data, boolean[] trackVisibility) {
  • trunk/src/org/openstreetmap/josm/data/gpx/WayPoint.java

    r7299 r7319  
    2525    public double time;
    2626    public Color customColoring;
    27     public Color customColoringTransparent;
    2827    public boolean drawLine;
    2928    public int dir;
     
    3736        time = p.time;
    3837        customColoring = p.customColoring;
    39         customColoringTransparent = p.customColoringTransparent;
    4038        drawLine = p.drawLine;
    4139        dir = p.dir;
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r7299 r7319  
    33package org.openstreetmap.josm.gui.layer;
    44
    5 import static org.openstreetmap.josm.tools.I18n.marktr;
    65import static org.openstreetmap.josm.tools.I18n.tr;
    76import static org.openstreetmap.josm.tools.I18n.trn;
    87
    9 import java.awt.BasicStroke;
    108import java.awt.Color;
    119import java.awt.Dimension;
    1210import java.awt.Graphics2D;
    13 import java.awt.Point;
    14 import java.awt.RenderingHints;
    15 import java.awt.Stroke;
    1611import java.io.File;
    1712import java.text.DateFormat;
     
    2722import javax.swing.JScrollPane;
    2823import javax.swing.SwingUtilities;
    29 
    3024import org.openstreetmap.josm.Main;
     25
    3126import org.openstreetmap.josm.actions.RenameLayerAction;
    3227import org.openstreetmap.josm.actions.SaveActionBase;
    3328import org.openstreetmap.josm.data.Bounds;
    34 import org.openstreetmap.josm.data.coor.LatLon;
    3529import org.openstreetmap.josm.data.gpx.GpxConstants;
    3630import org.openstreetmap.josm.data.gpx.GpxData;
     
    5044import org.openstreetmap.josm.gui.layer.gpx.DownloadAlongTrackAction;
    5145import org.openstreetmap.josm.gui.layer.gpx.DownloadWmsAlongTrackAction;
     46import org.openstreetmap.josm.gui.layer.gpx.GpxDrawHelper;
    5247import org.openstreetmap.josm.gui.layer.gpx.ImportAudioAction;
    5348import org.openstreetmap.josm.gui.layer.gpx.ImportImagesAction;
     
    5651import org.openstreetmap.josm.io.GpxImporter;
    5752import org.openstreetmap.josm.tools.ImageProvider;
    58 import org.openstreetmap.josm.tools.Utils;
    5953import org.openstreetmap.josm.tools.date.DateUtils;
    6054
     
    6256
    6357    public GpxData data;
    64     protected static final double PHI = Math.toRadians(15);
    65     private boolean computeCacheInSync;
    66     private int computeCacheMaxLineLengthUsed;
    67     private Color computeCacheColorUsed;
    68     private boolean computeCacheColorDynamic;
    69     private colorModes computeCacheColored;
    70     private int computeCacheColorTracksTune;
    7158    private boolean isLocalFile;
    7259    // used by ChooseTrackVisibilityAction to determine which tracks to show/hide
     
    7663    private int lastUpdateCount;
    7764
     65    private final GpxDrawHelper drawHelper;
     66   
    7867    public GpxLayer(GpxData d) {
    7968        super((String) d.attr.get("name"));
    8069        data = d;
    81         computeCacheInSync = false;
     70        drawHelper = new GpxDrawHelper(data);
    8271        ensureTrackVisibilityLength();
    8372    }
     
    9483    }
    9584
    96     /**
    97      * returns minimum and maximum timestamps in the track
    98      */
    99     public static Date[] getMinMaxTimeForTrack(GpxTrack trk) {
    100         WayPoint earliest = null, latest = null;
    101 
    102         for (GpxTrackSegment seg : trk.getSegments()) {
    103             for (WayPoint pnt : seg.getWayPoints()) {
    104                 if (latest == null) {
    105                     latest = earliest = pnt;
    106                 } else {
    107                     if (pnt.compareTo(earliest) < 0) {
    108                         earliest = pnt;
    109                     } else {
    110                         latest = pnt;
    111                     }
    112                 }
    113             }
    114         }
    115         if (earliest==null || latest==null) return null;
    116         return new Date[]{earliest.getTime(), latest.getTime()};
    117     }
    118 
    119     /**
    120     * Returns minimum and maximum timestamps for all tracks
    121     * Warning: there are lot of track with broken timestamps,
    122     * so we just ingore points from future and from year before 1970 in this method
    123     * works correctly @since 5815
    124     */
    125     public Date[] getMinMaxTimeForAllTracks() {
    126         double min=1e100, max=-1e100, t;
    127         double now = System.currentTimeMillis()/1000.0;
    128         for (GpxTrack trk: data.tracks) {
    129             for (GpxTrackSegment seg : trk.getSegments()) {
    130                 for (WayPoint pnt : seg.getWayPoints()) {
    131                     t = pnt.time;
    132                     if (t>0 && t<=now) {
    133                         if (t>max) max=t;
    134                         if (t<min) min=t;
    135                     }
    136                 }
    137             }
    138         }
    139         if (min==1e100 || max==-1e100) return null;
    140         return new Date[]{new Date((long) (min * 1000)), new Date((long) (max * 1000)), };
    141     }
    142 
    143 
     85    @Override
     86    public Color getColor(boolean ignoreCustom) {
     87        return drawHelper.getColor(getName(), ignoreCustom);
     88    }
     89   
    14490    /**
    14591     * Returns a human readable string that shows the timespan of the given track
     
    14894     */
    14995    public static String getTimespanForTrack(GpxTrack trk) {
    150         Date[] bounds = getMinMaxTimeForTrack(trk);
     96        Date[] bounds = GpxData.getMinMaxTimeForTrack(trk);
    15197        String ts = "";
    15298        if (bounds != null) {
     
    238184    public boolean isInfoResizable() {
    239185        return true;
    240     }
    241 
    242     @Override
    243     public Color getColor(boolean ignoreCustom) {
    244         Color c = Main.pref.getColor(marktr("gps point"), "layer " + getName(), Color.gray);
    245 
    246         return ignoreCustom || getColorMode() == colorModes.none ? c : null;
    247     }
    248 
    249     public colorModes getColorMode() {
    250         try {
    251             int i=Main.pref.getInteger("draw.rawgps.colors", "layer " + getName(), 0);
    252             return colorModes.values()[i];
    253         } catch (Exception e) {
    254             Main.warn(e);
    255         }
    256         return colorModes.none;
    257     }
    258 
    259     /* for preferences */
    260     public static Color getGenericColor() {
    261         return Main.pref.getColor(marktr("gps point"), Color.gray);
    262186    }
    263187
     
    337261        long to = toDate.getTime();
    338262        for (GpxTrack trk : data.tracks) {
    339             Date[] t = GpxLayer.getMinMaxTimeForTrack(trk);
     263            Date[] t = GpxData.getMinMaxTimeForTrack(trk);
    340264
    341265            if (t==null) continue;
     
    349273    public void mergeFrom(Layer from) {
    350274        data.mergeFrom(((GpxLayer) from).data);
    351         computeCacheInSync = false;
    352     }
    353 
    354     private static final Color[] colors = new Color[256];
    355     static {
    356         for (int i = 0; i < colors.length; i++) {
    357             colors[i] = Color.getHSBColor(i / 300.0f, 1, 1);
    358         }
    359     }
    360     /** Colors (with custom alpha channel, if given) for HDOP painting. */
    361     private final Color[] hdopColors;
    362     private final int hdopAlpha = Main.pref.getInteger("hdop.color.alpha", -1);
    363     {
    364         if (hdopAlpha >= 0) {
    365             hdopColors = new Color[256];
    366             for (int i = 0; i < hdopColors.length; i++) {
    367                 hdopColors[i] = new Color((colors[i].getRGB() & 0xFFFFFF) | ((hdopAlpha & 0xFF) << 24), true);
    368             }
    369         } else {
    370             hdopColors = colors;
    371         }
    372     }
    373 
    374     private static final Color[] colors_cyclic = new Color[256];
    375     static {
    376         for (int i = 0; i < colors_cyclic.length; i++) {
    377             //                    red   yellow  green   blue    red
    378             int[] h = new int[] { 0,    59,     127,    244,    360};
    379             int[] s = new int[] { 100,  84,     99,     100 };
    380             int[] b = new int[] { 90,   93,     74,     83 };
    381 
    382             float angle = 4 - i / 256f * 4;
    383             int quadrant = (int) angle;
    384             angle -= quadrant;
    385             quadrant = Utils.mod(quadrant+1, 4);
    386 
    387             float vh = h[quadrant] * w(angle) + h[quadrant+1] * (1 - w(angle));
    388             float vs = s[quadrant] * w(angle) + s[Utils.mod(quadrant+1, 4)] * (1 - w(angle));
    389             float vb = b[quadrant] * w(angle) + b[Utils.mod(quadrant+1, 4)] * (1 - w(angle));
    390 
    391             colors_cyclic[i] = Color.getHSBColor(vh/360f, vs/100f, vb/100f);
    392         }
    393     }
    394 
    395     /**
    396      * transition function:
    397      *  w(0)=1, w(1)=0, 0&lt;=w(x)&lt;=1
    398      * @param x number: 0&lt;=x&lt;=1
    399      * @return the weighted value
    400      */
    401     private static float w(float x) {
    402         if (x < 0.5)
    403             return 1 - 2*x*x;
    404         else
    405             return 2*(1-x)*(1-x);
    406     }
    407 
    408     // lookup array to draw arrows without doing any math
    409     private static final int ll0 = 9;
    410     private static final int sl4 = 5;
    411     private static final int sl9 = 3;
    412     private static final int[][] dir = { { +sl4, +ll0, +ll0, +sl4 }, { -sl9, +ll0, +sl9, +ll0 }, { -ll0, +sl4, -sl4, +ll0 },
    413         { -ll0, -sl9, -ll0, +sl9 }, { -sl4, -ll0, -ll0, -sl4 }, { +sl9, -ll0, -sl9, -ll0 },
    414         { +ll0, -sl4, +sl4, -ll0 }, { +ll0, +sl9, +ll0, -sl9 }, { +sl4, +ll0, +ll0, +sl4 },
    415         { -sl9, +ll0, +sl9, +ll0 }, { -ll0, +sl4, -sl4, +ll0 }, { -ll0, -sl9, -ll0, +sl9 } };
    416 
    417     // the different color modes
    418     enum colorModes {
    419         none, velocity, dilution, direction, time
     275        drawHelper.dataChanged();
    420276    }
    421277
     
    426282        lastTracks.addAll(data.tracks);
    427283
    428         g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
    429                 Main.pref.getBoolean("mappaint.gpx.use-antialiasing", false) ?
    430                         RenderingHints.VALUE_ANTIALIAS_ON : RenderingHints.VALUE_ANTIALIAS_OFF);
    431 
    432         /****************************************************************
    433          ********** STEP 1 - GET CONFIG VALUES **************************
    434          ****************************************************************/
    435         Color neutralColor = getColor(true);
    436         String spec="layer "+getName();
    437 
    438         // also draw lines between points belonging to different segments
    439         boolean forceLines = Main.pref.getBoolean("draw.rawgps.lines.force", spec, false);
    440         // draw direction arrows on the lines
    441         boolean direction = Main.pref.getBoolean("draw.rawgps.direction", spec, false);
    442         // don't draw lines if longer than x meters
    443         int lineWidth = Main.pref.getInteger("draw.rawgps.linewidth", spec, 0);
    444 
    445         int maxLineLength;
    446         boolean lines;
    447         if (!this.data.fromServer) {
    448             maxLineLength = Main.pref.getInteger("draw.rawgps.max-line-length.local", spec, -1);
    449             lines = Main.pref.getBoolean("draw.rawgps.lines.local", spec, true);
    450         } else {
    451             maxLineLength = Main.pref.getInteger("draw.rawgps.max-line-length", spec, 200);
    452             lines = Main.pref.getBoolean("draw.rawgps.lines", spec, true);
    453         }
    454         // paint large dots for points
    455         boolean large = Main.pref.getBoolean("draw.rawgps.large", spec, false);
    456         int largesize = Main.pref.getInteger("draw.rawgps.large.size", spec, 3);
    457         boolean hdopcircle = Main.pref.getBoolean("draw.rawgps.hdopcircle", spec, false);
    458         // color the lines
    459         colorModes colored = getColorMode();
    460         // paint direction arrow with alternate math. may be faster
    461         boolean alternatedirection = Main.pref.getBoolean("draw.rawgps.alternatedirection", spec, false);
    462         // don't draw arrows nearer to each other than this
    463         int delta = Main.pref.getInteger("draw.rawgps.min-arrow-distance", spec, 40);
    464         // allows to tweak line coloring for different speed levels.
    465         int colorTracksTune = Main.pref.getInteger("draw.rawgps.colorTracksTune", spec, 45);
    466         boolean colorModeDynamic = Main.pref.getBoolean("draw.rawgps.colors.dynamic", spec, false);
    467         int hdopfactor = Main.pref.getInteger("hdop.factor", 25);
    468 
    469         int largePointAlpha = Main.pref.getInteger("draw.rawgps.large.alpha", -1) & 0xFF;
    470 
    471         Stroke storedStroke = g.getStroke();
    472         if(lineWidth != 0)
    473         {
    474             g.setStroke(new BasicStroke(lineWidth,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND));
    475             largesize += lineWidth;
    476         }
    477 
    478         /****************************************************************
    479          ********** STEP 2a - CHECK CACHE VALIDITY **********************
    480          ****************************************************************/
    481         if ((computeCacheMaxLineLengthUsed != maxLineLength) || (!neutralColor.equals(computeCacheColorUsed))
    482                 || (computeCacheColored != colored) || (computeCacheColorTracksTune != colorTracksTune)
    483                 || (computeCacheColorDynamic != colorModeDynamic)) {
    484             computeCacheMaxLineLengthUsed = maxLineLength;
    485             computeCacheInSync = false;
    486             computeCacheColorUsed = neutralColor;
    487             computeCacheColored = colored;
    488             computeCacheColorTracksTune = colorTracksTune;
    489             computeCacheColorDynamic = colorModeDynamic;
    490         }
    491 
    492         /****************************************************************
    493          ********** STEP 2b - RE-COMPUTE CACHE DATA *********************
    494          ****************************************************************/
    495         if (!computeCacheInSync) { // don't compute if the cache is good
    496             double minval = +1e10;
    497             double maxval = -1e10;
    498             WayPoint oldWp = null;
    499             if (colorModeDynamic) {
    500                 if (colored == colorModes.velocity) {
    501                     for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
    502                         if(!forceLines) {
    503                             oldWp = null;
    504                         }
    505                         for (WayPoint trkPnt : segment) {
    506                             LatLon c = trkPnt.getCoor();
    507                             if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    508                                 continue;
    509                             }
    510                             if (oldWp != null && trkPnt.time > oldWp.time) {
    511                                 double vel = c.greatCircleDistance(oldWp.getCoor())
    512                                         / (trkPnt.time - oldWp.time);
    513                                 if(vel > maxval) {
    514                                     maxval = vel;
    515                                 }
    516                                 if(vel < minval) {
    517                                     minval = vel;
    518                                 }
    519                             }
    520                             oldWp = trkPnt;
    521                         }
    522                     }
    523                 } else if (colored == colorModes.dilution) {
    524                     for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
    525                         for (WayPoint trkPnt : segment) {
    526                             Object val = trkPnt.attr.get("hdop");
    527                             if (val != null) {
    528                                 double hdop = ((Float) val).doubleValue();
    529                                 if(hdop > maxval) {
    530                                     maxval = hdop;
    531                                 }
    532                                 if(hdop < minval) {
    533                                     minval = hdop;
    534                                 }
    535                             }
    536                         }
    537                     }
    538                 }
    539                 oldWp = null;
    540             }
    541             double now = System.currentTimeMillis()/1000.0;
    542             if (colored == colorModes.time) {
    543                 Date[] bounds = getMinMaxTimeForAllTracks();
    544                 if (bounds!=null) {
    545                     minval = bounds[0].getTime()/1000.0;
    546                     maxval = bounds[1].getTime()/1000.0;
    547                 } else {
    548                     minval = 0; maxval=now;
    549                 }
    550             }
    551 
    552             for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
    553                 if (!forceLines) { // don't draw lines between segments, unless forced to
    554                     oldWp = null;
    555                 }
    556                 for (WayPoint trkPnt : segment) {
    557                     LatLon c = trkPnt.getCoor();
    558                     if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    559                         continue;
    560                     }
    561                     trkPnt.customColoring = neutralColor;
    562                     if (trkPnt.attr.get("hdop") != null) {
    563                         if (colored == colorModes.dilution) {
    564                             float hdop = ((Float) trkPnt.attr.get("hdop")).floatValue();
    565                             int hdoplvl =(int) Math.round(colorModeDynamic ? ((hdop-minval)*255/(maxval-minval))
    566                                     : (hdop <= 0 ? 0 : hdop * hdopfactor));
    567                             // High hdop is bad, but high values in colors are green.
    568                             // Therefore inverse the logic
    569                             int hdopcolor = 255 - (hdoplvl > 255 ? 255 : hdoplvl);
    570                             trkPnt.customColoring = colors[hdopcolor];
    571                             trkPnt.customColoringTransparent = hdopColors[hdopcolor];
    572                         } else {
    573                             trkPnt.customColoringTransparent = new Color(
    574                                     neutralColor.getRed(), neutralColor.getGreen(), neutralColor.getBlue(), hdopAlpha & 0xFF);
    575                         }
    576                     }
    577                     if (oldWp != null) {
    578                         double dist = c.greatCircleDistance(oldWp.getCoor());
    579                         boolean noDraw=false;
    580                         switch (colored) {
    581                         case velocity:
    582                             double dtime = trkPnt.time - oldWp.time;
    583                             if(dtime > 0) {
    584                                 float vel = (float) (dist / dtime);
    585                                 int velColor =(int) Math.round(colorModeDynamic ? ((vel-minval)*255/(maxval-minval))
    586                                         : (vel <= 0 ? 0 : vel / colorTracksTune * 255));
    587                                 final int vIndex = Math.max(0, Math.min(velColor, 255));
    588                                 trkPnt.customColoring = vIndex == 255 ? neutralColor : colors[vIndex];
    589                             } else {
    590                                 trkPnt.customColoring = neutralColor;
    591                             }
    592                             break;
    593                         case direction:
    594                             double dirColor = oldWp.getCoor().heading(trkPnt.getCoor()) / (2.0 * Math.PI) * 256;
    595                             // Bad case first
    596                             if (dirColor != dirColor || dirColor < 0.0 || dirColor >= 256.0) {
    597                                 trkPnt.customColoring = colors_cyclic[0];
    598                             } else {
    599                                 trkPnt.customColoring = colors_cyclic[(int) (dirColor)];
    600                             }
    601                             break;
    602                         case time:
    603                             double t=trkPnt.time;
    604                             if (t > 0 && t <= now && maxval - minval > 1000) { // skip bad timestamps and very short tracks
    605                                 int tColor = (int) Math.round((t-minval)*255/(maxval-minval));
    606                                 trkPnt.customColoring = colors[tColor];
    607                             } else {
    608                                 trkPnt.customColoring = neutralColor;
    609                             }
    610                             break;
    611                         }
    612 
    613                         if (!noDraw && (maxLineLength == -1 || dist <= maxLineLength)) {
    614                             trkPnt.drawLine = true;
    615                             trkPnt.dir = (int) oldWp.getCoor().heading(trkPnt.getCoor());
    616                         } else {
    617                             trkPnt.drawLine = false;
    618                         }
    619                     } else { // make sure we reset outdated data
    620                         trkPnt.drawLine = false;
    621                     }
    622                     oldWp = trkPnt;
    623                 }
    624             }
    625             computeCacheInSync = true;
    626         }
    627 
     284        LinkedList<WayPoint> visibleSegments = listVisibleSegments(box);
     285        if(!visibleSegments.isEmpty()) {
     286            drawHelper.readPreferences(getName());
     287            drawHelper.drawAll(g, mv, visibleSegments);
     288            if (Main.map.mapView.getActiveLayer() == this) {
     289                drawHelper.drawColorBar(g, mv);
     290            }
     291        }
     292       
     293    }
     294   
     295    private LinkedList<WayPoint> listVisibleSegments(Bounds box) {
     296        WayPoint last = null;
    628297        LinkedList<WayPoint> visibleSegments = new LinkedList<>();
    629         WayPoint last = null;
     298       
    630299        ensureTrackVisibilityLength();
    631300        for (Collection<WayPoint> segment : data.getLinesIterable(trackVisibility)) {
    632 
     301           
    633302            for(WayPoint pt : segment)
    634303            {
     
    655324            }
    656325        }
    657         if(visibleSegments.isEmpty())
    658             return;
    659 
    660         /****************************************************************
    661          ********** STEP 3a - DRAW LINES ********************************
    662          ****************************************************************/
    663         if (lines) {
    664             Point old = null;
    665             for (WayPoint trkPnt : visibleSegments) {
    666                 LatLon c = trkPnt.getCoor();
    667                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    668                     continue;
    669                 }
    670                 Point screen = mv.getPoint(trkPnt.getEastNorth());
    671                 if (trkPnt.drawLine) {
    672                     // skip points that are on the same screenposition
    673                     if (old != null && ((old.x != screen.x) || (old.y != screen.y))) {
    674                         g.setColor(trkPnt.customColoring);
    675                         g.drawLine(old.x, old.y, screen.x, screen.y);
    676                     }
    677                 }
    678                 old = screen;
    679             } // end for trkpnt
    680         } // end if lines
    681 
    682         /****************************************************************
    683          ********** STEP 3b - DRAW NICE ARROWS **************************
    684          ****************************************************************/
    685         if (lines && direction && !alternatedirection) {
    686             Point old = null;
    687             Point oldA = null; // last arrow painted
    688             for (WayPoint trkPnt : visibleSegments) {
    689                 LatLon c = trkPnt.getCoor();
    690                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    691                     continue;
    692                 }
    693                 if (trkPnt.drawLine) {
    694                     Point screen = mv.getPoint(trkPnt.getEastNorth());
    695                     // skip points that are on the same screenposition
    696                     if (old != null
    697                             && (oldA == null || screen.x < oldA.x - delta || screen.x > oldA.x + delta
    698                             || screen.y < oldA.y - delta || screen.y > oldA.y + delta)) {
    699                         g.setColor(trkPnt.customColoring);
    700                         double t = Math.atan2(screen.y - old.y, screen.x - old.x) + Math.PI;
    701                         g.drawLine(screen.x, screen.y, (int) (screen.x + 10 * Math.cos(t - PHI)),
    702                                 (int) (screen.y + 10 * Math.sin(t - PHI)));
    703                         g.drawLine(screen.x, screen.y, (int) (screen.x + 10 * Math.cos(t + PHI)),
    704                                 (int) (screen.y + 10 * Math.sin(t + PHI)));
    705                         oldA = screen;
    706                     }
    707                     old = screen;
    708                 }
    709             } // end for trkpnt
    710         } // end if lines
    711 
    712         /****************************************************************
    713          ********** STEP 3c - DRAW FAST ARROWS **************************
    714          ****************************************************************/
    715         if (lines && direction && alternatedirection) {
    716             Point old = null;
    717             Point oldA = null; // last arrow painted
    718             for (WayPoint trkPnt : visibleSegments) {
    719                 LatLon c = trkPnt.getCoor();
    720                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    721                     continue;
    722                 }
    723                 if (trkPnt.drawLine) {
    724                     Point screen = mv.getPoint(trkPnt.getEastNorth());
    725                     // skip points that are on the same screenposition
    726                     if (old != null
    727                             && (oldA == null || screen.x < oldA.x - delta || screen.x > oldA.x + delta
    728                             || screen.y < oldA.y - delta || screen.y > oldA.y + delta)) {
    729                         g.setColor(trkPnt.customColoring);
    730                         g.drawLine(screen.x, screen.y, screen.x + dir[trkPnt.dir][0], screen.y
    731                                 + dir[trkPnt.dir][1]);
    732                         g.drawLine(screen.x, screen.y, screen.x + dir[trkPnt.dir][2], screen.y
    733                                 + dir[trkPnt.dir][3]);
    734                         oldA = screen;
    735                     }
    736                     old = screen;
    737                 }
    738             } // end for trkpnt
    739         } // end if lines
    740 
    741         /****************************************************************
    742          ********** STEP 3d - DRAW LARGE POINTS AND HDOP CIRCLE *********
    743          ****************************************************************/
    744         if (large || hdopcircle) {
    745             final int halfSize = largesize/2;
    746             g.setColor(neutralColor);
    747             for (WayPoint trkPnt : visibleSegments) {
    748                 LatLon c = trkPnt.getCoor();
    749                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    750                     continue;
    751                 }
    752                 Point screen = mv.getPoint(trkPnt.getEastNorth());
    753                 if (!hdopcircle) {
    754                     // color the large GPS points like the gps lines
    755                     trkPnt.customColoringTransparent = new Color(
    756                         trkPnt.customColoring.getRed(), trkPnt.customColoring.getGreen(), trkPnt.customColoring.getBlue(), largePointAlpha);
    757                 }
    758                 g.setColor(trkPnt.customColoringTransparent);
    759                 if (hdopcircle && trkPnt.attr.get("hdop") != null) {
    760                     // hdop value
    761                     float hdop = ((Float)trkPnt.attr.get("hdop")).floatValue();
    762                     if (hdop < 0) {
    763                         hdop = 0;
    764                     }
    765                     // hdop pixels
    766                     int hdopp = mv.getPoint(new LatLon(trkPnt.getCoor().lat(), trkPnt.getCoor().lon() + 2*6*hdop*360/40000000)).x - screen.x;
    767                     g.drawArc(screen.x-hdopp/2, screen.y-hdopp/2, hdopp, hdopp, 0, 360);
    768                 }
    769                 if (large) {
    770                     g.fillRect(screen.x-halfSize, screen.y-halfSize, largesize, largesize);
    771                 }
    772             } // end for trkpnt
    773         } // end if large || hdopcircle
    774 
    775         /****************************************************************
    776          ********** STEP 3e - DRAW SMALL POINTS FOR LINES ***************
    777          ****************************************************************/
    778         if (!large && lines) {
    779             g.setColor(neutralColor);
    780             for (WayPoint trkPnt : visibleSegments) {
    781                 LatLon c = trkPnt.getCoor();
    782                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    783                     continue;
    784                 }
    785                 if (!trkPnt.drawLine) {
    786                     Point screen = mv.getPoint(trkPnt.getEastNorth());
    787                     g.drawRect(screen.x, screen.y, 0, 0);
    788                 }
    789             } // end for trkpnt
    790         } // end if large
    791 
    792         /****************************************************************
    793          ********** STEP 3f - DRAW SMALL POINTS INSTEAD OF LINES ********
    794          ****************************************************************/
    795         if (!large && !lines) {
    796             g.setColor(neutralColor);
    797             for (WayPoint trkPnt : visibleSegments) {
    798                 LatLon c = trkPnt.getCoor();
    799                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    800                     continue;
    801                 }
    802                 Point screen = mv.getPoint(trkPnt.getEastNorth());
    803                 g.setColor(trkPnt.customColoring);
    804                 g.drawRect(screen.x, screen.y, 0, 0);
    805             } // end for trkpnt
    806         } // end if large
    807 
    808         if(lineWidth != 0)
    809         {
    810             g.setStroke(storedStroke);
    811         }
    812     } // end paint
     326        return visibleSegments;
     327    }
    813328
    814329    @Override
     
    830345     * additional entries are initialized to true;
    831346     */
    832     private final void ensureTrackVisibilityLength() {
     347    private void ensureTrackVisibilityLength() {
    833348        final int l = data.tracks.size();
    834349        if (l == trackVisibility.length)
     
    844359    public void projectionChanged(Projection oldValue, Projection newValue) {
    845360        if (newValue == null) return;
    846         if (data.waypoints != null) {
    847             for (WayPoint wp : data.waypoints){
    848                 wp.invalidateEastNorthCache();
    849             }
    850         }
    851         if (data.tracks != null){
    852             for (GpxTrack track: data.tracks) {
    853                 for (GpxTrackSegment segment: track.getSegments()) {
    854                     for (WayPoint wp: segment.getWayPoints()) {
    855                         wp.invalidateEastNorthCache();
    856                     }
    857                 }
    858             }
    859         }
    860         if (data.routes != null) {
    861             for (GpxRoute route: data.routes) {
    862                 if (route.routePoints == null) {
    863                     continue;
    864                 }
    865                 for (WayPoint wp: route.routePoints) {
    866                     wp.invalidateEastNorthCache();
    867                 }
    868             }
    869         }
     361        data.resetEastNorthCache();
    870362    }
    871363
  • trunk/src/org/openstreetmap/josm/gui/layer/gpx/DateFilterPanel.java

    r6890 r7319  
    4747       
    4848        final Date startTime, endTime;
    49         Date[] bounds = layer.getMinMaxTimeForAllTracks();
     49        Date[] bounds = layer.data.getMinMaxTimeForAllTracks();
    5050        startTime = (bounds==null) ? new GregorianCalendar(2000, 1, 1).getTime():bounds[0];
    5151        endTime = (bounds==null) ? new Date() : bounds[1];
  • trunk/src/org/openstreetmap/josm/gui/layer/gpx/DownloadAlongTrackAction.java

    r6070 r7319  
    4444     */
    4545    public DownloadAlongTrackAction(GpxData data) {
    46         super(tr("Download from OSM along this track"), "downloadalongtrack", null, null, true);
     46        super(tr("Download from OSM along this track"), "downloadalongtrack", null, null, false);
    4747        this.data = data;
    4848    }
  • trunk/src/org/openstreetmap/josm/gui/preferences/display/ColorPreference.java

    r7005 r7319  
    3838import org.openstreetmap.josm.gui.conflict.ConflictColors;
    3939import org.openstreetmap.josm.gui.dialogs.ConflictDialog;
     40import org.openstreetmap.josm.gui.layer.gpx.GpxDrawHelper;
    4041import org.openstreetmap.josm.gui.layer.GpxLayer;
    4142import org.openstreetmap.josm.gui.layer.ImageryLayer;
     
    266267        Severity.getColors();
    267268        MarkerLayer.getGenericColor();
    268         GpxLayer.getGenericColor();
     269        GpxDrawHelper.getGenericColor();
    269270        OsmDataLayer.getOutsideColor();
    270271        ImageryLayer.getFadeColor();
Note: See TracChangeset for help on using the changeset viewer.