Provides:
- protoc generated model for Mapbox Vector Tiles v2.1.
- Provides MVT encoding through use of the Java Topology Suite (JTS).
See:
- https://github.com/mapbox/vector-tile-spec/tree/master/2.1 for details on the MVT spec.
- https://developers.google.com/protocol-buffers/ for details on protoc.
- http://www.vividsolutions.com/jts/ for details on JTS.
<dependency>
<groupId>com.wdtinc</groupId>
<artifactId>mapbox-vector-tile</artifactId>
<version>1.1.1</version>
</dependency>
compile 'com.wdtinc:mapbox-vector-tile:1.1.1'
Use MvtReader.loadMvt() to load MVT data from a path or input stream into JTS geometry. The TagKeyValueMapConverter instance will convert MVT feature tags to a Map with primitive values. The map will be stored as a JTS geometry user data object within the Geometry.
GeometryFactory geomFactory = new GeometryFactory();
List<Geometry> geoms = MvtReader.loadMvt(
Paths.get("path/to/your.mvt"),
geomFactory,
new TagKeyValueMapConverter());
// Allow negative-area exterior rings with classifier
List<Geometry> geoms = MvtReader.loadMvt(
Paths.get("path/to/your.mvt"),
geomFactory,
new TagKeyValueMapConverter(),
MvtReader.RING_CLASSIFIER_V1);
Create or load any JTS Geometry that will be included in the MVT.
Create tiled JTS geometry with JtsAdapter#createTileGeom(). MVTs currently do not support feature collections so any JTS geometry will be flattened to a single level. A TileGeomResult will contain the intersection geometry from clipping as well as the actual MVT geometry that uses extent coordinates. The intersection geometry can be used for hierarchical processing.
IGeometryFilter acceptAllGeomFilter = geometry -> true;
Envelope tileEnvelope = new Envelope(0d, 100d, 0d, 100d); // TODO: Your tile extent here
MvtLayerParams layerParams = new MvtLayerParams(); // Default extent
TileGeomResult tileGeom = JtsAdapter.createTileGeom(
jtsGeom, // Your geometry
tileEnvelope,
geomFactory,
layerParams,
acceptAllGeomFilter);
Create the VectorTile.Tile.Builder responsible for the MVT protobuf byte array:
VectorTile.Tile.Builder tileBuilder = VectorTile.Tile.newBuilder();
Create an empty layer for the MVT:
VectorTile.Tile.Layer.Builder layerBuilder = MvtLayerBuild.newLayerBuilder("myLayerName", layerParams);
MVT JTS Geometry can be converted to MVT features.
MvtLayerProps is a supporting class for building MVT layer key/value dictionaries. A user data converter will take JTS Geometry user data and convert it to MVT tags:
MvtLayerProps layerProps = new MvtLayerProps();
IUserDataConverter userDataConverter = new UserDataKeyValueMapConverter();
List<VectorTile.Tile.Feature> features = JtsAdapter.toFeatures(tileGeom.mvtGeoms, layerProps, userDataConverter);
Use MvtLayerBuild#writeProps() to add the key/value dictionary to the MVT layer.
MvtLayerBuild.writeProps(layerBuilder, layerProps);
VectorTile.Tile mvt = tileBuilder.build();
try {
Files.write(path, mvt.toByteArray());
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
See tests.
If vector_tile.proto is changed in the specification, VectorTile may need to be regenerated.
Command protoc
version should be the same version as the POM.xml dependency.
protoc --java_out=src/main/java src/main/resources/vector_tile.proto
These options were added to the .proto file:
- syntax = "proto2";
- option java_package = "com.wdtinc.mapbox_vector_tile";
- option java_outer_classname = "VectorTile";
Use the Github issue tracker.
- Creating tile geometry with non-simple line strings that self-cross in many places will be 'noded' by JTS during an intersection operation. This results in ugly output.
- Invalid or non-simple geometry may not work correctly with JTS operations when creating tile geometry.
See CONTRIBUTING