0

我们正在尝试使用mapbox-vector-tile-java将矢量瓦片端点合并到后端框架中,以将地理特征编码到矢量瓦片中。除了一些奇怪的行为,即渲染的特征被放置在比它们应有的纬度高得多的地方之外,我们大部分时间都在工作。放大时,特征会跳到较低的纬度,直到最终在非常低的缩放级别下达到相当好的精度。例如,我的数据是新墨西哥州的县。在初始页面加载时,所有县都呈现在加拿大。当我放大到 2 级时,它们会跳到加拿大南部。我放大的越多,他们就越接近新墨西哥州的实际位置。有谁知道我为什么会看到这种行为?

一些高级细节:

  1. 数据库中的地理特征位于 EPSG:4326 中。
  2. JTS 与 mapbox-vector-tile-java 结合使用来处理数据的编码。
  3. 将基于 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 )。

我们有几个预感(只是猜测)

  1. 瓦片网格位置到 mapbox-gl 矢量瓦片网格之间的转换与上述公式不同,尽管我们使用了它们也在 TileBelt 中使用的公式。
  2. mapbox-vector-tile-java 提供了编码错误的图块。
  3. 我们错误地设置了 JTS 几何的边界。
4

1 回答 1

0

当然,这被证明是一个明显的解决方案,不知何故我们没有早点发现。我们只需要将 JTS 特征投影到 EPSG 3857,然后再对矢量切片进行编码。

于 2017-02-14T05:25:50.690 回答