## 一、經緯度轉像素
~~~
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 ( 已有判斷是否在中國區 )
以上都是本人親測使用~
- 事件
- mouse縮放與拖動
- drag拖動
- 事件兼容
- animation/transition
- canvas
- 改變圖片顏色
- html轉圖片
- 視頻操作
- 圖片縮放、水印、放大鏡
- 虛線
- 圓環進度條
- 形狀事件
- 圓角矩形
- 繪制注意
- arcTo與貝塞爾
- 橢圓及橢圓進度
- 五角星進度
- 常用圖形
- 計算顯示文本寬度
- 算法
- 幾何算法
- 地圖應用相關
- 運行符
- web安全
- 新窗口打開
- xss
- 分享交流
- php環境搭建及xhr交互
- node環境搭建及xhr交互
- node之socketio
- svg之入門介紹
- svg動畫
- vue之搜索聯想
- vue之登錄和echarts
- vue之組件交互與slot
- vue之loading
- vue之上傳進度
- webpack及cli
- 開發技巧
- 常用
- 移動端
- 錯誤處理
- 預加載
- 代理判斷
- 數組擴展
- 對象擴展
- 字符串擴展
- 語音播報
- 收集
- 文章/日記
- 框架/庫/插件
- 工具
- 學習網站
- 專業術語
- 正則
- 常用驗證
- 方法基礎
- es6擴展
- 深入實踐
- 快捷使用
- html
- css
- http協議
- http
- https
- socket
- 地圖/圖表
- mapbox
- echarts
- arcgis
- MapView及事件
- 添加WMS/WMTS層
- 增刪點線面
- 入門使用
- popup彈層
- 大數據處理
- 批量點
- 批量線
- 在線繪制
- GraphicLayer顯示/隱藏
- 動態改變位置
- 去除版權信息
- 添加控件
- Symbol
- 自定義path標記
- 圖片標記
- 文本標記
- 旋轉
- UI
- 自定義
- 3D地圖
- 創建實例
- basemap
- 底圖切換
- 自定義底圖
- 中心和范圍
- pupup彈層更新
- 坐標轉換
- 方向線
- leaflet
- amap
- 框架/類庫/腳手架
- vue
- 常見問題
- 組件框架
- vue-router
- 命名視圖
- url參數映射到prop
- sublime支持
- 隨手記
- 常用功能
- threejs
- 常用效果
- 其他特效
- requirejs
- 簡單使用
- jquery
- 方法擴展
- 使用筆記
- 組件擴展
- react
- 黨見問題
- 學習筆記
- 學習筆記-進階
- react-redux
- react-router
- redux
- 其他模塊說明
- 組件框架
- sublime支持
- gulp
- 安裝使用
- js壓縮
- css壓縮
- 組合使用
- copy文件
- 項目使用
- protobuf
- 入門
- layui
- 登錄驗證
- laydate
- 安裝工具
- yarn
- reactNative
- 入門介紹
- vueNative
- 入門介紹
- 版本控制
- git常用
- git擴展
- git問題
- git其他
- git擴展2
- 編輯器
- vscode
- atom
- webstorm
- 插件
- clipboard
- 奇淫巧技
- js
- 個性打印
- css
- 濾鏡效果
- 文本省略
- 當前色
- 新特性
- 花樣邊框效果
- 波紋效果
- 個性placeholder
- 偽元素內容
- 容器居中
- 知識點
- js
- 遞歸
- 沙箱
- 內存泄漏
- es6語法
- 變量介紹
- FileRead
- ajax
- web存儲
- css
- rem布局