Löcher werden bei der Implementierung des Polylabel-Algorithmus von Shapely nicht korrekt berücksichtigt.
from shapely.geometry import Polygon
from shapely.algorithms.polylabel import polylabel
poly1=Polygon(shell=[(0,0),(10,0),(10,10),(0,10),(0,0)][::-1], holes=[[(2,2),(6,2),(6,6),(2,6),(2,2)]])
import geopandas
gdf2 = geopandas.GeoDataFrame(geometry=[poly1])
gdf2.plot()
label_location = polylabel(poly1, tolerance=0.05)
print(label_location.x)
print(label_location.y)
Die Ausgabe dieses Skripts ist:
6.25
3.75
Aber die richtige Position ist etwas in der Nähe von 7.65625, 7.65625. Dies kann durch Betrachten eines Plots dieses Polygons überprüft werden
Vielleicht mache ich bei der Definition des Polygons etwas falsch, aber ich habe viele verschiedene Möglichkeiten zur Instanziierung dieses Polygons ausprobiert und erhalte immer das gleiche Ergebnis.
Linux
Getestet mit formschöner Version 1.6 und 1.7a3
Könnten Sie bitte überprüfen, ob die von https://github.com/mapbox/polylabel selbst vorgeschlagene Koordinate anders ist?
Ursprünglicher Algorithmus in TypeScript:
import polylabel from "polylabel";
let exterior = [[0,0],[10,0],[10,10],[0,10],[0,0]];
let hole = [[2,2],[6,2],[6,6],[2,6],[2,2]];
let polygon = [exterior, hole]
console.log(polylabel(polygon, 0.01));
PS> .\node_modules\.bin\tsc test.ts
PS> node .\test.js
[ 7.65625, 7.65625 ]
Formschön:
>>> from shapely.ops import polylabel
>>> from shapely.geometry import Polygon
>>> exterior = [[0,0],[10,0],[10,10],[0,10],[0,0]]
>>> hole = [[2,2],[6,2],[6,6],[2,6],[2,2]]
>>> p = Polygon(exterior, [hole])
>>> polylabel(p, 0.01).coords[:]
[(6.25, 3.75)]
Du hast recht @benediktbrandt. Die Shapely-Implementierung behandelt die Löcher nicht korrekt, da sie nur den Abstand zum Äußeren des Polygons berücksichtigt. Ich denke, dies ist ein Fehler, der behoben werden sollte, um dem Verhalten des ursprünglichen Algorithmus zu entsprechen.
Auch hier ist die Umwandlung der Polygonaußenseite in eine Linienfolge etwas ineffizient, da sie für jede erzeugte Zelle durchgeführt wird.
Hilfreichster Kommentar
Du hast recht @benediktbrandt. Die Shapely-Implementierung behandelt die Löcher nicht korrekt, da sie nur den Abstand zum Äußeren des Polygons berücksichtigt. Ich denke, dies ist ein Fehler, der behoben werden sollte, um dem Verhalten des ursprünglichen Algorithmus zu entsprechen.
https://github.com/Toblerity/Shapely/blob/cfa66d418fe3afe2fcb48438fcc9156142abaeb8/shapely/algorithms/polylabel.py#L44 -L53
Auch hier ist die Umwandlung der Polygonaußenseite in eine Linienfolge etwas ineffizient, da sie für jede erzeugte Zelle durchgeführt wird.