Pseudoknoten in freier GIS-Software finden?

16

Die Software gvSIG OA Digital Edition 2010 verfügt über Tools zur Topologie zum Auffinden von Pseudoknoten in linearer Geometrie. Ich habe die Clustertoleranz auf 0,00002 und die maximale Anzahl von Fehlern auf -10000 für die lineare Geometrie mit 20000 Verbindungszahlen festgelegt. Aber erfolgloses Ergebnis.

Gibt es Lösungen, die Pseudoknoten in freier GIS-Software finden?

Ich muss Pseudoknoten überlagern (eine Lösung für dieses Problem ist die Verwendung der Tools-Topologie von ArcInfo, aber für mich ist die Verwendung von freier Software die Priorität). Mit der linearen Geometrie wurden mehrere Benutzer in QGIS 1.8.0 in der PostGIS-Datenbank (Version 2.0.1) erstellt.

Neues Bild hinzufügen: 12 lineare Features mit drei Pseudoknoten in A (Zeile 4/5), B (Zeile 6/7), C (Zeile 9/10). Pseudoknoten sollten stattdessen Punkte sein - zwei lineare Merkmale mit Schnittpunkt in einem Punkt (Knoten) sollten ein lineares Merkmal sein (Linie 4/5 - Linie 4, ...).

Ist es möglich, eine Anfrage in PostGIS zu stellen, die zu einer Schicht von Pseudoknoten führt?

Neues Bild von Beispiel-Pseudoknoten hinzufügen: Wenn ich für die lineare Ebene Punktebene-Pseudoknoten (blaue Rechtecke) erhalte, habe ich folgende Fehler in der linearen Ebene korrigiert: A - fehlende Geometrie hinzufügen, B - Schnittlinie einrasten lassen, C - Pseudoknoten entfernen.

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

Bildbeschreibung hier eingeben

HasT
quelle
2
In GRASS gibt es den Befehl rmdangle, im Ergebnis jedoch eine shp-Datei ohne Pseudoknoten. Das Ergebnis sollte eine shp-Datei (oder eine andere) von Pseudoknoten sein (wie gvSIG OA Digital Edition 2010)
HasT
Verwenden Sie PostGIS 2.0? Wenn ja, versuchen Sie es mit den Funktionen Is_Valid und Makevalid.
Giovanni Manghi
Ja, ich benutze PostGIS 2.0. Wie soll ich diese Funktionen für die Suche nach Pseudoknoten verwenden? Ist es möglich, sie mit "PgQuery for QGIS" zu finden?
HasT
Ja, Sie können sie in QGIS in jedem Tool verwenden, mit dem Sie eine PostGIS-Abfrage ausführen können, z. B. DB Manager (der Syntaxhervorhebung und automatische Vervollständigung unterstützt).
Giovanni Manghi
Der rote Punkt im zweiten Bild ist ein Schnittpunkt zweier gültiger Geometrien.
Vinayan

Antworten:

8

Hier eine generische Lösung, die Sie mit PostGIS oder einer anderen OGC-konformen Software umsetzen können.

HINWEIS: wie ich sage vor , ein Schlüsselbegriff in FOSS und GIS ist Standardisierung : Die besten Lösungen verabschieden Standards wie OGC diejenigen.


Ihr Problem ist, "Pseudoknoten zu finden" ... Aber ich denke, dass es ein bisschen mehr ist, "Nicht-Pseudoknoten zu finden und Linien von Pseudoknoten zu verbinden". Meine Lösung kann für beide verwendet werden.

OGC-Standards bieten:

  • ST_Boundary (geom) : um die Knoten der Linien zu erkennen

  • ST_Dump (geom) : um jeden einzelnen Knoten in einen SQL-Tabellendatensatz einzufügen .

  • ST_DWithin, ST_Equals, ST_SnapToGrid, ST_Snap können für die Änderungstoleranz verwendet werden. Ich benutze ST_DWithin.

