当前位置: 首页 > article >正文

Cesium影像纠偏:高德地图加载与坐标系纠偏技巧

Cesium中UrlTemplateImageryProvider的扩展

前言

在Cesium中,UrlTemplateImageryProvider是一个用于加载网络上的图像服务的类。它可以用来加载WMTS(Web Map Tile Service)或TMS(Tile Map Service)等瓦片服务,也可以用来加载一般的图片URL。

使用UrlTemplateImageryProvider的示例代码

// 创建一个UrlTemplateImageryProvider实例,用于加载在线的地图服务
var provider = new Cesium.UrlTemplateImageryProvider({
    // 图片的URL模板,其中{z},{x},{y}会被相应的瓦片级别、列和行索引替换
    url: 'https://your.tile.service/tiles/{z}/{x}/{y}.png', 
    // 瓦片服务的范围和分辨率设置
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    // 瓦片服务的最小和最大级别
    minimumLevel: 0,
    maximumLevel: 18,
    // 用于缓存的瓦片名称的前缀
    credit: new Cesium.Credit('Your Tile Service provider '),
    // 用于处理网络请求的可选对象
    proxy: new Cesium.DefaultProxy('/your/proxy/server')
});
// 将创建的provider添加到Cesium的Viewer中
viewer.imagery.addImageryProvider(provider);

在这个例子中,我们创建了一个UrlTemplateImageryProvider的实例,并指定了用于获取瓦片的URL模板。tilingScheme属性定义了瓦片方案,minimumLevelmaximumLevel定义了瓦片的最小和最大级别。credit属性用于表示提供数据的组织或个人。如果服务器需要跨域访问,则可以使用proxy属性来设置代理服务器。

最后,我们将这个提供者添加到Cesium的Viewer中,这样就可以在Cesium的三维地图中看到我们加载的在线地图服务了。

高德地图

前文了解到,UrlTemplateImageryProvider通过制定url的format模板,方便用户实现自己的Provider,比如国内的高德,百度,腾讯等影像服务,url都是一个固定的规范。例如引入高德地图的代码如下:

var provider = new Cesium.UrlTemplateImageryProvider({
    url: 'https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}',
    tilingScheme: new Cesium.WebMercatorTilingScheme(),
    minimumLevel: 4,
    maximumLevel: 18,
});
viewer.imagery.addImageryProvider(provider);

但是高德地图采用中国国家测绘局制订的地理信息系统的坐标系GCJ02,即火星坐标系,它是在WGS84坐标系的基础上进行一次加密。因此Cesium在加载高德地图服务底图时,会存在偏差和纠偏的问题。

WebMercatorTilingScheme类,是Cesium自带的EPSG:3857切片方案,因为高德的加密偏移问题,需要基于该类进行扩展,自定义高德纠偏切片方案。

import CoordTransform from '@src/assets/calculate/CoordTransform'

class AmapMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
    constructor(options) {
        super(options)
        let projection = new Cesium.WebMercatorProjection()
        this._projection.project = function(cartographic, result) {
            result = CoordTransform.WGS84ToGCJ02(
                Cesium.Math.toDegrees(cartographic.longitude),
                Cesium.Math.toDegrees(cartographic.latitude)
            )
            result = projection.project(
                new Cesium.Cartographic(
                    Cesium.Math.toRadians(result[0]),
                    Cesium.Math.toRadians(result[1])
                )
            )
            return new Cesium.Cartesian2(result.x, result.y)
        }
        this._projection.unproject = function(cartesian, result) {
            let cartographic = projection.unproject(cartesian)
            result = CoordTransform.GCJ02ToWGS84(
                Cesium.Math.toDegrees(cartographic.longitude),
                Cesium.Math.toDegrees(cartographic.latitude)
            )
            return new Cesium.Cartographic(
                Cesium.Math.toRadians(result[0]),
                Cesium.Math.toRadians(result[1])
            )
        }
    }
}

export default AmapMercatorTilingScheme

其中CoordTransform类是WGS84与GCJ02的互相转换计算类,此方法原理不再解释,网上都有文章解释。

至此,将扩展类AmapMercatorTilingScheme引用到tilingScheme属性中,就可实现高德地图加载过程中的自动纠偏。

自定义影像

根据上文的高德地图的纠偏方式,可以举一反三出,当我们自己部署局部影像地图时,若出现了偏差,都可以在WebMercatorTilingScheme类的扩展下,手动设置纠偏的坐标计算函数,再赋予给tilingScheme属性。

