//随机生成十六进制颜色
|
function randomHexColor() {
|
var hex = Math.floor(Math.random() * 16777216).toString(16); //生成ffffff以内16进制数
|
while (hex.length < 6) { //while循环判断hex位数,少于6位前面加0凑够6位
|
hex = '0' + hex;
|
}
|
return '#' + hex; //返回‘#'开头16进制颜色
|
}
|
Array.prototype.getRandomItem = function() {
|
return this[Math.floor(Math.random() * this.length)];
|
};
|
|
//字符串数据转数字字符串
|
function stringToNumber(stringInput) {
|
var stringArray = stringInput.split(",");
|
var numberArrayOutput = new Array();
|
for (var i = 0; i < stringArray.length; i++) {
|
numberArrayOutput.push(Number(stringArray[i]));
|
}
|
return numberArrayOutput;
|
}
|
|
//截取字符串,返回经度数值,cj添加,mty改为判断
|
function substringLon(str) {
|
var lon,
|
lon1,
|
lon2;
|
if (str.toString().substring(0, 1) !== '1') {
|
lon1 = str.toString().substring(0, 2);
|
lon2 = str.toString().substring(2);
|
} else {
|
lon1 = str.toString().substring(0, 3);
|
lon2 = str.toString().substring(3);
|
}
|
if(str.indexOf('.')==-1){
|
lon = Number(lon1 + "." + lon2);
|
}else{
|
lon = Number(lon1 + lon2);
|
}
|
return lon;
|
}
|
|
//截取字符串,返回纬度数值,cj添加
|
function substringLat(str) {
|
var lat1 = str.toString().substring(0, 2);
|
var lat2 = str.toString().substring(2);
|
var lat;
|
if(str.indexOf('.')==-1){
|
lat = Number(lat1 + "." + lat2);
|
}else{
|
lat = Number(lat1 + lat2);
|
}
|
return lat;
|
}
|
|
//定义一些常量
|
var x_PI = 3.14159265358979324 * 3000.0 / 180.0;
|
var PI = 3.1415926535897932384626;
|
var a = 6378245.0;
|
var ee = 0.00669342162296594323;
|
|
//将WGS84坐标系,转换成百度坐标体系
|
function wgs84tobd09(lon, lat) {
|
var gcj02poi1 = wgs84togcj02(lon, lat);
|
var baidupoi1 = gcj02tobd09(gcj02poi1[0], gcj02poi1[1]);
|
return baidupoi1;
|
}
|
//将百度坐标体系,转换成WGS84坐标系
|
function bd09towgs84(lon, lat) {
|
var gcj02poi1 = bd09togcj02(lon, lat);
|
var wgs84poi1 = gcj02towgs84(gcj02poi1[0], gcj02poi1[1]);
|
return wgs84poi1;
|
}
|
/**
|
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
|
* 即 百度 转 谷歌、高德
|
* @param bd_lon
|
* @param bd_lat
|
* @returns {*[]}
|
*/
|
function bd09togcj02(bd_lon, bd_lat) {
|
var x_pi = 3.14159265358979324 * 3000.0 / 180.0;
|
var x = bd_lon - 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 [ gg_lng, gg_lat ];
|
}
|
/**
|
* GCJ02 转换为 WGS84
|
* @param lng
|
* @param lat
|
* @returns {*[]}
|
*/
|
function gcj02towgs84(lng, lat) {
|
if (out_of_china(lng, lat)) {
|
return [ lng, lat ];
|
} else {
|
var dlat = transformlat(lng - 105.0, lat - 35.0);
|
var dlng = transformlng(lng - 105.0, lat - 35.0);
|
var radlat = lat / 180.0 * PI;
|
var magic = Math.sin(radlat);
|
magic = 1 - ee * magic * magic;
|
var sqrtmagic = Math.sqrt(magic);
|
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
|
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
|
mglat = lat + dlat;
|
mglng = lng + dlng;
|
return [ lng * 2 - mglng, lat * 2 - mglat ];
|
}
|
}
|
//WGS84转GCj02
|
function wgs84togcj02(lng, lat) {
|
if (out_of_china(lng, lat)) {
|
return [ lng, lat ];
|
} else {
|
var dlat = transformlat(lng - 105.0, lat - 35.0);
|
var dlng = transformlng(lng - 105.0, lat - 35.0);
|
var radlat = lat / 180.0 * PI;
|
var magic = Math.sin(radlat);
|
magic = 1 - ee * magic * magic;
|
var sqrtmagic = Math.sqrt(magic);
|
dlat = (dlat * 180.0) / ((a * (1 - ee)) / (magic * sqrtmagic) * PI);
|
dlng = (dlng * 180.0) / (a / sqrtmagic * Math.cos(radlat) * PI);
|
var mglat = lat + dlat;
|
var mglng = lng + dlng;
|
return [ mglng, mglat ];
|
}
|
}
|
/**
|
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
|
* 即谷歌、高德 转 百度
|
* @param lng
|
* @param lat
|
* @returns {*[]}
|
*/
|
function gcj02tobd09(lng, lat) {
|
var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
|
var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
|
var bd_lng = z * Math.cos(theta) + 0.0065;
|
var bd_lat = z * Math.sin(theta) + 0.006;
|
return [ bd_lng, bd_lat ]
|
}
|
/**
|
* 判断是否在国内,不在国内则不做偏移
|
* @param lng
|
* @param lat
|
* @returns {boolean}
|
*/
|
function out_of_china(lng, lat) {
|
return (lng < 72.004 || lng > 137.8347) || ((lat < 0.8293 || lat > 55.8271) || false);
|
}
|
function transformlat(lng, lat) {
|
var 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) {
|
var 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
|
}
|
|
/**
|
* approx distance between two points on earth ellipsoid
|
* @param {Object} lat1
|
* @param {Object} lng1
|
* @param {Object} lat2
|
* @param {Object} lng2
|
*/
|
var EARTH_RADIUS = 6378137.0; //单位M
|
var PI = Math.PI;
|
function getRad(d) {
|
return d * PI / 180.0;
|
}
|
function getFlatternDistance(lng1, lat1, lng2, lat2) {
|
var f = getRad((lat1 + lat2) / 2);
|
var g = getRad((lat1 - lat2) / 2);
|
var l = getRad((lng1 - lng2) / 2);
|
|
var sg = Math.sin(g);
|
var sl = Math.sin(l);
|
var sf = Math.sin(f);
|
|
var s,
|
c,
|
w,
|
r,
|
d,
|
h1,
|
h2;
|
var a = EARTH_RADIUS;
|
var fl = 1 / 298.257;
|
|
sg = sg * sg;
|
sl = sl * sl;
|
sf = sf * sf;
|
|
s = sg * (1 - sl) + (1 - sf) * sl;
|
c = (1 - sg) * (1 - sl) + sf * sl;
|
|
w = Math.atan(Math.sqrt(s / c));
|
r = Math.sqrt(s * c) / w;
|
d = 2 * w * a;
|
h1 = (3 * r - 1) / 2 / c;
|
h2 = (3 * r + 1) / 2 / s;
|
|
return d * (1 + fl * (h1 * sf * (1 - sg) - h2 * (1 - sf) * sg));
|
}
|
|
/**
|
* 判断一个点是否在多边形内部
|
* @param points 多边形坐标集合
|
* @param testPoint 需检测点坐标
|
* 返回true为真,false为假
|
* */
|
function insidePolygon(points, testPoint) {
|
var x = testPoint[0],
|
y = testPoint[1];
|
var inside = false;
|
for (var i = 0, j = points.length - 1; i < points.length; j = i++) {
|
var xi = points[i][0],
|
yi = points[i][1];
|
var xj = points[j][0],
|
yj = points[j][1];
|
|
var intersect = ((yi > y) != (yj > y))
|
&& (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
|
if (intersect)
|
inside = !inside;
|
}
|
return inside;
|
}
|
|
/**
|
* 将秒转换为 分:秒
|
* s int 秒数
|
*/
|
function s_to_hs(s) {
|
//计算分钟
|
//算法:将秒数除以60,然后下舍入,既得到分钟数
|
var h;
|
h = Math.floor(s / 60);
|
//计算秒
|
//算法:取得秒%60的余数,既得到秒数
|
s = s % 60;
|
//将变量转换为字符串
|
h += '';
|
s += '';
|
//如果只有一位数,前面增加一个0
|
h = (h.length == 1) ? '0' + h : h;
|
s = (s.length == 1) ? '0' + s : s;
|
return h + ':' + s;
|
}
|
|
//判断点是否在另一平面图中
|
//点: { x: xxx, y: xxx }
|
//线: [{ x: xxx, y: xxx }, { x: xxx, y: xxx }]
|
//面: [{ x: xxx, y: xxx }, { x: xxx, y: xxx }, { x: xxx, y: xxx }...]
|
function isPointInPolygon(point, polygon) {
|
//下述代码来源:http://paulbourke.net/geometry/insidepoly/,进行了部分修改
|
//基本思想是利用射线法,计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则
|
//在多边形内。还会考虑一些特殊情况,如点在多边形顶点上,点在多边形边上等特殊情况。
|
|
var N = polygon.length;
|
var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
|
var intersectCount = 0; //cross points count of x
|
var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
|
var p1,
|
p2; //neighbour bound vertices
|
var p = point; //测试点
|
|
p1 = polygon[0]; //left vertex
|
for (var i = 1; i <= N; ++i) { //check all rays
|
if (p.x == p1.x && p.y == p1.y) {
|
return boundOrVertex; //p is an vertex
|
}
|
|
p2 = polygon[i % N]; //right vertex
|
if (p.y < Math.min(p1.y, p2.y) || p.y > Math.max(p1.y, p2.y)) { //ray is outside of our interests
|
p1 = p2;
|
continue; //next ray left point
|
}
|
|
if (p.y > Math.min(p1.y, p2.y) && p.y < Math.max(p1.y, p2.y)) { //ray is crossing over by the algorithm (common part of)
|
if (p.x <= Math.max(p1.x, p2.x)) { //x is before of ray
|
if (p1.y == p2.y && p.x >= Math.min(p1.x, p2.x)) { //overlies on a horizontal ray
|
return boundOrVertex;
|
}
|
|
if (p1.x == p2.x) { //ray is vertical
|
if (p1.x == p.x) { //overlies on a vertical ray
|
return boundOrVertex;
|
} else { //before ray
|
++intersectCount;
|
}
|
} else { //cross point on the left side
|
var xinters = (p.y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y) + p1.x; //cross point of x
|
if (Math.abs(p.x - xinters) < precision) { //overlies on a ray
|
return boundOrVertex;
|
}
|
|
if (p.x < xinters) { //before ray
|
++intersectCount;
|
}
|
}
|
}
|
} else { //special case when ray is crossing through the vertex
|
if (p.y == p2.y && p.x <= p2.x) { //p crossing over p2
|
var p3 = polygon[(i + 1) % N]; //next vertex
|
if (p.y >= Math.min(p1.y, p3.y) && p.y <= Math.max(p1.y, p3.y)) { //p.y lies between p1.y & p3.y
|
++intersectCount;
|
} else {
|
intersectCount += 2;
|
}
|
}
|
}
|
p1 = p2; //next ray left point
|
}
|
|
if (intersectCount % 2 == 0) { //偶数在多边形外
|
return false;
|
} else { //奇数在多边形内
|
return true;
|
}
|
}
|
|
//判断两多变形是否存在点与区域的包含关系(A的点在B的区域内或B的点在A的区域内)
|
function isPointInPolygonBidirectional(plyA, plyB) {
|
let [a, b] = [ false, false ];
|
a = plyA.some(item => isPointInPolygon(item, plyB));
|
if (!a) {
|
b = plyB.some(item => isPointInPolygon(item, plyA));
|
}
|
return a || b;
|
}
|
|
//根据两点坐标计算方位角
|
function azimuthtwopoi(x1,y1,x2,y2){
|
var result;
|
var a = Math.abs(Math.atan((y2-y1)/(x2-x1)))*180/Math.PI;
|
if((x2-x1)<0){
|
if((y2-y1)>0){
|
result = a + 270;
|
}else{
|
result = 90 - a + 180;
|
}
|
}else{
|
if((y2-y1)>0){
|
result = 90 - a;
|
}else{
|
result = a + 90;
|
}
|
}
|
return result;
|
}
|
//获取立方体中心点、方位角、边线长度
|
function fixtoboxvertex(floorPoiStrArr){
|
var oriLonArr = [], oriLatArr = [];
|
for (var i = 0; i < 12; i=i+3) {
|
oriLonArr.push(Number(floorPoiStrArr[i]));
|
oriLatArr.push(Number(floorPoiStrArr[i+1]));
|
}
|
oriLonArr.push(Number(floorPoiStrArr[0]));
|
oriLatArr.push(Number(floorPoiStrArr[1]));
|
var sumLon = 0, sumLat = 0;
|
var heading = [], distance = [];
|
for (var i = 0; i < oriLonArr.length-1; i++) {
|
sumLon += oriLonArr[i];
|
sumLat += oriLatArr[i];
|
heading.push(azimuthtwopoi(oriLonArr[i],oriLatArr[i],oriLonArr[i+1],oriLatArr[i+1]));
|
distance.push(getFlatternDistance(oriLonArr[i],oriLatArr[i],oriLonArr[i+1],oriLatArr[i+1]));
|
}
|
var centerLon = sumLon/4;
|
var centerLat = sumLat/4;
|
return {centerLon, centerLat, heading, distance};
|
}
|