Wir können davon ausgehen, dass Ihr Hauptproblem mit diesen Objekten und Eigenschaften spezifiziert werden kann.

  • nur Liniensegmente (eine Tabelle sind Liniensegment ), durch eine Linienfolge Geometrie dargestellt ... ich nicht mit MULTILNE getestet, wenn Sie GeometryType haben = MEHRFACH, können Sie teilen und Gussmultilinien mit ST_Dump und ST_LineMerge;

  • Jedes Liniensegment hat eine (Geometrie-ID) -ID und eine (Farb-ID) -ID .

Der erste Schritt besteht also darin, die Knoten zu ermitteln, die von Verbindungslinien stammen.

CREATE TABLE cache_bounds AS
  SELECT gid as gid_seg, (ST_Dump(ST_Boundary(the_geom))).geom AS the_geom,
         gid as color 
         -- if you not have something for "color label" of lines, use gid.
  FROM linesegment;
ALTER TABLE cache_bounds ADD column gid serial PRIMARY KEY;

CREATE TABLE cache_joinnodes AS
  -- Use your TOLERANCE instead "1" at ST_DWithin and ST_Buffer.
  SELECT *, array_length(colors,1) as ncolors FROM (
   SELECT gid, array_distinct(array_cat(a_colors,b_colors)) as colors, the_geom FROM (
    SELECT 
      a.gid, array_agg(a.color) as a_colors, array_agg(b.color) as b_colors
      , st_buffer(a.the_geom,1) as the_geom -- any one to represent the join point.
    FROM cache_bounds a, cache_bounds b 
    WHERE a.gid>b.gid AND ST_DWithin(a.the_geom,b.the_geom,1)
    -- use ST_equals(a.the_geom,b.the_geom) if no tolerance.
    GROUP BY a.gid, a.the_geom
   ) as t
  ) as t2;

HINWEIS: Verwenden von Caches, da diese schneller sind als Ansichten. Verwenden Sie "EXPLAIN SELECT ...", um die CPU-Zeit zu überprüfen. Dies kann sehr lange dauern.

Hier werden Zyklen und durchgehende (gleichfarbige) Linien als ncolors=1Punkte und die Pseudoknoten als Punkte erkannt. ncolors=2Sie haben also eine Ebene mit diesen Punkten.

Ihre Tabelle mit "guten Knoten" enthält die ursprünglichen "Begrenzungspunkte" und keine "Pseudoknoten".

CREATE VIEW vw_joinnodes_full AS
  SELECT b.*, j.ncolors
  FROM cache_joinnodes j INNER JOIN cache_bounds b 
       ON j.gid=b.gid;

CREATE TABLE cache_good_nodes AS
  SELECT *  
  FROM vw_joinnodes_full 
  WHERE ncolors=1 OR ncolors>2;

-- IF NEED ... CREATE VIEW vw_correct_linesegment AS ... 
Peter Krauss
quelle
Danke für die Lösung! Ich versuche, die Abfrage (in pgAdmin) auszuführen, erhalte jedoch die Ausnahme: "Funktion array_distinct (integer []) existiert nicht". Was mache ich falsch?
HasT
Die nicht zitierte array_distinctFunktion stammt aus einer postgres.cz-Bibliothek . Alle anderen Fehler, bitte melden, ich kann hier weitere Erklärungen hinzufügen.
Peter Krauss
Ich habe die Funktion array_distinct hinzugefügt. In der Datenbank haben lineare Layer den Geometriespaltennamen "the_geom" (stattdessen "geom" in der Abfrage). Ich ersetze "geom" durch "the_geom" für "ST_Boundary (the_geom)". Nach der Abfrage erhalte ich die Meldung "Spalte" geom "existiert nicht" in "als Farben, geom FROM". Ich ersetze "as colors, geom FROM" durch "as colors, the_geom FROM", erhalte aber erneut die Meldung "column" the_geom "not exist".
HasT
Ok, geändert (siehe bearbeitete Antwort) geomzu the_geom. (ST_Dump (x)) bleibt als Geom, ist kein Datenbankattribut.
Peter Krauss
Vielen Dank! Abfrage funktioniert. Ich habe ST_DWithin auf ST_equals ersetzt und für ST_Buffer 0,00002 DD Toleranz angegeben. Als Ergebnis erhielt ich korrekte Knoten (wobei sich in einem Knoten 3 und mehr lineare Merkmale schneiden). Ich möchte ein Empfangsergebnis erhalten, bei dem sich in einem Knoten 2 lineare Features überschneiden (FROM vw_joinnodes_full WHERE ncolors = 2;), aber eine Punktebene erhalten, bei der sich in einem Knoten 2 und mehr lineare Features überschneiden. Wie erhalte ich ein Ergebnis, bei dem sich in einem Knoten nur 2 lineare Merkmale schneiden?
HasT
7

