Shapely: Polylabel-Fehler

Erstellt am 8. Jan. 2020  ·  3Kommentare  ·  Quelle: Toblerity/Shapely

Erwartetes Verhalten und tatsächliches Verhalten.

Löcher werden bei der Implementierung des Polylabel-Algorithmus von Shapely nicht korrekt berücksichtigt.

Schritte zum Reproduzieren des Problems.

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

image

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.

Betriebssystem

Linux

Formschöne Version und Provenienz

Getestet mit formschöner Version 1.6 und 1.7a3

bug

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.

Alle 3 Kommentare

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.

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.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen