这是效果图,每隔22.5°就会有一个扇形区域,有三层区域,第一层是距离圆点5km,第二层是10km,第三层是50km。
第一步:高德地图中绘画圆
// 构造矢量圆形
let circle = new AMap.Circle({
center: position.value, // 圆心位置
radius: 5000, //半径
strokeColor: "#94D8F6", //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 1, //线粗细度
fillColor: "", //填充颜色
fillOpacity: 0.35, //填充透明度
});
let circle01 = new AMap.Circle({
center: position.value, // 圆心位置
radius: 10000, //半径
strokeColor: "#94D8F6", //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 1, //线粗细度
fillColor: "", //填充颜色
fillOpacity: 0.35, //填充透明度
});
let circle02 = new AMap.Circle({
center: position.value, // 圆心位置
radius: 50000, //半径
strokeColor: "#94D8F6", //线颜色
strokeOpacity: 1, //线透明度
strokeWeight: 1, //线粗细度
fillColor: "", //填充颜色
fillOpacity: 0.35, //填充透明度
});
map.add(circle); // 增加圆圈
map.add(circle01); // 增加圆圈
map.add(circle02); // 增加圆圈
第二步:绘制圆点到50km圆的分割线
就是每隔22.5°增加一条线
思路就是,要得知距离圆点50km某个方位的新点位。我写了一个方法。
// 已知某个点位,在相同经度下,计算沿纬度方向移动n米,然后旋转N度,获得的新点位:
calculateNewPoint(lat: number, lng: number, distance: number, angle: number) {
// lat 起始点纬度 lng起始点经度 distance 两点距离 angle 角度,顺时针为正,逆时针为负
const R = 6378137; // 地球半径,单位为米
const dRad = distance / R; // 距离转换为弧度
const angleRad = angle * Math.PI / 180; // 角度转换为弧度
const newLat = Math.asin(
Math.sin(lat * Math.PI / 180) * Math.cos(dRad) +
Math.cos(lat * Math.PI / 180) * Math.sin(dRad) * Math.cos(angleRad)
) * 180 / Math.PI;
const newLng = lng + Math.atan2(
Math.sin(angleRad) * Math.sin(dRad) * Math.cos(lat * Math.PI / 180),
Math.cos(dRad) - Math.sin(lat * Math.PI / 180) * Math.sin(newLat * Math.PI / 180)
) * 180 / Math.PI;
return { lat: newLat, lng: newLng };// return 新点位的经纬度
}
然后获取获取点位
for (let i = 1; i <= 31; i = i + 2) {
obj.push($tool.calculateNewPoint(position.value[1], position.value[0], n, 11.25 * i));// 获取最外圈的点位,因为第一条线,距离我的纬度是11.25,所以以此循环过后,就得到一周18个点
}
然后开始画线,将所有的50km获取的新点位,都和圆点进行连线
for (let index = 0; index < sectorPoints.value.length; index++) {
let line = new AMap.Polyline({
path: [
position.value,
[sectorPoints.value[index].lng, sectorPoints.value[index].lat],
],
isOutline: true,
outlineColor: index % 2 == 0 ? "#ff0056" : "#FFF766",
borderWeight: 0,
strokeColor: index % 2 == 0 ? "#ff0056" : "#FFF766",
strokeOpacity: 1,
strokeWeight: 1,
// 折线样式还支持 'dashed'
strokeStyle: "solid",
// strokeStyle是dashed时有效
// strokeDasharray: [15, 5],
lineJoin: "round",
lineCap: "round",
zIndex: 150,
});
pathline.push(line);
}
map.add(pathline);// 增加线段
然后我们就得到了这样的图案
第三步:寻找5km、10km、50的点,用来后期去分割区域
因为高德没有扇形的绘画功能,所以只能在扇形的两个点之间寻找很多个点,用来分割扇形,然后再画多边形
找点的代码
let setSector = (n: number, obj: any[]) => {
// 绘制扇形线条
// position.value 中心点
for (let i = 1; i <= 31; i = i + 2) {
obj.push($tool.calculateNewPoint(position.value[1], position.value[0], n, 11.25 * i));
let _path = [];
for (let j = 11.25 * (i - 2); j <= 11.25 * i; j = j + 0.5) {
let _one = $tool.calculateNewPoint(position.value[1], position.value[0], n, j);
_path.push([_one.lng, _one.lat]);
// [sectorPoints.value[index].lng, sectorPoints.value[index].lat]
}
if (n == 5000) {
// _path.push(position.value);
sector5kmLine.value.push({
path: _path,
});
} else if (n == 10000) {
sector10kmLine.value.push({
path: _path,
});
} else if (n == 50000) {
sector50kmLine.value.push({
path: _path,
});
}
}
};
setSector(50000, sectorPoints.value);// 存点
setSector(5000, sectorPoints5km.value);
setSector(10000, sectorPoints10km.value);
然后存储多边形的数据,都存到sectorArea中
for (let i = 0; i < sector5kmLine.value.length; i++) {
let _path01: any[] = [];
let _path02: any[] = [];
let _path03: any[] = [];
_path01 = JSON.parse(JSON.stringify(sector5kmLine.value[i].path));
_path01.push(position.value);
_path02 = JSON.parse(
JSON.stringify(
sector5kmLine.value[i].path.concat(
JSON.parse(JSON.stringify(sector10kmLine.value[i].path)).reverse()
)
)
);
_path03 = JSON.parse(
JSON.stringify(
sector50kmLine.value[i].path.concat(
JSON.parse(JSON.stringify(sector10kmLine.value[i].path)).reverse()
)
)
);
sectorArea.value.push({
// 5km 扇形区域
id: "5km" + i,// 预留每个区域id
status: 0, // 0 正常 1 撤离 2 隐蔽 3避迁 4 禁用食物
show: false,
path: _path01,
fillcolor: "#ee91fc",
polygon: "", // 多边形
});
sectorArea.value.push({
// 5km~10km 扇形区域
id: "5km10km" + i,// 预留每个区域id
status: 0, // 0 正常 1 撤离 2 隐蔽 3避迁 4 禁用食物
show: false,
path: _path02,
fillcolor: "#179188",
polygon: "", // 多边形
});
sectorArea.value.push({
// 50km~10km 扇形区域
id: "10km50km" + i,// 预留每个区域id
status: 0, // 0 正常 1 撤离 2 隐蔽 3避迁 4 禁用食物
show: false,
path: _path03,
fillcolor: "#17fffc",
polygon: "", // 多边形
});
}
正式画多边形
sectorArea.value.forEach((item: { path: any; fillcolor: any;id:string }) => {
let _polygon = new AMap.Polygon({
path: item.path,
strokeColor: "green",
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
fillColor: item.fillcolor,
zIndex: 150,
bubble: true,
extData:{
id:item.id// 区域标记
}
});
_polygon.on("mouseover", () => {
_polygon.setOptions({
//修改多边形属性的方法
fillColor: "#F47378",
});
});
_polygon.on("mouseout", () => {
_polygon.setOptions({
//修改多边形属性的方法
fillColor: item.fillcolor,
});
});
polygons.value.push(_polygon);
});
将画的多边形添加进地图中
map.add(polygons.value);
最终效果就是这样