Suite

GeoPandas : retour lat et long d'un point centroïde


je voudrais retourner lelatitudeetlonou alorsXetouià partir de l'objet ponctuel de la série suivante, car je prévois de les lier à une API que j'ai construite qui relie OSM et NetworkX. Les centroïdes seront ajoutés en tant que nouveaux nœuds pour l'analyse du réseau.

gp.GeoSeries(zones.centroid).x, etgp.GeoSeries(zones.centroid).ycomme indiqué dans la documentation soulèveAttributeError : l'objet 'GeoSeries' n'a pas d'attribut 'x'Erreur.

Modifier un peu les choses et imprimerlist(gp.GeoSeries(zones.centroid))renvoie des milliers de points galbés au format suivant :

[… , , , , , , , ]

Le code que j'utilise est le suivant :

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.623175496464002) # 97005548.2167378

Comment puis-je retourner leXetouide l'objet GeoPandas POINT ?


Laissant le reste ci-dessous, mais l'essentiel était d'accéder correctement à la géométrie. Si vous parcourez des lignes, par ex.pour l'index, ligne dans zones.iterrows() :vous pouvez simplement utiliserligne.geometry.centroid.xetrow.geometry.centroid.y. La géométrie est une colonne spéciale incluse dans un GeoDataFrame, donc chaque ligne a un attribut de géométrie.
Vous accédez à cet attribut, qui contient ungalbéobjet. Cegalbél'objet aura un attribut,centre de gravitéqui, à son tour, contient unshapely.geometry.Point, qui a des attributsXetoui, vous donnant enfin les propriétés que vous souhaitez.


(Cette partie était l'effort initial pour arriver à x,y aveccarteetshapely.geometry.Point.)
Je vais supposer que vous voulez une liste de (x, y) tuples ? Créez une fonction d'accès rapide pour les attributs x et y sur unIndiqueret utilisecarte.

Modifier : D'accord, j'ai compris que vous accédiez peut-être à la géométrie dans le GeoDataFrame de manière incorrecte. La géométrie est une colonne de votre GeoDataFrame, qui à elle seule produit une série. Appelcentre de gravitésur cette colonne devrait vous donner une nouvelle GeoSeries de ces centroïdes uniquement. Je soupçonne que la façon dont vous procédiez était de prendre le centroïde de chaque sommet de chaque polygone. Je ne peux toujours pas tester cela car je ne peux pas installer GeoPandas pour le moment.

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

ou si vous voulez deux listes distinctes de coordonnées x et y

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

Alternativement, vous devriez également être en mesure d'utiliserzones.geometry.centroidà la place dezones['géométrie'].centroïde. De toute façon, je pense qu'appelerzones.centroidpeut renvoyer un GeoDataFrame au lieu d'un GeoSeries, vous donnant une sortie inattendue lorsque vous l'enveloppez dans une autre GeoSeries.


J'ai moi-même rencontré ce problème. Si vous voulez leXetouien tant que colonnes GeoDataFrame distinctes, cela fonctionne bien :

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

À partir de GeoPandas 0.3.0, vous pouvez utiliser lesXetouipropriétés à la place :

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

Cela a été rendu plus facile à partir de GeoPandas 0.3.0.

Vous pouvez désormais accéderXetouidePoints galbésà l'intérieur d'unGeoSeries geopandasen utilisantyour_GeoDataFrame.geometry.xetvotre_GeoDataFrame.geometry.y

(Remarque : j'utilise python 3.6.1, je ne suis pas sûr du comportement en 2.7, désolé)

Source sur github


La solution pour extraire le point central (latitude et longitude) du polygone et du multi-polygone.

importer des géopandas en tant que gpd df = gpd.read_file(path + 'df.geojson') #Trouver le point central df['Center_point'] = df['geometry'].centroid #Extraire lat et lon du point central df["lat "] = df.Center_point.map(lambda p: px) df["long"] = df.Center_point.map(lambda p: py)

J'ai rencontré un problème similaire, en n'utilisant que des géométries de polygone et j'ai trouvé que cette solution fonctionnait bien pour moi, n'oubliez pas qu'elle utilise Python-3.6, elle peut donc ne pas fonctionner pour Python-2.7.

importer des géopandas en tant que 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]

si vous voulez juste un tableau numpy de centroïdes :

centroïdes = np.vstack([df.centroid.x, df.centroid.y]).T

ou en tant que dataframe avec des colonnes supplémentaires (c'est-à-dire un nom par exemple) :

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

ex.

nom géométrie 0 1 POLYGONE ((0.00000 1.00000, 0.00000 0.00000, 1… 1 2 POLYGONE ((2.00000 1.00000, 2.00000 0.00000, 3… # ==> # np.vstack([df.centroid.x, df.centroid.y] ).T # tableau([[0,5, 0,5], # [2,5, 0,5]])

Voici un rapide

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

Puis recréez le dataframe avec des géopandas

gdf = gpd.DataFrame(df) # crée un geodataframe avec une géométrie de point