/** * 创建者:王成 * 操作系统:MAC * 创建日期:2023年1月28日 * 描述:陈浩编写的坐标转换工具 */ /* 引入Cesium */ import * as Cesium from 'cesium'; 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 lng * @param lat * @returns {number[]} */ static BD09ToGCJ02(lng, lat) { let x = +lng - 0.0065 let y = +lat - 0.006 let z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * BD_FACTOR) let theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * BD_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 lng * @param lat * @returns {number[]} * @constructor */ static GCJ02ToBD09(lng, lat) { lat = +lat lng = +lng let z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * BD_FACTOR) let theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * BD_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 lng * @param lat * @returns {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 lng * @param lat * @returns {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 [lng * 2 - mgLng, lat * 2 - mgLat] } } /** * * @param lng * @param lat * @returns {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 - EE * magic * magic const sqrtMagic = Math.sqrt(magic) dLng = (dLng * 180) / ((RADIUS / sqrtMagic) * Math.cos(radLat) * PI) dLat = (dLat * 180) / (((RADIUS * (1 - EE)) / (magic * sqrtMagic)) * PI) return [dLng, dLat] } /** * * @param lng * @param lat * @returns {number} */ static transformLng(lng, lat) { lat = +lat lng = +lng let ret = 300.0 + lng + 2.0 * lat + 0.1 * lng * lng + 0.1 * lng * lat + 0.1 * Math.sqrt(Math.abs(lng)) ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0 ret += ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) / 3.0 ret += ((150.0 * Math.sin((lng / 12.0) * PI) + 300.0 * Math.sin((lng / 30.0) * PI)) * 2.0) / 3.0 return ret } /** * * @param lng * @param lat * @returns {number} */ static transformLat(lng, lat) { lat = +lat lng = +lng let ret = -100.0 + 2.0 * lng + 3.0 * lat + 0.2 * lat * lat + 0.1 * lng * lat + 0.2 * Math.sqrt(Math.abs(lng)) ret += ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) * 2.0) / 3.0 ret += ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) / 3.0 ret += ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) * 2.0) / 3.0 return ret } /** * * @param lng * @param lat * @returns {boolean} */ static out_of_china(lng, lat) { lat = +lat lng = +lng return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55) } /** * 坐标转换 84转笛卡尔 * @param {Viewer} viewer - 三维场景 * @param {object} position - {lng,lat,alt} 地理坐标 * @param {number} alt - 高度 * @returns {object} Cartesian3 笛卡尔坐标 */ static transformWGS84ToCartesian(viewer, position, alt) { return position ? Cesium.Cartesian3.fromDegrees( position.lng || position.lon, position.lat, (position.alt = alt || position.alt), Cesium.Ellipsoid.WGS84 ) : Cesium.Cartesian3.ZERO } /** * 坐标转换 笛卡尔转84 * @param {Viewer} viewer - 三维场景 * @param {object} cartesian - 笛卡尔坐标 * @returns {object} - {lng,lat,alt} 地理坐标 */ static transformCartesianToWGS84(viewer, cartesian) { let ellipsoid = Cesium.Ellipsoid.WGS84 let cartographic = ellipsoid.cartesianToCartographic(cartesian) return { lng: Cesium.Math.toDegrees(cartographic.longitude), lat: Cesium.Math.toDegrees(cartographic.latitude), alt: cartographic.height } } } export default CoordTransform