9
votes

Comment convertir un géos multiplestring en polygone?

Je développe une application Geodjango dans laquelle les utilisateurs peuvent télécharger des fichiers de carte et effectuer des opérations de mappage de base telles que les fonctions de requête à l'intérieur des polygones.

J'ai reconnu que les utilisateurs arrivaient à télécharger "MultiLinstring" s au lieu de "polygone" par parfois. Cela provoque l'échec des requêtes qui attendent des géométries fermées.

Quelle est la meilleure façon de convertir un objet multiliné à un polygone dans Python?


0 commentaires

3 Réponses :


10
votes

hehe, au début, j'ai écrit ceci: xxx pré>

mais j'ai découvert qu'il y avait une petite méthode astucieuse appelée CONVEX_HULL STRUT> qui fait la conversion de polygone pour vous automatiquement . P>

>>> s1 = LineString((0, 0), (1, 1), (1, 2), (0, 1))
>>> s1.convex_hull
<Polygon object at ...>
>>> s1.convex_hull.coords
(((0.0, 0.0), (0.0, 1.0), (1.0, 2.0), (1.0, 1.0), (0.0, 0.0)),)

>>> m1=MultiLineString(s1)
>>> m1.convex_hull
<Polygon object at...>
>>> m1.convex_hull.coords
(((0.0, 0.0), (0.0, 1.0), (1.0, 2.0), (1.0, 1.0), (0.0, 0.0)),)


4 commentaires

Un tel nom obscur pour une méthode qui sauve la journée. Merci. Si le multilintéring a plus d'une lignes, convexe_hull retourne 1 polygone qui les contient tous. Si vous souhaitez avoir chacun des lins de reproduction sous forme de polygone séparé, vous devez toujours faire boucle dans la multilinstring et appliquer Convex_Hull à chaque lintre.


Vrai, vous n'avez jamais mentionné que vous vouliez un polygone séparé pour chaque ligne. :-)


La coque convexe de la multiline peut ne pas être ce dont vous avez besoin. Une coque convexe définit le polygone minimal qui contient la forme, et peut ne pas être aussi précis que nécessaire, car il ne comprendra aucun point de la limite de la forme «à l'intérieur». C'est-à-dire que si vous avez une forme avec un morceau enlevé, vous ne verrez peut-être pas que la forme a un morceau de sa frontière.


Vous pouvez utiliser Shapely.Geometry.polygon pour se convertir simplement en chaîne de ligne à un polygone. Il connectera les premières et les dernières coordonnées. Essayez de polygone ([(0, 0), (1, 1), (1, 2), (0, 1)] ou polygone (S1) pour produire du polygone (0 0, 1 1, 1 2, 0 1 , 0 0)).



2
votes

Ce petit code peut économiser beaucoup de temps, peut-être plus tard, une forme plus courte en Geopandas sera incorporée.

import geopandas as gpd
from shapely.geometry import Polygon, mapping

def linestring_to_polygon(fili_shps):
    gdf = gpd.read_file(fili_shps) #LINESTRING
    geom = [x for x in gdf.geometry]
    all_coords = mapping(geom[0])['coordinates']
    lats = [x[1] for x in all_coords]
    lons = [x[0] for x in all_coords]
    polyg = Polygon(zip(lons, lats))
    return gpd.GeoDataFrame(index=[0], crs=gdf.crs, geometry=[polyg])


0 commentaires

1
votes

Voici une modification de la réponse Carlos, il est plus simple et renvoie non seulement un élément, mais toutes les lignes du fichier source xxx


0 commentaires