Being able to convert OpenStreetMap elements to JTS geometries allows us to perform a lot of interesting geometric operations on them.
For example, here is the the borough 'Mitte' of Berlin:
It can be built using the following code. The output is available here.
| public static void main(String[] args) |
| throws IOException, EntityNotFoundException |
| { |
| // String query = |
| // "http://overpass-api.de/api/interpreter?data=(rel(16566);>;);out;"; |
| String query = "http://osmtestdata.topobyte.de/relation-16566.osm"; |
| // Open a stream |
| InputStream input = new URL(query).openStream(); |
| OsmIterator iterator = new OsmXmlIterator(input, false); |
| InMemoryMapDataSet data = MapDataSetLoader.read(iterator, false, false, |
| true); |
| TLongObjectMap<OsmRelation> relations = data.getRelations(); |
| if (relations.isEmpty()) { |
| System.out.println("No relation found"); |
| return; |
| } |
| OsmRelation relation = relations.valueCollection().iterator().next(); |
| Geometry polygon = new GeometryBuilder().build(relation, data); |
| Map<String, String> tags = OsmModelUtil.getTagsAsMap(relation); |
| Map<String, Object> properties = new HashMap<>(); |
| for (String key : tags.keySet()) { |
| properties.put(key, tags.get(key)); |
| } |
| GeoJSONWriter writer = new GeoJSONWriter(); |
| org.wololo.geojson.Geometry g = writer.write(polygon); |
| Feature feature = new Feature(g, properties); |
| String json = feature.toString(); |
| System.out.println(GeoJsonHelper.prettyPrintFeature(json)); |
| } |
As a subclass of Geometry, the MultiPolygon implements the buffer() operation that produces an enlarged version of the polygon. As argument the operation accepts a distance that specifies how much larger the result will be.
| // Build the polygon from the relation |
| RegionBuilder regionBuilder = new RegionBuilder(); |
| RegionBuilderResult region = regionBuilder.build(relation, data); |
| MultiPolygon polygon = region.getMultiPolygon(); |
| // Create a buffer |
| Geometry buffer = polygon.buffer(0.005); |
| // Combine the polygon and its buffer into a GeometryCollection |
| Geometry both = new GeometryFactory() |
| .createGeometryCollection(new Geometry[] { polygon, buffer }); |
| // GeoJSON output |
| Map<String, Object> properties = new HashMap<>(); |
| GeoJSONWriter writer = new GeoJSONWriter(); |
| org.wololo.geojson.Geometry g = writer.write(both); |
| Feature feature = new Feature(g, properties); |
| String json = feature.toString(); |
| System.out.println(GeoJsonHelper.prettyPrintFeature(json)); |
The above example used a positive distance for the buffer() operation. It is however also possible to supply negative values, producing a polygon that is smaller than the input.
| // Build the polygon from the relation |
| RegionBuilder regionBuilder = new RegionBuilder(); |
| RegionBuilderResult region = regionBuilder.build(relation, data); |
| MultiPolygon polygon = region.getMultiPolygon(); |
| // Create a buffer |
| Geometry buffer = polygon.buffer(-0.005); |
| // Combine the polygon and its buffer into a GeometryCollection |
| GeometryCollection both = new GeometryFactory() |
| .createGeometryCollection(new Geometry[] { polygon, buffer }); |
| // GeoJSON output |
| Map<String, Object> properties = new HashMap<>(); |
| GeoJSONWriter writer = new GeoJSONWriter(); |
| org.wololo.geojson.Geometry g = writer.write(both); |
| Feature feature = new Feature(g, properties); |
| String json = feature.toString(); |
| System.out.println(GeoJsonHelper.prettyPrintFeature(json)); |
The Geometry class offers more operations, most notably the set operations: intersection, union, difference and symmetric difference. For example we can subtract the original polygon from its buffer using the difference operation:
| // Build the polygon from the relation |
| RegionBuilder regionBuilder = new RegionBuilder(); |
| RegionBuilderResult region = regionBuilder.build(relation, data); |
| MultiPolygon polygon = region.getMultiPolygon(); |
| // Create a buffer |
| Geometry buffer = polygon.buffer(0.005); |
| // Compute the difference, buffer - polygon |
| Geometry difference = buffer.difference(polygon); |
| // GeoJSON output |
| Map<String, Object> properties = new HashMap<>(); |
| GeoJSONWriter writer = new GeoJSONWriter(); |
| org.wololo.geojson.Geometry g = writer.write(difference); |
| Feature feature = new Feature(g, properties); |
| String json = feature.toString(); |
| System.out.println(GeoJsonHelper.prettyPrintFeature(json)); |