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

Last change on this file since 10632 was 10173, checked in by Don-vip, 8 years ago

sonar - squid:S1186 - Methods should not be empty

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