| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394 |
- /**
- * WGS84 → GCJ-02 → BD-09 坐标转换工具
- * 百度地图需要使用 BD-09 坐标系
- */
- const PI = Math.PI
- const X_PI = (PI * 3000.0) / 180.0
- const A = 6378245.0
- const EE = 0.00669342162296594323
- function transformLat(lng, lat) {
- 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
- }
- function transformLng(lng, lat) {
- 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
- }
- /** WGS84 → GCJ-02 (火星坐标) */
- function wgs84ToGcj02(lng, lat) {
- let dLat = transformLat(lng - 105.0, lat - 35.0)
- let dLng = transformLng(lng - 105.0, lat - 35.0)
- const radLat = (lat / 180.0) * PI
- let magic = Math.sin(radLat)
- magic = 1 - EE * magic * magic
- const sqrtMagic = Math.sqrt(magic)
- dLat = (dLat * 180.0) / (((A * (1 - EE)) / (magic * sqrtMagic)) * PI)
- dLng = (dLng * 180.0) / ((A / sqrtMagic) * Math.cos(radLat) * PI)
- return [lng + dLng, lat + dLat]
- }
- /** GCJ-02 → BD-09 (百度坐标) */
- function gcj02ToBd09(lng, lat) {
- const z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * X_PI)
- const theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * X_PI)
- return [z * Math.cos(theta) + 0.0065, z * Math.sin(theta) + 0.006]
- }
- /** WGS84 → BD-09 一步转换 */
- export function wgs84ToBd09(lng, lat) {
- const [gcjLng, gcjLat] = wgs84ToGcj02(lng, lat)
- return gcj02ToBd09(gcjLng, gcjLat)
- }
- /** 百度 BD-09 → WGS84,用于地图选点回填业务坐标 */
- export function bd09ToWgs84(lng, lat) {
- const x = Number(lng) - 0.0065
- const y = Number(lat) - 0.006
- const z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI)
- const theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI)
- const gcjLng = z * Math.cos(theta)
- const gcjLat = z * Math.sin(theta)
- const [wgsLng, wgsLat] = wgs84ToGcj02Inverse(gcjLng, gcjLat)
- return [wgsLng, wgsLat]
- }
- function wgs84ToGcj02Inverse(lng, lat) {
- const [forwardLng, forwardLat] = wgs84ToGcj02(lng, lat)
- return [lng * 2 - forwardLng, lat * 2 - forwardLat]
- }
- /** 转换管线数据中的坐标数组 */
- export function convertPipeline(pipeline) {
- return {
- ...pipeline,
- path: pipeline.path ? pipeline.path.map(([lng, lat]) => wgs84ToBd09(lng, lat)) : undefined,
- points: pipeline.points
- ? (Array.isArray(pipeline.points[0])
- ? pipeline.points.map(([lng, lat]) => wgs84ToBd09(lng, lat))
- : pipeline.points.map(p => ({ ...p, lng: wgs84ToBd09(p.lng, p.lat)[0], lat: wgs84ToBd09(p.lng, p.lat)[1] })))
- : undefined
- }
- }
- /** 转换单个坐标点 */
- export function convertCoord(lng, lat) {
- return wgs84ToBd09(lng, lat)
- }
- /** 批量转换点数组中的 lng/lat */
- export function convertPoints(points) {
- return points.map(p => {
- const [lng, lat] = wgs84ToBd09(p.lng, p.lat)
- return { ...p, lng, lat }
- })
- }
|