Changeset 18754 in josm for trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java
- Timestamp:
- 2023-06-14T00:22:08+02:00 (17 months ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/io/GeoJSONWriter.java
r18723 r18754 27 27 import jakarta.json.JsonValue; 28 28 import jakarta.json.JsonWriter; 29 import jakarta.json.spi.JsonProvider; 29 30 import jakarta.json.stream.JsonGenerator; 30 31 import jakarta.json.stream.JsonParser; … … 74 75 private static final BooleanProperty SKIP_EMPTY_NODES = new BooleanProperty("geojson.export.skip-empty-nodes", true); 75 76 private static final BooleanProperty UNTAGGED_CLOSED_IS_POLYGON = new BooleanProperty("geojson.export.untagged-closed-is-polygon", false); 77 78 /** 79 * Used to avoid many calls to {@link JsonProvider#provider} in {@link #getCoorArray(JsonArrayBuilder, EastNorth)}. 80 * For validating Mesa County, CO, this reduces CPU and memory usage of {@link #write()} by ~80%. By using this for 81 * other {@link Json} calls, {@link #write()} takes ~95% less resources than the original. And the entire process 82 * takes 1/4 of the time (38 minutes -> <10 minutes). 83 * <p> 84 * For more details, see <a href="https://github.com/jakartaee/jsonp-api/issues/346">JSONP #346</a>. 85 */ 86 protected static final JsonProvider JSON_PROVIDER = JsonProvider.provider(); 76 87 private static final Set<Way> processedMultipolygonWays = new HashSet<>(); 77 private EnumSet<Options> options = EnumSet.noneOf(Options.class);88 private final EnumSet<Options> options = EnumSet.noneOf(Options.class); 78 89 79 90 /** … … 138 149 public void write(boolean pretty, Writer writer) { 139 150 Map<String, Object> config = Collections.singletonMap(JsonGenerator.PRETTY_PRINTING, pretty); 140 try (JsonWriter jsonWriter = J son.createWriterFactory(config).createWriter(writer)) {141 JsonObjectBuilder object = J son.createObjectBuilder()151 try (JsonWriter jsonWriter = JSON_PROVIDER.createWriterFactory(config).createWriter(writer)) { 152 JsonObjectBuilder object = JSON_PROVIDER.createObjectBuilder() 142 153 .add("type", "FeatureCollection") 143 154 .add("generator", "JOSM"); … … 184 195 if (writeAsPolygon) { 185 196 geomObj.add("type", "Polygon"); 186 geomObj.add("coordinates", J son.createArrayBuilder().add(array));197 geomObj.add("coordinates", JSON_PROVIDER.createArrayBuilder().add(array)); 187 198 } else { 188 199 geomObj.add("type", "LineString"); … … 223 234 */ 224 235 private void visitMultiGeometry(final Relation r) { 225 final JsonArrayBuilder jsonArrayBuilder = J son.createArrayBuilder();236 final JsonArrayBuilder jsonArrayBuilder = JSON_PROVIDER.createArrayBuilder(); 226 237 r.getMemberPrimitives().stream().filter(p -> !(p instanceof Relation)) 227 238 .map(p -> { 228 final JsonObjectBuilder tempGeomObj = J son.createObjectBuilder();239 final JsonObjectBuilder tempGeomObj = JSON_PROVIDER.createObjectBuilder(); 229 240 p.accept(new GeometryPrimitiveVisitor(tempGeomObj)); 230 241 return tempGeomObj.build(); … … 239 250 */ 240 251 private void visitMultiPoints(final Relation r) { 241 final JsonArrayBuilder multiPoint = J son.createArrayBuilder();252 final JsonArrayBuilder multiPoint = JSON_PROVIDER.createArrayBuilder(); 242 253 r.getMembers().stream().map(RelationMember::getMember).filter(Node.class::isInstance).map(Node.class::cast) 243 254 .map(latLon -> getCoorArray(null, latLon)) … … 252 263 */ 253 264 private void visitMultiLineString(final Relation r) { 254 final JsonArrayBuilder multiLine = J son.createArrayBuilder();265 final JsonArrayBuilder multiLine = JSON_PROVIDER.createArrayBuilder(); 255 266 r.getMembers().stream().map(RelationMember::getMember).filter(Way.class::isInstance).map(Way.class::cast) 256 267 .map(Way::getNodes).map(p -> { … … 274 285 final Pair<List<MultipolygonBuilder.JoinedPolygon>, List<MultipolygonBuilder.JoinedPolygon>> mp = 275 286 MultipolygonBuilder.joinWays(r); 276 final JsonArrayBuilder polygon = J son.createArrayBuilder();287 final JsonArrayBuilder polygon = JSON_PROVIDER.createArrayBuilder(); 277 288 // Peek would theoretically be better for these two streams, but SonarLint doesn't like it. 278 289 // java:S3864: "Stream.peek" should be used with caution … … 303 314 }) 304 315 .forEach(polygon::add); 305 final JsonArrayBuilder multiPolygon = J son.createArrayBuilder().add(polygon);316 final JsonArrayBuilder multiPolygon = JSON_PROVIDER.createArrayBuilder().add(polygon); 306 317 geomObj.add("type", "MultiPolygon"); 307 318 geomObj.add("coordinates", multiPolygon); … … 310 321 311 322 private JsonArrayBuilder getCoorsArray(Iterable<Node> nodes) { 312 final JsonArrayBuilder builder = J son.createArrayBuilder();323 final JsonArrayBuilder builder = JSON_PROVIDER.createArrayBuilder(); 313 324 for (Node n : nodes) { 314 325 if (n.isLatLonKnown()) { … … 325 336 326 337 private static JsonArrayBuilder getCoorArray(JsonArrayBuilder builder, EastNorth c) { 327 return (builder != null ? builder : J son.createArrayBuilder())338 return (builder != null ? builder : JSON_PROVIDER.createArrayBuilder()) 328 339 .add(BigDecimal.valueOf(c.getX()).setScale(11, RoundingMode.HALF_UP)) 329 340 .add(BigDecimal.valueOf(c.getY()).setScale(11, RoundingMode.HALF_UP)); … … 337 348 338 349 // Properties 339 final JsonObjectBuilder propObj = J son.createObjectBuilder();350 final JsonObjectBuilder propObj = JSON_PROVIDER.createObjectBuilder(); 340 351 for (Map.Entry<String, String> t : p.getKeys().entrySet()) { 341 352 // If writing OSM information, follow Overpass syntax (escape `@` with another `@`) … … 357 368 } 358 369 if (options.contains(Options.WRITE_OSM_INFORMATION) && p.getReferrers(true).stream().anyMatch(Relation.class::isInstance)) { 359 final JsonArrayBuilder jsonArrayBuilder = J son.createArrayBuilder();370 final JsonArrayBuilder jsonArrayBuilder = JSON_PROVIDER.createArrayBuilder(); 360 371 for (Relation relation : Utils.filteredCollection(p.getReferrers(), Relation.class)) { 361 final JsonObjectBuilder relationObject = J son.createObjectBuilder();372 final JsonObjectBuilder relationObject = JSON_PROVIDER.createObjectBuilder(); 362 373 relationObject.add("rel", relation.getId()); 363 374 Collection<RelationMember> members = relation.getMembersFor(Collections.singleton(p)); … … 365 376 relationObject.add("role", 366 377 members.stream().map(RelationMember::getRole).collect(Collectors.joining(";"))); 367 final JsonObjectBuilder relationKeys = J son.createObjectBuilder();378 final JsonObjectBuilder relationKeys = JSON_PROVIDER.createObjectBuilder(); 368 379 // Uncertain if the @relation reltags need to be @ escaped. I don't think so, as example output 369 380 // didn't have any metadata in it. … … 379 390 380 391 // Geometry 381 final JsonObjectBuilder geomObj = J son.createObjectBuilder();392 final JsonObjectBuilder geomObj = JSON_PROVIDER.createObjectBuilder(); 382 393 p.accept(new GeometryPrimitiveVisitor(geomObj)); 383 394 final JsonObject geom = geomObj.build(); … … 385 396 if (!geom.isEmpty()) { 386 397 // Build primitive JSON object 387 array.add(J son.createObjectBuilder()398 array.add(JSON_PROVIDER.createObjectBuilder() 388 399 .add("type", "Feature") 389 400 .add("properties", prop.isEmpty() ? JsonValue.NULL : prop) … … 394 405 private static JsonValue convertValueToJson(String value) { 395 406 if (value.startsWith(JSON_VALUE_START_MARKER) && value.endsWith(JSON_VALUE_END_MARKER)) { 396 try (JsonParser parser = J son.createParser(new StringReader(value))) {407 try (JsonParser parser = JSON_PROVIDER.createParser(new StringReader(value))) { 397 408 if (parser.hasNext() && parser.next() != null) { 398 409 return parser.getValue(); … … 402 413 } 403 414 } 404 return J son.createValue(value);415 return JSON_PROVIDER.createValue(value); 405 416 } 406 417 … … 420 431 protected void appendBounds(Bounds b, JsonObjectBuilder object) { 421 432 if (b != null) { 422 JsonArrayBuilder builder = J son.createArrayBuilder();433 JsonArrayBuilder builder = JSON_PROVIDER.createArrayBuilder(); 423 434 getCoorArray(builder, b.getMin()); 424 435 getCoorArray(builder, b.getMax()); … … 428 439 429 440 protected void appendLayerFeatures(DataSet ds, JsonObjectBuilder object) { 430 JsonArrayBuilder array = J son.createArrayBuilder();441 JsonArrayBuilder array = JSON_PROVIDER.createArrayBuilder(); 431 442 if (ds != null) { 432 443 processedMultipolygonWays.clear();
Note:
See TracChangeset
for help on using the changeset viewer.