Tuli vastaan taannoin työtehtävä, jossa työpöydälle tipahti pari hakemistollista vanhoja karttoja. Kartat piti saada julkaistuksi WMS-rajapinnalta taustakarttana. Aivan nollista ei onneksi tarvinnut lähteä liikkeelle, sillä ennen kuin kartat päätyivät allekirjoittaneen käsittelyyn, oli ne ensin skannattu papereista digikuviksi ja saatettu paikkatietomuotoon oikaisuasemoinnin avulla. Karttoja oli sen verran, että ajatus GDAL-kirjaston esiinkaivelusta nousi mieleen jo heti alkumetreillä.
Meikäläisen tehtäväksi tässä prosessissa jäi karttojen valmistelu ja käsittely sellaiseen muotoon, että ne voidaan julkaista WMS-rajapinnalle GeoServer-palvelimelta. Lopputulokseen päästiin monien vaiheiden jälkeen hyödyntämällä muutamia GDAL-kirjastoon kuuluvia komentorivisovelluksia ja ajamalla niitä Windowsin komentorivin FOR-silmukassa. Samaan kirjastoon kuuluvalla ogr2ogr-sovelluksella voidaan käsitellä myös vektorimuotoisia paikkatietoaineistoja.
GDAL töihin – kuvien muunto JPEG-muodosta GeoTiff-muotoon
Kuvien georeferointi oli toteutettu MapInfo-paikkatietojärjestelmän avulla. Merkkinä tästä oli se, että jokaista JPEG-formaattiin pakattua karttakuvaa kohden oli olemassa samanniminen TAB-tiedosto. Sen tarkemmin en tutustunut tekniikkaan, jolla TAB-tiedosto asemoi rasterikuvan oikeaan sijaintiin. Ilmeisen toimivasta ratkaisusta oli kuitenkin kyse, sillä GDAL:in onnistui lukea kuvien sijaintitiedot ongelmitta.
Rasteriaineistojen jakelu GeoServeriltä onnistuu parhaiten, kun lähtöaineistot ovat GeoTiff-muodossa, joten ensimmäinen vaihe prosessissa oli muuttaa JPEG-muotoiset karttakuvat GeoTiff-muotoon. Pakkaamattomana GeoTiff-kuvat vievät julmetusti tilaa, joten kuvat päätettiin pakata. Formaatiksi valittiin häviötön LZW-menetelmä.
Kuvien muunto JPEG-muodosta GeoTiff-muotoon onnistuu GDAL-kirjaston gdal_translate -komennolla. Gdal_translate -komennon avulla voidaan määritellä myös ns. nodata -arvo, joka tässä yhteydessä haluttiin asettaa arvoksi 0. Gdal_translate luo toimiessaan uusia kuvia, jotka on kannattaa sijoittaa omaan kansioonsa.
Uuden kansion luonti onnistuu kätevästi komentorivillä MKDIR-komennolla. Luodaan siis uusi kansio nodata0 ja prosessoidaan sinne läjä GeoTiff-muotoisia rasterikuvia. Homma onnistuu seuraavalla komennolla:
MKDIR nodata0 FOR %f IN (alkuperaiset_karttakuvat\*.jpg) DO gdal_translate -of GTiff -a_nodata 0 -a_srs EPSG:3878 -co COMPRESS=LZW %f nodata0\%~nf.tif
Päällekkäiset alueet esiin maskaamalla
JPEG -> GeoTiff -muunnoksen jälkeen ruvettiin maskaushommiin, sillä vanhat kartat haluttiin julkaista yhtenäisenä taustakartta-aineistona. Aineistojen WMS-jakelun toteuttamisen näkökulmasta tämä tarkoittaa sitä, että kuvista halutaan muodostaa yhtenäinen kuvamosaiikki GeoServer-palvelimen ImageMosaic-toiminnallisuuden avulla.
Aineiston käsittelyn näkökulmasta katsottuna tämä tarkoitti puolestaan sitä, että skannatuista kuvista piti saada poistettua sellaiset alueet, jotka ovat itse kartan ulkopuolisia (ks. kuvassa 1 olevat valkoiset alueet).

