Scott Tiger Tech Blog

Blog technologiczny firmy Scott Tiger S.A.

Podstawy PostGIS

Autor: Piotr Karpiuk o piątek 4. Grudzień 2015

PostgreSQL został zaprojektowany z myślą o łatwej rozbudowie. Twórcy rozszerzeń mogą definiować własne typy danych, typy indeksów (korzystając z tzw. Generic Index Structure), jak również dodawać nowe funkcje. Rozszerzenie PostGIS korzysta z tych możliwości pełnymi garściami, aby uzupełnić relacyjną bazę danych o obsługę danych geograficznych, dzięki czemu duet PostgreSQL+PostGIS stał się podstawą systemów GISowych w świecie open source.

Co tam zatem mamy?

  • bogactwo funkcji do przeszukiwania, analizy, konwersji i zarządzania danymi przestrzennymi,
  • wsparcie zarówno dla danych wektorowych, jak i rastrowych,
  • zgodność ze standardami Open Geospatial Consortium,
  • PostGIS obrósł szeregiem korzystających z niego projektów takich jak Proj4 (do konwersji między odwzorowaniami kartograficznymi), GEOS, czy GDAL.

Tak jak powszechnie używanym interfejsem graficznym dla PostgreSQL jest pgAdmin, tak dla PostGISa jest to Quantum GIS (qGIS).

Tworzenie bazy z obiektami przestrzennymi jest proste:

$ createdb -U postgres Real-State
$ psql -d Real-Estate -U postgres
Real-State# CREATE EXTENSION postgis;

Tabela przestrzenna (ang. spatial table) to tabela zawierająca pole typu geometry do danych dwuwymiarowych (istnieje też typ geography do danych 4D używany do reprezentowania dużych odległości, z mniejszą ilością operujących na nim funkcji, ale uwzględniający różnice wysokości n.p.m. i krzywiznę Ziemi; ponadto mamy też typ danych raster dla danych rastrowych).

Real-State# CREATE TABLE tbl_landmarks ( ..., the_geom geometry, ... );

Wartości typu geometry możemy zapisywać w notacji Well-Known text (WKT):

INSERT INTO tbl_landmarks (the_geom) VALUES (ST_GeomFromText('POINT(-0.116190, 51.556173)'));

Oprócz POINT może być np. MULTIPOINT (zbiór punktów), LINESTRING (łamana), MULTILINESTRING (zbiór łamanych), POLYGON (wielokąt), MULTIPOLYGON, itp.

W praktyce dobrze jest dla każdej wartości typu geometry definiować odwzorowanie kartograficzne, i dlatego zamiast notacji WKT lepiej użyć tzw. Extended WKT (tutaj użyjemy odwzorowania WGS84, czyli SRID 4326 – używany w nawigacji satelitarnej i Google Maps):

INSERT INTO tbl_landmarks (the_geom) VALUES (ST_GeomFromEWKT('SRID=4326;POINT(51.556173, -0.116190)'));

Bardzo często chcemy zaimportować do bazy zawartość pliku *.shp. Do konwersji takiego pliku na polecenia INSERT do PostgreSQLa możemy użyć narzędzia shp2pgsql wchodzącego w skład PostGISu:

$ shp2pgsql -g the_geom points_file.shp tbl_landmarks > landmarks.sql

Do konwersji plików z danymi przestrzennymi do powszechnie używanego formatu *.shp można użyć biblioteki GDAL/OGR, która jest częścią PostGISa i jest dostępna jako zbiór programów wiersza poleceń oraz biblioteki do różnych języków programowania. GDAL jest do danych rastrowych, OGR do wektorowych. Polecenia:

gdalinfo --formats
ogrinfo --formats

wyświetlą dostępne formaty. Konwersja wygląda tak:

ogr2ogr -f "Format name" output_file input_file

np.:

ogr2ogr -f "ESRI Shapefile" postcode-boundaries.shp postcode-boundaries.kml

Metadane pliku rastrowego (w tym m.in. zastosowane odwzorowanie kartograficzne) poznamy za pomocą polecenia gdalinfo, np.:

gdalinfo PLOverview.tif

Do przekonwertowania danych rastrowych na inne odwzorowanie kartograficzne używamy gdalwrap:

gdalwrap -s_srs EPSG:2810 -t_srs EPSG:4326 PLOverview.tif PLOverview4326.tif

Aby załadować dane rastrowe do bazy (do kolumny typu raster):

raster2pgsql PLOverview.tif -F tableName > PLOverview.sql

Jeśli zastosowanym odwzorowaniem kartograficznym jest WGS84, to wyniki wszelkich funkcji mierzących odległość, pole powierzchni itp. będą stopnie/stopnie kwadratowe, które trzeba we własnym zakresie zamienić na metry. Możemy jednak „w locie” przetransformować układ na metryczny (np. polski EPSG:2180) i np. zwrócić powierzchnię w hektarach:

select st_area( st_transform( the_geom, 2180 )) / 10000 from tbl_landmarks;

Podobnie obwód w km:

select st_perimeter( st_transform( the_geom, 2180 )) / 1000 from tbl_landmarks;

Przydatne funkcje

Jakiego rodzaju obiekty znajduja sie w kolumnie geometria (np. ST_Point, ST_Multipolygon, itp.)

select distinct st_geometrytype(geometria) from public.powiaty_2rp;

Jakie jest odwzorowanie EPSG wartości w kolumnie?

select distinct st_srid(geometria) from public.woj_2rp;

Ustawienie odwzorowania dla wszystkich wartości kolumny:

update woj_osm set geometria = st_setsrid(geometria, 3857);

Geometria jako WKT (inne możliwości to asewkt, asgml, asgeojson):

select st_astext(geometria) from public.powiaty_2rp where pow = 'wołkowyski';

Spis wszystkich funkcji PostGIS

Indeksy

Aby założyć indeks na kolumnie przestrzennej:

CREATE INDEX [indexname] ON [tablename] USING GIST ( [geometryfield] );

Warto przed tym wykonać polecenie VACUUM:

VACUUM ANALYZE tablename (geometryfield);

Share and Enjoy:
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • Śledzik
  • Blip
  • Blogger.com
  • Gadu-Gadu Live
  • LinkedIn
  • MySpace
  • Wykop

Zostaw komentarz

XHTML: Możesz użyć następujących tagów: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>