startPoint和endPoint是地图上选中的起点和终点,有经纬度和高度信息。 noFlyPositions是多个多边形的geoJSON格式数组。
function getNoDangerRoadNew(startPoint, endPoint) {
const lineSegment = turf.lineString([
[startPoint.lng, startPoint.lat],
[endPoint.lng, endPoint.lat]
])
let insectPolygon
for (let i = 0; i < noFlyPositions.length; i++) {
const polygon = turf.polygon([noFlyPositions[i]])
if (turf.booleanIntersects(lineSegment, polygon)) {
insectPolygon = polygon
break
}
}
if (!insectPolygon) { return [] }
// 目前只支持凸多边形
// turf.convex(insectPolygon)
const start = turf.point([startPoint.lng, startPoint.lat])
const end = turf.point([endPoint.lng, endPoint.lat])
const pointsAll = turf.explode(insectPolygon)
pointsAll.features.push(start, end)
const polygonNew = turf.convex(pointsAll)
// 提取多边形的顶点
const vertices = JSON.parse(JSON.stringify(polygonNew.geometry.coordinates[0]))
vertices.pop()
// 查找起始点和终点的索引
const startIdx = vertices.findIndex(pt => turf.booleanEqual(turf.point(pt), start))
const endIdx = vertices.findIndex(pt => turf.booleanEqual(turf.point(pt), end))
const clockwisePath = []
const counterClockwisePath = []
if (startIdx < endIdx) {
// 计算顺时针路径
for (let i = startIdx; i <= endIdx; i++) {
clockwisePath.push(vertices[i % vertices.length]) // 顺时针
}
// 计算逆时针路径
for (let i = startIdx; i + vertices.length >= endIdx; i--) {
counterClockwisePath.push(vertices[(i + vertices.length) % vertices.length]) // 逆时针
}
} else {
// 计算顺时针路径
for (let i = startIdx; i - vertices.length <= endIdx; i++) {
clockwisePath.push(vertices[i % vertices.length]) // 顺时针
}
// 计算逆时针路径
for (let i = startIdx; i >= endIdx; i--) {
counterClockwisePath.push(vertices[i % vertices.length]) // 逆时针
}
}
const clockwiseLine = turf.lineString(clockwisePath)
const counterClockwiseLine = turf.lineString(counterClockwisePath)
// 计算两条线段的长度
const clockwiseLength = turf.length(clockwiseLine)
const counterClockwiseLength = turf.length(counterClockwiseLine)
const selectedLine = clockwiseLength < counterClockwiseLength ? clockwisePath : counterClockwisePath
const centroid = turf.centroid(polygonNew)
// 添加绕过效果
for (let i = 1; i < selectedLine.length - 1; i++) {
const vertexPoint = turf.point(selectedLine[i])
selectedLine[i] = getDest(centroid, vertexPoint)
}
// 添加上升过程
const flyLine = []
flyLine.push(addAltToVertex(selectedLine[0], startPoint.alt))
for (let i = 0; i < selectedLine.length; i++) {
const tmpPoint = addAltToVertex(selectedLine[i], startPoint.alt + 100)
flyLine.push(tmpPoint)
}
flyLine.push(addAltToVertex(selectedLine[selectedLine.length - 1], endPoint.alt))
return flyLine
}
//添加高度到经纬度数据中
function addAltToVertex(vertex, height) {
return [vertex[0], vertex[1], height]
}
//求延长线上0.3km的点
function getDest(centroid, vertexPoint) {
const distance = 0.3
const bearing = turf.bearing(centroid, vertexPoint)
const extendedPoint = turf.destination(vertexPoint, distance, bearing)
return extendedPoint.geometry.coordinates
}