Tällaisia kartan ulkopuolisia alueita olivat esimerkiksi kuvissa esiintyvät reunukset, karttaselitteet ja karttoihin tehdyt merkinnät. Ratkaisun ongelmaan tarjoaa gdal_rasterize -komento, jonka avulla kuviin voidaan polttaa haluttu pikseliarvo vektorimuotoisen maskin avulla.
Jokainen kuvankäsittelyä tunteva tietää, mitä kuvien maskaamisella tarkoitetaan, joten maskaamista käsitteenä ei käsitellä tässä sen enempää. Syötteeksi gdal_rasterize -sovellus tarvitsee vektorimuotoisen (ESRI shapefile) aluerajauksen, jonka sisälle osuvat pikselit poltettaan haluttuun pikseliarvoon.
Maskien piirtely oli tämän toimeksiannon työteliän vaihe, sillä maskit täytyi piirtää käsipelissä. Käytännössä tässä edettiin siten, että jokainen karttakuva käsiteltiin QGIS:llä siten, että jokaiselle kuvalle piirrettiin oma maski. Piirtämisellä tarkoitetaan tässä yhteydessä aluemaisia geometrioita sisältävän ESRI shapefile -tiedoston luomista.
Valmiit maskit tallennettiin maskit-kansioon muodossa alkuperäisen_kuvan_nimi_maski.shp. Sitten kun kaikille kuville oli saatu askarreltua sopivat maskit, voitiin siirtyä varsinaiseen maskaamiseen. Maskaaminen onnistuu tosiaan jo mainitulla gdal_rasterize -komennolla. Määrityksiksi gdal_rasterize -työkalulle annetaan maskattavat kaistat (b = band) ja maskaamisessa käytettävä väriarvo (255).
Ja koska kyseessä on kolmikanavainen RGB-kuva, tulee GDAL komentaa ajamaan maski jokaiselle kanavalle (parametrit: -b 1 -b 2 -b 3) siten, että jokaisen kanavan pikselit, jotka sijoittuvat vektorimuotoisen maskin alle, saavat arvon 255 (parametrit: -burn 255 -burn 255 -burn 255). Maskaaminen onnistuu seuraavalla komennolla:
FOR %f IN (nodata0\*.tif) DO gdal_rasterize -b 1 -b 2 -b 3 -burn 255 -burn 255 -burn 255 -l %~nf_maski maskit\%~nf_maski.shp %f
Maskin jälkeen alpha-kanava kehiin
Kuten kuvasta 1 voidaan havaita, ei pelkällä maskaamisella mennä vielä kovin pitkälle. Ongelmaksi nousevat kuvaan maskatut valkoiset alueet, jotka peittävät alleen karttainformaatiota toisista karttakuvista. Tästä johtuen valkoinen väri määriteltiin läpinäkyväksi lisäämällä kuviin ns. alpha-kanavat ja määrittämällä nodata-arvon saaneet pikselit alpha-kanavalle.
Alpha-kanavan lisääminen RGB-kuvaan onnistuu gdalwarp-komennon avulla. Ennen kuvien käsittelemistä luodaan vielä uusi alpha-niminen kansio MKDIR-komennolla. Kansiota tarvitaan alpha-kanavan sisältävien kuvien tallennukseen, sillä gdalwarp muodostaa toimiessaan uusia rasterikuvia. Uuden alpha-kansion luonti ja alpha-kanavan luonti nodata-arvojen määrittelyineen onnistuu seuraavan komennon avulla:
MKDIR alpha FOR %f IN (nodata0\*.tif) DO gdalwarp -srcnodata 255 -dstalpha -co COMPRESS=LZW %f alpha\%~nf.tif