Refractions Research hat ein Linienreinigungs-Tool entwickelt , das zu tun scheint, was Sie wollen.

Line Cleaner bereinigt Netzwerke durch Vereinfachung komplexer, zyklischer, sehr kurzer und längenloser Geometrien und durch Entfernen von Pseudoknoten und unbedeutenden Scheitelpunkten. Am wichtigsten ist, dass in der Bereinigungsphase sichergestellt werden kann, dass Feature-Übereinstimmungen automatisch berücksichtigt werden

Bildbeschreibung hier eingeben

Der Quellcode ist bei GitHub zu finden.

RK
quelle
Danke für die Antwort. Aufgrund von Fehlern benötigt der Pseudoknoten jedoch eine Punktschicht. Diese Fehler müssen von Benutzern manuell korrigiert werden, da es Zeiten gibt, in denen sich in einem Knoten drei Linien schneiden sollten, aber eine der Linien am Scheitelpunkt übersprungen oder nicht gefangen wurde.
HatT
Das sieht so aus, als sollte es funktionieren. Sie haben Schwierigkeiten, genau zu verstehen, was Sie hier sagen möchten. "Aufgrund von Fehlern braucht Pseudoknoten eine Punktschicht" Ich verstehe nicht, was Sie damit meinen. Benötigen Sie eine Punktebene mit Punkten, die am Ende jeder Linie ausgerichtet sind, damit dies funktioniert?
Rayner
@Rayner, füge ein neues Bild von Beispiel-Pseudoknoten (3) hinzu: Wenn ich für die lineare Ebene Punktebene-Pseudoknoten (blaue Rechtecke) erhalte, behebe ich die nächsten Fehler in der linearen Ebene manuell (nicht automatisch): A - füge fehlende Geometrie hinzu, B - gefangen Schnittlinie, C - Pseudoknoten entfernen. Wenn ich automatisch Pseudoknoten behebe, habe ich Fehler an den Stellen A, B hinterlassen.
HasT
Okay, ich verstehe B und C. Wenn Sie "A - fehlende Geometrie hinzufügen" sagen, was bedeutet das? Gibt es einen Punkt, der hinzugefügt werden muss, an dem sich die beiden Linien treffen?
Rayner
@Rayner, es bedeutet, was in 'A' lineares Merkmal hinzugefügt werden sollte (Straße / Straße gemäß Bild). In А - Knoten wurde vorbereitet, um neue Geometrie entsprechend der Bildsprache hinzuzufügen, aber Geometrie wurde nicht hinzugefügt (verwenden Sie Layer-Pseudoknoten, die ich nicht bemalte Geometrie finde)
HasT
2

Non-Free-Lösung: FME + MRF + SmartCleaner-Transformator

Kostenlose Lösung GRASS v.clean (das neueste QGIS 1.8.0 mit GRASS-Tools ist die einfachste Möglichkeit, es zu verwenden) und andere Tools zur Reinigung der Topologie

