Cesium 高德纠偏教程

📅 2026/7/13 12:21:30
Cesium 高德纠偏教程
高德纠偏 ·Gaode Transform· ▶ 在线运行案例案例合集三维可视化功能案例threehub.cn开源仓库github地址https://github.com/z2586300277/three-cesium-examples400个案例代码:网盘链接你将学到什么Cesium Entity 高层实体 API效果说明本案例演示高德纠偏效果BD-09(百度坐标系) To GCJ-02(火星坐标系)核心用到 Cesium。建议先打开文首在线案例查看动态画面再对照下方源码逐步理解。核心概念Viewer聚合 Scene、Camera、Clock 与渲染循环是 Cesium 应用入口。Entity面向点线面/模型/标签的高层 API与 Primitive 相比更适合交互与属性驱动。阅读下方完整源码时建议从init/load/animate三条主线入手再深入 shader 与工具函数。实现步骤创建 Viewer配置地形/影像若案例需要并设置初始相机在requestAnimationFrame循环中更新状态并 renderCesium 为viewer.render或自动渲染代码要点import * as Cesium from cesium;import * as dat from dat.gui;// 定义一些常量 const BD_FACTOR (3.14159265358979324 * 3000.0) / 180.0; const PI 3.1415926535897932384626; const RADIUS 6378245.0; const EE 0.00669342162296594323;class CoordTransform { /**BD-09(百度坐标系) To GCJ-02(火星坐标系)param lngparam latreturns {number[]}*/ static BD09ToGCJ02(lng, lat) { let x lng - 0.0065; let y lat - 0.006; let z Math.sqrt(xx yy) - 0.00002Math.sin(yBD_FACTOR); let theta Math.atan2(y, x) - 0.000003Math.cos(xBD_FACTOR); let gg_lng z * Math.cos(theta); let gg_lat z * Math.sin(theta); return [gg_lng, gg_lat]; }/**GCJ-02(火星坐标系) To BD-09(百度坐标系)param lngparam latreturns {number[]}constructor*/ static GCJ02ToBD09(lng, lat) { lat lat; lng lng; let z Math.sqrt(lnglng latlat) 0.00002Math.sin(latBD_FACTOR); let theta Math.atan2(lat, lng) 0.000003Math.cos(lngBD_FACTOR); let bd_lng z * Math.cos(theta) 0.0065; let bd_lat z * Math.sin(theta) 0.006; return [bd_lng, bd_lat]; }/**WGS-84(世界大地坐标系) To GCJ-02(火星坐标系)param lngparam latreturns {number[]}*/ static WGS84ToGCJ02(lng, lat) { lat lat; lng lng; if (this.out_of_china(lng, lat)) { return [lng, lat]; } else { let d this.delta(lng, lat); return [lng d[0], lat d[1]]; } }/**GCJ-02(火星坐标系) To WGS-84(世界大地坐标系)param lngparam latreturns {number[]}constructor*/ static GCJ02ToWGS84(lng, lat) { lat lat; lng lng; if (this.out_of_china(lng, lat)) { return [lng, lat]; } else { let d this.delta(lng, lat); let mgLng lng d[0]; let mgLat lat d[1]; return [lng2 - mgLng, lat2 - mgLat]; } }/*** param lngparam latreturns {number[]}*/ static delta(lng, lat) { let dLng this.transformLng(lng - 105, lat - 35); let dLat this.transformLat(lng - 105, lat - 35); const radLat (lat / 180) * PI; let magic Math.sin(radLat); magic 1 - EEmagicmagic; const sqrtMagic Math.sqrt(magic); dLng (dLng180) / ((RADIUS / sqrtMagic)Math.cos(radLat) * PI); dLat (dLat180) / (((RADIUS(1 - EE)) / (magicsqrtMagic))PI); return [dLng, dLat]; }/*** param lngparam latreturns {number}*/ static transformLng(lng, lat) { lat lat; lng lng; let ret 300.0 lng 2.0lat 0.1lnglng 0.1lnglat 0.1Math.sqrt(Math.abs(lng)); ret ((20.0Math.sin(6.0lngPI) 20.0Math.sin(2.0lngPI)) * 2.0) / 3.0; ret ((20.0Math.sin(lngPI) 40.0Math.sin((lng / 3.0)PI)) * 2.0) / 3.0; ret ((150.0Math.sin((lng / 12.0)PI) 300.0Math.sin((lng / 30.0)PI)) * 2.0) / 3.0; return ret; }/*** param lngparam latreturns {number}*/ static transformLat(lng, lat) { lat lat; lng lng; let ret -100.0 2.0lng 3.0lat 0.2latlat 0.1lnglat 0.2 * Math.sqrt(Math.abs(lng)); ret ((20.0Math.sin(6.0lngPI) 20.0Math.sin(2.0lngPI)) * 2.0) / 3.0; ret ((20.0Math.sin(latPI) 40.0Math.sin((lat / 3.0)PI)) * 2.0) / 3.0; ret ((160.0Math.sin((lat / 12.0)PI) 320Math.sin((latPI) / 30.0)) * 2.0) / 3.0; return ret; }/**判断是否在国内。不在国内不做偏移param lngparam latreturns {boolean}*/ static out_of_china(lng, lat) { lat lat; lng lng; return !(lng 73.66 lng 135.05 lat 3.86 lat 53.55); } }class AmapMercatorTilingScheme extends Cesium.WebMercatorTilingScheme {constructor() { super();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])); }; } }const box document.getElementById(box)const viewer new Cesium.Viewer(box, {animation: false,//是否创建动画小器件左下角仪表baseLayerPicker: false,//是否显示图层选择器右上角图层选择按钮baseLayer: false, // 不显示默认图层fullscreenButton: false,//是否显示全屏按钮右下角全屏选择按钮timeline: false,//是否显示时间轴infoBox: false,//是否显示信息框})viewer.imageryLayers.addImageryProvider( new Cesium.UrlTemplateImageryProvider({ url: https://webrd02.is.autonavi.com/appmaptile?langzh_cnsize1scale2style8x{x}y{y}z{z}, maximumLevel: 18, tilingScheme: new AmapMercatorTilingScheme() }) )viewer.entities.add({name: gltf,position: Cesium.Cartesian3.fromDegrees(116.3975, 39.9085, 0), // 北京的经纬度和高度model: {uri: FILE_HOST /files/model/LittlestTokyo.glb,minimumPixelSize: 128,maximumScale: 200,}})const gui new dat.GUI();const mapParams { mapType: 纠偏校正, // 默认使用纠偏后的高德地图 locations: 北京, };// 预定义常用位置 const locations { 北京: [116.3975, 39.9085, 2000], 上海: [121.4737, 31.2304, 2000], 广州: [113.2644, 23.1292, 2000], 深圳: [114.0579, 22.5431, 2000] };// 飞行到指定位置 function flyToLocation(name) { const position locations[name]; if (position) { viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(position[0], position[1], position[2]), duration: 1.5 }); } }// 添加GUI控制 const mapFolder gui.addFolder(坐标纠偏对比);// 添加地图类型选择 mapFolder.add(mapParams, mapType, [纠偏校正, 未纠正]).name(地图类型).onChange(function (value) { viewer.imageryLayers.removeAll(); viewer.imageryLayers.addImageryProvider( new Cesium.UrlTemplateImageryProvider({ url: https://webrd02.is.autonavi.com/appmaptile?langzh_cnsize1scale2style8x{x}y{y}z{z}, maximumLevel: 18, tilingScheme: value 纠偏校正 ? new AmapMercatorTilingScheme() : null }) ) });// 添加位置选择 mapFolder.add(mapParams, locations, Object.keys(locations)).name(常用位置) .onChange(function (value) { flyToLocation(value); });// 默认展开文件夹 mapFolder.open();flyToLocation(mapParams.locations);完整源码GitHub小结本文提供高德纠偏完整 Cesium.js 源码与在线 Demo建议先运行案例再改 uniform/参数做二次实验更多 Cesium.js 实战案例见 three-cesium-examples 合集 与 GitHub 开源仓库