Kuvassa 2 nähdään miten alpha-kanavan määrittäminen vaikuttaa kuvamosaiikin toimivuuteen. Nodata-pikseleiden (255) tuuppaaminen alpha-kanavalle paljastaa aikaisemmin piilossa olleet pikselit. Kuva näyttää varsin hyvältä, mutta eräs ongelma siinä vielä on.
Tämä ongelma näkyy kuvan keskivaiheilla, jossa nähdään vanhan paperin värinen suikale, joka syystä tai toisesta jäi maskaamatta. Tässä tapauksessa vika oli siinä, että kyseiselle kuvalle oli jäänyt maski piirtämättä. Ongelman pystyisikin ratkaisemaan piirtämällä ko. kuvatiedostolle halutut osat kuvasta poistava maski ja ajamalla maskauskomento uudelleen.
Ongelman voi ratkaista myös GeoServerin ImageMosaic-toiminnon puolella erillistä Sorting-toimintoa hyödyntäen. Tässä artikkelissä tämän sorting-toiminnon käyttämiseen ei sen suuremmin kuitenkaan perehdytä, sillä kuvamosaiikin konffaaminen GeoServerin puolella on jo aivan oma lukunsa.
Kuvien esivalmistelu WMS-jakelua varten
Rasterikuvien WMS-jakelua varten aineistoille kannattaa tehdä parit esivalmistelut. Esivalmistelut nopeuttavat karttakuvien muodostumista GeoServer-palvelimella, joten ne kannattaa ehdottomasti toteuttaa. WMS-palvelun suorituskyvyn kannalta kaikkein tärkeimmät esivalmistelut ovat karttatiilijaon esilaskenta GeoTiff-kuviin (tiling) ja yleistystasojen muodostaminen (adding overviews).
Oletusasetuksilla GeoTiff-kuvia tiiliteltäessä, kuviin muodostetaan 256 pikseliä suuntaansa oleva tiilijako, joka on yleisesti käytetty. Tiilien kokoa voi halutessaan muuttaa BLOCKXSIZE– ja BLOCKXSIZE-parametreilla. Tiilityksen lisääminen kuviin toteutetaan gdal_translate-komennolla.
Haluttaessa muodostaa kuviin tiilijako, käytetään parametria -co TILED=YES. Tiilitettyjä rasterikuvia vasten tarvitaan oma kansio, joka luodaan aikaisemmista komennoista tutulla MKDIR-komennolla. Uuden kansion luonti ja tiilitettyjen kuvien tallennus juuri luotuun kansioon onnistuu seuraavalla komennolla:
MKDIR tiilitetty FOR %f IN (alpha\*.tif) DO gdal_translate -of GTiff -co TILED=YES -co COMPRESS=LZW %f tiilitetty\%~nf.tif
Yleistystasojen lisääminen kuviin tuo nopeutta
Toinen tärkeä esivalmistelu liittyy ns. yleistystasojen muodostamiseen. Yleistystasojen muodostamisen hyödyt konkretisoituvat tilanteessa, jossa rasterikuvaa tarkastellaan natiiviresoluutioon nähden huomattavasti poikkeavassa mittakaavassa. Selvennettäköön tilannetta esimerkin avulla.
Otetaan esimerkiksi vaikkapa korkean spatiaalisen resoluution (5 cm) laaja-alainen ortokuvamosaiikki, jota tarkastellaan mittakaavassa 1 : 50 000. Tarkan aineiston tarkastelu näin korkealta on todella hidasta, sillä ruudulla näkyvän kuvan muodostamiseksi tietokone joutuu lukemaan ensin ortokuvamosaiikkia natiiviresoluutiossa ja skaalaamaan sitä sen jälkeen rajusti alaspäin. Skaalaaminen tai oikeammin resamplaaminen kuluttaa paljon suoritintehoa.
Piirtoon käytettävän suoritintehon minimoinnilla voidaan nopeuttaa kuvan latautumista ja juuri tähän pyritään muodostamalla yleistystasot ennakolta. Käytettäessä ennakkoon muodostettuja yleistystasoja, ei jokaisen kuvan palauttamiseksi suoritettava laskentaoperaatio ole niin raskas ja kuva latautuu nopeammin.
GeoTiff-rasteriformaatti tukee ns. sisäisiä yleistystasoja (inner overviews) jolloin yleistystasot voidaan kirjoittaa olemassa olevan GeoTiff-tiedoston sisään. Tarvittaessa yleistystasot voidaan kirjoittaa myös ulkoiseen tiedostoon, jolloin kuvatiedoston kylkeen syntyy yleistystasot sisältävä ovr-tiedostotarkenteiden tiedosto.
Ulkoisia yleistystasoja tarvitaan etenkin sellaisten kuvaformaattien kanssa, jotka eivät tue sisäisten yleistystasojen käyttämistä. Tällaisia formaatteja ovat esimerkiksi JPEG- ja PNG-kuvat (em. kuvatformaatit eivät voi sisältää myöskään koordinaattitietoa, jolloin tarvitaan lisäksi ns. World-tiedosto sijainnin määrittämistä varten).
Yleistystasojen lisäämistä varten GDAL-kirjastosta löytyy komento gdaladdo, jota käyttämällä yleistystasot saadaan näppärästi lisättyä. Gdaladdo-komennolle voidaan antaa parametreja, joista tärkeimpiä ovat käytettävän resamplausmenetelmän valinta (-r average) ja tuotettavien yleistystasojen määrittely (2 4 8 16 32 64).
Tuotettavat yleistystasot määritellään kokonaislukuina siten, että esimerkiksi luku neljä tarkoittaa sitä, että gdaladdo muodostaa yleistystason, jonka resoluutio on 1/4 alkuperäisestä resoluutiosta. Yleistystasojen luonti onnistuu seuraavalla komennolla:
FOR %f IN (tiilitetty\*.tif) DO gdaladdo -r average --config COMPRESS_OVERVIEW LZW %f 2 4 8 16 32 64
Rasterikuvat virtuaalirasteriksi GDAL-kirjastolla
Aineisto on nyt valmis GeoServer-palvelimen kuvamosaiikkia varten. Tässä artikkelissa kuvamosaiikkia ei kuitenkaan julkaista GeoServer-palvelimelle, mutta tokihan me lopputulemaa halutaan tarkastella. Useista kuvapalasista koostuvaa kuvamosaiikkia voidaan esikatsella GeoServer-palvelinohjelmiston lisäksi QGIS-paikkatietosovelluksella, joten kerrottakoon vielä tähän loppuun kuinka se on tehdään.
Vaihtoehtoina on, että käyttäjä lisää manuaalisesti n kappaletta kuvia omiksi rasteritasoikseen QGIS:iin ja hallitsee kokonaisuutta QGIS-paikkatietosovelluksen karttatasoikkunan kautta. Toinen vaihtoehto on muodostaa kuvista ns. virtuaalirasteri, jota voi käsitellä QGIS-paikkatietosovelluksessa yksittäisenä rasteritasona.
Tässä esimerkissä hyödynnetään virtuaalirasteria, sillä useiden kymmenien rasterikuvien hallintaa QGIS:n karttatasoikkunassa ei voi pitää sujuvana. Virtuaalirasteri luodaan GDAL-kirjastoon kuuluvan gdalbuildvrt -komennon avulla. Tässä esimerkiksi luodaan kaikki_kartat -nimellä oleva virtuaalirasteri kaikista tiilitetty-kansiossa olevista GeoTiff-kuvista. Ohessa komento virtuaalirasterin luomiseksi.
gdalbuildvrt kaikki_kartat.vrt tiilitetty\*.tif
Näin loppuun on paikallaan todeta, että GDAL-kirjasto taipuu oikein mainiosti monenlaiseen rasterikuvien sarjakäsittelyyn. GDAL-kirjaston avulla voi tehdä paljon muutakin. Itselläni on kokemusta mm. rasterikuvien yhdistelystä yhdeksi kuvaksi gdal_merge-komennolla, vektorimuotoisten korkeuskäyrien muodostamisesta rasterimuotoisesta korkeusmallista gdal_contour-komennolla ja rasterikuvien speksien ihmettelystä gdalinfo-komennolla.
FOR-silmukan avulla hakemistollisen kuvia pyöräyttää läpi nopeasti eikä skriptipohjainen käsittely ainakaan heikennä ajettujen komentojen toistettavuutta. Haasteena tekstimuotoisten komentojen kanssa puljatessa on toki se, että komennot pitää kirjoitella käsin.