source: josm/trunk/src/org/openstreetmap/josm/io/GpxWriter.java@ 2751

Last change on this file since 2751 was 2620, checked in by jttt, 14 years ago

Remove OsmPrimitive.setIncomplete()

  • Property svn:eol-style set to native
File size: 7.9 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.io.BufferedWriter;
7import java.io.OutputStream;
8import java.io.OutputStreamWriter;
9import java.io.PrintWriter;
10import java.io.UnsupportedEncodingException;
11import java.util.Collection;
12import java.util.Map;
13
14import org.openstreetmap.josm.data.Bounds;
15import org.openstreetmap.josm.data.coor.LatLon;
16import org.openstreetmap.josm.data.gpx.GpxData;
17import org.openstreetmap.josm.data.gpx.GpxLink;
18import org.openstreetmap.josm.data.gpx.GpxRoute;
19import org.openstreetmap.josm.data.gpx.GpxTrack;
20import org.openstreetmap.josm.data.gpx.WayPoint;
21
22/**
23 * Writes GPX files from GPX data or OSM data.
24 */
25public class GpxWriter extends XmlWriter {
26
27 public GpxWriter(PrintWriter out) {
28 super(out);
29 }
30
31 public GpxWriter(OutputStream out) throws UnsupportedEncodingException {
32 super(new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, "UTF-8"))));
33 }
34
35 public GpxWriter() {
36 super(null);
37 //sorry for this one here, this will be cleaned up once the new scheme works
38 }
39
40 private GpxData data;
41 private String indent = "";
42
43 private final static int WAY_POINT = 0;
44 private final static int ROUTE_POINT = 1;
45 private final static int TRACK_POINT = 2;
46
47 public void write(GpxData data) {
48 this.data = data;
49 out.println("<?xml version='1.0' encoding='UTF-8'?>");
50 out.println("<gpx version=\"1.1\" creator=\"JOSM GPX export\" xmlns=\"http://www.topografix.com/GPX/1/1\"\n" +
51 " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" +
52 " xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\">");
53 indent = " ";
54 writeMetaData();
55 writeWayPoints();
56 writeRoutes();
57 writeTracks();
58 out.print("</gpx>");
59 out.flush();
60 }
61
62 @SuppressWarnings("unchecked")
63 private void writeAttr(Map<String, Object> attr) {
64 // FIXME this loop is evil, because it does not assure the
65 // correct element order specified by the xml schema.
66 // for now it works, but future extension could get very complex and unmaintainable
67 for (Map.Entry<String, Object> ent : attr.entrySet()) {
68 String k = ent.getKey();
69 if (k.equals(GpxData.META_LINKS)) {
70 for (GpxLink link : (Collection<GpxLink>) ent.getValue()) {
71 gpxLink(link);
72 }
73 } else {
74 simpleTag(k, ent.getValue().toString());
75 }
76 }
77 }
78
79 @SuppressWarnings("unchecked")
80 private void writeMetaData() {
81 Map<String, Object> attr = data.attr;
82 openln("metadata");
83
84 // write the description
85 if (attr.containsKey(GpxData.META_DESC)) {
86 simpleTag("desc", (String)attr.get(GpxData.META_DESC));
87 }
88
89 // write the author details
90 if (attr.containsKey(GpxData.META_AUTHOR_NAME)
91 || attr.containsKey(GpxData.META_AUTHOR_EMAIL)) {
92 openln("author");
93 // write the name
94 simpleTag("name", (String) attr.get(GpxData.META_AUTHOR_NAME));
95 // write the email address
96 if(attr.containsKey(GpxData.META_AUTHOR_EMAIL)) {
97 String[] tmp = ((String)attr.get(GpxData.META_AUTHOR_EMAIL)).split("@");
98 if(tmp.length == 2) {
99 inline("email", "id=\"" + tmp[0] + "\" domain=\""+tmp[1]+"\"");
100 }
101 }
102 // write the author link
103 gpxLink((GpxLink) attr.get(GpxData.META_AUTHOR_LINK));
104 closeln("author");
105 }
106
107 // write the copyright details
108 if(attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)
109 || attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
110 openAtt("copyright", "author=\""+ attr.get(GpxData.META_COPYRIGHT_AUTHOR) +"\"");
111 if(attr.containsKey(GpxData.META_COPYRIGHT_YEAR)) {
112 simpleTag("year", (String) attr.get(GpxData.META_COPYRIGHT_YEAR));
113 }
114 if(attr.containsKey(GpxData.META_COPYRIGHT_LICENSE)) {
115 simpleTag("license", encode((String) attr.get(GpxData.META_COPYRIGHT_LICENSE)));
116 }
117 closeln("copyright");
118 }
119
120 // write links
121 if(attr.containsKey(GpxData.META_LINKS)) {
122 for (GpxLink link : (Collection<GpxLink>) attr.get(GpxData.META_LINKS)) {
123 gpxLink(link);
124 }
125 }
126
127 // write keywords
128 if (attr.containsKey(GpxData.META_KEYWORDS)) {
129 simpleTag("keywords", (String)attr.get(GpxData.META_KEYWORDS));
130 }
131
132 Bounds bounds = data.recalculateBounds();
133 if(bounds != null)
134 {
135 String b = "minlat=\"" + bounds.getMin().lat() + "\" minlon=\"" + bounds.getMin().lon() +
136 "\" maxlat=\"" + bounds.getMax().lat() + "\" maxlon=\"" + bounds.getMax().lon() + "\"" ;
137 inline("bounds", b);
138 }
139
140 closeln("metadata");
141 }
142
143 private void writeWayPoints() {
144 for (WayPoint pnt : data.waypoints) {
145 wayPoint(pnt, WAY_POINT);
146 }
147 }
148
149 private void writeRoutes() {
150 for (GpxRoute rte : data.routes) {
151 openln("rte");
152 writeAttr(rte.attr);
153 for (WayPoint pnt : rte.routePoints) {
154 wayPoint(pnt, ROUTE_POINT);
155 }
156 closeln("rte");
157 }
158 }
159
160 private void writeTracks() {
161 for (GpxTrack trk : data.tracks) {
162 open("trk");
163 writeAttr(trk.attr);
164 for (Collection<WayPoint> seg : trk.trackSegs) {
165 openln("trkseg");
166 for (WayPoint pnt : seg) {
167 wayPoint(pnt, TRACK_POINT);
168 }
169 closeln("trkseg");
170 }
171 closeln("trk");
172 }
173 }
174
175 private void openln(String tag) {
176 open(tag);
177 out.println();
178 }
179
180 private void open(String tag) {
181 out.print(indent + "<" + tag + ">");
182 indent += " ";
183 }
184
185 private void openAtt(String tag, String attributes) {
186 out.println(indent + "<" + tag + " " + attributes + ">");
187 indent += " ";
188 }
189
190 private void inline(String tag, String attributes) {
191 out.println(indent + "<" + tag + " " + attributes + " />");
192 }
193
194 private void close(String tag) {
195 indent = indent.substring(2);
196 out.print(indent + "</" + tag + ">");
197 }
198
199 private void closeln(String tag) {
200 close(tag);
201 out.println();
202 }
203
204 /**
205 * if content not null, open tag, write encoded content, and close tag
206 * else do nothing.
207 */
208 private void simpleTag(String tag, String content) {
209 if (content != null && content.length() > 0) {
210 open(tag);
211 out.print(encode(content));
212 out.println("</" + tag + ">");
213 indent = indent.substring(2);
214 }
215 }
216
217 /**
218 * output link
219 */
220 private void gpxLink(GpxLink link) {
221 if (link != null) {
222 openAtt("link", "href=\"" + link.uri + "\"");
223 simpleTag("text", link.text);
224 simpleTag("type", link.type);
225 closeln("link");
226 }
227 }
228
229 /**
230 * output a point
231 */
232 private void wayPoint(WayPoint pnt, int mode) {
233 String type;
234 switch(mode) {
235 case WAY_POINT:
236 type = "wpt";
237 break;
238 case ROUTE_POINT:
239 type = "rtept";
240 break;
241 case TRACK_POINT:
242 type = "trkpt";
243 break;
244 default:
245 throw new RuntimeException(tr("Unknown mode {0}.", mode));
246 }
247 if (pnt != null) {
248 LatLon c = pnt.getCoor();
249 openAtt(type, "lat=\"" + c.lat() + "\" lon=\"" + c.lon() + "\"");
250 writeAttr(pnt.attr);
251 closeln(type);
252 }
253 }
254}
Note: See TracBrowser for help on using the repository browser.