我试图找到一种方法来检查一对纬度/经度坐标是否在一个区域内(由其他纬度/经度坐标生成)。
例如,如果我的区域是用这些坐标生成的矩形:
43.672162 , -79.43585
43.629845 , -79.314585
我想检查这些坐标是否在那个区域内:
43.651989 , -79.371993
我试过使用这个包,但我不能让它工作:
github.com/kellydunn/golang-geo
p1 := geo.NewPoint(coords[0].LatX, coords[0].LonX)
p2 := geo.NewPoint(coords[0].LatY, coords[0].LonY)
geo.NewPolygon(p1, p2)
我想知道是否有人可以分享他们的实现,或者任何可以为我指明正确方向的资源?我也愿意使用谷歌地图 API。
这只是一个数学,比较坐标。
如果 A 坐标在矩形内部,则 A.x 必须小于 rect.x1 并大于 rect.x2 或其他。和 y 坐标类似的算法。
我不会围棋,但是你可以用叉积来判断你的兴趣点是在向量的左边还是右边。矢量可以是 p1 -> p2,然后是 p2 -> p3,等等。如果它们都在同一侧,则该点位于多边形形状内。
请记住,您必须考虑地球的子午线和其他可能的因素。
这还假设您的多边形点形成一个凸形(船体)。如果它不是船体,那么它可能会更困难。
// This is mock code, I dont know Go
// This is a single iteration of a loop
// Vector p1->p2
vx1 = p2.lat - p1.lat
vy1 = p2.long - p1.long
// Vector p1->pm
vx2 = pm.lat - p1.lat
vy2 = pm.long - p1.long
// Cross product
crp = vx1*vy2 - vx2*vy1
if(cpr > 0){
// main point sits to the left of vector p1->p2
if(first_iteration){
left_side = true
first_ieration = false
} else {
// check if also left side, if true continue, if false return false
if(! left_side){
return false
}
}
} else {
// main point sits to the right (or on the line) of vector p1->p2
if(first_iteration){
left_side = false
first_ieration = false
} else {
if(left_side){
return false
}
}
}
// outside loop, at the end of method
return true
在你的例子中,它是一个矩形,你可以这样计算它:
MinimumPoint.X = Min(p1.X, p2.X)
和MinimumPoint.Y = Min(p1.Y, p2.Y)
MaximumPoint.X = Max(p1.X, p2.X)
和MaximumPoint.Y = Max(p1.Y, p2.Y)
CheckPoint.X > MinimumPoint.X
和CheckPoint.X < MaximumPoint.X
和CheckPoint.Y > MinimumPoint.Y
和CheckPoint.Y < MaximumPoint.Y
或者您可以使用 contains 函数:https://pkg.go.dev/github.com/paulmach/orb
添加到项目:
go get github.com/paulmach/orb
这是我为你的问题写的示例代码:
package main
import (
"fmt"
"github.com/paulmach/orb"
)
func main() {
p1 := orb.Point{43.672162, -79.43585}
p2 := orb.Point{43.629845, -79.314585}
bound := orb.MultiPoint{p1, p2}.Bound()
fmt.Printf("bound: %+v\n", bound)
checkList := []orb.Point{orb.Point{43.651989, -79.371993}, p1, p2, orb.Point{43, -79}}
fmt.Printf("\ncontains?\n")
for _, checkPoint := range checkList {
fmt.Printf(" %+v:%t\n", checkPoint, bound.Contains(checkPoint))
}
}
结果:
bound: {Min:[43.629845 -79.43585] Max:[43.672162 -79.314585]}
contains?
[43.651989 -79.371993]:true
[43.672162 -79.43585]:true
[43.629845 -79.314585]:true
[43 -79]:false