检查经纬度点是否在某个区域内。

huangapple go评论86阅读模式
英文:

Check if lat/long point within an area

问题

我正在尝试找到一种方法来检查一对经纬度坐标是否在一个区域内(由其他经纬度坐标生成)。

例如,如果我的区域是由以下坐标生成的矩形:

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)

我想知道是否有人有这方面的实现可以分享,或者有任何可以指导我的资源?我也可以使用Google Maps API。

英文:

I am trying to find a way of checking if a pair of lat/lng coordinates are within an area (generated by other lat/lng coordinates).

For example, if my area is a rectangle generated with these coordinates:

43.672162 , -79.43585
43.629845 , -79.314585

And I wanted to check if these coordinates are within that area:
43.651989 , -79.371993

I have tried using this package but I can't make it work: 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)

I was wondering if anyone has an implementation of this they can share, or any resources that can point me in the right direction? I am open to using google maps API as well.

答案1

得分: 2

在你的示例中,一个矩形的计算可以按照以下方式进行:

  1. 找到区域的最小点。MinimumPoint.X = Min(p1.X, p2.X)MinimumPoint.Y = Min(p1.Y, p2.Y)
  2. 找到区域的最大点。MaximumPoint.X = Max(p1.X, p2.X)MaximumPoint.Y = Max(p1.Y, p2.Y)
  3. 检查点是否在它们之间:
    CheckPoint.X >= MinimumPoint.XCheckPoint.X <= MaximumPoint.XCheckPoint.Y >= MinimumPoint.YCheckPoint.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
英文:

In your example, which is a rectangle, you can calculate it like this:

  1. find MinPoint of area. MinimumPoint.X = Min(p1.X, p2.X) and MinimumPoint.Y = Min(p1.Y, p2.Y)
  2. find MaxPoint of area. MaximumPoint.X = Max(p1.X, p2.X) and MaximumPoint.Y = Max(p1.Y, p2.Y)
  3. check the point is between them:
    CheckPoint.X &gt;= MinimumPoint.X and CheckPoint.X &lt;= MaximumPoint.X and CheckPoint.Y &gt;= MinimumPoint.Y and CheckPoint.Y &lt;= MaximumPoint.Y

Or you can use contains function from this: https://pkg.go.dev/github.com/paulmach/orb

Add to project: go get github.com/paulmach/orb

This is the sample code I wrote for your question:

package main

import (
	&quot;fmt&quot;

	&quot;github.com/paulmach/orb&quot;
)

func main() {
	p1 := orb.Point{43.672162, -79.43585}
	p2 := orb.Point{43.629845, -79.314585}

	bound := orb.MultiPoint{p1, p2}.Bound()

	fmt.Printf(&quot;bound: %+v\n&quot;, bound)

	checkList := []orb.Point{orb.Point{43.651989, -79.371993}, p1, p2, orb.Point{43, -79}}

	fmt.Printf(&quot;\ncontains?\n&quot;)
	for _, checkPoint := range checkList {
		fmt.Printf(&quot;    %+v:%t\n&quot;, checkPoint, bound.Contains(checkPoint))
	}
}

result:

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

答案2

得分: 0

这只是一个数学问题,比较坐标。

如果一个坐标A在矩形内部,那么A的x坐标必须小于矩形的x1,并且大于矩形的x2,或者反之。对于y坐标也是类似的算法。

英文:

It’s just a math, compare coordinates.

If A coordinate inside of a rectangle, then A.x must be less then rect.x1 and greater then rect.x2 or otherwise. And similar algorithm to the y coordinates.

答案3

得分: 0

我不懂Go语言,但是你可以使用叉积来确定你感兴趣的点在向量的左侧还是右侧。向量可以是p1 -> p2,然后是p2 -> p3,依此类推。如果它们都在同一侧,那么该点位于多边形内部。

请注意,你需要考虑地球的子午线和其他可能的因素。

这还假设你的多边形点形成一个凸形状(凸包)。如果它不是凸包,那么可能会更加困难。

以下是一个伪代码示例,我不懂Go语言:

// 这是循环的单次迭代

// 向量 p1->p2
vx1 = p2.lat - p1.lat
vy1 = p2.long - p1.long

// 向量 p1->pm
vx2 = pm.lat - p1.lat
vy2 = pm.long - p1.long

// 叉积
crp = vx1*vy2 - vx2*vy1

if(crp > 0){
   // 主要点位于向量 p1->p2 的左侧
   if(first_iteration){
      left_side = true
      first_iteration = false
   } else {
      // 检查是否也在左侧,如果是则继续,如果不是则返回 false
      if(!left_side){
         return false
      }
   }
} else {
   // 主要点位于向量 p1->p2 的右侧(或在直线上)
   if(first_iteration){
      left_side = false
      first_iteration = false
   } else {
      if(left_side){
         return false
      }
   }
}

// 循环结束后,在方法的末尾
return true

希望对你有帮助!

英文:

I don't know Go, but you can use the cross product to determine if your point of interest is on the left or right of a vector. The vector can be p1 -> p2, then p2 -> p3, etc. If all of them are on the same side then the point sits inside your polygon shape.

Keep in mind you'll have to account for the earth's meridian and possibly other things.

This also assumes your polygon points form a convex shape (of a hull). If it is not a hull, then it may be more difficult.

// This is mock code, I dont know Go



// This is a single iteration of a loop

// Vector p1-&gt;p2
vx1 = p2.lat - p1.lat
vy1 = p2.long - p1.long

// Vector p1-&gt;pm
vx2 = pm.lat - p1.lat
vy2 = pm.long - p1.long

// Cross product
crp = vx1*vy2 - vx2*vy1

if(cpr &gt; 0){
   // main point sits to the left of vector p1-&gt;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-&gt;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

huangapple
  • 本文由 发表于 2023年3月5日 11:45:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/75640075.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定