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
属性定义了瓦片方案,minimumLevel
和maximumLevel
定义了瓦片的最小和最大级别。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);
结果示例
纠偏前
纠偏后
– 欢迎点赞、关注、转发、收藏【我码玄黄】,各大平台同名。