How to check if coordinate inside certain area Python
Asked Answered
E

3

19

Lets say I have 2 kind of coordinate, first called center_point and second called test_point. I want to know if test_point coordinate is inside near or not to center_point coordinate by applying radius threshold. If I write it, its like:

center_point = [{'lat': -7.7940023, 'lng': 110.3656535}]
test_point = [{'lat': -7.79457, 'lng': 110.36563}]

radius = 5 # in kilometer

How to check if the test_point inside or outside the radius from center_point in Python? how I perform this kind task in Python?

Result expected will say that test_point inside or outside the radius from center_point coordinate.

Englishman answered 9/3, 2017 at 3:47 Comment(2)
Calculate distance using haversine formula #4913849 and see if it is less than rVaporescence
hi @user1753919 thanks, it works.Englishman
E
37

from recommendation of @user1753919 in his/her comment, I got the answer here: Haversine Formula in Python (Bearing and Distance between two GPS points)

final code:

from math import radians, cos, sin, asin, sqrt

def haversine(lon1, lat1, lon2, lat2):
    """
    Calculate the great circle distance between two points 
    on the earth (specified in decimal degrees)
    """
    # convert decimal degrees to radians 
    lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2])

    # haversine formula 
    dlon = lon2 - lon1 
    dlat = lat2 - lat1 
    a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2
    c = 2 * asin(sqrt(a)) 
    r = 6371 # Radius of earth in kilometers. Use 3956 for miles
    return c * r

center_point = [{'lat': -7.7940023, 'lng': 110.3656535}]
test_point = [{'lat': -7.79457, 'lng': 110.36563}]

lat1 = center_point[0]['lat']
lon1 = center_point[0]['lng']
lat2 = test_point[0]['lat']
lon2 = test_point[0]['lng']

radius = 1.00 # in kilometer

a = haversine(lon1, lat1, lon2, lat2)

print('Distance (km) : ', a)
if a <= radius:
    print('Inside the area')
else:
    print('Outside the area')

Thanks

Englishman answered 9/3, 2017 at 4:51 Comment(1)
Thanks for this solution! Works great for our project :)Gessner
C
21

GeoPy can handle it gracefully:

from geopy import distance

center_point = [{'lat': -7.7940023, 'lng': 110.3656535}]
test_point = [{'lat': -7.79457, 'lng': 110.36563}]
radius = 5 # in kilometer

center_point_tuple = tuple(center_point[0].values()) # (-7.7940023, 110.3656535)
test_point_tuple = tuple(test_point[0].values()) # (-7.79457, 110.36563)

dis = distance.distance(center_point_tuple, test_point_tuple).km
print("Distance: {}".format(dis)) # Distance: 0.0628380925748918

if dis <= radius:
    print("{} point is inside the {} km radius from {} coordinate".format(test_point_tuple, radius, center_point_tuple))
else:
    print("{} point is outside the {} km radius from {} coordinate".format(test_point_tuple, radius, center_point_tuple))

or if you need to know the great circle distance:

dis = distance.great_circle(center_point_tuple, test_point_tuple).km
print("Distance: {}".format(dis)) # Distance: 0.0631785164583489
Cockaleekie answered 20/9, 2019 at 20:4 Comment(2)
That's the format that was in the question. It's also more explicit where is latitude and where is longitude.Cockaleekie
Oh yes. Sorry. You're right. That makes sense. I wanted to update the previous comment but I can't do that. So I'm gonna delete itYelena
R
2
from math import sqrt
a = center_point[0]['lat'] - test_point[0]['lat']
b = center_point[0]['lng'] - test_point[0]['lng']
c = sqrt(a * a  +  b * b)
if (c < radius):
        print("inside")
else:
        print("outside")
Recurve answered 9/3, 2017 at 3:57 Comment(4)
hi, whats the aa and bb inside c = math.sqrt(aa + bb) refer to?Englishman
Sorry, bad formatting. I edited it to be more clear.Recurve
how can this be used to be tested on the entire dataframe with less computational cost?Receiver
This should be done more efficiently with a KDTree or kNearestNeighbors algorithm, but I haven't found any examples that actually work with lat-lon points yet.Sinotibetan

© 2022 - 2024 — McMap. All rights reserved.