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

Last change on this file since 169 was 169, checked in by imi, 17 years ago
  • added "new empty map" action
  • added osm-server.version property (set the OSM server verion. For expert users only)
  • added first support for ongoing 0.4 server api
  • fixed Class-Path manifest attribute for plugins (" " is Seperator)
File size: 4.9 KB
Line 
1package org.openstreetmap.josm.io;
2
3import java.io.PrintWriter;
4import java.util.HashMap;
5import java.util.Map.Entry;
6
7import org.openstreetmap.josm.Main;
8import org.openstreetmap.josm.data.osm.DataSet;
9import org.openstreetmap.josm.data.osm.Node;
10import org.openstreetmap.josm.data.osm.OsmPrimitive;
11import org.openstreetmap.josm.data.osm.Segment;
12import org.openstreetmap.josm.data.osm.Way;
13import org.openstreetmap.josm.data.osm.visitor.Visitor;
14
15/**
16 * Save the dataset into a stream as osm intern xml format. This is not using any
17 * xml library for storing.
18 * @author imi
19 */
20public class OsmWriter extends XmlWriter implements Visitor {
21
22 /**
23 * The counter for new created objects. Starting at -1 and goes down.
24 */
25 private long newIdCounter = -1;
26 /**
27 * All newly created ids and their primitive that uses it. This is a back reference
28 * map to allow references to use the correnct primitives.
29 */
30 private HashMap<OsmPrimitive, Long> usedNewIds = new HashMap<OsmPrimitive, Long>();
31
32 private final boolean osmConform;
33
34 public abstract static class Osm implements OsmWriterInterface {
35 public void header(PrintWriter out) {
36 out.print("<osm version='");
37 out.print(Main.pref.get("osm-server.version", "0.3"));
38 out.println("' generator='JOSM'>");
39 }
40 public void footer(PrintWriter out) {
41 out.println("</osm>");
42 }
43 }
44
45 /**
46 * An output writer for function output that writes everything of the given dataset into
47 * the xml
48 */
49 public static final class All extends Osm {
50 private final DataSet ds;
51 private final boolean osmConform;
52
53 /**
54 * Construct an writer function
55 * @param osmConform <code>true</code>, if the xml should be 100% osm conform. In this
56 * case, not all information can be retrieved later (as example, modified state
57 * is lost and id's remain 0 instead of decrementing from -1)
58 */
59 public All(DataSet ds, boolean osmConform) {
60 this.ds = ds;
61 this.osmConform = osmConform;
62 }
63
64 public void write(PrintWriter out) {
65 Visitor writer = new OsmWriter(out, osmConform);
66 for (Node n : ds.nodes)
67 if (shouldWrite(n))
68 writer.visit(n);
69 for (Segment ls : ds.segments)
70 if (shouldWrite(ls))
71 writer.visit(ls);
72 for (Way w : ds.ways)
73 if (shouldWrite(w))
74 writer.visit(w);
75 }
76
77 private boolean shouldWrite(OsmPrimitive osm) {
78 return osm.id != 0 || !osm.deleted;
79 }
80 }
81
82 /**
83 * An output writer for functino output that writes only one specific primitive into
84 * the xml
85 */
86 public static final class Single extends Osm {
87 private final OsmPrimitive osm;
88 private final boolean osmConform;
89
90 public Single(OsmPrimitive osm, boolean osmConform) {
91 this.osm = osm;
92 this.osmConform = osmConform;
93 }
94
95 public void write(PrintWriter out) {
96 osm.visit(new OsmWriter(out, osmConform));
97 }
98 }
99
100 private OsmWriter(PrintWriter out, boolean osmConform) {
101 super(out);
102 this.osmConform = osmConform;
103 }
104
105 public void visit(Node n) {
106 addCommon(n, "node");
107 out.print(" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'");
108 addTags(n, "node", true);
109 }
110
111 public void visit(Segment ls) {
112 if (ls.incomplete)
113 return; // Do not write an incomplete segment
114 addCommon(ls, "segment");
115 out.print(" from='"+getUsedId(ls.from)+"' to='"+getUsedId(ls.to)+"'");
116 addTags(ls, "segment", true);
117 }
118
119 public void visit(Way w) {
120 addCommon(w, "way");
121 out.println(">");
122 for (Segment ls : w.segments)
123 out.println(" <seg id='"+getUsedId(ls)+"' />");
124 addTags(w, "way", false);
125 }
126
127 /**
128 * Return the id for the given osm primitive (may access the usedId map)
129 */
130 private long getUsedId(OsmPrimitive osm) {
131 if (osm.id != 0)
132 return osm.id;
133 if (usedNewIds.containsKey(osm))
134 return usedNewIds.get(osm);
135 usedNewIds.put(osm, newIdCounter);
136 return osmConform ? 0 : newIdCounter--;
137 }
138
139
140 private void addTags(OsmPrimitive osm, String tagname, boolean tagOpen) {
141 if (osm.keys != null) {
142 if (tagOpen)
143 out.println(">");
144 for (Entry<String, String> e : osm.keys.entrySet())
145 out.println(" <tag k='"+ XmlWriter.encode(e.getKey()) +
146 "' v='"+XmlWriter.encode(e.getValue())+ "' />");
147 out.println(" </" + tagname + ">");
148 } else if (tagOpen)
149 out.println(" />");
150 else
151 out.println(" </" + tagname + ">");
152 }
153
154 /**
155 * Add the common part as the from of the tag as well as the id or the action tag.
156 */
157 private void addCommon(OsmPrimitive osm, String tagname) {
158 out.print(" <"+tagname+" id='"+getUsedId(osm)+"'");
159 if (!osmConform) {
160 String action = null;
161 if (osm.deleted)
162 action = "delete";
163 else if (osm.modified)
164 action = "modify";
165 if (action != null)
166 out.print(" action='"+action+"'");
167 }
168 if (osm.timestamp != null) {
169 String time = osm.getTimeStr();
170 out.print(" timestamp='"+time+"'");
171 }
172 }
173}
Note: See TracBrowser for help on using the repository browser.