mapbox矢量图块java中的矢量图块会导致在异常高纬度的mapbox gl中渲染特征

mapbox矢量图块java中的矢量图块会导致在异常高纬度的mapbox gl中渲染特征,mapbox,mapbox-gl,mapbox-gl-js,vector-tiles,Mapbox,Mapbox Gl,Mapbox Gl Js,Vector Tiles,我们正在尝试将矢量图块端点合并到后端框架中,使用它将地理特征编码到矢量图块中。除了一些奇怪的行为,渲染的特征被放置在比它们应该高出很多的纬度上,我们几乎都能正常工作。放大时,特征会跳到较低的纬度,直到最终在非常低的缩放级别达到相当高的精度。例如,我的数据是新墨西哥州的县。在初始页面上加载加拿大所有呈现的县。当我放大到二级放大时,它们会跳到加拿大南部。我放大的越多,他们就越接近新墨西哥州的实际位置。有人知道我为什么会看到这种行为吗 一些高层细节: 数据库中的地理特征见EPSG:4326 JTS与m

我们正在尝试将矢量图块端点合并到后端框架中,使用它将地理特征编码到矢量图块中。除了一些奇怪的行为,渲染的特征被放置在比它们应该高出很多的纬度上,我们几乎都能正常工作。放大时,特征会跳到较低的纬度,直到最终在非常低的缩放级别达到相当高的精度。例如,我的数据是新墨西哥州的县。在初始页面上加载加拿大所有呈现的县。当我放大到二级放大时,它们会跳到加拿大南部。我放大的越多,他们就越接近新墨西哥州的实际位置。有人知道我为什么会看到这种行为吗

一些高层细节:
  • 数据库中的地理特征见EPSG:4326
  • JTS与mapbox矢量图块java结合使用,以处理数据编码
  • 将基于URL的xyz平铺位置转换为平铺边界使用Mapbox用于此类转换的精确公式,如Mapbox的平铺边界中所引用 示例URL {some:json}

    构建向量图块的后端Java代码 平铺网格转换结果 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矢量瓷砖网格之间的转换与上述等式不同,尽管我们使用了一个等式,它们也在瓷砖中使用
  • mapbox矢量磁贴java提供的磁贴编码不正确
  • 我们错误地设置了JTS几何体的边界

  • 当然,这是一个显而易见的解决方案,但不知何故,我们没有更早地抓住。我们只需要在编码矢量块之前将JTS特性投影到EPSG3857

    将要素投影到3857时如何制作封套?
      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)));
    }