//随机生成十六进制颜色 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}; }