I am getting totally different distances from shapely and geopy. On one hand – it makes total sense, shapely measures on a plane and geopy measures on a spheroid. But the differences are so dramatic, I am wondering if something is truly off here.
Using:
- Shapely 1.3.2
- geopy 1.9.1
- Fiona 1.l.5
my prj (for shapely/fiona) IS Web-Merc EPSG: 3857 (w/o flattening):
>>print input_crs
>>{u'a': 6378137, u'lon_0': 0, u'k': 1, u'y_0': 0, u'b': 6378137, u'proj': u'merc', u'x_0': 0, u'units': u'm', u'no_defs': True}
>>print to_string(input_crs)
>>+a=6378137 +b=6378137 +k=1 +lon_0 +no_defs +proj=merc +units=m +x_0 +y_0
Test Pts (*Arizona/N.Mex general area):
city: POINT (-12352678.6153664 3384049.040913342)
capital: POINT (-12318614.85118365 3417715.06365641)
My code, using shapely for .buffer and Vincenty for the ellipsoid measure (geopy)
def evaluate_point(city_pt, capital_pts):
#tests whether the capitals are within a certain distance of a
#city point
# set the ellipsoid for measurement
distance.VincentyDistance.ELLIPSOID = 'WGS-84'
d = distance.distance
# create a wkt obj of city pt
city_wkt = dumps(city_pt)
dist = 300000
# create a shapely obj of all the capitals
for pt in capital_pts:
# create a shapely obj of all the captial_pts
capital_pt = shape(pt['geometry'])
# create a wkt obj of the admin1_pt
capital_to_measure = dumps(capital_pt)
## BUFFER USING SHAPELY - DIST = 300000 meters due to prj
capital_buffer = capital_pt.buffer(dist)
# city_pt is a shapely obj
if city_pt.within(capital_buffer):
distance_between_pts = d(capital_to_measure, city_wkt).meters
print"within the buffer" + " " + str(distance_between_pts)
print "city: " + city_wkt
print "capital: " + capital_to_measure
else:
print "outside the buffer"
FOR this data I get this:
city: POINT (-12352678.6153664 3384049.040913342)
capital: POINT (-12318614.85118365 3417715.06365641)
within the buffer # shapely buffer set to (300000 meters)
14815370.7894 # Vincenty ellipsoid measured distance reported in meters
Best Answer
1) For calculate the Vincenty distance, you need coordinates in longitude, latitude (degrees) and you choose WGS84 (look at with Geopy:distance)
2) The coordinates of your points are in meters: u'units': u'm' (according to your Proj4 string (+a=6378137 +b=6378137 +k=1 +lon_0 +no_defs +proj=merc +units=m +x_0 +y_0)
As your coordinates are in meters, you can use the Shapely distance (Euclidean Distance or Linear distance) between two points (What is the unit the shapely length attribute?)
3) If you really want to use the Geopy Vincenty distance you need to change the projection of your data (with Pyproj, for example)