001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.io; 003 004import java.util.Iterator; 005import java.util.Map; 006import java.util.Map.Entry; 007 008import org.json.JSONStringer; 009import org.openstreetmap.josm.data.Bounds; 010import org.openstreetmap.josm.data.coor.LatLon; 011import org.openstreetmap.josm.data.osm.Changeset; 012import org.openstreetmap.josm.data.osm.Node; 013import org.openstreetmap.josm.data.osm.OsmPrimitive; 014import org.openstreetmap.josm.data.osm.Relation; 015import org.openstreetmap.josm.data.osm.Way; 016import org.openstreetmap.josm.data.osm.visitor.Visitor; 017import org.openstreetmap.josm.gui.layer.OsmDataLayer; 018 019public class GeoJSONWriter implements Visitor { 020 021 private OsmDataLayer layer; 022 private JSONStringer out; 023 private static final boolean skipEmptyNodes = true; 024 025 public GeoJSONWriter(OsmDataLayer layer) { 026 this.layer = layer; 027 } 028 029 public String write() { 030 out = new JSONStringer(); 031 out.object().key("type").value("FeatureCollection"); 032 out.key("generator").value("JOSM"); 033 appendLayerBounds(); 034 out.key("features").array(); 035 for (Node n : layer.data.getNodes()) { 036 appendPrimitive(n); 037 } 038 for (Way w : layer.data.getWays()) { 039 appendPrimitive(w); 040 } 041 out.endArray().endObject(); 042 return out.toString(); 043 } 044 045 @Override 046 public void visit(Node n) { 047 out.key("type").value("Point").key("coordinates"); 048 appendCoord(n.getCoor()); 049 } 050 051 @Override 052 public void visit(Way w) { 053 out.key("type").value("LineString").key("coordinates").array(); 054 for (Node n : w.getNodes()) { 055 appendCoord(n.getCoor()); 056 } 057 out.endArray(); 058 } 059 060 @Override 061 public void visit(Relation e) { 062 } 063 064 @Override 065 public void visit(Changeset cs) { 066 } 067 068 protected void appendPrimitive(OsmPrimitive p) { 069 if (p.isIncomplete()) { 070 return; 071 } else if (skipEmptyNodes && p instanceof Node && p.getKeys().isEmpty()) { 072 return; 073 } 074 out.object().key("type").value("Feature"); 075 Map<String, String> tags = p.getKeys(); 076 out.key("properties").object(); 077 for (Entry<String, String> t : tags.entrySet()) { 078 out.key(t.getKey()).value(t.getValue()); 079 } 080 out.endObject(); 081 // append primitive specific 082 out.key("geometry").object(); 083 p.accept(this); 084 out.endObject(); 085 out.endObject(); 086 } 087 088 protected void appendCoord(LatLon c) { 089 if (c != null) { 090 out.array().value(c.lon()).value(c.lat()).endArray(); 091 } 092 } 093 094 protected void appendLayerBounds() { 095 Iterator<Bounds> it = layer.data.getDataSourceBounds().iterator(); 096 if (it.hasNext()) { 097 Bounds b = new Bounds(it.next()); 098 while (it.hasNext()) { 099 b.extend(it.next()); 100 } 101 appendBounds(b); 102 } 103 } 104 105 protected void appendBounds(Bounds b) { 106 if (b != null) { 107 out.key("bbox").array() 108 .value(b.getMinLon()).value(b.getMinLat()) 109 .value(b.getMaxLon()).value(b.getMaxLat()).endArray(); 110 } 111 } 112}