1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others
|
---|
2 | package org.openstreetmap.josm.io;
|
---|
3 |
|
---|
4 | import java.io.PrintWriter;
|
---|
5 | import java.util.Collection;
|
---|
6 | import java.util.LinkedList;
|
---|
7 |
|
---|
8 | import org.openstreetmap.josm.data.Bounds;
|
---|
9 | import org.openstreetmap.josm.data.coor.LatLon;
|
---|
10 | import org.openstreetmap.josm.data.osm.DataSet;
|
---|
11 | import org.openstreetmap.josm.data.osm.Node;
|
---|
12 | import org.openstreetmap.josm.data.osm.OsmPrimitive;
|
---|
13 | import org.openstreetmap.josm.data.osm.Way;
|
---|
14 | import org.openstreetmap.josm.gui.layer.RawGpsLayer.GpsPoint;
|
---|
15 |
|
---|
16 | /**
|
---|
17 | * Exports a dataset to GPX data. All information available are tried to store in
|
---|
18 | * the gpx. If no corresponding tag is available in GPX, use
|
---|
19 | * <code><extensions></code> instead.
|
---|
20 | *
|
---|
21 | * GPX-Way segments are stored as 2-node-pairs, so no <trkseg> with more
|
---|
22 | * or less than 2 <trkpt> are exported.
|
---|
23 | *
|
---|
24 | * @author imi
|
---|
25 | */
|
---|
26 | public class GpxWriter extends XmlWriter {
|
---|
27 |
|
---|
28 | public GpxWriter(PrintWriter out) {
|
---|
29 | super(out);
|
---|
30 | }
|
---|
31 |
|
---|
32 | /**
|
---|
33 | * Export the dataset to gpx. The ways are converted to trksegs, each in
|
---|
34 | * a seperate trk. Finally, all remaining nodes are added as wpt.
|
---|
35 | */
|
---|
36 | public static final class All implements XmlWriter.OsmWriterInterface {
|
---|
37 | private final DataSet data;
|
---|
38 | private final String name;
|
---|
39 | private final String desc;
|
---|
40 | private final String author;
|
---|
41 | private final String email;
|
---|
42 | private final String copyright;
|
---|
43 | private final String year;
|
---|
44 | private final String keywords;
|
---|
45 | private boolean metadataClosed = false;
|
---|
46 |
|
---|
47 | public All(DataSet data, String name, String desc, String author, String email, String copyright, String year, String keywords) {
|
---|
48 | this.data = data;
|
---|
49 | this.name = name;
|
---|
50 | this.desc = desc;
|
---|
51 | this.author = author;
|
---|
52 | this.email = email;
|
---|
53 | this.copyright = copyright;
|
---|
54 | this.year = year;
|
---|
55 | this.keywords = keywords;
|
---|
56 | }
|
---|
57 |
|
---|
58 | public void header(PrintWriter out) {
|
---|
59 | out.println("<gpx version='1.1' creator='JOSM' xmlns='http://www.topografix.com/GPX/1/1'>");
|
---|
60 | out.println(" <metadata>");
|
---|
61 | if (!name.equals(""))
|
---|
62 | out.println(" <name>"+XmlWriter.encode(name)+"</name>");
|
---|
63 | if (!desc.equals(""))
|
---|
64 | out.println(" <desc>"+XmlWriter.encode(desc)+"</desc>");
|
---|
65 | if (!author.equals("")) {
|
---|
66 | out.println(" <author>");
|
---|
67 | out.println(" <name>"+XmlWriter.encode(author)+"</name>");
|
---|
68 | if (!email.equals(""))
|
---|
69 | out.println(" <email>"+XmlWriter.encode(email)+"</email>");
|
---|
70 | out.println(" </author>");
|
---|
71 | if (!copyright.equals("")) {
|
---|
72 | out.println(" <copyright author='"+XmlWriter.encode(author)+"'>");
|
---|
73 | if (!year.equals(""))
|
---|
74 | out.println(" <year>"+XmlWriter.encode(year)+"</year>");
|
---|
75 | out.println(" <license>"+XmlWriter.encode(copyright)+"</license>");
|
---|
76 | out.println(" </copyright>");
|
---|
77 | }
|
---|
78 | }
|
---|
79 | if (!keywords.equals("")) {
|
---|
80 | out.println(" <keywords>"+XmlWriter.encode(keywords)+"</keywords>");
|
---|
81 | }
|
---|
82 | // don't finish here, to give output functions the chance to add <bounds>
|
---|
83 | }
|
---|
84 |
|
---|
85 | public void write(PrintWriter out) {
|
---|
86 | Collection<OsmPrimitive> all = data.allNonDeletedPrimitives();
|
---|
87 | if (all.isEmpty())
|
---|
88 | return;
|
---|
89 | GpxWriter writer = new GpxWriter(out);
|
---|
90 | // calculate bounds
|
---|
91 | Bounds b = new Bounds(new LatLon(Double.MAX_VALUE, Double.MAX_VALUE), new LatLon(-Double.MAX_VALUE, -Double.MAX_VALUE));
|
---|
92 | for (Node n : data.nodes)
|
---|
93 | if (!n.deleted)
|
---|
94 | b.extend(n.coor);
|
---|
95 | out.println(" <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
|
---|
96 | out.println(" </metadata>");
|
---|
97 | metadataClosed = true;
|
---|
98 |
|
---|
99 | // add ways
|
---|
100 | for (Way w : data.ways) {
|
---|
101 | if (w.deleted)
|
---|
102 | continue;
|
---|
103 | out.println(" <trk>");
|
---|
104 | out.println(" <trkseg>");
|
---|
105 | for (Node n : w.nodes) {
|
---|
106 | writer.outputNode(n, false);
|
---|
107 | all.remove(n);
|
---|
108 | }
|
---|
109 | out.println(" </trkseg>");
|
---|
110 | out.println(" </trk>");
|
---|
111 | all.remove(w);
|
---|
112 | }
|
---|
113 |
|
---|
114 | // finally add the remaining nodes
|
---|
115 | for (OsmPrimitive osm : all)
|
---|
116 | if (osm instanceof Node)
|
---|
117 | writer.outputNode((Node)osm, true);
|
---|
118 | }
|
---|
119 |
|
---|
120 | public void footer(PrintWriter out) {
|
---|
121 | if (!metadataClosed)
|
---|
122 | out.println(" </metadata>");
|
---|
123 | out.println("</gpx>");
|
---|
124 | }
|
---|
125 | }
|
---|
126 |
|
---|
127 |
|
---|
128 | /**
|
---|
129 | * Export the collection structure to gpx. The gpx will consists of only one
|
---|
130 | * trk with as many trkseg as there are collections in the outer collection.
|
---|
131 | */
|
---|
132 | public static final class Trk implements XmlWriter.OsmWriterInterface {
|
---|
133 | private final Collection<Collection<GpsPoint>> data;
|
---|
134 | public Trk(Collection<Collection<GpsPoint>> data) {
|
---|
135 | this.data = data;
|
---|
136 | }
|
---|
137 |
|
---|
138 | public void header(PrintWriter out) {
|
---|
139 | out.println("<gpx version='1.1' creator='JOSM' xmlns='http://www.topografix.com/GPX/1/1'>");
|
---|
140 | }
|
---|
141 |
|
---|
142 | public void write(PrintWriter out) {
|
---|
143 | if (data.size() == 0)
|
---|
144 | return;
|
---|
145 | // calculate bounds
|
---|
146 | Bounds b = new Bounds(new LatLon(Double.MAX_VALUE, Double.MAX_VALUE), new LatLon(Double.MIN_VALUE, Double.MIN_VALUE));
|
---|
147 | for (Collection<GpsPoint> c : data)
|
---|
148 | for (GpsPoint p : c)
|
---|
149 | b.extend(p.latlon);
|
---|
150 | out.println(" <metadata>");
|
---|
151 | out.println(" <bounds minlat='"+b.min.lat()+"' minlon='"+b.min.lon()+"' maxlat='"+b.max.lat()+"' maxlon='"+b.max.lon()+"' />");
|
---|
152 | out.println(" </metadata>");
|
---|
153 |
|
---|
154 | out.println(" <trk>");
|
---|
155 | for (Collection<GpsPoint> c : data) {
|
---|
156 | out.println(" <trkseg>");
|
---|
157 | LatLon last = null;
|
---|
158 | for (GpsPoint p : c) {
|
---|
159 | // skip double entries
|
---|
160 | if (p.latlon.equals(last))
|
---|
161 | continue;
|
---|
162 | last = p.latlon;
|
---|
163 | LatLon ll = p.latlon;
|
---|
164 | out.print(" <trkpt lat='"+ll.lat()+"' lon='"+ll.lon()+"'");
|
---|
165 | if (p.time != null && p.time.length()!=0) {
|
---|
166 | out.println(">");
|
---|
167 | out.println(" <time>"+p.time+"</time>");
|
---|
168 | out.println(" </trkpt>");
|
---|
169 | } else
|
---|
170 | out.println(" />");
|
---|
171 | }
|
---|
172 | out.println(" </trkseg>");
|
---|
173 | }
|
---|
174 | out.println(" </trk>");
|
---|
175 | }
|
---|
176 |
|
---|
177 | public void footer(PrintWriter out) {
|
---|
178 | out.println("</gpx>");
|
---|
179 | }
|
---|
180 | }
|
---|
181 |
|
---|
182 | private void outputNode(Node n, boolean wpt) {
|
---|
183 | out.print((wpt?" <wpt":" <trkpt")+" lat='"+n.coor.lat()+"' lon='"+n.coor.lon()+"'");
|
---|
184 | if (n.keys == null) {
|
---|
185 | out.println(" />");
|
---|
186 | return;
|
---|
187 | }
|
---|
188 | boolean found = false;
|
---|
189 | String[] possibleKeys = {"ele", "time", "magvar", "geoidheight", "name",
|
---|
190 | "cmt", "desc", "src", "link", "sym", "type", "fix", "sat",
|
---|
191 | "hdop", "vdop", "pdop", "ageofgpsdata", "dgpsid"};
|
---|
192 | Collection<String> keys = n.keySet();
|
---|
193 | for (String k : possibleKeys) {
|
---|
194 | if (keys.contains(k)) {
|
---|
195 | if (!found) {
|
---|
196 | found = true;
|
---|
197 | out.println(">");
|
---|
198 | }
|
---|
199 | if (k.equals("link")) {
|
---|
200 | out.println(" <link>");
|
---|
201 | out.println(" <text>"+XmlWriter.encode(n.get(k))+"</text>");
|
---|
202 | out.println(" </link>");
|
---|
203 | } else
|
---|
204 | out.println(" <"+k+">"+XmlWriter.encode(n.get(k))+"</"+k+">");
|
---|
205 | }
|
---|
206 | }
|
---|
207 | if (found)
|
---|
208 | out.println(wpt?" </wpt>":" </trkpt>");
|
---|
209 | else
|
---|
210 | out.println(" />");
|
---|
211 | }
|
---|
212 | }
|
---|