simplexio
quelle
QGIS 1.8.0. Installieren Sie das SEXTANTE-Plugin im Verzeichnis C: \ Programme \ Quantum GIS Lisboa \ apps \ qgis \ python \ plugins (1.0.7). Laden Sie die lineare shp-Datei in das QGIS-Projekt (CRS-Ebene und Projekt WGS1984, on-the-fly-Transformation). Dann wende ich 'Define GRASS region on canvas' (GRASS-Befehle - Tools) an und führe den Befehl v.clean -rmdangle aus (Thershold = 0, geben Sie dir / name für den Ausgabevektor / error ein). Nach dem Ausführen erhalten Sie den Fehler 'Layer konnte nicht geladen werden: D: /error.shp Überprüfen Sie das SEXTANTE-Protokoll auf Fehler'. Im Inhaltsverzeichnis neue Ebene hinzugefügt, Ebene mit Fehlern nicht geladen.
HasT
1
In GRASS gibt es den Befehl v.build.polylines - Ich erhalte eine von zwei Linien, die sich in einem Scheitelpunkt schneiden (gelöschter Pseudoknoten), aber diesen Befehl finde ich nicht im SEXTANTE-Plugin
HasT
@simplexio Kannst du bitte vorschlagen, welche Option von v.clean verwendet werden kann, um die Pseudoknoten zu identifizieren
osmjit
2

Hier sind Schritte, um Ihre Pseudoknoten mithilfe von OpenJump, einem kostenlosen GIS, zu finden.
QGIS und gvSIG haben das Sextante-Plugin, daher sollten die gleichen Schritte auch funktionieren, da
der Spatial-Join möglicherweise etwas anders ist.
Ich habe zum Testen Version 1.2 verwendet.

- Speichern Sie die
Toolbox Sextante Linienendpunkte , Topologie, Linienendpunkte extrahieren -> endpt_0

- Aufheben der Teilung Ihrer Linien
Toolbox Sextante, Werkzeuge für

Linienebenen , Verbinden benachbarter Linien - Speichern Sie die Toolbox
Sextante Linienendpunkte , Topologie, Extrahieren der Endpunkte von line -> endpt_1

- die Punkte Ende durch Pseudo - Knoten „benachbarte Linien verbinden“ entfernt

Werkzeuge, Abfragen, Spatial Query -
Source - Schicht „endpt_0“
Relation „erbohrt“
Maskenebene "endpt_1"

aktivieren oder auf Ergebnis ergänzen klicken

klewis
quelle
Danke für die Antwort! Ich versuche, diese Schritte in QGIS Sextante auszuführen, finde dort jedoch keine Befehle zum Extrahieren von Endpunkten von Linien und zum Verbinden benachbarter Linien. Ist es möglich, in QGIS Sextante (in gvSIG 1.12 existieren diese Befehle) oder Befehl v.build.polylines hinzuzufügen?
HasT
Ich habe gerade das QGIS Sextante Plugin installiert. Ich sehe auch nicht die vollen Funktionen, viele fehlen. Es sollte einfach sein, die Schritte in gvSIG auf einem Shapefile zu testen.
Klewis
Ich habe gerade den obigen Workflow in gvSIG 2.4.0.2834 überprüft und er funktioniert einwandfrei. Ich habe den letzten Schritt durch zwei andere Toolbox-Geoprozesse ersetzt: erstens die gvSIG "Spatial Join" , zweitens die "Filter Vector Layer" , die DIST > 0als Ausdruck verwendet wird. Darüber hinaus können alle Geoprozesse in einem SEXTANTE-Modell verkettet werden, um ein neues Werkzeug zu erstellen, z. B. "Pseudonodensuche" .
Antonio Falciano
1

In PostGIS können Sie eine geänderte Version der Abfrage verwenden, um in diesem Thema behandelte Dangles zu finden , da Pseudoknoten Knoten sind, die 2 Linienfolgen abfangen, und Dangles Knoten sind, die 1 Linienfolge abfangen.

WITH nodes AS 
(SELECT ST_StartPoint(geom) AS pt FROM
linestring_table UNION ALL 
SELECT ST_EndPoint(geom) AS pt FROM
linestring_table) 
SELECT pt FROM nodes
GROUP BY pt HAVING count(*) = 2;
Gauchoguitar10
quelle