/** * 地图坐标相关计算 */ import { map } from './index_old'; function _prepare4convert(lnglats) { var coor = []; var maxLength = 1000; var start = 0; var end = start + maxLength; while (end <= lnglats.length) { coor.push(lnglats.slice(start, end)); start += maxLength; end += maxLength; } if (start < lnglats.length) { coor.push(lnglats.slice(start)); } return coor; } function parse2LngLat(lnglats) { // 创建包含4个节点的折线及文字标注 var path = []; lnglats.forEach(function (value) { // eslint-disable-next-line no-undef path.push(new AMap.LngLat(value[0], value[1])); }); return path; } //定义一些常量 const PI = 3.1415926535897932384626; const a = 6378245.0; //长半轴 const ee = 0.00669342162296594323; //扁率/*** GCJ02 转换为 WGS84* @param lng* @param lat* @returns {*[]}*/ /** * 判断是否在国内,不在国内则不做偏移 * @param lng * @param lat * @returns {boolean} */ function out_of_china(lng, lat) { // 纬度3.86~53.55,经度73.66~135.05 return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55); } function 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; } function transformlng(lng, lat) { // lat = +latlng = +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; } /** * 将gps经纬度转换为高德地图经纬度 * @param {*} lnglats * @param {*} callback */ function _convertLatlng(index, coor, lnglats, type = 'gps', callback) { if (index < coor.length) { var path = parse2LngLat(coor[index]); // eslint-disable-next-line no-undef AMap.convertFrom(path, type, function (status, result) { if (result.info === 'ok') { lnglats.push.apply(lnglats, result.locations); _convertLatlng(index + 1, coor, lnglats, type, callback); } }); } else { callback(lnglats); } } export default { /** * 根据坐标点、距离和角度,得到另一个坐标点 * @param {*} pos * @param {*} distance 米 * @param {*} angle */ getLatLon: function (pos, distance, angle) { var Ea = 6378137; // 赤道半径 var Eb = 6356725; // 极半径 var dx = distance * Math.sin((angle * Math.PI) / 180); var dy = distance * Math.cos((angle * Math.PI) / 180); var ec = Eb + ((Ea - Eb) * (90.0 - pos[1])) / 90.0; var ed = ec * Math.cos((pos[1] * Math.PI) / 180); var lng = ((dx / ed + (pos[0] * Math.PI) / 180.0) * 180.0) / Math.PI; var lat = ((dy / ec + (pos[1] * Math.PI) / 180.0) * 180.0) / Math.PI; return [lng, lat]; }, /** * 将二维数组形式的坐标点数组转换为高德地图中 LngLat 类 * @param {*} lnglats * @returns */ parse2LngLat: function (lnglats) { // 创建包含4个节点的折线及文字标注 var path = []; lnglats.forEach(function (value) { // eslint-disable-next-line no-undef path.push(new AMap.LngLat(value[0], value[1])); }); return path; }, /** * 将高德地图的经纬度坐标转换为图形坐标 * @param {*} lnglats_GD * @returns */ lngLatToGeodeticCoord: function (lnglats_GD) { var coors_GD = []; for (let i = 0; i < lnglats_GD.length; i++) { var gd = lnglats_GD[i]; // eslint-disable-next-line no-undef var r = new AMap.LngLat(...gd); var p = map.lngLatToGeodeticCoord(r); // **记录转换后的3D地图图形坐标 coors_GD.push(p); } return coors_GD; }, convertFromGPS: function (gps, callback, type = 'gps') { var coor = _prepare4convert(gps); _convertLatlng(0, coor, [], type, function (result) { var gd = []; result.forEach((r) => { gd.push([r.lng, r.lat]); }); callback(gd); }); }, /** * 高德地图坐标转GPS坐标算法 */ gcj02towgs84(lng, lat) { // lat = +latlng = +lng if (out_of_china(lng, lat)) { return [lng, lat]; } else { let dlat = transformlat(lng - 105.0, lat - 35.0); let dlng = transformlng(lng - 105.0, lat - 35.0); let radlat = (lat / 180.0) * PI; let magic = Math.sin(radlat); magic = 1 - ee * magic * magic; let sqrtmagic = Math.sqrt(magic); dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI); dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI); let mglat = Math.round((lat * 2 - lat - dlat) * 1000000) / 1000000; let mglng = Math.round((lng * 2 - lng - dlng) * 1000000) / 1000000; return [mglng, mglat]; } } };