我们正在尝试使用mapbox-vector-tile-java将矢量瓦片端点合并到后端框架中,以将地理特征编码到矢量瓦片中。除了一些奇怪的行为,即渲染的特征被放置在比它们应有的纬度高得多的地方之外,我们大部分时间都在工作。放大时,特征会跳到较低的纬度,直到最终在非常低的缩放级别下达到相当好的精度。例如,我的数据是新墨西哥州的县。在初始页面加载时,所有县都呈现在加拿大。当我放大到 2 级时,它们会跳到加拿大南部。我放大的越多,他们就越接近新墨西哥州的实际位置。有谁知道我为什么会看到这种行为?
一些高级细节:
- 数据库中的地理特征位于 EPSG:4326 中。
- JTS 与 mapbox-vector-tile-java 结合使用来处理数据的编码。
- 将基于 URL 的 xyz 瓦片位置转换为瓦片边界使用 Mapbox 用于此类转换的精确方程式,如 MapBox 的 TileBelt 中所引用的。
示例网址
https://localhost:8443/app/location/data?x=0&y=0&z=0&config= {some:json}
构建向量图块的后端 Java 代码
Envelope tileEnvelope = this.getTileBounds(x, y, zoom);
GeometryFactory geomFactory = new GeometryFactory();
IGeometryFilter acceptAllGeomFilter = geometry -> true;
MvtLayerParams layerParams = new MvtLayerParams();
TileGeomResult tileGeom = JtsAdapter.createTileGeom(geometries, tileEnvelope, geomFactory, layerParams, acceptAllGeomFilter);
final VectorTile.Tile.Builder tileBuilder = VectorTile.Tile.newBuilder();
// Create MVT layer
final MvtLayerProps layerProps = new MvtLayerProps();
final IUserDataConverter ignoreUserData = new UserDataConverter();
// MVT tile geometry to MVT features
final List<VectorTile.Tile.Feature> features = JtsAdapter.toFeatures(tileGeom.mvtGeoms, layerProps, ignoreUserData);
final VectorTile.Tile.Layer.Builder layerBuilder = MvtLayerBuild.newLayerBuilder(layerName, layerParams);
layerBuilder.addAllFeatures(features);
MvtLayerBuild.writeProps(layerBuilder, layerProps);
// Build MVT layer
final VectorTile.Tile.Layer layer = layerBuilder.build();
// Add built layer to MVT
tileBuilder.addLayers(layer);
/// Build MVT
Tile mvt = tileBuilder.build();
return mvt.toByteArray();
将平铺网格位置转换为平铺边界的代码
public Envelope getTileBounds(int x, int y, int zoom)
{
return new Envelope(this.getLong(x, zoom), this.getLong(x + 1, zoom), this.getLat(y, zoom), this.getLat(y + 1, zoom));
}
public double getLong(int x, int zoom)
{
return ( x / Math.pow(2, zoom) * 360 - 180 );
}
public double getLat(int y, int zoom)
{
double r2d = 180 / Math.PI;
double n = Math.PI - 2 * Math.PI * y / Math.pow(2, zoom);
return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));
}
瓦片格网转换结果
x=0,y=0,z=1 的 URL 会导致 Env[-180.0 : 0.0, 0.0 : 85.0511287798066] 这是一个按预期覆盖北美的图块(我们确定了这个网站的有效性:www.maptiler .org/google-maps-coordinates-tile-bounds-projection )。
我们有几个预感(只是猜测)
- 瓦片网格位置到 mapbox-gl 矢量瓦片网格之间的转换与上述公式不同,尽管我们使用了它们也在 TileBelt 中使用的公式。
- mapbox-vector-tile-java 提供了编码错误的图块。
- 我们错误地设置了 JTS 几何的边界。