Ignore:
Timestamp:
2013-01-27T18:36:34+01:00 (11 years ago)
Author:
bastiK
Message:

fixed #2900 - Saving and reopening of downloaded gpx segments displays distorted data (see #7247; namespace aware xml parsing is needed now, so #7247 is open again)

Location:
trunk/src/org/openstreetmap/josm/io
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/BoundingBoxDownloader.java

    r5494 r5679  
    4444            GpxReader reader = new GpxReader(in);
    4545            gpxParsedProperly = reader.parse(false);
    46             GpxData currentGpx = reader.data;
     46            GpxData currentGpx = reader.getGpxData();
    4747            if (result == null) {
    4848                result = currentGpx;
  • trunk/src/org/openstreetmap/josm/io/GpxImporter.java

    r5501 r5679  
    8989            GpxReader r = new GpxReader(is);
    9090            boolean parsedProperly = r.parse(true);
    91             r.data.storageFile = file;
    92             addLayers(loadLayers(r.data, parsedProperly, fileName, tr("Markers from {0}", fileName)));
     91            r.getGpxData().storageFile = file;
     92            addLayers(loadLayers(r.getGpxData(), parsedProperly, fileName, tr("Markers from {0}", fileName)));
    9393        } catch (SAXException e) {
    9494            e.printStackTrace();
     
    163163            final GpxReader r = new GpxReader(is);
    164164            final boolean parsedProperly = r.parse(true);
    165             r.data.storageFile = associatedFile;
    166             return loadLayers(r.data, parsedProperly, gpxLayerName, markerLayerName);
     165            r.getGpxData().storageFile = associatedFile;
     166            return loadLayers(r.getGpxData(), parsedProperly, gpxLayerName, markerLayerName);
    167167        } catch (SAXException e) {
    168168            e.printStackTrace();
  • trunk/src/org/openstreetmap/josm/io/GpxReader.java

    r5590 r5679  
    2020
    2121import org.openstreetmap.josm.data.coor.LatLon;
     22import org.openstreetmap.josm.data.gpx.Extensions;
    2223import org.openstreetmap.josm.data.gpx.GpxData;
    2324import org.openstreetmap.josm.data.gpx.GpxLink;
     
    4445     * The resulting gpx data
    4546     */
    46     public GpxData data;
     47    private GpxData gpxData;
    4748    private enum State { init, gpx, metadata, wpt, rte, trk, ext, author, link, trkseg, copyright}
    4849    private InputSource inputSource;
     
    5051    private class Parser extends DefaultHandler {
    5152
    52         private GpxData currentData;
     53        private GpxData data;
    5354        private Collection<Collection<WayPoint>> currentTrack;
    5455        private Map<String, Object> currentTrackAttr;
     
    6061
    6162        private GpxLink currentLink;
     63        private Extensions currentExtensions;
    6264        private Stack<State> states;
    6365        private final Stack<String> elements = new Stack<String>();
     
    7072            accumulator = new StringBuffer();
    7173            states = new Stack<State>();
    72             currentData = new GpxData();
     74            data = new GpxData();
    7375        }
    7476
     
    8890
    8991        @Override public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
    90             elements.push(qName);
     92            elements.push(localName);
    9193            switch(currentState) {
    9294            case init:
    9395                states.push(currentState);
    9496                currentState = State.gpx;
    95                 currentData.creator = atts.getValue("creator");
     97                data.creator = atts.getValue("creator");
    9698                version = atts.getValue("version");
    9799                if (version != null && version.startsWith("1.0")) {
     
    103105                break;
    104106            case gpx:
    105                 if (qName.equals("metadata")) {
     107                if (localName.equals("metadata")) {
    106108                    states.push(currentState);
    107109                    currentState = State.metadata;
    108                 } else if (qName.equals("wpt")) {
     110                } else if (localName.equals("wpt")) {
    109111                    states.push(currentState);
    110112                    currentState = State.wpt;
    111113                    currentWayPoint = new WayPoint(parseLatLon(atts));
    112                 } else if (qName.equals("rte")) {
     114                } else if (localName.equals("rte")) {
    113115                    states.push(currentState);
    114116                    currentState = State.rte;
    115117                    currentRoute = new GpxRoute();
    116                 } else if (qName.equals("trk")) {
     118                } else if (localName.equals("trk")) {
    117119                    states.push(currentState);
    118120                    currentState = State.trk;
    119121                    currentTrack = new ArrayList<Collection<WayPoint>>();
    120122                    currentTrackAttr = new HashMap<String, Object>();
    121                 } else if (qName.equals("extensions")) {
     123                } else if (localName.equals("extensions")) {
    122124                    states.push(currentState);
    123125                    currentState = State.ext;
    124                 } else if (qName.equals("gpx") && atts.getValue("creator") != null && atts.getValue("creator").startsWith("Nokia Sports Tracker")) {
     126                    currentExtensions = new Extensions();
     127                } else if (localName.equals("gpx") && atts.getValue("creator") != null && atts.getValue("creator").startsWith("Nokia Sports Tracker")) {
    125128                    nokiaSportsTrackerBug = true;
    126129                }
    127130                break;
    128131            case metadata:
    129                 if (qName.equals("author")) {
     132                if (localName.equals("author")) {
    130133                    states.push(currentState);
    131134                    currentState = State.author;
    132                 } else if (qName.equals("extensions")) {
     135                } else if (localName.equals("extensions")) {
    133136                    states.push(currentState);
    134137                    currentState = State.ext;
    135                 } else if (qName.equals("copyright")) {
     138                    currentExtensions = new Extensions();
     139                } else if (localName.equals("copyright")) {
    136140                    states.push(currentState);
    137141                    currentState = State.copyright;
    138                     currentData.attr.put(GpxData.META_COPYRIGHT_AUTHOR, atts.getValue("author"));
    139                 } else if (qName.equals("link")) {
     142                    data.attr.put(GpxData.META_COPYRIGHT_AUTHOR, atts.getValue("author"));
     143                } else if (localName.equals("link")) {
    140144                    states.push(currentState);
    141145                    currentState = State.link;
     
    144148                break;
    145149            case author:
    146                 if (qName.equals("link")) {
     150                if (localName.equals("link")) {
    147151                    states.push(currentState);
    148152                    currentState = State.link;
    149153                    currentLink = new GpxLink(atts.getValue("href"));
    150                 } else if (qName.equals("email")) {
    151                     currentData.attr.put(GpxData.META_AUTHOR_EMAIL, atts.getValue("id") + "@" + atts.getValue("domain"));
     154                } else if (localName.equals("email")) {
     155                    data.attr.put(GpxData.META_AUTHOR_EMAIL, atts.getValue("id") + "@" + atts.getValue("domain"));
    152156                }
    153157                break;
    154158            case trk:
    155                 if (qName.equals("trkseg")) {
     159                if (localName.equals("trkseg")) {
    156160                    states.push(currentState);
    157161                    currentState = State.trkseg;
    158162                    currentTrackSeg = new ArrayList<WayPoint>();
    159                 } else if (qName.equals("link")) {
     163                } else if (localName.equals("link")) {
    160164                    states.push(currentState);
    161165                    currentState = State.link;
    162166                    currentLink = new GpxLink(atts.getValue("href"));
    163                 } else if (qName.equals("extensions")) {
     167                } else if (localName.equals("extensions")) {
    164168                    states.push(currentState);
    165169                    currentState = State.ext;
     170                    currentExtensions = new Extensions();
    166171                }
    167172                break;
    168173            case trkseg:
    169                 if (qName.equals("trkpt")) {
     174                if (localName.equals("trkpt")) {
    170175                    states.push(currentState);
    171176                    currentState = State.wpt;
     
    174179                break;
    175180            case wpt:
    176                 if (qName.equals("link")) {
     181                if (localName.equals("link")) {
    177182                    states.push(currentState);
    178183                    currentState = State.link;
    179184                    currentLink = new GpxLink(atts.getValue("href"));
    180                 } else if (qName.equals("extensions")) {
     185                } else if (localName.equals("extensions")) {
    181186                    states.push(currentState);
    182187                    currentState = State.ext;
     188                    currentExtensions = new Extensions();
    183189                }
    184190                break;
    185191            case rte:
    186                 if (qName.equals("link")) {
     192                if (localName.equals("link")) {
    187193                    states.push(currentState);
    188194                    currentState = State.link;
    189195                    currentLink = new GpxLink(atts.getValue("href"));
    190                 } else if (qName.equals("rtept")) {
     196                } else if (localName.equals("rtept")) {
    191197                    states.push(currentState);
    192198                    currentState = State.wpt;
    193199                    currentWayPoint = new WayPoint(parseLatLon(atts));
    194                 } else if (qName.equals("extensions")) {
     200                } else if (localName.equals("extensions")) {
    195201                    states.push(currentState);
    196202                    currentState = State.ext;
    197                 }
    198                 break;
    199             default:
     203                    currentExtensions = new Extensions();
     204                }
     205                break;
    200206            }
    201207            accumulator.setLength(0);
     
    223229            switch (currentState) {
    224230            case rte: return currentRoute.attr;
    225             case metadata: return currentData.attr;
     231            case metadata: return data.attr;
    226232            case wpt: return currentWayPoint.attr;
    227233            case trk: return currentTrackAttr;
     
    236242            case gpx:       // GPX 1.0
    237243            case metadata:  // GPX 1.1
    238                 if (qName.equals("name")) {
    239                     currentData.attr.put(GpxData.META_NAME, accumulator.toString());
    240                 } else if (qName.equals("desc")) {
    241                     currentData.attr.put(GpxData.META_DESC, accumulator.toString());
    242                 } else if (qName.equals("time")) {
    243                     currentData.attr.put(GpxData.META_TIME, accumulator.toString());
    244                 } else if (qName.equals("keywords")) {
    245                     currentData.attr.put(GpxData.META_KEYWORDS, accumulator.toString());
    246                 } else if (version.equals("1.0") && qName.equals("author")) {
     244                if (localName.equals("name")) {
     245                    data.attr.put(GpxData.META_NAME, accumulator.toString());
     246                } else if (localName.equals("desc")) {
     247                    data.attr.put(GpxData.META_DESC, accumulator.toString());
     248                } else if (localName.equals("time")) {
     249                    data.attr.put(GpxData.META_TIME, accumulator.toString());
     250                } else if (localName.equals("keywords")) {
     251                    data.attr.put(GpxData.META_KEYWORDS, accumulator.toString());
     252                } else if (version.equals("1.0") && localName.equals("author")) {
    247253                    // author is a string in 1.0, but complex element in 1.1
    248                     currentData.attr.put(GpxData.META_AUTHOR_NAME, accumulator.toString());
    249                 } else if (version.equals("1.0") && qName.equals("email")) {
    250                     currentData.attr.put(GpxData.META_AUTHOR_EMAIL, accumulator.toString());
    251                 } else if (qName.equals("url") || qName.equals("urlname")) {
    252                     currentData.attr.put(qName, accumulator.toString());
    253                 } else if ((currentState == State.metadata && qName.equals("metadata")) ||
    254                         (currentState == State.gpx && qName.equals("gpx"))) {
    255                     convertUrlToLink(currentData.attr);
     254                    data.attr.put(GpxData.META_AUTHOR_NAME, accumulator.toString());
     255                } else if (version.equals("1.0") && localName.equals("email")) {
     256                    data.attr.put(GpxData.META_AUTHOR_EMAIL, accumulator.toString());
     257                } else if (localName.equals("url") || localName.equals("urlname")) {
     258                    data.attr.put(localName, accumulator.toString());
     259                } else if ((currentState == State.metadata && localName.equals("metadata")) ||
     260                        (currentState == State.gpx && localName.equals("gpx"))) {
     261                    convertUrlToLink(data.attr);
     262                    if (currentExtensions != null && !currentExtensions.isEmpty()) {
     263                        data.attr.put(GpxData.META_EXTENSIONS, currentExtensions);
     264                    }
    256265                    currentState = states.pop();
    257266                }
     
    259268                break;
    260269            case author:
    261                 if (qName.equals("author")) {
    262                     currentState = states.pop();
    263                 } else if (qName.equals("name")) {
    264                     currentData.attr.put(GpxData.META_AUTHOR_NAME, accumulator.toString());
    265                 } else if (qName.equals("email")) {
     270                if (localName.equals("author")) {
     271                    currentState = states.pop();
     272                } else if (localName.equals("name")) {
     273                    data.attr.put(GpxData.META_AUTHOR_NAME, accumulator.toString());
     274                } else if (localName.equals("email")) {
    266275                    // do nothing, has been parsed on startElement
    267                 } else if (qName.equals("link")) {
    268                     currentData.attr.put(GpxData.META_AUTHOR_LINK, currentLink);
     276                } else if (localName.equals("link")) {
     277                    data.attr.put(GpxData.META_AUTHOR_LINK, currentLink);
    269278                }
    270279                break;
    271280            case copyright:
    272                 if (qName.equals("copyright")) {
    273                     currentState = states.pop();
    274                 } else if (qName.equals("year")) {
    275                     currentData.attr.put(GpxData.META_COPYRIGHT_YEAR, accumulator.toString());
    276                 } else if (qName.equals("license")) {
    277                     currentData.attr.put(GpxData.META_COPYRIGHT_LICENSE, accumulator.toString());
     281                if (localName.equals("copyright")) {
     282                    currentState = states.pop();
     283                } else if (localName.equals("year")) {
     284                    data.attr.put(GpxData.META_COPYRIGHT_YEAR, accumulator.toString());
     285                } else if (localName.equals("license")) {
     286                    data.attr.put(GpxData.META_COPYRIGHT_LICENSE, accumulator.toString());
    278287                }
    279288                break;
    280289            case link:
    281                 if (qName.equals("text")) {
     290                if (localName.equals("text")) {
    282291                    currentLink.text = accumulator.toString();
    283                 } else if (qName.equals("type")) {
     292                } else if (localName.equals("type")) {
    284293                    currentLink.type = accumulator.toString();
    285                 } else if (qName.equals("link")) {
     294                } else if (localName.equals("link")) {
    286295                    if (currentLink.uri == null && accumulator != null && accumulator.toString().length() != 0) {
    287296                        currentLink = new GpxLink(accumulator.toString());
     
    290299                }
    291300                if (currentState == State.author) {
    292                     currentData.attr.put(GpxData.META_AUTHOR_LINK, currentLink);
     301                    data.attr.put(GpxData.META_AUTHOR_LINK, currentLink);
    293302                } else if (currentState != State.link) {
    294303                    Map<String, Object> attr = getAttr();
     
    300309                break;
    301310            case wpt:
    302                 if (   qName.equals("ele")  || qName.equals("magvar")
    303                         || qName.equals("name") || qName.equals("src")
    304                         || qName.equals("geoidheight") || qName.equals("type")
    305                         || qName.equals("sym") || qName.equals("url")
    306                         || qName.equals("urlname")) {
    307                     currentWayPoint.attr.put(qName, accumulator.toString());
    308                 } else if(qName.equals("hdop") || qName.equals("vdop") ||
    309                         qName.equals("pdop")) {
     311                if (   localName.equals("ele")  || localName.equals("magvar")
     312                        || localName.equals("name") || localName.equals("src")
     313                        || localName.equals("geoidheight") || localName.equals("type")
     314                        || localName.equals("sym") || localName.equals("url")
     315                        || localName.equals("urlname")) {
     316                    currentWayPoint.attr.put(localName, accumulator.toString());
     317                } else if(localName.equals("hdop") || localName.equals("vdop") ||
     318                        localName.equals("pdop")) {
    310319                    try {
    311                         currentWayPoint.attr.put(qName, Float.parseFloat(accumulator.toString()));
     320                        currentWayPoint.attr.put(localName, Float.parseFloat(accumulator.toString()));
    312321                    } catch(Exception e) {
    313                         currentWayPoint.attr.put(qName, new Float(0));
     322                        currentWayPoint.attr.put(localName, new Float(0));
    314323                    }
    315                 } else if (qName.equals("time")) {
    316                     currentWayPoint.attr.put(qName, accumulator.toString());
     324                } else if (localName.equals("time")) {
     325                    currentWayPoint.attr.put(localName, accumulator.toString());
    317326                    currentWayPoint.setTime();
    318                 } else if (qName.equals("cmt") || qName.equals("desc")) {
    319                     currentWayPoint.attr.put(qName, accumulator.toString());
     327                } else if (localName.equals("cmt") || localName.equals("desc")) {
     328                    currentWayPoint.attr.put(localName, accumulator.toString());
    320329                    currentWayPoint.setTime();
    321                 } else if (qName.equals("rtept")) {
     330                } else if (localName.equals("rtept")) {
    322331                    currentState = states.pop();
    323332                    convertUrlToLink(currentWayPoint.attr);
    324333                    currentRoute.routePoints.add(currentWayPoint);
    325                 } else if (qName.equals("trkpt")) {
     334                } else if (localName.equals("trkpt")) {
    326335                    currentState = states.pop();
    327336                    convertUrlToLink(currentWayPoint.attr);
    328337                    currentTrackSeg.add(currentWayPoint);
    329                 } else if (qName.equals("wpt")) {
     338                } else if (localName.equals("wpt")) {
    330339                    currentState = states.pop();
    331340                    convertUrlToLink(currentWayPoint.attr);
    332                     currentData.waypoints.add(currentWayPoint);
     341                    data.waypoints.add(currentWayPoint);
    333342                }
    334343                break;
    335344            case trkseg:
    336                 if (qName.equals("trkseg")) {
     345                if (localName.equals("trkseg")) {
    337346                    currentState = states.pop();
    338347                    currentTrack.add(currentTrackSeg);
     
    340349                break;
    341350            case trk:
    342                 if (qName.equals("trk")) {
     351                if (localName.equals("trk")) {
    343352                    currentState = states.pop();
    344353                    convertUrlToLink(currentTrackAttr);
    345                     currentData.tracks.add(new ImmutableGpxTrack(currentTrack, currentTrackAttr));
    346                 } else if (qName.equals("name") || qName.equals("cmt")
    347                         || qName.equals("desc") || qName.equals("src")
    348                         || qName.equals("type") || qName.equals("number")
    349                         || qName.equals("url") || qName.equals("urlname")) {
    350                     currentTrackAttr.put(qName, accumulator.toString());
     354                    data.tracks.add(new ImmutableGpxTrack(currentTrack, currentTrackAttr));
     355                } else if (localName.equals("name") || localName.equals("cmt")
     356                        || localName.equals("desc") || localName.equals("src")
     357                        || localName.equals("type") || localName.equals("number")
     358                        || localName.equals("url") || localName.equals("urlname")) {
     359                    currentTrackAttr.put(localName, accumulator.toString());
    351360                }
    352361                break;
    353362            case ext:
    354                 if (qName.equals("extensions")) {
    355                     currentState = states.pop();
     363                if (localName.equals("extensions")) {
     364                    currentState = states.pop();
     365                // only interested in extensions written by JOSM
     366                } else if (GpxData.JOSM_EXTENSIONS_NAMESPACE_URI.equals(namespaceURI)) {
     367                    currentExtensions.put(localName, accumulator.toString());
    356368                }
    357369                break;
    358370            default:
    359                 if (qName.equals("wpt")) {
    360                     currentState = states.pop();
    361                 } else if (qName.equals("rte")) {
     371                if (localName.equals("wpt")) {
     372                    currentState = states.pop();
     373                } else if (localName.equals("rte")) {
    362374                    currentState = states.pop();
    363375                    convertUrlToLink(currentRoute.attr);
    364                     currentData.routes.add(currentRoute);
     376                    data.routes.add(currentRoute);
    365377                }
    366378            }
     
    370382            if (!states.empty())
    371383                throw new SAXException(tr("Parse error: invalid document structure for GPX document."));
    372             data = currentData;
     384            Extensions metaExt = (Extensions) data.attr.get(GpxData.META_EXTENSIONS);
     385            if (metaExt != null && "true".equals(metaExt.get("from-server"))) {
     386                data.fromServer = true;
     387            }
     388            gpxData = data;
    373389        }
    374390
     
    418434        try {
    419435            SAXParserFactory factory = SAXParserFactory.newInstance();
    420             // support files with invalid xml namespace declarations (see #7247)
    421             factory.setNamespaceAware(false);
     436            factory.setNamespaceAware(true);
    422437            factory.newSAXParser().parse(inputSource, parser);
    423438            return true;
     
    425440            if (tryToFinish) {
    426441                parser.tryToFinish();
    427                 if (parser.currentData.isEmpty())
     442                if (parser.data.isEmpty())
    428443                    throw e;
    429444                return false;
     
    435450        }
    436451    }
     452
     453    public GpxData getGpxData() {
     454        return gpxData;
     455    }
    437456}
  • trunk/src/org/openstreetmap/josm/io/GpxWriter.java

    r5397 r5679  
    5252        out.println("<?xml version='1.0' encoding='UTF-8'?>");
    5353        out.println("<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
     54                (data.fromServer ? String.format("    xmlns:josm=\"%s\"\n", GpxData.JOSM_EXTENSIONS_NAMESPACE_URI) : "") +
    5455                "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" +
    55         "    xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">");
     56                "    xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">");
    5657        indent = "  ";
    5758        writeMetaData();
     
    99100            simpleTag("name", (String) attr.get(GpxData.META_AUTHOR_NAME));
    100101            // write the email address
    101             if(attr.containsKey(GpxData.META_AUTHOR_EMAIL)) {
     102            if (attr.containsKey(GpxData.META_AUTHOR_EMAIL)) {
    102103                String[] tmp = ((String)attr.get(GpxData.META_AUTHOR_EMAIL)).split("@");
    103                 if(tmp.length == 2) {
     104                if (tmp.length == 2) {
    104105                    inline("email", "id=\"" + tmp[0] + "\" domain=\""+tmp[1]+"\"");
    105106                }
     
    111112
    112113        // write the copyright details
    113         if(attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)
     114        if (attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)
    114115                || attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
    115116            openAtt("copyright", "author=\""+ attr.get(GpxData.META_COPYRIGHT_AUTHOR) +"\"");
    116             if(attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
     117            if (attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
    117118                simpleTag("year", (String) attr.get(GpxData.META_COPYRIGHT_YEAR));
    118119            }
    119             if(attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)) {
     120            if (attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)) {
    120121                simpleTag("license", encode((String) attr.get(GpxData.META_COPYRIGHT_LICENSE)));
    121122            }
     
    124125
    125126        // write links
    126         if(attr.containsKey(GpxData.META_LINKS)) {
     127        if (attr.containsKey(GpxData.META_LINKS)) {
    127128            for (GpxLink link : (Collection<GpxLink>) attr.get(GpxData.META_LINKS)) {
    128129                gpxLink(link);
     
    136137
    137138        Bounds bounds = data.recalculateBounds();
    138         if(bounds != null)
    139         {
     139        if (bounds != null) {
    140140            String b = "minlat=\"" + bounds.getMin().lat() + "\" minlon=\"" + bounds.getMin().lon() +
    141141            "\" maxlat=\"" + bounds.getMax().lat() + "\" maxlon=\"" + bounds.getMax().lon() + "\"" ;
    142142            inline("bounds", b);
     143        }
     144
     145        if (data.fromServer) {
     146            openln("extensions");
     147            simpleTag("josm:from-server", "true");
     148            closeln("extensions");
    143149        }
    144150
  • trunk/src/org/openstreetmap/josm/io/OsmServerLocationReader.java

    r5494 r5679  
    167167                GpxReader reader = new GpxReader(in);
    168168                gpxParsedProperly = reader.parse(false);
    169                 GpxData result = reader.data;
     169                GpxData result = reader.getGpxData();
    170170                result.fromServer = true;
    171171                return result;
Note: See TracChangeset for help on using the changeset viewer.