Znaleźć pseudo-węzły w darmowym oprogramowaniu GIS?

16

Oprogramowanie gvSIG OA Digital Edition 2010 ma topologię narzędzi do wyszukiwania pseudo-węzłów w geometrii liniowej. Ustawiam tolerancję klastra 0,00002 i maksymalną liczbę błędów -10000 dla geometrii liniowej liczby łączy 20000. Ale nieudany wynik.

Czy są jakieś rozwiązania, które znajdują pseudo-węzły w darmowym oprogramowaniu GIS?

Muszę warstwować pseudo-węzły (jedno rozwiązanie tego problemu - aby korzystać z topologii narzędzi ArcInfo, ale dla mnie priorytetem jest korzystanie z wolnego oprogramowania). Geometria liniowa stworzyła kilku użytkowników w QGIS 1.8.0 w bazie danych PostGIS (wer. 2.0.1).

Dodaj nowy obraz: 12 elementów liniowych z trzema pseudo-węzłami w A (linia 4/5), B (linia 6/7), C (linia 9/10). Pseudo-węzły powinny być zamiast tego punktami - dwie cechy liniowe z przecięciem w jednym punkcie (węzeł) powinny być jedną cechą liniową (linia 4/5 - linia 4, ...).

Czy w PostGIS można złożyć żądanie, które spowoduje powstanie warstwy pseudo-węzłów?

Dodaj nowy obraz przykładów pseudo-węzłów: jeśli otrzymuję pseudo-węzły warstwy punktowej warstwy (niebieskie prostokąty), poprawiłem następujące błędy w warstwie liniowej: A - dodaj brakującą geometrię, B - przerywana linia na przecięciu, C - usuń pseudo-węzeł.

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

HasT
źródło
2
W GRASS istnieje polecenie rmdangle, ale w rezultacie plik shp bez pseudo-węzłów. W rezultacie powinien powstać plik shp (lub inny) z pseudo-węzłów (takich jak gvSIG OA Digital Edition 2010)
HasT
Czy korzystasz z PostGIS 2.0? Jeśli tak, spróbuj funkcji Is_Valid i Makevalid.
Giovanni Manghi
Tak, używam PostGIS 2.0. Jak powinienem używać tych funkcji do wyszukiwania pseudo-węzłów? Czy można je znaleźć za pomocą „PgQuery dla QGIS”?
HasT
tak, możesz używać ich w QGIS w dowolnym narzędziu, które pozwala na uruchomienie zapytania PostGIS, na przykład DB Manager (który obsługuje podświetlanie składni i automatyczne uzupełnianie).
Giovanni Manghi
czerwony punkt na drugim zdjęciu jest przecięciem dwóch prawidłowych geometrii .. prawda?
vinayan

Odpowiedzi:

8

Oto ogólne rozwiązanie, które można wdrożyć za pomocą PostGIS lub dowolnego innego oprogramowania zgodnego z OGC.

UWAGA: jak mówiłem wcześniej , kluczową koncepcją w FOSS i GIS jest normalizacja : najlepsze rozwiązania przyjmują standardy, takie jak OGC .


Twoim problemem jest „znaleźć pseudo-węzły” ... Ale myślę, że to trochę więcej, „znaleźć niepseudo-węzły i połączyć linie pseudo-węzłów”. Moje rozwiązanie może być wykorzystane w obu przypadkach.

Standardy OGC oferują:

  • ST_Boundary (geom) : do wykrywania węzłów linii

  • ST_Dump (geom) : aby umieścić każdy pojedynczy węzeł w rekordzie tabeli SQL.

  • ST_DWithin, ST_Equals, ST_SnapToGrid, ST_Snap mogą być używane do tolerancji zmian. Używam ST_DWithin.

Możemy przypuszczać, że główny problem można określić za pomocą tych obiektów i właściwości,

  • są tylko odcinki (z tabeli odcinek ), reprezentowana przez geometrii LineString ... Nie testowane MULTILNE, jeśli masz geometrytype = MULTIPOINT, można podzielić i multilinie odlewane z ST_Dump i ST_LineMerge;

  • każdy odcinek ma geometrię (ID) gid i kolor (ID) idline .

Pierwszym krokiem jest uzyskanie węzłów pochodzących z linii łączących,

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;

