1 | package org.openstreetmap.josm.io;
|
---|
2 |
|
---|
3 | import java.io.IOException;
|
---|
4 | import java.io.Writer;
|
---|
5 | import java.util.Collection;
|
---|
6 | import java.util.LinkedList;
|
---|
7 | import java.util.List;
|
---|
8 | import java.util.Map.Entry;
|
---|
9 |
|
---|
10 | import org.jdom.Document;
|
---|
11 | import org.jdom.Element;
|
---|
12 | import org.jdom.output.Format;
|
---|
13 | import org.jdom.output.XMLOutputter;
|
---|
14 | import org.openstreetmap.josm.data.osm.DataSet;
|
---|
15 | import org.openstreetmap.josm.data.osm.Key;
|
---|
16 | import org.openstreetmap.josm.data.osm.LineSegment;
|
---|
17 | import org.openstreetmap.josm.data.osm.Node;
|
---|
18 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
19 | import org.openstreetmap.josm.data.osm.Track;
|
---|
20 | import org.openstreetmap.josm.data.osm.visitor.Visitor;
|
---|
21 |
|
---|
22 |
|
---|
23 | /**
|
---|
24 | * Save the dataset into a stream as osm intern xml format.
|
---|
25 | * @author imi
|
---|
26 | */
|
---|
27 | public class OsmWriter implements Visitor {
|
---|
28 |
|
---|
29 | /**
|
---|
30 | * The output writer to write the xml stream to.
|
---|
31 | */
|
---|
32 | private final Writer out;
|
---|
33 | /**
|
---|
34 | * The commands that should be uploaded on the server.
|
---|
35 | */
|
---|
36 | private DataSet ds;
|
---|
37 | /**
|
---|
38 | * The counter for new created objects. Starting at -1 and goes down.
|
---|
39 | */
|
---|
40 | private long newIdCounter = -1;
|
---|
41 |
|
---|
42 | /**
|
---|
43 | * Set from the visitor functions as result.
|
---|
44 | */
|
---|
45 | private Element element;
|
---|
46 | /**
|
---|
47 | * Filled with all generated properties tags.
|
---|
48 | */
|
---|
49 | private Collection<Element> properties;
|
---|
50 |
|
---|
51 | public OsmWriter(Writer out, DataSet dataSet) {
|
---|
52 | this.out = out;
|
---|
53 | ds = dataSet;
|
---|
54 | }
|
---|
55 |
|
---|
56 | /**
|
---|
57 | * Output the data to the stream
|
---|
58 | * @throws IOException In case of stream IO errors.
|
---|
59 | */
|
---|
60 | @SuppressWarnings("unchecked")
|
---|
61 | public void output() throws IOException {
|
---|
62 | Element root = new Element("osm");
|
---|
63 | List<Element> list = root.getChildren();
|
---|
64 | properties = new LinkedList<Element>();
|
---|
65 | for (OsmPrimitive osm : ds.allPrimitives()) {
|
---|
66 | if (!osm.isDeleted()) {
|
---|
67 | osm.visit(this);
|
---|
68 | list.add(element);
|
---|
69 | }
|
---|
70 | }
|
---|
71 | list.addAll(properties);
|
---|
72 | properties = new LinkedList<Element>();
|
---|
73 | Element deleted = new Element("deleted");
|
---|
74 | Collection<Element> allDeleted = deleted.getChildren();
|
---|
75 | for (OsmPrimitive osm : ds.allPrimitives()) {
|
---|
76 | if (osm.isDeleted()) {
|
---|
77 | osm.visit(this);
|
---|
78 | allDeleted.add(element);
|
---|
79 | }
|
---|
80 | }
|
---|
81 | allDeleted.addAll(properties);
|
---|
82 | if (!allDeleted.isEmpty())
|
---|
83 | list.add(deleted);
|
---|
84 |
|
---|
85 | Document d = new Document(root);
|
---|
86 | XMLOutputter xmlOut = new XMLOutputter(Format.getPrettyFormat());
|
---|
87 | xmlOut.output(d, out);
|
---|
88 | }
|
---|
89 |
|
---|
90 | /**
|
---|
91 | * Create a properties element.
|
---|
92 | */
|
---|
93 | private Element parseProperty(OsmPrimitive osm, Entry<Key, String> entry) {
|
---|
94 | Element e = new Element("property");
|
---|
95 | Key key = entry.getKey();
|
---|
96 | e.setAttribute("uid", ""+osm.id);
|
---|
97 | e.setAttribute("key", key.name);
|
---|
98 | e.setAttribute("value", entry.getValue());
|
---|
99 | return e;
|
---|
100 | }
|
---|
101 |
|
---|
102 | /**
|
---|
103 | * Add the id attribute to the element and the properties to the collection.
|
---|
104 | */
|
---|
105 | private void addProperties(Element e, OsmPrimitive osm) {
|
---|
106 | if (osm.id == 0)
|
---|
107 | osm.id = newIdCounter--;
|
---|
108 | e.setAttribute("uid", ""+osm.id);
|
---|
109 | if (osm.keys != null)
|
---|
110 | for (Entry<Key, String> entry : osm.keys.entrySet())
|
---|
111 | properties.add(parseProperty(osm, entry));
|
---|
112 | }
|
---|
113 |
|
---|
114 | /**
|
---|
115 | * Create an node element. Add all properties of the node to the properties-list.
|
---|
116 | */
|
---|
117 | public void visit(Node n) {
|
---|
118 | element = new Element("node");
|
---|
119 | addProperties(element, n);
|
---|
120 | element.setAttribute("lat", ""+n.coor.lat);
|
---|
121 | element.setAttribute("lon", ""+n.coor.lon);
|
---|
122 | }
|
---|
123 |
|
---|
124 | /**
|
---|
125 | * Create an line segment element. Add all properties of the node to the properties-list.
|
---|
126 | */
|
---|
127 | public void visit(LineSegment ls) {
|
---|
128 | element = new Element("segment");
|
---|
129 | addProperties(element, ls);
|
---|
130 | element.setAttribute("from", ""+ls.start.id);
|
---|
131 | element.setAttribute("to", ""+ls.end.id);
|
---|
132 | }
|
---|
133 |
|
---|
134 | /**
|
---|
135 | * Create an track element. Add all properties of the node to the properties-list.
|
---|
136 | */
|
---|
137 | @SuppressWarnings("unchecked")
|
---|
138 | public void visit(Track t) {
|
---|
139 | Element e = new Element("track");
|
---|
140 | addProperties(e, t);
|
---|
141 | for (LineSegment ls : t.segments)
|
---|
142 | e.getChildren().add(new Element("segment").setAttribute("uid", ""+ls.id));
|
---|
143 | }
|
---|
144 |
|
---|
145 | public void visit(Key k) {
|
---|
146 | element = new Element("property");
|
---|
147 | addProperties(element, k);
|
---|
148 | }
|
---|
149 | }
|
---|
150 |
|
---|