Erstellen von Thiessen (Voronoi) -Polygonen unter Verwendung von Linien (anstelle von Punkten) als Eingabe-Features?


24

Ich habe eine Reihe von Linienelementen innerhalb einer bestimmten polygonalen Grenze. Für jede Linie möchte ich ein Polygon erzeugen, in dem jeder mögliche Punkt näher an der angegebenen Linie liegt als an jeder anderen Linie in der Ebene. Ich habe dies in der Vergangenheit für Punkteingabe-Features mit Delaunay-Triangulation gemacht, aber wenn es einen ähnlichen Vorgang für Linien-Features gibt, konnte ich ihn nicht finden.

ETA: Die Lösung von Geogeek war mir eingefallen, aber in geraden Abschnitten, in denen die Eingabezeilen weniger Scheitelpunkte haben, kommen die resultierenden Polygone einer Linie viel zu nahe (sogar überlappend), als dass sie dies tun sollten. Hier sind die roten Linien meine Eingaben, Sie können die Scheitelpunkte und die daraus erzeugten Thiessen-Polygone sehen.

Bildbeschreibung hier eingeben

Möglicherweise besteht eine schnelle und (sehr) schmutzige Lösung darin, jede Linie in eine Vielzahl von Punkten mit gleichmäßigem Abstand zu konvertieren (anstatt nur die Eckpunkte der Linie), Thiessen-Polygone aus diesen zu generieren und sie dann basierend auf der Ursprungslinien-ID aufzulösen.


4
Voronoi-Diagramme, die Liniensegmente zusammen mit Punkten enthalten, bestehen nicht aus "Polygonen". Vielmehr haben ihre Zellen Grenzen, die Teile von Parabeln enthalten können. Aus diesem Grund besteht eine der effizientesten und genauesten Möglichkeiten zum Erstellen von Voronoi-Tessellationen in der Verwendung einer Raster-Darstellung. ESRI nennt diese Prozedur Euklidische Allokation .
whuber

Antworten:


11

Um eine Raster- / Bildverarbeitungslösung zu veranschaulichen, habe ich mit dem bereitgestellten Bild begonnen. Aufgrund der Überlagerung von blauen Punkten, grauen Linien, farbigen Bereichen und Text ist die Qualität viel geringer als bei den Originaldaten. und die Verdickung der ursprünglichen roten Linien. Als solches stellt es eine Herausforderung dar: Dennoch können wir Voronoi-Zellen mit hoher Genauigkeit erhalten.

Ich extrahierte die sichtbaren Teile der roten linearen Merkmale, indem ich den grünen vom roten Kanal subtrahierte und dann die hellsten Teile um drei Pixel erweiterte und erodierte. Dies wurde als Grundlage für eine euklidische Entfernungsberechnung verwendet:

i = Import["http://i.stack.imgur.com/y8xlS.png"];
{r, g, b} = ColorSeparate[i];
string = With[{n = 3}, Erosion[Dilation[Binarize[ImageSubtract[r, g]], n], n]];
ReliefPlot[Reverse@ImageData@DistanceTransform[ColorNegate[string]]]

Erleichterung Handlung

(Der gesamte hier gezeigte Code ist Mathematica 8.)

Das Erkennen der offensichtlichen "Grate", die alle Punkte enthalten müssen, die zwei benachbarte Voronoi-Zellen trennen, und das erneute Kombinieren mit der Linienebene liefert das meiste, was wir zum Fortfahren benötigen:

ridges = Binarize[ColorNegate[
   LaplacianGaussianFilter[DistanceTransform[ColorNegate[string]], 2] // ImageAdjust], .65];
ColorCombine[{ridges, string}]

Kombinierte Bilder

Das rote Band stellt dar, was ich von der Linie retten könnte, und das cyan-blaue Band zeigt die Grate in der Abstandstransformation. (Aufgrund der Unterbrechungen in der ursprünglichen Linie selbst ist immer noch viel Müll vorhanden.) Diese Rippen müssen gereinigt und durch eine weitere Ausdehnung geschlossen werden - zwei Pixel reichen aus - und dann können wir die verbundenen Regionen identifizieren, die durch bestimmt werden die ursprünglichen Linien und die Grate zwischen ihnen (von denen einige explizit neu kombiniert werden müssen):

Dilation[MorphologicalComponents[
  ColorNegate[ImageAdd[ridges, Dilation[string, 2]]]] /. {2 -> 5, 8 -> 0, 4 -> 3} // Colorize, 2]

Dies hat im Endeffekt dazu geführt, fünf orientierte lineare Merkmale zu identifizieren . Wir können drei separate lineare Merkmale sehen, die von einem Zusammenflusspunkt ausgehen. Jeder hat zwei Seiten. Ich habe die rechte Seite der beiden Merkmale ganz rechts als gleich angesehen, aber ansonsten alles andere unterschieden und die fünf Merkmale angegeben. Die farbigen Bereiche zeigen das Voronoi-Diagramm dieser fünf Merkmale.

Ergebnis

Ein euklidischer Zuordnungsbefehl, der auf einer Ebene basiert, die die drei linearen Merkmale unterscheidet (die ich für diese Abbildung nicht zur Verfügung hatte), würde die verschiedenen Seiten jedes linearen Merkmals nicht unterscheiden und so die grünen und orangefarbenen Bereiche kombinieren, die die äußerste linke Linie flankieren ; es würde das Merkmal ganz rechts in zwei Teile teilen; und es würde diese gespaltenen Stücke mit den entsprechenden beige und magentafarbenen Merkmalen auf ihren anderen Seiten kombinieren.

Offensichtlich hat dieser Raster-Ansatz die Fähigkeit, Voronoi-Tessellationen von beliebigen Merkmalen - Punkten, linearen Teilen und sogar Polygonen, unabhängig von ihrer Form - zu konstruieren und Seiten von linearen Merkmalen zu unterscheiden.


1
Eine ähnliche Lösung finden Sie unter mathematica.stackexchange.com/questions/20696/… .
Whuber

5

Ich glaube du kannst:

  • Konvertieren Sie Linienscheitelpunkte in Punkte (line_points).
  • Erstellen Sie Voronoi-Polygone mit den Punkten (line_points).
  • Lösen Sie die resultierenden Polygone entweder mit einem ID-Attribut auf, das aus der Linienebene gespeichert wurde, oder durch eine räumliche Verknüpfung mit der Linienebene.

Ich hoffe, ich habe Ihre Frage wirklich verstanden. Wenn nicht, können Sie eine Zeichnung vorlegen, um Ihre Bedürfnisse näher zu erläutern.


2
Ich denke, Sie haben es verstanden, und diese Lösung ist mir eingefallen, aber Sie haben Probleme, wenn die Linien weniger Eckpunkte haben. Ich werde meine Frage mit einem Screenshot aktualisieren.
Dan C

3
Dies würde gut funktionieren, wenn Sie die Punkte entlang der Linie dichter machen würden. Obwohl ich vermuten würde, dass ein rasterbasierter Ansatz (wie in den Kommentaren zu dieser Frage erwähnt) viel effizienter wäre.
Andy W
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.