Ten projekt ma ułatwić zrozumienie i wdrożenie:
- QGIS-a,
- bazy danych postgresql z rozszerzeniem postgis,
- relacji pomiędzy warstwami - skonfigurowanymi zarówno w bazie jak i w samym QGIS-ie (we właściwościach atrybutów).
- zaawansowana instalacja QGIS-a za pomocą OSGeo4W,
- instalacja i konfiguracja postgresql z rozszerzeniem postgis,
- konfiguracja połączenia z bazą,
- wczytanie załączonego projektu i skopiowanie warstw z projektu do bazy,
- konfiguracja triggerów. Część 1: podstawowe relacje pomiędzy warstwami,
- konfiguracja relacji za pomocą właściwości atrybutów,
- pobranie i obróbka danych z zewnętrznej bazy (na przykładzie LMS-plus).
3. Wymagania (prawdopodobnie projekt zadziała na wcześniejszych wersjach, ale został utworzony i przetestowany na następujących):
- QGIS v. 3.30.2-'s-Hertogenbosch,
- Rocky Linux 9.2,
- postgresql v. 15+,
- postgis v. 3.3.2.
1. Instalacja QGIS-a za pomocą OSGeo4W
2. Instalacja i konfiguracja postgresql z rozszerzeniem postgis
3. Konfiguracja połączenia z bazą
4. Wczytanie załączonego projektu i skopiowanie warstw z projektu do bazy
5. Konfiguracja triggerów. Część 1: podstawowe relacje pomiędzy warstwami
6. Konfiguracja relacji za pomocą właściwości atrybutów
7. Pobranie i obróbka danych z zewnętrznej bazy
- tabele z kolumną geometrii tworzoną jako "GENERATED ALWAYS AS (ST_Point(pe10_dlugosc, pe09_szerokosc, 4326))" - nie działają w QGIS-ie, problemem jest sam QGIS (powinien pomijać kolumnę generowaną w komunikacji z bazą - a akurat w przypadku geometrii nie pomija),
- relacje między tabelami przy użyciu "kluczy obcych" (tak to się tłumaczy?) - czyli "postgresql foreign keys". Kiepsko to działa w tym konkretnym projekcie oraz i tak wymaga dodatkowych triggerrów, więc skoro i tak musiałem pisać triggery - z foreign keys kompletnie zrezygnowałem
QGIS bardzo słabo radzi sobie z bardziej skomplikowanymi zapytaniami do baz zewnętrznych. ALE - jest rozwiązanie i na to. Zamiast w QGISIE używać np.:
SELECT DISTINCT n.id /*:int*/ AS lms_dev_id, CONCAT(n.id, '_', REPLACE(n.name, ' ', '')),
CONCAT(ls.ident, ld.ident, lb.ident, lb.type) /*:int*/ AS TERC,
(...)
ls.name /*:text*/ AS state_name, ls.ident /*:int*/ AS state_ident
FROM lms_netdevices n
INNER JOIN lms_addresses addr ON n.address_id = addr.id
(...)
INNER JOIN lms_netlinks nl ON (n.id = nl.src OR n.id = nl.dst)
ORDER BY n.id;
wystarczy w naszej bazie źródłowej utworzyć widok (VIEW):
CREATE VIEW vtable_for_qgis AS
SELECT DISTINCT n.id /*:int*/ AS lms_dev_id, CONCAT(n.id, '_', REPLACE(n.name, ' ', '')),
CONCAT(ls.ident, ld.ident, lb.ident, lb.type) /*:int*/ AS TERC,
(...)
ls.name /*:text*/ AS state_name, ls.ident /*:int*/ AS state_ident
FROM lms_netdevices n
INNER JOIN lms_addresses addr ON n.address_id = addr.id
(...)
INNER JOIN lms_netlinks nl ON (n.id = nl.src OR n.id = nl.dst)
ORDER BY n.id;
i teraz zapytanie SELECT * FROM vtable_for_qgis;
w QGIS-ie zwróci nam wynik w pół sekundy.
Projekt do otwarcia w QGIS-ie i dalszej zabawy znajduje się tutaj
Mam nadzieję że komuś się te informacje przydadzą.
Pozdrawiam i powodzenia! :]
English version soon to come...