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

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

Replaced OsmPrimtive.user by setters/getters

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