1

I am a beginner in GIS. Using the code below to get the distance between two Point objects from two separate GeoDataframe. Using the shapely distance function.

Can someone please explain to me what I am doing wrong?

import geopandas as gpd

# Read file using gpd.read_file()
transit_data = gpd.read_file(transit)
stations_data = gpd.read_file(stations)
address_pts = gpd.read_file(city_pts)

# Point #1
address_pt = address_pts.loc[address_pts.full_address == '20 W 34th St, New York, NY 10001', 'geometry']

# Point #2
stop_pt = stations_data.loc[stations_data.name == '34th St - Hudson Yards', 'geometry']

# Calculate the distance between the 2 points
dist = stop_pt.distance(address_pt )
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-40-b60223ead16e> in <module>
----> 1 dist = stop_pt.distance(pt)

~\anaconda3\envs\gis\lib\site-packages\shapely\geometry\base.py in distance(self, other)
    440     def distance(self, other):
    441         """Unitless distance to other geometry (float)"""
--> 442         return self.impl['distance'](self, other)
    443 
    444     def hausdorff_distance(self, other):

~\anaconda3\envs\gis\lib\site-packages\shapely\topology.py in __call__(self, this, other)
     44     def __call__(self, this, other):
     45         self._validate(this)
---> 46         self._validate(other, stop_prepared=True)
     47         d = c_double()
     48         retval = self.fn(this._geom, other._geom, byref(d))

~\anaconda3\envs\gis\lib\site-packages\shapely\topology.py in _validate(self, ob, stop_prepared)
     15 
     16     def _validate(self, ob, stop_prepared=False):
---> 17         if ob is None or ob._geom is None:
     18             raise ValueError("Null geometry supports no operations")
     19         if stop_prepared and hasattr(ob, 'prepared'):

~\anaconda3\envs\gis\lib\site-packages\pandas\core\generic.py in __getattr__(self, name)
   5272             if self._info_axis._can_hold_identifiers_and_holds_name(name):
   5273                 return self[name]
-> 5274             return object.__getattribute__(self, name)
   5275 
   5276     def __setattr__(self, name: str, value) -> None:

AttributeError: 'GeoSeries' object has no attribute '_geom'
0

1 Answer 1

2

With the .loc[] you made you have a single row GeoSeries, and I'm not sure why the .distance operation doesn't work frequently well on them sometimes. Try using directly with the shapely objects:

dist = stop_pt.values[0].distance(address_pt.values[0])

Or maybe you are looking for calculating the distance between all stations_data and all address_pt. You can do it with a simple line.

stations_data['geometry'].apply(lambda x: address_pts.distance(x)).unstack()
2
  • Thanks a lot! This did the trick. Basic question for you, so the values function allows access to the Shapely object, which are just the values in the Point Object in GeoSeries? If so, why do we not need to apply the value function in the apply & lambda functions?
    – P. Saha
    Apr 16, 2020 at 4:22
  • .values is actually not a function, but an attribute that allow us to access the data inside the dataframe as a numpy array. With the .values[0] I got the shapely object. Using apply(), I can use a function to each individual shapely object of the series. Apr 16, 2020 at 4:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.