使用高德地图js api 自动画出电子围栏
因直接画多边形不太准确,需要沿路来画围栏
电子围栏思路:
1. 找到原点经纬度 x
const CENTER = [116.397504,39.89619]
const DISTANCE = 300 //单位m
const map = new AMap.Map("container", {
center: CENTER,
zoom: 14
});
2. 根据x点在地图上画出一个圆
const circle = new AMap.Circle({
center: CENTER,
radius: DISTANCE, //半径
borderWeight: 3,
strokeColor: "#FF33FF",
strokeOpacity: 1,
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
strokeStyle: 'dashed',
strokeDasharray: [10, 10],
fillColor: '#1791fc',
zIndex: 50
})
circle.setMap(map)
// 缩放地图到合适的视野级别
map.setFitView([ circle ])
参考:
https://lbs.amap.com/api/java...
3. 在圆边线上 分别找到向 东、东南、南、西南、西、西北、北、东北 8个方向的位置
得到 x1,y1 ~ x8,y8 ,8个 位置的 经纬度,定义为 A1 ~ A8 的坐标
先根据圆的公式,找到圆上的各点,再用各点转换成地图的经纬度
/**
*
* 获取圆上的点(步长 45度)
*
**/
function setCirclePoint(centerpoint = CENTER, radius = DISTANCE) {
const r = 6371000; //地球的平均半径
const numpoints = 360;
const phase = 2 * Math.PI / numpoints;
let pointArr = []
//画点
for (let i = 0; i < numpoints; i+=45) {
// 计算坐标点
let dx = (radius * Math.cos(i * phase));
let dy = (radius * Math.sin(i * phase));
// 转换成经纬度
let dlng = dx / (r * Math.cos(centerpoint.lat * Math.PI / 180) * Math.PI / 180);
let dlat = dy / (r * Math.PI / 180);
let newlng = centerpoint.lng + dlng;
let newlag = centerpoint.lat + dlat;
pointArr.push([newlng,newlag])
// 实例化点标记
const marker = new AMap.Marker({
position: [newlng, newlag],
icon: startIcon,
offset: new AMap.Pixel(-13, -30)
});
markers.push(marker);
marker.setMap(map);
}
return pointArr
}
如图:
参考:
https://blog.csdn.net/jinshit...
https://blog.csdn.net/Dust_Ev...
https://lbs.amap.com/api/andr...
4. 搜索 A1 ~ A8 8个坐标最近的 POI点,A1 = “国贸三期”,A2 = “东直门”,A3 = “奥体森林公园”。。。。类推
// 高德地图查询周边
function aMapSearchNearBy(centerPoint) {
return new Promise((resolve,reject)=>{
AMap.service(["AMap.PlaceSearch"], () => {
const placeSearch = new AMap.PlaceSearch({
pageSize: 10, // 每页10条
pageIndex: 1, // 获取第一页
});
// 第一个参数是关键字,这里传入的空表示不需要根据关键字过滤
// 第二个参数是经纬度,数组类型
// 第三个参数是半径,周边的范围
// 第四个参数为回调函数
placeSearch.searchNearBy('', centerPoint, 1000, (status, result) => {
if(result.info === 'OK') {
const locationList = result.poiList.pois; // 周边地标建筑列表
resolve(locationList[0])
} else {
console.log('获取位置信息失败!');
reject()
}
});
});
})
}
因必须是A1-A8顺序返回POI结果,高德API为异步,所以使用Promise进行同步处理
//获取POI信息
const POIArr = await Promise.all(points.map(async (item)=>{
return await aMapSearchNearBy(item)
}))
参考:
https://lbs.amap.com/api/java...
5. 将这8个POI点依次相连(A1-A2,A2-A3,A3-A4,...A8-A1)用导航路径画出 (步行),得到 L1 ~ L8 这 8条路径
/**
* 绘制路线(步行)
*/
function drawWalk(data, i){
return new Promise((resolve,reject)=>{
//步行导航
const walking = new AMap.Walking({
map: map,
panel: "panel",
hideMarkers: true, //设置隐藏路径规划的起始点图标
});
let start = [POIArr[i].location.lng, POIArr[i].location.lat]
let end = i === POIArr.length-1 ? [POIArr[0].location.lng, POIArr[0].location.lat] : [POIArr[i+1].location.lng, POIArr[i+1].location.lat]
//根据起终点坐标规划步行路线
walking.search(start, end, (status, result) => {
resolve(result)
if (status === 'complete') {
log.success('绘制步行路线完成')
} else {
log.error('步行路线数据查询失败' + result)
}
});
});
}
依次画出步行路径
const walkRes = await Promise.all(POIArr.map(async (item, index)=>{
return await drawWalk(item, index)
}))
如图:
参考:
https://lbs.amap.com/api/java...
6. 存储8条路线的拐点
根据各步行路径返回的信息找到路的拐点,并保存起来,保存之前需要去重。
walkRes.map((key)=>{
const steps = key.routes[0].steps
steps.map((item, index)=>{
item.path.map((pos)=>{
formatData(pos)
})
})
})
7. 验证保存的拐点数据,画出的多边形是否和路线一致
第一次取的值为steps属性下的start_location,但出如下图
但不是沿路的,也缺失了一些拐点
第二次取steps下的path中的路线,搞定
8. 完成。
注:代码不全,仅供参考
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。