UWAGA: używanie pamięci podręcznej, ponieważ są one szybsze niż widoki. Użyj „WYBIERZ WYBÓR ...”, aby sprawdzić czas procesora, może to zająć dużo czasu.

Tutaj cykle i linie ciągłe (tego samego koloru) są wykrywane jako ncolors=1punkty, a pseudo-węzły według ncolors=2punktów, więc masz warstwę z tymi punktami.

Tabela „dobrych węzłów” zawiera oryginalne „punkty graniczne” i „pseudo-węzłów”.

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
źródło
Dziękuję za rozwiązanie! Próbuję uruchomić zapytanie (w pgAdmin), ale otrzymuję wyjątek: „funkcja array_distinct (liczba całkowita []) nie istnieje”. Co ja robię źle?
HasT
Przepraszamy, nie cytowana array_distinctfunkcja pochodzi z biblioteki postgres.cz . Wszelkie inne błędy, proszę zgłaszać, mogę dodać więcej wyjaśnień tutaj.
Peter Krauss,
Dodałem funkcję array_distinct. W bazie danych warstwa liniowa ma nazwę kolumny „the_geom” (zamiast „geom” w zapytaniu). Zamieniam „geom” na „the_geom” dla „ST_Boundary (the_geom)” po uruchomieniu zapytania otrzymuję komunikat „kolumna” geom „nie istnieje” w „jako kolory, geom FROM” miejsce. Zamieniam „as colours, geom FROM” na „as colors, the_geom FROM”, ale ponownie otrzymuję komunikat „kolumna” the_geom „nie istnieje”.
HasT
Ok, zmieniono (patrz edytowana odpowiedź) geomna the_geom. (ST_Dump (x)) pozostaje jako geom, nie jest atrybutem bazy danych.
Peter Krauss,
Dzięki! Zapytanie działa. Zastąpiłem ST_DWithin na ST_equals i dla ST_Buffer podaję 0,00002 DD tolerancję. W rezultacie otrzymałem prawidłowe węzły (gdzie w jednym węźle przecina 3 i więcej cech liniowych). Chcę otrzymać wynik, w którym w jednym węźle przecina 2 cechy liniowe (OD vw_joinnodes_full GDZIE ncolors = 2;), ale otrzymałem warstwę punktową, w której w jednym węźle przecina 2 i więcej cech liniowych. Jak otrzymać wynik, gdy w jednym węźle przecinają tylko 2 elementy liniowe?
HasT
7

Refractions Research stworzyło narzędzie do czyszczenia linii, które wydaje się robić to, co chcesz.

Line Cleaner czyści sieci, upraszczając złożone, cykliczne, bardzo krótkie geometrie o zerowej długości oraz usuwając pseudo-węzły i nieznaczne wierzchołki. Co najważniejsze, w fazie oczyszczania jest w stanie zapewnić automatyczne uwzględnianie dopasowań funkcji

wprowadź opis zdjęcia tutaj

Kod źródłowy można znaleźć na GitHub.

RK
źródło
Dziękuję za Twoją odpowiedź. Ale w wyniku błędów pseudo-węzeł potrzebuje warstwy punktowej. Błędy te muszą być ręcznie poprawione przez użytkowników, ponieważ zdarza się, że w jednym węźle przecinają się trzy linie, ale jedna z linii została pominięta lub nie została przyciągnięta do wierzchołka.
HasT
Wygląda na to, że powinno działać. Masz problem ze zrozumieniem, co chcesz tu powiedzieć. „w wyniku błędów pseudo-węzeł potrzebuje warstwy punktowej”. Nie rozumiem, co przez to rozumiesz. Czy potrzebujesz warstwy punktowej z punktami przyciągniętymi do końca każdej linii, aby to działało?
Rayner,
@Rayner, dodaj nowy obraz przykładów pseudo-węzłów (3): jeśli otrzymam pseudo-węzły warstwy punktowej warstwy (niebieskie prostokąty), naprawiam ręcznie (nie automatycznie) kolejne błędy w warstwie liniowej: A - dodaj brakującą geometrię, B - przyciągnięte linia na przecięciu, C - usuń pseudo-węzeł. Jeśli naprawię automatycznie pseudo-węzły, zostawiłem błędy w miejscach A, B.
HasT
OK, rozumiem B i C. Kiedy mówisz „A - dodaj brakującą geometrię”, co to znaczy? Czy należy dodać punkt, w którym spotykają się 2 linie?
Rayner,
@Rayner, oznacza to, że w „A” należy dodać element liniowy (ulica / droga zgodnie ze zdjęciami). W А - węzeł został przygotowany do dodania nowej geometrii zgodnie ze zdjęciami, ale geometria nie została dodana (użyj pseudo-węzłów warstwy, dla których nie znalazłem geometrii malowanej)
HasT
2

