source: josm/trunk/src/org/openstreetmap/josm/io/OsmWriter.java@ 2025

Last change on this file since 2025 was 2025, checked in by Gubaer, 15 years ago

new: improved dialog for uploading/saving modified layers on exit
new: improved dialog for uploading/saving modified layers if layers are deleted
new: new progress monitor which can delegate rendering to any Swing component
more setters/getters for properties in OSM data classes (fields are @deprecated); started to update references in the code base

  • Property svn:eol-style set to native
File size: 7.0 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.io;
3
4import java.io.PrintWriter;
5import java.util.HashMap;
6import java.util.Map.Entry;
7
8import org.openstreetmap.josm.data.osm.Changeset;
9import org.openstreetmap.josm.data.osm.DataSet;
10import org.openstreetmap.josm.data.osm.DataSource;
11import org.openstreetmap.josm.data.osm.Node;
12import org.openstreetmap.josm.data.osm.OsmPrimitive;
13import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
14import org.openstreetmap.josm.data.osm.Relation;
15import org.openstreetmap.josm.data.osm.RelationMember;
16import org.openstreetmap.josm.data.osm.Way;
17import org.openstreetmap.josm.data.osm.visitor.Visitor;
18import org.openstreetmap.josm.tools.DateUtils;
19
20/**
21 * Save the dataset into a stream as osm intern xml format. This is not using any
22 * xml library for storing.
23 * @author imi
24 */
25public class OsmWriter extends XmlWriter implements Visitor {
26
27 public final String DEFAULT_API_VERSION = "0.6";
28
29 /**
30 * The counter for newly created objects. Starts at -1 and goes down.
31 */
32 private long newIdCounter = -1;
33
34 /**
35 * All newly created ids and their primitive that uses it. This is a back reference
36 * map to allow references to use the correnct primitives.
37 */
38 public HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();
39
40 private boolean osmConform;
41 private boolean withBody = true;
42 private String version;
43 private Changeset changeset;
44
45 public OsmWriter(PrintWriter out, boolean osmConform, String version) {
46 super(out);
47 this.osmConform = osmConform;
48 this.version = (version == null ? DEFAULT_API_VERSION : version);
49 }
50
51 public void setWithBody(boolean wb) {
52 this.withBody = wb;
53 }
54 public void setChangeset(Changeset cs) {
55 this.changeset = cs;
56 }
57 public void setVersion(String v) {
58 this.version = v;
59 }
60
61 public void header() {
62 out.println("<?xml version='1.0' encoding='UTF-8'?>");
63 out.print("<osm version='");
64 out.print(version);
65 out.println("' generator='JOSM'>");
66 }
67 public void footer() {
68 out.println("</osm>");
69 }
70
71 public void writeContent(DataSet ds) {
72 for (Node n : ds.nodes)
73 if (shouldWrite(n)) {
74 visit(n);
75 }
76 for (Way w : ds.ways)
77 if (shouldWrite(w)) {
78 visit(w);
79 }
80 for (Relation e : ds.relations)
81 if (shouldWrite(e)) {
82 visit(e);
83 }
84 }
85
86 private boolean shouldWrite(OsmPrimitive osm) {
87 return osm.getId() != 0 || !osm.isDeleted();
88 }
89
90 public void writeDataSources(DataSet ds) {
91 for (DataSource s : ds.dataSources) {
92 out.println(" <bounds minlat='"
93 + s.bounds.min.lat()+"' minlon='"
94 + s.bounds.min.lon()+"' maxlat='"
95 + s.bounds.max.lat()+"' maxlon='"
96 + s.bounds.max.lon()
97 +"' origin='"+XmlWriter.encode(s.origin)+"' />");
98 }
99 }
100
101 public void visit(Node n) {
102 if (n.incomplete) return;
103 addCommon(n, "node");
104 out.print(" lat='"+n.getCoor().lat()+"' lon='"+n.getCoor().lon()+"'");
105 if (!withBody) {
106 out.println("/>");
107 } else {
108 addTags(n, "node", true);
109 }
110 }
111
112 public void visit(Way w) {
113 if (w.incomplete) return;
114 addCommon(w, "way");
115 if (!withBody) {
116 out.println("/>");
117 } else {
118 out.println(">");
119 for (Node n : w.getNodes()) {
120 out.println(" <nd ref='"+getUsedId(n)+"' />");
121 }
122 addTags(w, "way", false);
123 }
124 }
125
126 public void visit(Relation e) {
127 if (e.incomplete) return;
128 addCommon(e, "relation");
129 if (!withBody) {
130 out.println("/>");
131 } else {
132 out.println(">");
133 for (RelationMember em : e.getMembers()) {
134 out.print(" <member type='");
135 out.print(OsmPrimitiveType.from(em.getMember()).getAPIName());
136 out.println("' ref='"+getUsedId(em.getMember())+"' role='" +
137 XmlWriter.encode(em.getRole()) + "' />");
138 }
139 addTags(e, "relation", false);
140 }
141 }
142
143 public void visit(Changeset cs) {
144 addCommon(cs, "changeset");
145 out.println(">\n");
146 addTags(cs, "changeset", false);
147 }
148
149 public final void footer(PrintWriter out) {
150 out.println("</osm>");
151 }
152
153 /**
154 * Return the id for the given osm primitive (may access the usedId map)
155 */
156 private long getUsedId(OsmPrimitive osm) {
157 if (osm.getId() != 0)
158 return osm.getId();
159 if (usedNewIds.containsKey(osm))
160 return usedNewIds.get(osm);
161 usedNewIds.put(osm, newIdCounter);
162 return osmConform ? 0 : newIdCounter--;
163 }
164
165 private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) {
166 if (osm.hasKeys()) {
167 if (tagOpen) {
168 out.println(">");
169 }
170 for (Entry<String, String> e : osm.entrySet()) {
171 if ((osm instanceof Changeset) || !("created_by".equals(e.getKey()))) {
172 out.println(" <tag k='"+ XmlWriter.encode(e.getKey()) +
173 "' v='"+XmlWriter.encode(e.getValue())+ "' />");
174 }
175 }
176 out.println(" </" + tagname + ">");
177 } else if (tagOpen) {
178 out.println(" />");
179 } else {
180 out.println(" </" + tagname + ">");
181 }
182 }
183
184 /**
185 * Add the common part as the form of the tag as well as the XML attributes
186 * id, action, user, and visible.
187 */
188 private void addCommon(OsmPrimitive osm, String tagname) {
189 long id = getUsedId(osm);
190 out.print(" <"+tagname);
191 if (id != 0) {
192 out.print(" id='"+getUsedId(osm)+"'");
193 }
194 if (!osmConform) {
195 String action = null;
196 if (osm.isDeleted()) {
197 action = "delete";
198 } else if (osm.isModified()) {
199 action = "modify";
200 }
201 if (action != null) {
202 out.print(" action='"+action+"'");
203 }
204 }
205 if (!osm.isTimestampEmpty()) {
206 out.print(" timestamp='"+DateUtils.fromDate(osm.getTimestamp())+"'");
207 }
208 // user and visible added with 0.4 API
209 if (osm.user != null) {
210 out.print(" user='"+XmlWriter.encode(osm.user.name)+"'");
211 }
212 out.print(" visible='"+osm.isVisible()+"'");
213 if (osm.version != -1) {
214 out.print(" version='"+osm.version+"'");
215 }
216 if (this.changeset != null && this.changeset.getId() != 0) {
217 out.print(" changeset='"+this.changeset.getId()+"'" );
218 }
219 }
220
221 public void close() {
222 out.close();
223 }
224
225 public void flush() {
226 out.flush();
227 }
228}
Note: See TracBrowser for help on using the repository browser.