source: josm/trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java@ 8851

Last change on this file since 8851 was 8839, checked in by Don-vip, 9 years ago

sonar - squid:S2325 - "private" methods that don't access instance data should be "static"

  • Property svn:eol-style set to native
File size: 6.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import java.io.StringWriter;
5import java.util.HashMap;
6import java.util.Iterator;
7import java.util.Map;
8import java.util.Map.Entry;
9
10import javax.json.Json;
11import javax.json.JsonArrayBuilder;
12import javax.json.JsonObjectBuilder;
13import javax.json.JsonWriter;
14import javax.json.stream.JsonGenerator;
15
16import org.openstreetmap.josm.data.Bounds;
17import org.openstreetmap.josm.data.coor.EastNorth;
18import org.openstreetmap.josm.data.coor.LatLon;
19import org.openstreetmap.josm.data.osm.DataSet;
20import org.openstreetmap.josm.data.osm.INode;
21import org.openstreetmap.josm.data.osm.IRelation;
22import org.openstreetmap.josm.data.osm.IWay;
23import org.openstreetmap.josm.data.osm.Node;
24import org.openstreetmap.josm.data.osm.OsmPrimitive;
25import org.openstreetmap.josm.data.osm.Way;
26import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
27import org.openstreetmap.josm.data.projection.Projection;
28import org.openstreetmap.josm.gui.layer.OsmDataLayer;
29
30/**
31 * Writes OSM data as a GeoJSON string, using JSR 353: Java API for JSON Processing (JSON-P).
32 */
33public class GeoJSONWriter {
34
35 private final OsmDataLayer layer;
36 private final Projection projection;
37 private static final boolean skipEmptyNodes = true;
38
39 /**
40 * Constructs a new {@code GeoJSONWriter}.
41 * @param layer The OSM data layer to save
42 * @param projection The projection to use for coordinates
43 */
44 public GeoJSONWriter(OsmDataLayer layer, Projection projection) {
45 this.layer = layer;
46 this.projection = projection;
47 }
48
49 /**
50 * Writes OSM data as a GeoJSON string (prettified).
51 * @return The GeoJSON data
52 */
53 public String write() {
54 return write(true);
55 }
56
57 /**
58 * Writes OSM data as a GeoJSON string (prettified or not).
59 * @param pretty {@code true} to have pretty output, {@code false} otherwise
60 * @return The GeoJSON data
61 * @since 6756
62 */
63 public String write(boolean pretty) {
64 StringWriter stringWriter = new StringWriter();
65 Map<String, Object> config = new HashMap<>(1);
66 config.put(JsonGenerator.PRETTY_PRINTING, pretty);
67 try (JsonWriter writer = Json.createWriterFactory(config).createWriter(stringWriter)) {
68 JsonObjectBuilder object = Json.createObjectBuilder()
69 .add("type", "FeatureCollection")
70 .add("crs", Json.createObjectBuilder().add("type", "name").add("name", projection.toCode()))
71 .add("generator", "JOSM");
72 appendLayerBounds(layer.data, object);
73 appendLayerFeatures(layer.data, object);
74 writer.writeObject(object.build());
75 return stringWriter.toString();
76 }
77 }
78
79 private class GeometryPrimitiveVisitor implements PrimitiveVisitor {
80
81 private final JsonObjectBuilder geomObj;
82
83 GeometryPrimitiveVisitor(JsonObjectBuilder geomObj) {
84 this.geomObj = geomObj;
85 }
86
87 @Override
88 public void visit(INode n) {
89 geomObj.add("type", "Point");
90 LatLon ll = n.getCoor();
91 if (ll != null) {
92 geomObj.add("coordinates", getCoorArray(Json.createArrayBuilder(), n.getCoor()));
93 }
94 }
95
96 @Override
97 public void visit(IWay w) {
98 geomObj.add("type", "LineString");
99 if (w instanceof Way) {
100 JsonArrayBuilder array = Json.createArrayBuilder();
101 for (Node n : ((Way) w).getNodes()) {
102 LatLon ll = n.getCoor();
103 if (ll != null) {
104 array.add(getCoorArray(Json.createArrayBuilder(), ll));
105 }
106 }
107 geomObj.add("coordinates", array);
108 }
109 }
110
111 @Override
112 public void visit(IRelation r) {
113 }
114 }
115
116 private JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, LatLon c) {
117 return getCoorArray(builder, projection.latlon2eastNorth(c));
118 }
119
120 private static JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, EastNorth c) {
121 return builder.add(c.getX()).add(c.getY());
122 }
123
124 protected void appendPrimitive(OsmPrimitive p, JsonArrayBuilder array) {
125 if (p.isIncomplete()) {
126 return;
127 } else if (skipEmptyNodes && p instanceof Node && p.getKeys().isEmpty()) {
128 return;
129 }
130
131 // Properties
132 final JsonObjectBuilder propObj = Json.createObjectBuilder();
133 for (Entry<String, String> t : p.getKeys().entrySet()) {
134 propObj.add(t.getKey(), t.getValue());
135 }
136
137 // Geometry
138 final JsonObjectBuilder geomObj = Json.createObjectBuilder();
139 p.accept(new GeometryPrimitiveVisitor(geomObj));
140
141 // Build primitive JSON object
142 array.add(Json.createObjectBuilder()
143 .add("type", "Feature")
144 .add("properties", propObj)
145 .add("geometry", geomObj));
146 }
147
148 protected void appendLayerBounds(DataSet ds, JsonObjectBuilder object) {
149 if (ds != null) {
150 Iterator<Bounds> it = ds.getDataSourceBounds().iterator();
151 if (it.hasNext()) {
152 Bounds b = new Bounds(it.next());
153 while (it.hasNext()) {
154 b.extend(it.next());
155 }
156 appendBounds(b, object);
157 }
158 }
159 }
160
161 protected void appendBounds(Bounds b, JsonObjectBuilder object) {
162 if (b != null) {
163 JsonArrayBuilder builder = Json.createArrayBuilder();
164 getCoorArray(builder, b.getMin());
165 getCoorArray(builder, b.getMax());
166 object.add("bbox", builder);
167 }
168 }
169
170 protected void appendLayerFeatures(DataSet ds, JsonObjectBuilder object) {
171 JsonArrayBuilder array = Json.createArrayBuilder();
172 if (ds != null) {
173 for (Node n : ds.getNodes()) {
174 appendPrimitive(n, array);
175 }
176 for (Way w : ds.getWays()) {
177 appendPrimitive(w, array);
178 }
179 }
180 object.add("features", array);
181 }
182}
Note: See TracBrowser for help on using the repository browser.