Ignore:
Timestamp:
2016-08-15T21:30:34+02:00 (4 years ago)
Author:
simon04
Message:

see #7307 - Enhance GeoJSON export

  • Save ways as LineString or Polygon depending on the area style.
  • Save multipolygons as MultiPolygon.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java

    r10173 r10817  
    77import java.util.HashMap;
    88import java.util.Iterator;
     9import java.util.List;
    910import java.util.Map;
    1011import java.util.Map.Entry;
     12import java.util.stream.Stream;
    1113
    1214import javax.json.Json;
     
    2022import org.openstreetmap.josm.data.coor.LatLon;
    2123import org.openstreetmap.josm.data.osm.DataSet;
    22 import org.openstreetmap.josm.data.osm.INode;
    23 import org.openstreetmap.josm.data.osm.IRelation;
    24 import org.openstreetmap.josm.data.osm.IWay;
     24import org.openstreetmap.josm.data.osm.MultipolygonBuilder;
     25import org.openstreetmap.josm.data.osm.MultipolygonBuilder.JoinedPolygon;
    2526import org.openstreetmap.josm.data.osm.Node;
    2627import org.openstreetmap.josm.data.osm.OsmPrimitive;
     28import org.openstreetmap.josm.data.osm.Relation;
    2729import org.openstreetmap.josm.data.osm.Way;
    28 import org.openstreetmap.josm.data.osm.visitor.PrimitiveVisitor;
     30import org.openstreetmap.josm.data.osm.visitor.AbstractVisitor;
    2931import org.openstreetmap.josm.data.projection.Projection;
    3032import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     33import org.openstreetmap.josm.gui.mappaint.ElemStyles;
     34import org.openstreetmap.josm.tools.Pair;
    3135
    3236/**
     
    8084    }
    8185
    82     private class GeometryPrimitiveVisitor implements PrimitiveVisitor {
     86    private class GeometryPrimitiveVisitor extends AbstractVisitor {
    8387
    8488        private final JsonObjectBuilder geomObj;
     
    8993
    9094        @Override
    91         public void visit(INode n) {
     95        public void visit(Node n) {
    9296            geomObj.add("type", "Point");
    9397            LatLon ll = n.getCoor();
    9498            if (ll != null) {
    95                 geomObj.add("coordinates", getCoorArray(Json.createArrayBuilder(), n.getCoor()));
     99                geomObj.add("coordinates", getCoorArray(null, n.getCoor()));
    96100            }
    97101        }
    98102
    99103        @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                     }
     104        public void visit(Way w) {
     105            if (w != null) {
     106                final JsonArrayBuilder array = getCoorsArray(w.getNodes());
     107                if (ElemStyles.hasAreaElemStyle(w, false)) {
     108                    final JsonArrayBuilder container = Json.createArrayBuilder().add(array);
     109                    geomObj.add("type", "Polygon");
     110                    geomObj.add("coordinates", container);
     111                } else {
     112                    geomObj.add("type", "LineString");
     113                    geomObj.add("coordinates", array);
    109114                }
    110                 geomObj.add("coordinates", array);
    111115            }
    112116        }
    113117
    114118        @Override
    115         public void visit(IRelation r) {
    116             // Do nothing
     119        public void visit(Relation r) {
     120            if (r != null && r.isMultipolygon() && !r.hasIncompleteMembers()) {
     121                final Pair<List<JoinedPolygon>, List<JoinedPolygon>> mp = MultipolygonBuilder.joinWays(r);
     122                final JsonArrayBuilder polygon = Json.createArrayBuilder();
     123                Stream.concat(mp.a.stream(), mp.b.stream())
     124                        .map(p -> getCoorsArray(p.getNodes())
     125                                // since first node is not duplicated as last node
     126                                .add(getCoorArray(null, p.getNodes().get(0).getCoor())))
     127                        .forEach(polygon::add);
     128                geomObj.add("type", "MultiPolygon");
     129                final JsonArrayBuilder multiPolygon = Json.createArrayBuilder().add(polygon);
     130                geomObj.add("coordinates", multiPolygon);
     131            }
    117132        }
    118133    }
     
    123138
    124139    private static JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, EastNorth c) {
    125         return builder
     140        return builder != null ? builder : Json.createArrayBuilder()
    126141                .add(BigDecimal.valueOf(c.getX()).setScale(11, RoundingMode.HALF_UP))
    127142                .add(BigDecimal.valueOf(c.getY()).setScale(11, RoundingMode.HALF_UP));
     143    }
     144
     145    private JsonArrayBuilder getCoorsArray(Iterable<Node> nodes) {
     146        final JsonArrayBuilder builder = Json.createArrayBuilder();
     147        for (Node n : nodes) {
     148            LatLon ll = n.getCoor();
     149            if (ll != null) {
     150                builder.add(getCoorArray(null, ll));
     151            }
     152        }
     153        return builder;
    128154    }
    129155
     
    177203        JsonArrayBuilder array = Json.createArrayBuilder();
    178204        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             }
     205            ds.allPrimitives().forEach(p -> appendPrimitive(p, array));
    185206        }
    186207        object.add("features", array);
Note: See TracChangeset for help on using the changeset viewer.