Intersekcja warstw w PostgreSQL\PostGIS

Wiemy już jak zainstalować PostgreSQL z rozszerzeniem PostGIS i stworzyć nową bazę z obsługą warstw GIS. W dzisiejszym wpisie pokażemy jak napisać zapytania SQL zwracające wynik intersekcji dwóch warstw wektorowych. Użyjemy do tego wykorzystywanych wcześniej warstw z liniami kolejowymi i drogami (pobierz).

Wczytajmy warstwy do naszej bazy danych korzystając z narzędzia shp2psql. Otwieramy pgAdmina i sprawdzamy, czy dane są zapisane w bazie:

Wczytane dane możemy wyświetlić w QGIS-ie (jak to zrobić pisaliśmy w jednym z poprzednich postów):

W pgAdminie rozwińmy kolumny warstwy drogi:

Warstwa drogi ma wiele atrybutów opisowych oraz atrybut geom zawierający geometrię obiektów. Wartości atrybutu zapisanego w kolumnie geom wykorzystywane są do zapytań przestrzennych w SQL.

Do otrzymania informacji o intersekcji obiektów z dwóch warstw w języku SQL musimy wykorzystać funkcję zdefiniowaną w PostGIS-ie. Funkcja ta to ST_INTERSECTION(). Jako argumenty tej funkcji podajemy atrybuty geom z dwóch tabel (warstw). Zapytanie dające w wyniku geometryczną intersekcję warstw zapisaną w tabeli przejazdy będzie miało postać:

W wyniku zapytania otrzymujemy tabelę zawierająca 248784 rekordów. Tak duża liczba rekordów jest związana z tym, że funkcja sprawdza intersekcje każdego obiektu z każdym i zwraca wynik nawet w przypadku gdy obiekty się nie przecinają – wtedy otrzymujemy pusty obiekt geometryczny. Takiej warstwy nie będziemy mogli wyświetlić w QGIS-ie. Puste obiety moźnaby usunąć z utworzonej tabeli, ale spróbujmy zrobić to w jednym zapytaniu do którego dodamy warunek, że wynik intersekcji nie może być pusty. Do tego wykorzystamy funkcję ST_ISEMPTY():

W wyniku otrzymaliśmy tabelę z 57 rekordami. Dodajmy wynik do QGIS-a:

Przeanalizujmy poprzednie zapytanie krok po kroku:

Tworzymy nową tabelę o nazwie przejazdy zawierającą

Wynik intersekcji kolumn z geometrią pod nazwą geom

Z tabel drogi i kolej

Gdzie wynik intersekcji nie jest pusty

Funkcja ST_INTERSECTION() zwraca wynik intersekcji – w naszym przypadku punkty przecięć dróg z koleją. W przypadku gdy chcemy wybierać drogi przecinające kolej skorzystamy z innej funkcji ST_INTERSECTS() zwracającej wartości prawda/fałsz. Nasze zapytanie możemy napisać tak:

Zapytanie zwróciło nam tabelę drogi_przez_kolej z 57 rekordami. Wyświetlamy ją w QGIS-ie:

Niektóre linie kolejowe przebiegają przez jeden i ten sam odcinek drogi, co spowodowało że niektóre odcinki drogi zostały wybrane wielokrotnie. Funkcja ST_INTERSECTS zwróciła dla nich wartość PRAWDA. Wyeliminować powtórzenia można dodając do zapytania funkcję DISTINCT o której pisaliśmy już wcześniej. Po modyfikacji nasze zapytanie wygląda następująco:

Zapytanie zwraca 37 nie powtarzających się rekordów. Spróbujmy jeszcze na koniec zastosować dwie poznane funkcje do wyznaczenia przejazdów:

Czas wykonania zapytania wyniósł 330 msek. W porównaniu do poprzedniego tworzącego tabelę przejazdy, które zajęło 12 sek jest to znaczące przyspieszenie. Na podstawie tego małego porównania widzicie, że do określonego wyniku można dojść wieloma drogami (zapytaniami). Niektóre z nich mogą być kręte i długie:) Szukacie zatem zawsze optymalnego rozwiązania, testując kilka możliwych:)

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany.

Translate using Google Translate»
Social media & sharing icons powered by UltimatelySocial

Podoba Ci się nasza strona? Odwiedź nasz profil