多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## 一、经纬度转像素 ~~~ function latlng2px(lat, lng) { var LatLng = (function(){ function LatLng(lat, lng){ this.lat = lat; this.lng = lng; } return LatLng; })(); var Point = (function(){ function Point(x, y){ this.x = x; this.y = y; } return Point; })(); var pointToLineDis = function(ps, pe, p){ var a = pe.lat - ps.lat; var b = ps.lng - pe.lng; var c = pe.lng * ps.lat - ps.lng * pe.lat; var dis = (a * p.lng + b * p.lat + c) / Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); return dis; }; var lineDis = function(p1, p2){ return Math.sqrt(Math.pow(p1.lat - p2.lat, 2) + Math.pow(p1.lng - p2.lng, 2)) }; var p = new LatLng(25.084816, 102.933879); // 左下 var pl = new LatLng(25.102940, 102.911459); // 左上 var pr = new LatLng(25.115624, 102.960745); // 右下 var getScreenPoint = function(latLngPoint){ var lineLeft = lineDis(pl, p); var lineRight = lineDis(p, pr); var leftDis = pointToLineDis(p, pl, latLngPoint); var rightDis = pointToLineDis(pr, p, latLngPoint); var leftPercent = rightDis / lineLeft; var rightPercent = leftDis / lineRight; var x = (1920) * rightPercent; // 1920:div容器的宽度 var y = (964) * (1 - leftPercent); // 964:div容器的高度 return new Point(x, y); }; var latlng = new LatLng(lat, lng); return getScreenPoint(latlng); } // latlng2px(25.102940, 102.911459) ~~~ 由于高德地图 **map.lngLatToContainer([Lon, Lat])** 方法在 **<=IE11** 下缩放的时候有问题,所以可以考虑使用上面的方式处理,解决兼容性问题 ~~~ function latlng2px(lat, lng) { var bounds = map.getBounds(); var northeast = bounds.northeast, southwest = bounds.southwest; var LatLng = (function(){ function LatLng(lat, lng){ this.lat = lat; this.lng = lng; } return LatLng; })(); var Point = (function(){ function Point(x, y){ this.x = x; this.y = y; } return Point; })(); var pointToLineDis = function(ps, pe, p){ var a = pe.lat - ps.lat; var b = ps.lng - pe.lng; var c = pe.lng * ps.lat - ps.lng * pe.lat; var dis = (a * p.lng + b * p.lat + c) / Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); return dis; }; var lineDis = function(p1, p2){ return Math.sqrt(Math.pow(p1.lat - p2.lat, 2) + Math.pow(p1.lng - p2.lng, 2)) }; var p = new LatLng(southwest.lat, southwest.lng); // 左下 var pl = new LatLng(northeast.lat, southwest.lng); // 左上 var pr = new LatLng(southwest.lat, northeast.lng); // 右下 var getScreenPoint = function(latLngPoint){ var lineLeft = lineDis(pl, p); var lineRight = lineDis(p, pr); var leftDis = pointToLineDis(p, pl, latLngPoint); var rightDis = pointToLineDis(pr, p, latLngPoint); var leftPercent = rightDis / lineLeft; var rightPercent = leftDis / lineRight; var x = (window.innerWidth) * rightPercent; // 1920:div容器的宽度 var y = (window.innerHeight) * (1 - leftPercent); // 964:div容器的高度 return new Point(x, y); }; var latlng = new LatLng(lat, lng); return getScreenPoint(latlng); } // console.log(latlng2px(25.102940, 102.911459)) ~~~ ## 二、计算两点连线的角度(平面) ~~~ function calcAngle(px1, py1, px2, py2) { //两点的x、y值 var x = px2-px1; var y = py2-py1; var hypotenuse = Math.sqrt(Math.pow(x, 2)+Math.pow(y, 2)); //斜边长度 var cos = x/hypotenuse; var radian = Math.acos(cos); //求出弧度 var angle = 180/(Math.PI/radian); //用弧度算出角度 if (y<0) { angle = -angle; } else if ((y == 0) && (x<0)) { angle = 180; } return angle; } // calcAngle(10, 10, 20, 20) ~~~ ## 三、已知一个点、长度、角度求延长线的坐标点 ~~~ // 绘制虚拟轨迹 function drawVirtualTrack() { if(orgDstCoord.orgLon && orgDstCoord.orgLat && orgDstCoord.dstLon && orgDstCoord.dstLat) { // 删除上一次的虚拟轨迹 if(vTrackLineArr.length > 0) { vTrackCoordsArr = []; map.remove(vTrackLineArr); vTrackLineArr = []; } // 最后一点坐标 var last = trackCoordsArr[trackCoordsArr.length-1]; // 最后一点到目的地距离 var distance = new AMap.LngLat(orgDstCoord.dstLon, orgDstCoord.dstLat).distance([last.lng, last.lat]); // 飞行角度 var extData = planeMarkers[selectedPlaneNum].getExtData(); var ang = extData.ang; var spd = extData.spd/3600; // 计算偏移坐标 var lengthen = spd*600000; // 延长10分钟的距离 var d = lengthen/6371004; // 6371004地球平均半径 var lng = (Math.PI/180)*last.lng; var lat = (Math.PI/180)*last.lat; var tc = (Math.PI/180)*ang; var y = Math.asin(Math.sin(lat)*Math.cos(d)+Math.cos(lat)*Math.sin(d)*Math.cos(tc)); var dlng = Math.atan2(Math.sin(tc)*Math.sin(d)*Math.cos(lat), Math.cos(d)-Math.sin(lat)*Math.sin(y)); var x = lng+dlng; var lon2 = (x*(180/Math.PI)+540%360-180).toFixed(5); var lat2 = (y*(180/Math.PI)).toFixed(5); // 虚拟线 var offsetDistance = new AMap.LngLat(lon2, lat2).distance([last.lng, last.lat]); vTrackCoordsArr = [[last.lng, last.lat]]; if(distance > 2*offsetDistance) { vTrackCoordsArr.push([lon2, lat2]); } vTrackCoordsArr.push([orgDstCoord.dstLon, orgDstCoord.dstLat]); // 绘制线段 var vpolyline = new AMap.Polyline({ path: vTrackCoordsArr, strokeColor: '#A4A9B1', strokeOpacity: 1, strokeWeight: 2, strokeStyle: "solid" }); vTrackLineArr.push(vpolyline); vpolyline.setMap(map); } } ~~~ ## 四、计算两点间的角度(地图) ~~~ function calcAngle(start, end) { var p_start = map.lngLatToContainer(start), p_end = map.lngLatToContainer(end); var diff_x = p_end.x - p_start.x, diff_y = p_end.y - p_start.y; return 360*Math.atan2(diff_y, diff_x)/(2*Math.PI)+90; } // calcAngle([88.926756, 42.37309], [119.687036, 29.6309]); ~~~ 注:如果在地图canvas上使用rotate,还需要再 * Math.PI/180 才行 ## 五、经纬度、高度转成three.js的xyz ~~~ function getPosition(lng, lat, alt) { var phi = (90-lat)*(Math.PI/180), theta = (lng+180)*(Math.PI/180), radius = alt+200, x = -(radius * Math.sin(phi) * Math.cos(theta)), z = (radius * Math.sin(phi) * Math.sin(theta)), y = (radius * Math.cos(phi)); return {x: x, y: y, z: z}; } ~~~ ## 六、地球坐标系 (WGS-84)转火星坐标系 (GCJ-02) 传送门:https://github.com/hiwanz/wgs2mars.js ( 已有判断是否在中国区 ) 以上都是本人亲测使用~