129 lines
2.9 KiB
Go
129 lines
2.9 KiB
Go
// Package timeutil
|
|
// @Author 铁憨憨[cory] 2025/6/11 20:08:00
|
|
package timeutil
|
|
|
|
import (
|
|
"github.com/paulmach/orb"
|
|
"github.com/paulmach/orb/geo"
|
|
"github.com/paulmach/orb/planar"
|
|
"github.com/tiger1103/gfast/v3/api/v1/common/shp"
|
|
"math"
|
|
)
|
|
|
|
// 将 Polygon 结构体转换为 [][]float64 格式
|
|
func ConvertPolygonToFloatArray(polygon shp.Polygon) [][]float64 {
|
|
// 创建结果切片,长度与 Polygon 中的 Positions 相同
|
|
result := make([][]float64, len(polygon.Positions))
|
|
|
|
// 遍历每个 Point 并转换为 []float64
|
|
for i, point := range polygon.Positions {
|
|
// 每个点转换为 [经度, 纬度, 高度, 宽度]
|
|
result[i] = []float64{
|
|
point.Lng,
|
|
point.Lat,
|
|
point.Alt,
|
|
point.Width,
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
// 判断点是否在多边形内
|
|
func FanWei(mian [][]float64, dian []float64) bool {
|
|
if len(mian) < 3 || len(dian) != 2 {
|
|
return false
|
|
}
|
|
|
|
var ring orb.Ring
|
|
for _, vertex := range mian {
|
|
ring = append(ring, orb.Point{vertex[0], vertex[1]})
|
|
}
|
|
|
|
// 闭合环
|
|
if !ring[0].Equal(ring[len(ring)-1]) {
|
|
ring = append(ring, ring[0])
|
|
}
|
|
|
|
polygon := orb.Polygon{ring}
|
|
point := orb.Point{dian[0], dian[1]}
|
|
|
|
return planar.PolygonContains(polygon, point)
|
|
}
|
|
|
|
// 点到线段最近点(投影点)
|
|
func closestPointOnSegment(p, a, b orb.Point) orb.Point {
|
|
ax, ay := a[0], a[1]
|
|
bx, by := b[0], b[1]
|
|
px, py := p[0], p[1]
|
|
|
|
abx := bx - ax
|
|
aby := by - ay
|
|
apx := px - ax
|
|
apy := py - ay
|
|
|
|
t := (apx*abx + apy*aby) / (abx*abx + aby*aby)
|
|
if t < 0 {
|
|
t = 0
|
|
} else if t > 1 {
|
|
t = 1
|
|
}
|
|
|
|
return orb.Point{ax + t*abx, ay + t*aby}
|
|
}
|
|
|
|
// 点到多边形的最近距离(米)
|
|
func PointToPolygonDistance(mian [][]float64, dian []float64) float64 {
|
|
point := orb.Point{dian[0], dian[1]}
|
|
|
|
ring := make(orb.Ring, len(mian))
|
|
for i, pt := range mian {
|
|
ring[i] = orb.Point{pt[0], pt[1]}
|
|
}
|
|
|
|
// 闭合多边形
|
|
if !ring[0].Equal(ring[len(ring)-1]) {
|
|
ring = append(ring, ring[0])
|
|
}
|
|
|
|
polygon := orb.Polygon{ring}
|
|
|
|
if planar.PolygonContains(polygon, point) {
|
|
return 0
|
|
}
|
|
|
|
minDist := math.MaxFloat64
|
|
for i := 0; i < len(ring)-1; i++ {
|
|
proj := closestPointOnSegment(point, ring[i], ring[i+1])
|
|
dist := geo.Distance(point, proj) // 单位:米
|
|
if dist < minDist {
|
|
minDist = dist
|
|
}
|
|
}
|
|
return minDist
|
|
}
|
|
|
|
// 计算两个经纬度点之间的球面距离(单位:米)
|
|
func PointToPointDistance(p1 []float64, p2 []float64) float64 {
|
|
point1 := orb.Point{p1[0], p1[1]}
|
|
point2 := orb.Point{p2[0], p2[1]}
|
|
return geo.Distance(point1, point2)
|
|
}
|
|
|
|
//func main() {
|
|
// polygonVertices := [][]float64{
|
|
// {106.518314, 29.627223},
|
|
// {106.519419, 29.627223},
|
|
// {106.518238, 29.626399},
|
|
// {106.519491, 29.626435},
|
|
// }
|
|
//
|
|
// targetPoint := []float64{117.51, 40.74}
|
|
//
|
|
// inPolygon := FanWei(polygonVertices, targetPoint)
|
|
// fmt.Printf("点是否在多边形内:%v\n", inPolygon)
|
|
//
|
|
// distance := pointToPolygonDistance(polygonVertices, targetPoint)
|
|
// fmt.Printf("点到多边形的最短距离(单位米):%.2f m\n", distance)
|
|
//}
|