Suite

Fiona + Shapely : Chargement d'un ensemble de LineStrings et écriture de leurs centroïdes dans un fichier de formes, y compris les propriétés d'origine

Fiona + Shapely : Chargement d'un ensemble de LineStrings et écriture de leurs centroïdes dans un fichier de formes, y compris les propriétés d'origine


J'utilise Fiona pour charger un ensemble de liens. Ensuite, j'ai mis chaque enregistrement dans les rangées d'un pandas.DataFrame. Ensuite, j'obtiens le centroïde de chaque LineString en utilisant Shapely. Ensuite, je copie le schéma du links.shp d'origine et change sa géométrie en 'Point'. Ensuite, j'écris les enregistrements à partir du DataFrame, en ne changeant que les coordonnées. Regarde:

importer des pandas en tant que pd importer fiona de shapely.geometry importer LineString def links_centroider(links, name_for_centroids): collection = fiona.open(links) records = [] for i in range(len(collection)): records.append( next(collection) )) collection.close() geoDF = pd.DataFrame({'type': [i['geometry']['type'] for i in records], 'properties': [i['properties'] for i in records], 'coordinates' : [i['geometry']['coordinates'] pour i dans les enregistrements]}, index = [i['id'] pour i dans les enregistrements]) geoDF['centroid'] = geoDF. coordinates.apply(lambda x: LineString(x).centroid.coords[:][0]) avec fiona.open(links) comme source : source_driver = source.driver source_crs = source.crs source_schema = source.schema source_schema[' geometry'] = 'Point' avec fiona.open(name_for_centroids, 'w', driver=source_driver, crs=source_crs, schema=source_schema) comme collection : print(len(collection)) for i dans geoDF.index : a_record = { 'geometry':{'coordinates':geoDF.loc[i].centroid, 'type': 'Point'}, 'id': str(i), 'properties': geoDF.loc[i] .properties, 'type': 'Feature'} collection.write(a_record) print(len(collection)) print collection.closed

Le fichier de formes de sortie n'a aucune information pour les propriétés de chaîne. Pour les nombres dans ces propriétés, j'obtiens principalement des zéros. En d'autres termes, les valeurs des champs de la table attributaire d'origine de links.shp ne sont pas écrites dans le centroids.shp que je souhaite obtenir.

Une idée sur la façon de résoudre cela?


Ensuite, j'ai mis chaque enregistrement dans les rangées d'un pandas.DataFrame

Pourquoi ?

Si vous souhaitez uniquement copier les attributs d'origine (LineString) dans le nouveau fichier de formes (Points), après avoir calculé le centroïde, vous n'avez pas besoin de Pandas :

import fiona from shapely.geometry import shape, mapping avec fiona.open("polyline.shp") en entrée : # ne modifie que la géométrie du schéma : LineString -> Point input.schema['geometry'] = "Point" # écrivez le fichier de formes Point avec fiona.open('centroid.shp', 'w', 'ESRI Shapefile', input.schema.copy(), input.crs) en sortie : pour elem en entrée : # GeoJSON to shapely geometry geom = shape(elem['geometry']) # centroïde galbé à GeoJSON elem['geometry'] = mapping(geom.centroid) output.write(elem)

Si vous voulez absolument utiliser des Pandas, utilisez des GeoPandas qui "mixent" Pandas, Fiona et galbés.

importer des géopandas en tant qu'entrée gp = gp.read_file('polyline.shp') type d'impression (entrée)  -> a GeoDataFrame print input['geometry'] 0 LINESTRING (266351.05107 161433.039507, 266362… # ne modifie que la géométrie du dataframe input['geometry'] = input['geometry'].centroid print input['geometry'] 0 POINT (266369.1881962401 161457.6017265563)… # enregistrer le fichier de formes résultant input.to_file("centroids.shp")

Voir la vidéo: 7 - How to Create a Shapefile with Fiona, Shapely and Python