Files
FunJiaLib_Package/mapLib.js
T

195 lines
7.1 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Convert = exports.pointInsideCircle = exports.isInPolygon = exports.VerifyCoordinate = void 0;
/**
* 获取中心坐标
*/
class CenterGps {
rad2degr(rad) { return rad * 180 / Math.PI; }
degr2rad(degr) { return degr * Math.PI / 180; }
/**
* 计算多个经纬度的中心点 | 在一组坐标中获取中心坐标
* @param latLngInDeg array of arrays with latitude and longtitude
* pairs in degrees. e.g. [[latitude1, longtitude1], [latitude2
* [longtitude2] ...]
*
* @return array with the center latitude longtitude pairs in
* degrees.
*/
GetCenterFromDegrees(latLngInDegr, latIdx = 0, lngIdx = 1) {
var LATIDX = latIdx;
var LNGIDX = lngIdx;
var sumX = 0;
var sumY = 0;
var sumZ = 0;
for (var i = 0; i < latLngInDegr.length; i++) {
var lat = this.degr2rad(latLngInDegr[i][LATIDX]);
var lng = this.degr2rad(latLngInDegr[i][LNGIDX]);
// sum of cartesian coordinates
sumX += Math.cos(lat) * Math.cos(lng);
sumY += Math.cos(lat) * Math.sin(lng);
sumZ += Math.sin(lat);
}
var avgX = sumX / latLngInDegr.length;
var avgY = sumY / latLngInDegr.length;
var avgZ = sumZ / latLngInDegr.length;
// convert average x, y, z coordinate to latitude and longtitude
var lng = Math.atan2(avgY, avgX);
var hyp = Math.sqrt(avgX * avgX + avgY * avgY);
var lat = Math.atan2(avgZ, hyp);
return ([this.rad2degr(lat), this.rad2degr(lng)]);
}
}
exports.default = CenterGps;
/**
* 验证经纬度格式
*/
const VerifyCoordinate = (lat, lng) => {
var latreg = /^(\-|\+)?([0-8]?\d{1}\.\d{0,}|90\.0{0,}|[0-8]?\d{1}|90)$/;
if (!latreg.test(lat.toString())) {
console.log("纬度整数部分为0-90,小数部分为0到6位!");
return false;
}
var longrg = /^(\-|\+)?(((\d|[1-9]\d|1[0-7]\d|0{1,3})\.\d{0,})|(\d|[1-9]\d|1[0-7]\d|0{1,3})|180\.0{0,}|180)$/;
if (!longrg.test(lng.toString())) {
console.log("经度整数部分为0-180,小数部分为0到6位!");
return false;
}
return true;
};
exports.VerifyCoordinate = VerifyCoordinate;
/**
* 判断给定坐标是否在多边形中
*/
function isInPolygon(checkPoint, polygonPoints) {
var counter = 0;
var i;
var xinters;
var p1, p2;
var pointCount = polygonPoints.length;
p1 = polygonPoints[0];
for (i = 1; i <= pointCount; i++) {
p2 = polygonPoints[i % pointCount];
if (checkPoint[0] > Math.min(p1[0], p2[0]) &&
checkPoint[0] <= Math.max(p1[0], p2[0])) {
if (checkPoint[1] <= Math.max(p1[1], p2[1])) {
if (p1[0] != p2[0]) {
xinters =
(checkPoint[0] - p1[0]) *
(p2[1] - p1[1]) /
(p2[0] - p1[0]) +
p1[1];
if (p1[1] == p2[1] || checkPoint[1] <= xinters) {
counter++;
}
}
}
}
p1 = p2;
}
if (counter % 2 == 0) {
return false;
}
else {
return true;
}
}
exports.isInPolygon = isInPolygon;
/**
* 判断一个点是否在圆的内部
* @param point 测试点坐标
* @param circle 圆心坐标
* @param r 圆半径
* 返回true为真,false为假
* */
function pointInsideCircle(point, circle, r) {
if (r === 0)
return false;
var dx = circle[0] - point[0];
var dy = circle[1] - point[1];
return dx * dx + dy * dy <= r * r;
}
exports.pointInsideCircle = pointInsideCircle;
/**
* 火星坐标,GPS,转换
*/
exports.Convert = {
PI: 3.14159265358979324,
x_pi: 3.14159265358979324 * 3000.0 / 180.0,
delta: function (lat, lng) {
let lon = lng;
// Krasovsky 1940
//
// a = 6378245.0, 1/f = 298.3
// b = a * (1 - f)
// ee = (a^2 - b^2) / a^2;
let a = 6378245.0; // a: 卫星椭球坐标投影到平面地图坐标系的投影因子。
let ee = 0.00669342162296594323; // ee: 椭球的偏心率。
let dLat = this.transformLat(lon - 105.0, lat - 35.0);
let dLon = this.transformLon(lon - 105.0, lat - 35.0);
let radLat = lat / 180.0 * this.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) * this.PI);
dLon = (dLon * 180.0) / (a / sqrtMagic * Math.cos(radLat) * this.PI);
return { 'lat': dLat, 'lon': dLon };
},
//GPS---高德
gcj_encrypt: function (wgsLat, wgsLon) {
if (this.outOfChina(wgsLat, wgsLon))
return { 'lat': wgsLat, 'lon': wgsLon };
let d = this.delta(wgsLat, wgsLon);
return { 'lat': wgsLat + d.lat, 'lon': wgsLon + d.lon };
},
/**
*百度坐标转高德(传入经度、纬度)
* @param bd_lng
* @param bd_lat
*/
bd_decrypt: function (bd_lng, bd_lat) {
var X_PI = Math.PI * 3000.0 / 180.0;
var x = bd_lng - 0.0065;
var y = bd_lat - 0.006;
var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * X_PI);
var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * X_PI);
var gg_lng = z * Math.cos(theta);
var gg_lat = z * Math.sin(theta);
return { lng: gg_lng, lat: gg_lat };
},
//高德坐标转百度(传入经度、纬度)
bd_encrypt: function (gg_lng, gg_lat) {
var X_PI = Math.PI * 3000.0 / 180.0;
var x = gg_lng, y = gg_lat;
var z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * X_PI);
var theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * X_PI);
var bd_lng = z * Math.cos(theta) + 0.0065;
var bd_lat = z * Math.sin(theta) + 0.006;
return {
bd_lat: bd_lat,
bd_lng: bd_lng
};
},
outOfChina: function (lat, lng) {
if (lng < 72.004 || lng > 137.8347)
return true;
if (lat < 0.8293 || lat > 55.8271)
return true;
return false;
},
transformLat: function (x, y) {
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 * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(y * this.PI) + 40.0 * Math.sin(y / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (160.0 * Math.sin(y / 12.0 * this.PI) + 320 * Math.sin(y * this.PI / 30.0)) * 2.0 / 3.0;
return ret;
},
transformLon: function (x, y) {
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 * this.PI) + 20.0 * Math.sin(2.0 * x * this.PI)) * 2.0 / 3.0;
ret += (20.0 * Math.sin(x * this.PI) + 40.0 * Math.sin(x / 3.0 * this.PI)) * 2.0 / 3.0;
ret += (150.0 * Math.sin(x / 12.0 * this.PI) + 300.0 * Math.sin(x / 30.0 * this.PI)) * 2.0 / 3.0;
return ret;
}
};