java - 确定铯 map 图 block 的纬度/经度范围

标签 java math latitude-longitude cesiumjs

我正在尝试根据我们存储在数据库中的数据生成 map 图 block ,并使用 UrlTemplateImageryProvider 将它们提供给 Cesium。对于每个 map 图 block ,我需要知道纬度/经度边界才能找到匹配的数据。我使用与 Google map 相同的图 block 方案,并发出类似 http://host/tiles/zoom/x/y 的请求。最初,我一直使用方程将这些 map 图 block 坐标转换为此处找到的纬度/经度边界:http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Tile_bounding_box但现在我想知道这是否不是要使用的正确投影。

对于初学者来说,我看到的所有 Web Mercator 文档都说 Tile 0,0 @ Zoom lvl 0 应该覆盖整个世界。这不是我在 Cesium 中看到的情况(缩放级别 0 有 2 个图 block )。也就是说,我的计算似乎适用于缩放级别 0、1、2 和 3,但当我转到缩放级别 4 时,纬度计算开始向南移动。如果我在 2D Google map 上绘制生成的经纬度点,它们看起来是正确的,但我可以清楚地看到 cesium 请求的图 block 具有不同的边界。所以我现在假设我只是使用错误的投影来计算图 block 边界。

我也在这里尝试过计算:http://www.maptiler.org/google-maps-coordinates-tile-bounds-projection/ 从像素转换为米,转换为纬度/经度,但它们似乎与网络墨卡托计算的结果相同。

那么有人可以帮我弄清楚如何计算铯所要求的图 block 的纬度/经度边界框吗?

以下是我基于 Slippy Map Tiles 的方法:

public static Box getLatLonBoundsForTile(int zoom, int x, int y) {
    double longitudeMin = tile2lon(x, zoom);
    double longitudeMax = tile2lon(x + 1, zoom);
    double latitudeMin = tile2lat(y + 1, zoom);
    double latitudeMax = tile2lat(y, zoom);

    Point swPoint = new Point(longitudeMin, latitudeMin);
    Point nePoint = new Point(longitudeMax, latitudeMax);

    return new Box(swPoint, nePoint);
}

public static double getColsForZoomLevel(int zoom) {
    if (zoom == 0) return 2;
    int noTiles = 8 * (int) (Math.pow(4, zoom - 1));
    return noTiles / getRowsForZoomLevel(zoom);
}
public static double getRowsForZoomLevel(int zoom) {
    if (zoom == 0) return 1;
    return Math.pow(2, zoom);
}
public static double tile2lon(int x, int zoom) {
    return x / getColsForZoomLevel(zoom) * 360.0 - 180;
}

public static double tile2lat(int y, int zoom) {
    double n = Math.PI - (2.0 * Math.PI * y) / getRowsForZoomLevel(zoom);
    return Math.toDegrees(Math.atan(Math.sinh(n)));
}

最佳答案

Cesium 包含一个类 WebMercatorTilingScheme ( source ) 计算图 block 的纬度/经度值(以弧度为单位),并在根级别具有可配置数量的图 block 。

对于 3D 渲染,通常图 block 是正方形的,边缘长度为 2 的幂,例如,所有级别的 256 x 256 像素图像。地球仪本身通常用矩形纹理包裹(360 度宽,180 度高)。为了解决这个问题,切片方案的级别 0 通常是两个图 block 宽,但只有一个图 block 高 (2 x 1)。下一层是 4 x 2 block ,然后是 8 x 4、16 x 8 等。

要实时查看此操作,请加载 Cesium Inspector ,在页面右侧查找一些选项,单击地形旁边的小+,然后选中显示图 block 坐标 >。坐标用 L 表示水平,用 XY 表示平铺方案中的位置。

关于java - 确定铯 map 图 block 的纬度/经度范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36205840/

相关文章:

mysql - 在大表中查找半径MySQL(纬度经度)内的点的最快方法是什么

java - 在java中通过ftp上传文件时出现错误

java - 在 Observer 内部的行中找不到可执行代码 - Android Studio gradle 断点

javascript - 我将如何在 Canvas 上旋转图像以面向其运动方向?

JavaScript 数学给出了完全错误的结果

python - 用 Pygame 画抛物线

ST_Distance_Spheroid 的 MySQL GeoSpatial 函数?返回 GLength 类型时使用的指标?

java - 查询 Jersey REST 服务时发生消息异常 (com.sun.jersey.api.MessageException)

java - 对数组进行循环操作的函数式方法

c++ - 如何使用 boost 处理经纬度值?