Changeset 49 in josm for src


Ignore:
Timestamp:
2006-02-09T23:46:27+01:00 (18 years ago)
Author:
imi
Message:
  • added JUnit test cases src tree
  • fixed save/reload of GPX and OSM data of new object ids
  • GPX load does not merge nodes if JOSM namespace is found
Location:
src/org/openstreetmap/josm
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • src/org/openstreetmap/josm/actions/SaveAction.java

    r40 r49  
    5454                        FileWriter fileWriter;
    5555                        if (fn.endsWith(".gpx"))
    56                                 new GpxWriter(fileWriter = new FileWriter(file)).output();
     56                                new GpxWriter(fileWriter = new FileWriter(file), Main.main.ds).output();
    5757                        else if (fn.endsWith(".xml") || fn.endsWith(".osm"))
    5858                                new OsmWriter(fileWriter = new FileWriter(file), Main.main.ds).output();
  • src/org/openstreetmap/josm/io/GpxReader.java

    r47 r49  
    22
    33import static org.openstreetmap.josm.io.GpxWriter.GPX;
     4import static org.openstreetmap.josm.io.GpxWriter.JOSM;
    45import static org.openstreetmap.josm.io.GpxWriter.OSM;
    5 import static org.openstreetmap.josm.io.GpxWriter.JOSM;
    66
    77import java.io.IOException;
     
    3333         */
    3434        public Reader source;
     35        /**
     36         * Mapper to find new created objects that occoure more than once.
     37         */
     38        private HashMap<Long, OsmPrimitive> newCreatedPrimitives = new HashMap<Long, OsmPrimitive>();
     39        /**
     40         * Either set to true or false, depending whether the JOSM namespace declaration
     41         * was found.
     42         */
     43        private boolean mergeNodes = false;
    3544
    3645        /**
     
    4958                        final SAXBuilder builder = new SAXBuilder();
    5059                        Element root = builder.build(source).getRootElement();
     60                        mergeNodes = !root.getAdditionalNamespaces().contains(JOSM);
    5161                        return parseDataSet(root);
    5262                } catch (NullPointerException npe) {
     
    7888                                parseKeyValueTag(data, child);
    7989                }
     90                data = (Node)getNewIfSeenBefore(data);
    8091                return data;
    8192        }
     
    89100                DataSet data = new DataSet();
    90101                // read waypoints not contained in tracks or areas
    91                 for (Object o : e.getChildren("wpt", GPX))
    92                         addNode(data, parseWaypoint((Element)o));
     102                for (Object o : e.getChildren("wpt", GPX)) {
     103                        Node node = parseWaypoint((Element)o);
     104                        addNode(data, node);
     105                }
    93106       
    94107                // read tracks (and line segments)
    95108                for (Object trackElement : e.getChildren("trk", GPX))
    96109                        parseTrack((Element)trackElement, data);
    97        
     110
     111                // reset new created ids to zero
     112                for (OsmPrimitive osm : data.allPrimitives())
     113                        if (osm.id < 0)
     114                                osm.id = 0;
     115               
    98116                return data;
    99117        }
     
    116134                                Node start = null;
    117135                                for (Object w : child.getChildren("trkpt", GPX)) {
    118                                         Node node = parseWaypoint((Element)w);
    119                                         node = addNode(ds, node);
     136                                        Node node = addNode(ds, parseWaypoint((Element)w));
    120137                                        if (start == null)
    121138                                                start = node;
     
    123140                                                LineSegment lineSegment = new LineSegment(start, node);
    124141                                                parseKeyValueExtensions(lineSegment, child.getChild("extensions", GPX));
     142                                                lineSegment = (LineSegment)getNewIfSeenBefore(lineSegment);
    125143                                                track.segments.add(lineSegment);
    126144                                                start = node;
     
    136154                                parseKeyValueTag(track, child);
    137155                }
     156                track = (Track)getNewIfSeenBefore(track);
    138157                ds.lineSegments.addAll(track.segments);
    139158                if (!realLineSegment)
    140159                        ds.tracks.add(track);
    141160        }
    142        
    143161
    144162        /**
    145163         * Adds the node to allNodes if it is not already listed. Does respect the
    146          * preference setting "mergeNodes". Return the node in the list that correspond
     164         * setting "mergeNodes". Return the node in the list that correspond
    147165         * to the node in the list (either the new added or the old found).
    148          *
    149          * If reading raw gps data, mergeNodes are always on (To save memory. You
    150          * can't edit raw gps nodes anyway.)
    151166         *
    152167         * @param data The DataSet to add the node to.
     
    155170         */
    156171        private Node addNode(DataSet data, Node node) {
    157                 for (Node n : data.nodes)
    158                         if (node.coor.equalsLatLon(n.coor))
    159                                 return n;
     172                if (mergeNodes)
     173                        for (Node n : data.nodes)
     174                                if (node.coor.equalsLatLon(n.coor))
     175                                        return n;
    160176                data.nodes.add(node);
    161177                return node;
     178        }
     179       
     180
     181        /**
     182         * @return Either the parameter or an index from the newCreatedPrimitives map
     183         *              with the id seen before.
     184         */
     185        private OsmPrimitive getNewIfSeenBefore(OsmPrimitive osm) {
     186                if (newCreatedPrimitives.containsKey(osm.id))
     187                        return newCreatedPrimitives.get(osm.id);
     188                return osm;
    162189        }
    163190
     
    189216                        if (idElement != null)
    190217                                osm.id = Long.parseLong(idElement.getText());
     218                        if (osm.id < 0 && !newCreatedPrimitives.containsKey(osm.id))
     219                                newCreatedPrimitives.put(osm.id, osm);
    191220                        osm.modified = e.getChild("modified", JOSM) != null;
    192221                        osm.setDeleted(e.getChild("deleted", JOSM) != null);
  • src/org/openstreetmap/josm/io/GpxWriter.java

    r44 r49  
    33import java.io.IOException;
    44import java.io.Writer;
     5import java.util.Collection;
    56import java.util.HashMap;
    67import java.util.LinkedList;
     
    1415import org.jdom.output.Format;
    1516import org.jdom.output.XMLOutputter;
    16 import org.openstreetmap.josm.Main;
     17import org.openstreetmap.josm.data.osm.DataSet;
    1718import org.openstreetmap.josm.data.osm.Key;
    1819import org.openstreetmap.josm.data.osm.LineSegment;
     
    5051         */
    5152        private Writer out;
     53        /**
     54         * The dataset beeing processed.
     55         */
     56        private DataSet ds;
     57        /**
     58         * Map all new primitives to the element which hold them. After inserting everything,
     59         * the writer sets ids to every element that was in the list and had more than one
     60         * element using it.
     61         */
     62        private HashMap<OsmPrimitive, Collection<Element>> usedNewPrimitives = new HashMap<OsmPrimitive, Collection<Element>>();
     63        /**
     64         * The counter for new created objects used more than once.
     65         * Starting at -1 and goes down.
     66         */
     67        private long newIdCounter = -1;
    5268       
    5369        /**
     
    5773         * @param out The Writer to store the result data in.
    5874         */
    59         public GpxWriter(Writer out) {
     75        public GpxWriter(Writer out, DataSet ds) {
    6076                this.out = out;
     77                this.ds = ds;
    6178        }
    6279
     
    86103                e.setAttribute("creator", "JOSM");
    87104                // for getting all unreferenced waypoints in the wpt-list
    88                 LinkedList<Node> unrefNodes = new LinkedList<Node>(Main.main.ds.nodes);
     105                LinkedList<Node> unrefNodes = new LinkedList<Node>(ds.nodes);
    89106                // for getting all unreferenced line segments
    90                 LinkedList<LineSegment> unrefLs = new LinkedList<LineSegment>(Main.main.ds.lineSegments);
     107                LinkedList<LineSegment> unrefLs = new LinkedList<LineSegment>(ds.lineSegments);
    91108
    92109                // tracks
    93                 for (Track t : Main.main.ds.tracks) {
     110                for (Track t : ds.tracks) {
     111                        if (t.isDeleted() && t.id == 0)
     112                                continue;
    94113                        Element tElem = new Element("trk", GPX);
    95114                        HashMap<Key, String> keys = null;
     
    119138                // encode pending line segments as tracks
    120139                for (LineSegment ls : unrefLs) {
     140                        if (ls.isDeleted() && ls.id == 0)
     141                                continue;
    121142                        Element t = new Element("trk", GPX);
    122143                        t.getChildren().add(parseLineSegment(ls));
     
    130151
    131152                // waypoints (missing nodes)
    132                 for (Node n : unrefNodes)
     153                for (Node n : unrefNodes) {
     154                        if (n.isDeleted() && n.id == 0)
     155                                continue;
    133156                        e.getChildren().add(parseWaypoint(n, "wpt"));
     157                }
     158
     159                // link all ids used more than once
     160                for (Entry<OsmPrimitive, Collection<Element>> entry : usedNewPrimitives.entrySet()) {
     161                        if (entry.getValue().size() > 1) {
     162                                long id = newIdCounter--;
     163                                for (Element element : entry.getValue()) {
     164                                        Element ext = element.getChild("extensions", GPX);
     165                                        if (ext == null)
     166                                                element.getChildren().add(ext = new Element("extensions", GPX));
     167                                        ext.getChildren().add(new Element("uid", JOSM).setText(""+id));
     168                                }
     169                        }
     170                }
    134171
    135172                return e;
     
    242279        @SuppressWarnings("unchecked")
    243280        private void addPropertyExtensions(Element e, Map<Key, String> keys, OsmPrimitive osm) {
    244                 if ((keys == null || keys.isEmpty()) && osm.id == 0 && !osm.modified && !osm.isDeleted() && !osm.modifiedProperties)
    245                         return;
    246                 Element extensions = e.getChild("extensions", GPX);
    247                 if (extensions == null)
    248                         e.getChildren().add(extensions = new Element("extensions", GPX));
     281                LinkedList<Element> extensions = new LinkedList<Element>();
    249282                if (keys != null && !keys.isEmpty()) {
    250283                        for (Entry<Key, String> prop : keys.entrySet()) {
     
    252285                                propElement.setAttribute("key", prop.getKey().name);
    253286                                propElement.setAttribute("value", prop.getValue());
    254                                 extensions.getChildren().add(propElement);
     287                                extensions.add(propElement);
    255288                        }
    256289                }
     290               
    257291                if (osm.id != 0) {
    258292                        Element propElement = new Element("uid", JOSM);
    259293                        propElement.setText(""+osm.id);
    260                         extensions.getChildren().add(propElement);
     294                        extensions.add(propElement);
     295                } else {
     296                        Collection<Element> l = usedNewPrimitives.get(osm);
     297                        if (l == null)
     298                                l = new LinkedList<Element>();
     299                        l.add(e);
     300                        usedNewPrimitives.put(osm, l);
    261301                }
    262302                if (osm.modified) {
    263303                        Element modElement = new Element("modified", JOSM);
    264                         extensions.getChildren().add(modElement);
     304                        extensions.add(modElement);
    265305                }
    266306                if (osm.isDeleted()) {
    267307                        Element modElement = new Element("deleted", JOSM);
    268                         extensions.getChildren().add(modElement);
     308                        extensions.add(modElement);
    269309                }
    270310                if (osm.modifiedProperties) {
    271311                        Element modElement = new Element("modifiedProperties", JOSM);
    272                         extensions.getChildren().add(modElement);
    273                 }
     312                        extensions.add(modElement);
     313                }
     314               
     315                if (extensions.isEmpty())
     316                        return;
     317
     318                Element ext = e.getChild("extensions", GPX);
     319                if (ext == null)
     320                        e.getChildren().add(ext = new Element("extensions", GPX));
     321                ext.getChildren().addAll(extensions);
    274322        }
    275323}
  • src/org/openstreetmap/josm/io/OsmWriter.java

    r44 r49  
    44import java.io.Writer;
    55import java.util.Collection;
     6import java.util.HashMap;
    67import java.util.LinkedList;
    78import java.util.List;
     
    3940         */
    4041        private long newIdCounter = -1;
     42        /**
     43         * All newly created ids and their primitive that uses it. This is a back reference
     44         * map to allow references to use the correnct primitives.
     45         */
     46        private HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();
    4147
    4248        /**
     
    7278                Collection<Element> allDeleted = deleted.getChildren();
    7379                for (OsmPrimitive osm : ds.allPrimitives()) {
    74                         if (osm.isDeleted()) {
     80                        if (osm.isDeleted() && osm.id != 0) {
    7581                                osm.visit(this);
    7682                                allDeleted.add(element);
     
    103109        private void addProperties(Element e, OsmPrimitive osm) {
    104110                long id = osm.id;
    105                 if (id == 0)
     111                if (id == 0) {
    106112                        id = newIdCounter--;
     113                        usedNewIds.put(osm, id);
     114                }
    107115                e.setAttribute("uid", ""+id);
    108116                if (osm.keys != null)
     
    127135                element = new Element("segment");
    128136                addProperties(element, ls);
    129                 element.setAttribute("from", ""+ls.start.id);
    130                 element.setAttribute("to", ""+ls.end.id);
     137                element.setAttribute("from", ""+getUsedId(ls.start));
     138                element.setAttribute("to", ""+getUsedId(ls.end));
     139        }
     140
     141        /**
     142         * Return the id for the given osm primitive (may access the usedId map)
     143         */
     144        private Long getUsedId(OsmPrimitive osm) {
     145                return osm.id == 0 ? usedNewIds.get(osm) : osm.id;
    131146        }
    132147
     
    139154                addProperties(element, t);
    140155                for (LineSegment ls : t.segments)
    141                         element.getChildren().add(new Element("segment").setAttribute("uid", ""+ls.id));
     156                        element.getChildren().add(new Element("segment").setAttribute("uid", ""+getUsedId(ls)));
    142157        }
    143158
     
    147162        }
    148163}
    149 
Note: See TracChangeset for help on using the changeset viewer.