Changeset 6206 in josm for trunk/src/org/openstreetmap


Ignore:
Timestamp:
2013-08-28T12:15:41+02:00 (11 years ago)
Author:
bastiK
Message:

fixed #8323 - Add support for GPX routes (<rte> element)

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

Legend:

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

    r6069 r6206  
    55import java.io.File;
    66import java.util.Collection;
     7import java.util.Iterator;
    78import java.util.LinkedList;
    89import java.util.Map;
     
    238239        return best;
    239240    }
     241
     242    /**
     243     * Iterate over all track segments and over all routes.
     244     *
     245     * @param trackVisibility An array indicating which tracks should be
     246     * included in the iteration. Can be null, then all tracks are included.
     247     * @return an Iterable object, which iterates over all track segments and
     248     * over all routes
     249     */
     250    public Iterable<Collection<WayPoint>> getLinesIterable(final boolean[] trackVisibility) {
     251        return new Iterable<Collection<WayPoint>>() {
     252            @Override
     253            public Iterator<Collection<WayPoint>> iterator() {
     254                return new LinesIterator(GpxData.this, trackVisibility);
     255            }
     256        };
     257    }
     258   
     259    /**
     260     * Iterates over all track segments and then over all routes.
     261     */
     262    public static class LinesIterator implements Iterator<Collection<WayPoint>> {
     263
     264        private Iterator<GpxTrack> itTracks;
     265        private int idxTracks;
     266        private Iterator<GpxTrackSegment> itTrackSegments;
     267        private Iterator<GpxRoute> itRoutes;
     268
     269        private Collection<WayPoint> next;
     270        private boolean[] trackVisibility;
     271
     272        public LinesIterator(GpxData data, boolean[] trackVisibility) {
     273            itTracks = data.tracks.iterator();
     274            idxTracks = -1;
     275            itRoutes = data.routes.iterator();
     276            this.trackVisibility = trackVisibility;
     277            next = getNext();
     278        }
     279
     280        @Override
     281        public boolean hasNext() {
     282            return next != null;
     283        }
     284
     285        @Override
     286        public Collection<WayPoint> next() {
     287            Collection<WayPoint> current = next;
     288            next = getNext();
     289            return current;
     290        }
     291
     292        private Collection<WayPoint> getNext() {
     293            if (itTracks != null) {
     294                if (itTrackSegments != null && itTrackSegments.hasNext()) {
     295                    return itTrackSegments.next().getWayPoints();
     296                } else {
     297                    while (itTracks.hasNext()) {
     298                        GpxTrack nxtTrack = itTracks.next();
     299                        idxTracks++;
     300                        if (trackVisibility != null && !trackVisibility[idxTracks])
     301                            continue;
     302                        itTrackSegments = nxtTrack.getSegments().iterator();
     303                        if (itTrackSegments.hasNext()) {
     304                            return itTrackSegments.next().getWayPoints();
     305                        }
     306                    }
     307                    // if we get here, all the Tracks are finished; Continue with
     308                    // Routes
     309                    itTracks = null;
     310                }
     311            }
     312            if (itRoutes.hasNext()) {
     313                return itRoutes.next().routePoints;
     314            }
     315            return null;
     316        }
     317
     318        @Override
     319        public void remove() {
     320            throw new UnsupportedOperationException();
     321        }
     322    }
     323   
    240324}
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r6102 r6206  
    1717import java.text.DateFormat;
    1818import java.util.ArrayList;
     19import java.util.Collection;
    1920import java.util.Date;
    2021import java.util.LinkedList;
     
    489490            if (colorModeDynamic) {
    490491                if (colored == colorModes.velocity) {
    491                     for (GpxTrack trk : data.tracks) {
    492                         for (GpxTrackSegment segment : trk.getSegments()) {
    493                             if(!forceLines) {
    494                                 oldWp = null;
     492                    for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
     493                        if(!forceLines) {
     494                            oldWp = null;
     495                        }
     496                        for (WayPoint trkPnt : segment) {
     497                            LatLon c = trkPnt.getCoor();
     498                            if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
     499                                continue;
    495500                            }
    496                             for (WayPoint trkPnt : segment.getWayPoints()) {
    497                                 LatLon c = trkPnt.getCoor();
    498                                 if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    499                                     continue;
     501                            if (oldWp != null && trkPnt.time > oldWp.time) {
     502                                double vel = c.greatCircleDistance(oldWp.getCoor())
     503                                        / (trkPnt.time - oldWp.time);
     504                                if(vel > maxval) {
     505                                    maxval = vel;
    500506                                }
    501                                 if (oldWp != null && trkPnt.time > oldWp.time) {
    502                                     double vel = c.greatCircleDistance(oldWp.getCoor())
    503                                             / (trkPnt.time - oldWp.time);
    504                                     if(vel > maxval) {
    505                                         maxval = vel;
    506                                     }
    507                                     if(vel < minval) {
    508                                         minval = vel;
    509                                     }
     507                                if(vel < minval) {
     508                                    minval = vel;
    510509                                }
    511                                 oldWp = trkPnt;
    512510                            }
     511                            oldWp = trkPnt;
    513512                        }
    514513                    }
    515514                } else if (colored == colorModes.dilution) {
    516                     for (GpxTrack trk : data.tracks) {
    517                         for (GpxTrackSegment segment : trk.getSegments()) {
    518                             for (WayPoint trkPnt : segment.getWayPoints()) {
    519                                 Object val = trkPnt.attr.get("hdop");
    520                                 if (val != null) {
    521                                     double hdop = ((Float) val).doubleValue();
    522                                     if(hdop > maxval) {
    523                                         maxval = hdop;
    524                                     }
    525                                     if(hdop < minval) {
    526                                         minval = hdop;
    527                                     }
     515                    for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
     516                        for (WayPoint trkPnt : segment) {
     517                            Object val = trkPnt.attr.get("hdop");
     518                            if (val != null) {
     519                                double hdop = ((Float) val).doubleValue();
     520                                if(hdop > maxval) {
     521                                    maxval = hdop;
     522                                }
     523                                if(hdop < minval) {
     524                                    minval = hdop;
    528525                                }
    529526                            }
     
    544541            }
    545542
    546             for (GpxTrack trk : data.tracks) {
    547                 for (GpxTrackSegment segment : trk.getSegments()) {
    548                     if (!forceLines) { // don't draw lines between segments, unless forced to
    549                         oldWp = null;
    550                     }
    551                     for (WayPoint trkPnt : segment.getWayPoints()) {
    552                         LatLon c = trkPnt.getCoor();
    553                         if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
    554                             continue;
     543            for (Collection<WayPoint> segment : data.getLinesIterable(null)) {
     544                if (!forceLines) { // don't draw lines between segments, unless forced to
     545                    oldWp = null;
     546                }
     547                for (WayPoint trkPnt : segment) {
     548                    LatLon c = trkPnt.getCoor();
     549                    if (Double.isNaN(c.lat()) || Double.isNaN(c.lon())) {
     550                        continue;
     551                    }
     552                    trkPnt.customColoring = neutralColor;
     553                    if(colored == colorModes.dilution && trkPnt.attr.get("hdop") != null) {
     554                        float hdop = ((Float) trkPnt.attr.get("hdop")).floatValue();
     555                        int hdoplvl =(int) Math.round(colorModeDynamic ? ((hdop-minval)*255/(maxval-minval))
     556                                : (hdop <= 0 ? 0 : hdop * hdopfactor));
     557                        // High hdop is bad, but high values in colors are green.
     558                        // Therefore inverse the logic
     559                        int hdopcolor = 255 - (hdoplvl > 255 ? 255 : hdoplvl);
     560                        trkPnt.customColoring = colors[hdopcolor];
     561                    }
     562                    if (oldWp != null) {
     563                        double dist = c.greatCircleDistance(oldWp.getCoor());
     564                        boolean noDraw=false;
     565                        switch (colored) {
     566                        case velocity:
     567                            double dtime = trkPnt.time - oldWp.time;
     568                            if(dtime > 0) {
     569                                float vel = (float) (dist / dtime);
     570                                int velColor =(int) Math.round(colorModeDynamic ? ((vel-minval)*255/(maxval-minval))
     571                                        : (vel <= 0 ? 0 : vel / colorTracksTune * 255));
     572                                trkPnt.customColoring = colors[Math.max(0, Math.min(velColor, 255))];
     573                            } else {
     574                                trkPnt.customColoring = colors[255];
     575                            }
     576                            break;
     577                        case direction:
     578                            double dirColor = oldWp.getCoor().heading(trkPnt.getCoor()) / (2.0 * Math.PI) * 256;
     579                            // Bad case first
     580                            if (dirColor != dirColor || dirColor < 0.0 || dirColor >= 256.0) {
     581                                trkPnt.customColoring = colors_cyclic[0];
     582                            } else {
     583                                trkPnt.customColoring = colors_cyclic[(int) (dirColor)];
     584                            }
     585                            break;
     586                        case time:
     587                            double t=trkPnt.time;
     588                            if (t>0 && t<=now){ // skip bad timestamps
     589                                int tColor = (int) Math.round((t-minval)*255/(maxval-minval));
     590                                trkPnt.customColoring = colors[tColor];
     591                            } else {
     592                                trkPnt.customColoring = neutralColor;
     593                            }
     594                            break;
    555595                        }
    556                         trkPnt.customColoring = neutralColor;
    557                         if(colored == colorModes.dilution && trkPnt.attr.get("hdop") != null) {
    558                             float hdop = ((Float) trkPnt.attr.get("hdop")).floatValue();
    559                             int hdoplvl =(int) Math.round(colorModeDynamic ? ((hdop-minval)*255/(maxval-minval))
    560                                     : (hdop <= 0 ? 0 : hdop * hdopfactor));
    561                             // High hdop is bad, but high values in colors are green.
    562                             // Therefore inverse the logic
    563                             int hdopcolor = 255 - (hdoplvl > 255 ? 255 : hdoplvl);
    564                             trkPnt.customColoring = colors[hdopcolor];
    565                         }
    566                         if (oldWp != null) {
    567                             double dist = c.greatCircleDistance(oldWp.getCoor());
    568                             boolean noDraw=false;
    569                             switch (colored) {
    570                             case velocity:
    571                                 double dtime = trkPnt.time - oldWp.time;
    572                                 if(dtime > 0) {
    573                                     float vel = (float) (dist / dtime);
    574                                     int velColor =(int) Math.round(colorModeDynamic ? ((vel-minval)*255/(maxval-minval))
    575                                             : (vel <= 0 ? 0 : vel / colorTracksTune * 255));
    576                                     trkPnt.customColoring = colors[Math.max(0, Math.min(velColor, 255))];
    577                                 } else {
    578                                     trkPnt.customColoring = colors[255];
    579                                 }
    580                                 break;
    581                             case direction:
    582                                 double dirColor = oldWp.getCoor().heading(trkPnt.getCoor()) / (2.0 * Math.PI) * 256;
    583                                 // Bad case first
    584                                 if (dirColor != dirColor || dirColor < 0.0 || dirColor >= 256.0) {
    585                                     trkPnt.customColoring = colors_cyclic[0];
    586                                 } else {
    587                                     trkPnt.customColoring = colors_cyclic[(int) (dirColor)];
    588                                 }
    589                                 break;
    590                             case time:
    591                                 double t=trkPnt.time;
    592                                 if (t>0 && t<=now){ // skip bad timestamps
    593                                     int tColor = (int) Math.round((t-minval)*255/(maxval-minval));
    594                                     trkPnt.customColoring = colors[tColor];
    595                                 } else {
    596                                     trkPnt.customColoring = neutralColor;
    597                                 }
    598                                 break;
    599                             }
    600 
    601                             if (!noDraw && (maxLineLength == -1 || dist <= maxLineLength)) {
    602                                 trkPnt.drawLine = true;
    603                                 trkPnt.dir = (int) oldWp.getCoor().heading(trkPnt.getCoor());
    604                             } else {
    605                                 trkPnt.drawLine = false;
    606                             }
    607                         } else { // make sure we reset outdated data
     596
     597                        if (!noDraw && (maxLineLength == -1 || dist <= maxLineLength)) {
     598                            trkPnt.drawLine = true;
     599                            trkPnt.dir = (int) oldWp.getCoor().heading(trkPnt.getCoor());
     600                        } else {
    608601                            trkPnt.drawLine = false;
    609602                        }
    610                         oldWp = trkPnt;
    611                     }
     603                    } else { // make sure we reset outdated data
     604                        trkPnt.drawLine = false;
     605                    }
     606                    oldWp = trkPnt;
    612607                }
    613608            }
     
    619614        int i = 0;
    620615        ensureTrackVisibilityLength();
    621         for (GpxTrack trk: data.tracks) {
    622             // hide tracks that were de-selected in ChooseTrackVisibilityAction
    623             if(!trackVisibility[i++]) {
    624                 continue;
    625             }
    626 
    627             for (GpxTrackSegment trkSeg: trk.getSegments()) {
    628                 for(WayPoint pt : trkSeg.getWayPoints())
     616        for (Collection<WayPoint> segment : data.getLinesIterable(trackVisibility)) {
     617
     618            for(WayPoint pt : segment)
     619            {
     620                Bounds b = new Bounds(pt.getCoor());
     621                // last should never be null when this is true!
     622                if(pt.drawLine) {
     623                    b.extend(last.getCoor());
     624                }
     625                if(b.intersects(box))
    629626                {
    630                     Bounds b = new Bounds(pt.getCoor());
    631                     // last should never be null when this is true!
    632                     if(pt.drawLine) {
    633                         b.extend(last.getCoor());
    634                     }
    635                     if(b.intersects(box))
    636                     {
    637                         if(last != null && (visibleSegments.isEmpty()
    638                                 || visibleSegments.getLast() != last)) {
    639                             if(last.drawLine) {
    640                                 WayPoint l = new WayPoint(last);
    641                                 l.drawLine = false;
    642                                 visibleSegments.add(l);
    643                             } else {
    644                                 visibleSegments.add(last);
    645                             }
     627                    if(last != null && (visibleSegments.isEmpty()
     628                            || visibleSegments.getLast() != last)) {
     629                        if(last.drawLine) {
     630                            WayPoint l = new WayPoint(last);
     631                            l.drawLine = false;
     632                            visibleSegments.add(l);
     633                        } else {
     634                            visibleSegments.add(last);
    646635                        }
    647                         visibleSegments.add(pt);
    648                     }
    649                     last = pt;
    650                 }
     636                    }
     637                    visibleSegments.add(pt);
     638                }
     639                last = pt;
    651640            }
    652641        }
Note: See TracChangeset for help on using the changeset viewer.