// 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) //}