6 Harjoitus 5: Paikkatietokohteiden geometria
Harjoituksen sisältö - Harjoituksessa tutustutaan PostGISin tapaan käsitellä geometrioita.
Harjoituksen tavoite - Harjoituksen jälkeen opiskelija tuntee PostGIS-geometrioiden käsittelyn perusteet.
6.0.1 Valmistautuminen
Avaa pgAdmin selaimeen ja kirjaudu sisään. Avaa Query Tool (Valitse trainingdatabase -> Ylhäältä Tools -> Query Tool).
6.1 Harjoitus 5.1
Luodaan aluksi tietokantaan uusi taulu, johon muodostetaan erilaisia geometrioita:
DROP TABLE IF EXISTS geom_test;
CREATE TABLE IF NOT EXISTS geom_test
(
gid serial PRIMARY KEY,
name varchar(50),
geom geometry(geometry, 3067)
);Lisää sen jälkeen tauluun yksittäinen piste seuraavalla komennolla:
INSERT INTO
geom_test(name, geom)
VALUES
('Single point', 'SRID=3067; POINT(0 0)');Voit tarkastella taulun tietoja SQL-kyselyllä tai QGIS-ohjelmiston avulla:
SELECT
name, ST_AsText(geom), ST_GeometryType(geom)
FROM
geom_test;6.2 Harjoitus 5.2
Lisää vielä tauluun viiva ja monikulmio.
Voit käyttää joko WKT-formaattia (LINESTRING(0 1, 2 3) ja POLYGON((4 5, 6 7, 8 9, 10 11, 4 5)), tai PostGIS:n funktioita ST_MakeLine, ST_MakePolygon ja ST_MakeEnvelope.
Tarkista PostGISin ohjekirjasta funktioiden oikeat muodot: 8.4 Geometry Constructors.
WKT- formaatti:
INSERT INTO
VALUES-- viivageometria
INSERT INTO
geom_test(name, geom)
VALUES
(..., '...; ...'); -- täytä arvot. Ota mallia ylhäällä olevasta piste- esimerkistä.
-- polygonigeometria (monikulmio, alue)
INSERT INTO
geom_test(name, geom)
VALUES
(..., '...; ...'); -- täytä arvot. Ota mallia ylhäällä olevasta piste- esimerkistä.INSERT INTO
geom_test(name, geom)
VALUES
('Single linestring', 'SRID=3067; LINESTRING(0 1, 2 3)');
INSERT INTO
geom_test(name,geom)
VALUES
('Single polygon', 'SRID=3067; POLYGON((4 5, 6 7, 8 9, 10 11, 4 5))');PostGIS- funktiolla:
INSERT INTO
VALUES-- Tarkista dokumentaatiosta, miten funktioita käytetään ja täydennä arvot.
INSERT INTO
geom_test(name,geom)
VALUES
('Simple polygon using ST_MakeEnvelope', ST_MakeEnvelope());
INSERT INTO
geom_test(name,geom)
VALUES
('Single point using ST_MakePoint', ST_SetSRID(ST_MakePoint(),3067));
INSERT INTO
geom_test(name,geom)
VALUES
('Single linestring using ST_MakeLine',
ST_SetSRID(ST_MakeLine(ST_MakePoint(),ST_MakePoint()),3067));INSERT INTO
geom_test(name,geom)
VALUES
('Simple polygon using ST_MakeEnvelope', ST_MakeEnvelope(20,20,40,40,3067));
INSERT INTO
geom_test(name,geom)
VALUES
('Single point using ST_MakePoint', ST_SetSRID(ST_MakePoint(100,200),3067));
INSERT INTO
geom_test(name,geom)
VALUES
('Single linestring using ST_MakeLine',
ST_SetSRID(ST_MakeLine(ST_MakePoint(1,1),ST_MakePoint(50,50)),3067));6.2.1 Pinta-alat
Geometrioihin liittyviä ominaisuuksia voidaan käyttää erilaisilla SQL-funktioilla. Seuraavalla hakulausekkeella haetaan Suomen pinta-alaltaan 10 pienintä kuntaa:
SELECT
kunta_ni1 as "Nimi", ST_Area(wkb_geometry) as "Pinta-ala"
FROM
nlsfi.hallintoalue
ORDER BY
ST_Area(wkb_geometry) asc
LIMIT 10;Pinta-alat esitetään käytetyn koordinaattijärjestelmän yksiköissä, tässä neliömetreinä. Jos haluat pinta-alan hehtaareina, jaa alue 10 000:lla (100 m x 100 m).
6.3 Harjoitus 5.3
Mikä on Uudenmaan maakunnan viidenneksi pienimmän kunnan pinta-ala neliökilometreinä?
SELECT
...
FROM
...
WHERE
...
ORDER BY
...
LIMIT ...
OFFSET ...;-- täydennä sarakkeet
-- round() funktio pyöristää arvon. Parametri '2' tarkoittaa, että luku
-- palautuu kahden desimaaliluvun tarkkuudella
SELECT
kunta_nimi_fi, maakunta
round((pinta_ala_funktio(geometria)/ ... ::numeric, 2) as "Pinta-ala (km2)"
-- selvitä, millä PostGIS- funktiolla voidaan laskea polygonin pinta-ala.
-- funktio palauttaa arvon koordinaattijärjestelmän yksiköissä,
-- tässä tapauksessa neliömetreinä. Yksikkö tulee muuntaa neliökilometreiksi
-- jakolaskulla. Täydennä oikea arvo.
FROM
nlsfi.hallintoalue
WHERE
maakunta = 'Uusimaa'
ORDER BY
pinta_ala_funktio(geometria) ... -- järjestä nousevaan järjestykseen
LIMIT 1
OFFSET ...;
-- OFFSET- avainsana siirtää palautuvan tulosjoukon alkamaan tietueesta x.
-- Millä arvolla saat viidenneksi pienimmän kunnan?SELECT
kunta_ni1 as "Kunta", maaku_ni1 As "Maakunta",
round((ST_Area(wkb_geometry)/(1000*1000))::numeric,2) as "Pinta-ala (km2)"
FROM
nlsfi.hallintoalue
WHERE
maaku_ni1 = 'Uusimaa'
ORDER BY
ST_Area(wkb_geometry) asc
LIMIT 1
OFFSET 4;6.3.1 Topologia
Voimme tutkia paikkatietoaineistojen geometrioiden topologiaa monella eri tavalla, esimerkiksi luettelo suomalaisista kunnista, joissa on reikä:
SELECT
kunta_ni1 as "Nimi"
FROM
nlsfi.hallintoalue
WHERE
ST_NumInteriorRings(ST_GeometryN(wkb_geometry,1)) > 0;6.3.2 Pituus
Paikkatietoaineistojen viivojen pituuksia voi tutkia ST_Length-funktiolla, harjoitusaineistossa olevien rautateiden yhteispituus:
SELECT
sum(ST_Length(wkb_geometry))/1000 as "Rautateiden yhteenlaskettu pituus"
FROM
nlsfi.rautatieviiva;6.4 Harjoitus 5.4
Mikä on suomalaisen tien nro 66 kokonaispituus?
SELECT
...
FROM
...
WHERE
...;-- Millä PostGIS- funktiolla saat laskettua pituuden?
-- käytä SUM- funktiota laskemaan tietueiden kokonaispituus
SELECT
round(SUM(pituus_funktio(wkb_geometry))::numeric,2) as "Reitin 66 kokonaispituus (m)"
FROM
nlsfi.tieviiva
WHERE
...; -- valitse tietueet tienumeron mukaanSELECT
round(SUM(ST_Length(wkb_geometry))::numeric,2) as "Reitin 66 kokonaispituus (m)"
FROM
nlsfi.tieviiva
WHERE
tienumero = 66;6.4.1 Esitysmuodot
Aikaisemmin katsoimme jo geometrioita tekstimuotoisena. PostGIS sisältää myös muita esitystapoja:
SELECT
ST_asGeoJSON(wkb_geometry)
FROM
nlsfi.hallintoalue
WHERE
kunta_ni1 = 'Ilomantsi';Kokeile eri tiedostomuotoja:
- GML
- SVG
- KML
- X3D
- EWKB, EWKT
6.4.2 Eri tieluokkien pituudet
Käytössä olevan aineiston tieluokittainen kokonaispituus:
SELECT
tieluokka as "Tieluokka", sum(st_length(wkb_geometry))/1000 as "Kokonaispituus"
FROM
nlsfi.tieviiva
GROUP BY
tieluokka
ORDER BY
"Kokonaispituus" desc;6.4.3 Tietotyyppien muutokset
PostgreSQL sisältää kaksi tapaa tietotyyppien muutoksiin (casting):
cast(varchar_col AS int) -- SQL yhteensopiva
varchar_col::int -- PostgreSQLn perinteinen tapa
SELECT CAST('POINT(0 0)' as geometry);
SELECT 'POINT(0 0)'::geometry;6.5 Harjoitus 5.5
Muodosta ensimmäisen harjoituksen lentokenttiä kuvaavasta tiedosta uusi paikkatietotaso, jossa lentokenttien sijainti ilmoitetaan PostGIS:n geometria-tyyppinä.
Alla näkyvästä SQL-komennosta kannattaa ottaa vähän vinkkiä (myös sen suhteen, että kannattaa tarkastella vain pientä otosta lentokenttä-aineistosta):
SELECT name, longitude, latitude, 'POINT(' || longitude || ' '|| latitude || ')' as WKT_uudet
FROM airports
ORDER BY name
LIMIT 10;DROP TABLE IF EXISTS airports_geom
CREATE TABLE airports_geom AS
(
SELECT
...
FROM
...
);
SELECT
...
FROM
...
ORDER BY
...
LIMIT ...;-- Millä PostGIS- funktiolla voit määrittää koordinaattijärjestelmän?
DROP TABLE IF EXISTS airports_geom;
CREATE TABLE airports_geom AS
(
SELECT
*, aseta_koordinaattijärjestelmä(CAST('...' as geometry),4326) as geometry
FROM
airports
);
-- täydennä funktio CAST() oikein. Katso ylhäältä mallia.
-- tarkastele uutta taulua:
SELECT
name, longitude, latitude, geom
FROM
airports_geom
ORDER BY
name
LIMIT 10;
DROP TABLE IF EXISTS airports_geom;
CREATE TABLE airports_geom AS
(
SELECT
*, ST_SetSRID(CAST('POINT(' || longitude || ' '|| latitude || ')' as geometry),4326) as geometry
FROM
airports
);
-- tarkastele uutta taulua:
SELECT
name, longitude, latitude, geom
FROM
airports_geom
ORDER BY
name
LIMIT 10;Harkitse geometrian esitystapaa: geometry vai geography?