## 一、经纬度转像素
~~~
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布局