import CoordTransform from '@src/assets/calculate/CoordTransform'

class CustomMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {
    constructor(options) {
        super(options)
        let projection = new Cesium.WebMercatorProjection()
        this._projection.project = function(cartographic, result) {
            // LinearTransform为自定义的线性纠偏坐标的函数
            result = CoordTransform.linearTransform(
                Cesium.Math.toDegrees(cartographic.longitude),
                Cesium.Math.toDegrees(cartographic.latitude),
                options.fromPoint,
                options.toPoint
            )
            result = projection.project(
                new Cesium.Cartographic(
                    Cesium.Math.toRadians(result[0]),
                    Cesium.Math.toRadians(result[1])
                )
            )
            return new Cesium.Cartesian2(result.x, result.y)
        }
        this._projection.unproject = function(cartesian, result) {
            let cartographic = projection.unproject(cartesian)
            // LinearTransform为自定义的反线性纠偏坐标的函数
            result = CoordTransform.linearTransformReverse(
                Cesium.Math.toDegrees(cartographic.longitude),
                Cesium.Math.toDegrees(cartographic.latitude),
                options.fromPoint,
                options.toPoint
            )
            return new Cesium.Cartographic(
                Cesium.Math.toRadians(result[0]),
                Cesium.Math.toRadians(result[1])
            )
        }
    }
}

export default CustomMercatorTilingScheme

WebMercatorTilingScheme的扩展类赋予给tilingScheme属性,代码如下:

import CustomMercatorTilingScheme from './CustomMercatorTilingScheme'

class CustomImageryProvider extends Cesium.UrlTemplateImageryProvider {
    constructor(options = {}) {
        if (options.schemeOptions) {
            options['tilingScheme'] = new CustomMercatorTilingScheme(options.schemeOptions)
        }
        super(options)
    }
}
export default CustomImageryProvider

// 最后,在Viewer中创建一个实例Provider对象并添加。
const imageryProvider = new Cesium.CustomImageryProvider({
    url: mapUrl,
    minimumLevel: minLevel,
    maximumLevel: maxLevel,
    schemeOptions: {
        toPoint: { lng: 108.17547739, lat: 22.60060366 },
        fromPoint: { lng: 108.17554578, lat: 22.60056109 }
    }
});
let layer = viewer.imageryLayers.addImageryProvider(imageryProvider);

结果示例

纠偏前

纠偏后

– 欢迎点赞、关注、转发、收藏【我码玄黄】,各大平台同名。


http://www.kler.cn/a/317380.html

相关文章:

  • 【项目组件】第三方库——websocketpp
  • [JAVAEE] 面试题(四) - 多线程下使用ArrayList涉及到的线程安全问题及解决
  • 《Django 5 By Example》阅读笔记:p76-p104
  • Python——NumPy库的简单用法,超级详细教程使用
  • 如何使用 Web Scraper API 高效采集 Facebook 用户帖子信息
  • 数字孪生在智慧能源项目中的关键作用,你了解多少?
  • 【机器学习(九)】分类和回归任务-多层感知机 (MLP) -Sentosa_DSML社区版
  • Github 2024-09-21Rust开源项目日报 Top10
  • Qt/C++ 了解NTFS文件系统,解析0x80 $Data属性,获取Run Lists数据列表
  • 仓颉编程语言4,遇到BUG求助
  • 数据中心里全速运行的处理器正在浪费能源
  • golang格式化输入输出
  • 【3D打印】使用simplify 3D切片更改Gcode手动断电续打、掉电、未打完继续打印、补救
  • Parallels Desktop 20 for Mac 推出:完美兼容 macOS Sequoia 与 Win11 24H2
  • 【Godot4.3】自定义数列类NumList
  • 【Qt | Qstring】Qstring详细介绍(字符串的添加、删除、修改、查询、截断、删除空白字符等)
  • Gitlab runner的使用示例(二):Maven + Docker 自动化构建与部署
  • 【游戏引擎】C++自制游戏引擎 Lunar Game Engine
  • 基于vue框架的宠物销售管理系统3m9h3(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。
  • 微软开源GraphRAG的使用教程-使用自定义数据测试GraphRAG
  • Java中的快速排序算法详解
  • c++ pair
  • ubuntu下检查端口是否占用问题,编写shell脚本检查端口是否占用
  • 使用Python实现图形学曲线和曲面的NURBS算法
  • ChartLlama: A Multimodal LLM for Chart Understanding and Generation论文阅读
  • unity Compute Shaders 使程序在GPU中运行