Rozwiązanie niewolne: transformator FME + MRF + SmartCleaner

Darmowe rozwiązanie GRASS v.clean (najnowszy QGIS 1.8.0 z narzędziami GRASS jest najłatwiejszym sposobem użycia) i inne narzędzia do czyszczenia topologii

simplexio
źródło
QGIS 1.8.0. Zainstaluj wtyczkę SEXTANTE w katalogu C: \ Program Files \ Quantum GIS Lisboa \ apps \ qgis \ python \ plugins (1.0.7). Załaduj liniowy plik shp do projektu QGIS (warstwa CRS i projekt WGS1984, włączona transformacja „w locie”). Następnie stosuję „Zdefiniuj region GRASS na kanwie” (polecenia GRASS - Narzędzia) i uruchamiam polecenie v.clean - rmdangle (Thershold = 0, wpisz katalog / nazwa dla wektora wyjściowego / błędów). Po uruchomieniu procesu pojawia się błąd „Nie można załadować warstwy: D: /error.shp Sprawdź dziennik SEXTANTE, aby wyszukać błędy”. W TOC dodano nową warstwę, warstwa z błędami nie została załadowana.
HasT
1
W GRASS istnieje polecenie v.build.polilines - otrzymuję jeden z dwóch wierszy, które przecinają się w jednym wierzchołku (usunięty pseudo-węzeł), ale polecenia tego nie znajduję we wtyczce
SEXTANTE
@simplexio Czy możesz zasugerować, której opcji v.clean można użyć do identyfikacji pseudo-węzłów
osmjit
2

Oto kroki, aby znaleźć swoje pseudo-węzły za pomocą OpenJump darmowego GIS.
QGIS i gvSIG mają wtyczkę Sextante, więc te same kroki również powinny działać, łączenie
przestrzenne może się nieco różnić.
Do testowania użyłem wersji 1.2.

- zapisz punkt końcowy linii
Sextante przybornik, topologia, wyodrębnij punkty końcowe linii -> endpt_0

- odznacz swoje linie
Sextante przybornik, narzędzia do warstw linii,

połącz sąsiednie linie - zapisz punkty
nieoznaczone linii końcowej Sextante linia -> endpt_1

- punkty końcowe usunięte przez „Połącz sąsiednie linie” to pseudo-węzły

Narzędzia, zapytania, zapytania przestrzenne,
warstwa źródłowa „endpt_0”
Relacja „Przecina”
Warstwa maski „endpt_1”

włącz lub kliknij opcję Uzupełnij wynik

Klewis
źródło
Dziękuję za odpowiedź! Próbuję wykonać te kroki w QGIS Sextante, ale nie znajduję tam poleceń „Wyodrębnij punkty końcowe linii” i „Połącz sąsiednie linie”. Możliwe jest dodanie w QGIS Sextante (w gvSIG 1.12 istnieją te polecenia) lub polecenie v.build.polilines?
HasT
Właśnie zainstalowałem wtyczkę sextante QGIS. Nie widzę też pełnych funkcji, wielu brakuje. Testowanie kroków w gvSIG powinno być łatwe na pliku shapefile.
klewis
Właśnie zweryfikowałem powyższy przepływ pracy w gvSIG 2.4.0.2834 i działa dobrze. Ostatni krok zastąpiłem dwoma innymi geoprocesami z zestawu narzędzi: po pierwsze gvSIG „Spatial Join” , po drugie „Filter vector layer” wykorzystując DIST > 0jako wyrażenie. Ponadto wszystkie geoprocesy można połączyć w łańcuch w modelu SEXTANTE w celu stworzenia nowego narzędzia, np. „Znajdź pseudonody” .
Antonio Falciano,
1

Za pomocą PostGIS można użyć zmodyfikowanej wersji zapytania, aby znaleźć zawieszki omówione w tym temacie , ponieważ pseudonody to węzły przechwytujące 2 linie liniowe, a wiszące to węzły przechwytujące 1 liniowy.

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
źródło