/**
|
* 地图坐标相关计算
|
*/
|
|
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];
|
}
|
},
|
|
//从GPS转高德
|
wgs84_To_Gcj02(lon, lat) {
|
if (out_of_china(lon, lat)) {
|
return [lon, lat];
|
} else {
|
let dLat = transformlat(lon - 105.0, lat - 35.0);
|
let dLon = transformlng(lon - 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);
|
dLon = (dLon * 180.0) / ((a / sqrtMagic) * Math.cos(radLat) * PI);
|
let mgLat = lat + dLat;
|
let mgLon = lon + dLon;
|
return [mgLon, mgLat];
|
}
|
}
|
};
|