uniappx 开发微信小程序 腾讯地图偏移量计算
// utils/coordTransform.uts/*** 坐标转换工具类* 提供WGS84与腾讯地图坐标系之间的高精度转换*/
class CoordTransform {// 定义常量private static readonly a: number = 6378245.0private static readonly ee: number = 0.00669342162296594323private static readonly pi: number = 3.1415926535897932384626/*** WGS84转腾讯地图坐标系(GCJ02)* @param wgLat WGS84纬度* @param wgLon WGS84经度* @returns 腾讯地图坐标系 { lat: number, lng: number }*/static wgs84ToTencent(wgLat: number, wgLon: number): { lat: number, lng: number } {// 如果坐标在国外,直接返回if (!this.isInChina(wgLon, wgLat)) {return { lat: wgLat, lng: wgLon }}let dLat = this.transformLat(wgLon - 105.0, wgLat - 35.0)let dLng = this.transformLng(wgLon - 105.0, wgLat - 35.0)let radLat = wgLat / 180.0 * this.pilet magic = Math.sin(radLat)magic = 1 - this.ee * magic * magiclet sqrtMagic = Math.sqrt(magic)dLat = (dLat * 180.0) / ((this.a * (1 - this.ee)) / (magic * sqrtMagic) * this.pi)dLng = (dLng * 180.0) / (this.a / sqrtMagic * Math.cos(radLat) * this.pi)const mgLat = wgLat + dLatconst mgLng = wgLon + dLngreturn { lat: Number(mgLat.toFixed(6)), lng: Number(mgLng.toFixed(6))}}/*** 腾讯地图坐标系转WGS84(使用高精度算法)* @param tcLat 腾讯地图纬度* @param tcLon 腾讯地图经度* @returns WGS84坐标系 { lat: number, lng: number }*/static tencentToWgs84(tcLat: number, tcLon: number): { lat: number, lng: number } {// 如果坐标在国外,直接返回if (!this.isInChina(tcLon, tcLat)) {return { lat: tcLat, lng: tcLon }}// 使用高精度迭代算法let wgsLat = tcLatlet wgsLng = tcLonfor (let i = 0; i < 5; i++) {const gcj02 = this.wgs84ToTencent(wgsLat, wgsLng)const deltaLat = tcLat - gcj02.latconst deltaLng = tcLon - gcj02.lngwgsLat += deltaLatwgsLng += deltaLng// 如果误差已经很小,提前结束if (Math.abs(deltaLat) < 1e-7 && Math.abs(deltaLng) < 1e-7) {break}}return {lat: Number(wgsLat.toFixed(6)),lng: Number(wgsLng.toFixed(6))}}/*** 批量转换坐标(内部使用高精度转换)* @param devices 设备数组* @param targetSystem 目标坐标系 'tencent' | 'wgs84'* @returns 转换后的设备数组*/static batchConvertCoordinates(devices: Array<any>, targetSystem: string = 'tencent'): Array<any> {if (!Array.isArray(devices)) return []return devices.map(device => {if (!device) return deviceconst lat = Number(device.latitude)const lng = Number(device.longitude)if (isNaN(lat) || isNaN(lng)) {console.warn('设备经纬度无效', device)return device}let convertedif (targetSystem === 'tencent') {// WGS84转腾讯地图converted = this.wgs84ToTencent(lat, lng)} else {// 腾讯地图转WGS84(使用高精度算法)converted = this.tencentToWgs84(lat, lng)}return {...device,latitude: converted.lat,longitude: converted.lng,originalLatitude: lat, // 保留原始坐标originalLongitude: lng}})}/*** 转换单个坐标点(内部使用高精度转换)* @param lat 纬度* @param lng 经度* @param fromSystem 原坐标系 'wgs84' | 'tencent'* @param toSystem 目标坐标系 'tencent' | 'wgs84'* @returns 转换后的坐标 { lat: number, lng: number }*/static convertCoordinate(lat: number, lng: number, fromSystem: string = 'wgs84', toSystem: string = 'tencent'): { lat: number, lng: number } {if (fromSystem === 'wgs84' && toSystem === 'tencent') {return this.wgs84ToTencent(lat, lng)} else if (fromSystem === 'tencent' && toSystem === 'wgs84') {return this.tencentToWgs84(lat, lng)} else {console.warn('不支持的坐标系转换', fromSystem, '->', toSystem)return { lat, lng }}}/*** 检查坐标是否在中国境内* @param lat 纬度* @param lng 经度* @returns 是否在中国境内*/static isInChina(lng: number, lat: number): boolean {return lng >= 72.004 && lng <= 137.8347 && lat >= 0.8293 && lat <= 55.8271}// 私有方法:纬度转换private static transformLat(x: number, y: number): number {let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0return ret}// 私有方法:经度转换private static transformLng(x: number, y: number): number {let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0return ret}
}// 导出工具类
export default CoordTransform
使用方法:
//页面里引入插件
import CoordTransform from '../../utils/coordTransform.uts'
//使用
const getLatLog = CoordTransform.wgs84ToTencent(latitude, longitude)console.log(getLatLog)
