More

GeoPandas: return lat and long of a centroid point


I would like to return thelatandlonorxandyfrom the point object in the following series as I plan to link them with an API I built that links OSM and NetworkX. The centroids will be added as new nodes for network analysis.

gp.GeoSeries(zones.centroid).x, andgp.GeoSeries(zones.centroid).yas outlined in docs raiseAttributeError: 'GeoSeries' object has no attribute 'x'error.

Modifying things a bit and printinglist(gp.GeoSeries(zones.centroid))return thousands of shapely points of the following format:

[… , , , , , , , ]

The code I'm using is the following:

import geopandas as gp zones = gp.GeoDataFrame.from_file(shp_file) for index, row in zones.iterrows(): print index, gp.GeoSeries(zones.centroid) # result: # 9700022.00 POINT (-122.8196050489696 54.00617624128658) # 9700023.00 POINT (-122.7474362519174 53.99998921974029) # 9700100.00 POINT (-121.4904983300892 53.98447191612864) # 9700101.00 POINT (-122.5513619751679 53.73999791511078) # 9700102.00 POINT (-123.0624037191615 53.62317549646422) # 9700103.00 POINT (-123.0848175548173 54.05921695782788)

How can I return thexandyfrom the GeoPandas POINT object?


Leaving the rest below, but the main thing was accessing the geometry properly. If iterating over rows, e.g.for index, row in zones.iterrows():you can simply userow.geometry.centroid.xandrow.geometry.centroid.y. Geometry is a special column included in a GeoDataFrame, so every row has a geometry attribute.
You are accessing that attribute, which contains ashapelyobject. Thatshapelyobject will have an attribute,centroidthat, in turn contains ashapely.geometry.Point, which has attributesxandy, finally giving you the properties you want.


(This part was the original effort to get to x,y withmapandshapely.geometry.Point.)
I am going to assume you want a list of (x, y) tuples? Create a quick accessor function for the x and y attributes on aPointand usemap.

Edit: Okay, figured out that you may be accessing the geometry in the GeoDataFrame in an incorrect way. Geometry is a column in your GeoDataFrame, which by itself produces a series. Callingcentroidon that column should give you a new GeoSeries of only those centroids. I suspect the way you were going about things was taking the centroid of every vertex in each polygon. Still cannot test this since I cannot install GeoPandas right now.

def getXY(pt): return (pt.x, pt.y) centroidseries = zones['geometry'].centroid centroidlist = map(getXY, centroidseries)

or if you want two separate lists of x and y coordinates

def getXY(pt): return (pt.x, pt.y) centroidseries = zones['geometry'].centroid x,y = [list(t) for t in zip(*map(getXY, centroidseries))]

Alternately, you should also be able to usezones.geometry.centroidinstead ofzones['geometry'].centroid. Either way, I think callingzones.centroidmay be returning a GeoDataFrame instead of a GeoSeries, giving you the unexpected output when you wrap it in another GeoSeries.


Ran into this problem myself. If you want thexandyas separate GeoDataFrame columns, then this works nicely:

gdf["x"] = gdf.centroid.map(lambda p: p.x) gdf["y"] = gdf.centroid.map(lambda p: p.y)

Starting with GeoPandas 0.3.0, you can use the providedxandyproperties instead:

gdf["x"] = gdf.centroid.x gdf["y"] = gdf.centroid.y

This has been made easier as of GeoPandas 0.3.0.

You can now accessxandyofshapely Pointsinside ageopandas GeoSeriesusingyour_GeoDataFrame.geometry.xandyour_GeoDataFrame.geometry.y

(Note : I'm using python 3.6.1, not sure about behavior in 2.7, sorry)

Source on github


The solution to extract the center point (latitude and longitude) from the polygon and multi-polygon.

import geopandas as gpd df = gpd.read_file(path + 'df.geojson') #Find the center point df['Center_point'] = df['geometry'].centroid #Extract lat and lon from the centerpoint df["lat"] = df.Center_point.map(lambda p: p.x) df["long"] = df.Center_point.map(lambda p: p.y)

I ran into a similar problem, only using polygon geometries and found this solution worked well for me, mind you it's using Python-3.6 so it may not work for Python-2.7.

import geopandas as gpd zones = gpd.read_file('file_to_read.shp') for i in range(0,len(zones)): zones.loc[i,'centroid_lon'] = zones.geometry.centroid.x.iloc[i] zones.loc[i,'centroid_lat'] = zones.geometry.centroid.y.iloc[i]

if you just want a numpy array of centroids:

centroids = np.vstack([df.centroid.x, df.centroid.y]).T

or as a dataframe with extra columns (i.e name for example):

pd.DataFrame(np.vstack([df.name, df.centroid.x, df.centroid.y]).T, columns=['name', 'x', 'y'])

ex.

name geometry 0 1 POLYGON ((0.00000 1.00000, 0.00000 0.00000, 1… 1 2 POLYGON ((2.00000 1.00000, 2.00000 0.00000, 3… # ==> # np.vstack([df.centroid.x, df.centroid.y]).T # array([[0.5, 0.5], # [2.5, 0.5]])

Here's a quick

df = pd.read_csv('data/hospitals.csv') df.columns # 'Ownership', 'Lat', 'Long' from shapely.geometry import Point df['geometry'] = df.apply(lambda row: Point(row.Long,row.Lat),axis=1)

Then recreate the dataframe with geopandas

gdf = gpd.DataFrame(df) # creates geodataframe with Point geometry