Ticket #17453: 17453.patch

File 17453.patch, 5.5 KB (added by GerdP, 7 years ago)

simple solution, not trying to produce output similar to osmtogeojson

  • src/org/openstreetmap/josm/io/GeoJSONWriter.java

     
    44import java.io.StringWriter;
    55import java.math.BigDecimal;
    66import java.math.RoundingMode;
     7import java.util.Collection;
    78import java.util.HashMap;
     9import java.util.HashSet;
    810import java.util.Iterator;
    911import java.util.List;
    1012import java.util.Map;
    1113import java.util.Map.Entry;
     14import java.util.Set;
    1215import java.util.stream.Stream;
    1316
    1417import javax.json.Json;
     
    4750    private final DataSet data;
    4851    private final Projection projection;
    4952    private static final BooleanProperty SKIP_EMPTY_NODES = new BooleanProperty("geojson.export.skip-empty-nodes", true);
     53    private static final Set<Way> processedMultipolygonWays = new HashSet<>();
    5054
    5155    /**
    5256     * Constructs a new {@code GeoJSONWriter}.
     
    108112        public void visit(Way w) {
    109113            if (w != null) {
    110114                final JsonArrayBuilder array = getCoorsArray(w.getNodes());
    111                 if (w.isClosed() && ElemStyles.hasAreaElemStyle(w, false)) {
    112                     final JsonArrayBuilder container = Json.createArrayBuilder().add(array);
    113                     geomObj.add("type", "Polygon");
    114                     geomObj.add("coordinates", container);
     115                if (w.isClosed()) {
     116                    if (ElemStyles.hasAreaElemStyle(w, false) || !processedMultipolygonWays.contains(w)) {
     117                        final JsonArrayBuilder container = Json.createArrayBuilder().add(array);
     118                        geomObj.add("type", "Polygon");
     119                        geomObj.add("coordinates", container);
     120                    }
    115121                } else {
    116                     geomObj.add("type", "LineString");
    117                     geomObj.add("coordinates", array);
     122                    if (w.isTagged() || !processedMultipolygonWays.contains(w)) {
     123                        geomObj.add("type", "LineString");
     124                        geomObj.add("coordinates", array);
     125                    }
    118126                }
    119127            }
    120128        }
     
    135143                geomObj.add("type", "MultiPolygon");
    136144                final JsonArrayBuilder multiPolygon = Json.createArrayBuilder().add(polygon);
    137145                geomObj.add("coordinates", multiPolygon);
     146                processedMultipolygonWays.addAll(r.getMemberPrimitives(Way.class));
    138147            } catch (MultipolygonBuilder.JoinedPolygonCreationException ex) {
    139148                Logging.warn("GeoJSON: Failed to export multipolygon {0}", r.getUniqueId());
    140149                Logging.warn(ex);
    141150            }
    142151        }
     152
     153        private JsonArrayBuilder getCoorsArray(Iterable<Node> nodes) {
     154            final JsonArrayBuilder builder = Json.createArrayBuilder();
     155            for (Node n : nodes) {
     156                LatLon ll = n.getCoor();
     157                if (ll != null) {
     158                    builder.add(getCoorArray(null, ll));
     159                }
     160            }
     161            return builder;
     162        }
    143163    }
    144164
    145165    private JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, LatLon c) {
     
    152172                .add(BigDecimal.valueOf(c.getY()).setScale(11, RoundingMode.HALF_UP));
    153173    }
    154174
    155     private JsonArrayBuilder getCoorsArray(Iterable<Node> nodes) {
    156         final JsonArrayBuilder builder = Json.createArrayBuilder();
    157         for (Node n : nodes) {
    158             LatLon ll = n.getCoor();
    159             if (ll != null) {
    160                 builder.add(getCoorArray(null, ll));
    161             }
    162         }
    163         return builder;
    164     }
    165 
    166175    protected void appendPrimitive(OsmPrimitive p, JsonArrayBuilder array) {
    167176        if (p.isIncomplete() ||
    168177            (SKIP_EMPTY_NODES.get() && p instanceof Node && p.getKeys().isEmpty())) {
     
    181190        p.accept(new GeometryPrimitiveVisitor(geomObj));
    182191        final JsonObject geom = geomObj.build();
    183192
    184         // Build primitive JSON object
    185         array.add(Json.createObjectBuilder()
    186                 .add("type", "Feature")
    187                 .add("properties", prop.isEmpty() ? JsonValue.NULL : prop)
    188                 .add("geometry", geom.isEmpty() ? JsonValue.NULL : geom));
     193        if (!geom.isEmpty()) {
     194            // Build primitive JSON object
     195            array.add(Json.createObjectBuilder()
     196                    .add("type", "Feature")
     197                    .add("properties", prop.isEmpty() ? JsonValue.NULL : prop)
     198                    .add("geometry", geom.isEmpty() ? JsonValue.NULL : geom));
     199        }
    189200    }
    190201
    191202    protected void appendLayerBounds(DataSet ds, JsonObjectBuilder object) {
     
    213224    protected void appendLayerFeatures(DataSet ds, JsonObjectBuilder object) {
    214225        JsonArrayBuilder array = Json.createArrayBuilder();
    215226        if (ds != null) {
    216             ds.allNonDeletedPrimitives().forEach(p -> appendPrimitive(p, array));
     227            processedMultipolygonWays.clear();
     228            Collection<OsmPrimitive> primitives = ds.allNonDeletedPrimitives();
     229            // Relations first
     230            for (OsmPrimitive p : primitives) {
     231                if (p instanceof Relation)
     232                    appendPrimitive(p, array);
     233            }
     234            for (OsmPrimitive p : primitives) {
     235                if (!(p instanceof Relation))
     236                    appendPrimitive(p, array);
     237            }
     238            processedMultipolygonWays.clear();
    217239        }
    218240        object.add("features", array);
    219241    }