Check if lat/long point within an area

928 Views Asked by At

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.

3

There are 3 best solutions below

0
On BEST ANSWER

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 >= MinimumPoint.X and CheckPoint.X <= MaximumPoint.X and CheckPoint.Y >= MinimumPoint.Y and CheckPoint.Y <= 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 (
    "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))
    }
}

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
0
On

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.

0
On

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->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