wiki:ol3
Last modified 3 years ago Last modified on 2014-05-12 11:00:35

OpenLayers? 3 tutoriaali

Projektiot

Ongelma: maapallo on muodoltaan geoidi ja kartta esitetään useimmiten tasolla (esim. tietokoneen näyttö). Jatko-ongelma: tasolla esitetty projektio pallomaisesta pinnasta vääristyy aina jossain kohden. Ratkaisu: useita eri projektioita eri käyttötarkoituksiin

Lisätietoa: http://fi.wikipedia.org/wiki/Karttaprojektio

Koordinaattijärjestelmät Tarkoituksena esittää jonkin pisteen sijainti maapallolla

Esim: WGS84 (EPSG:4326) Maailmanlaajuinen koordinaatisto, joka on määritetty maapallon ympärille määritellyn abstraktin ellipsoidin avulla. GPS käyttää tätä järjestelmää. Lisätietoa: http://fi.wikipedia.org/wiki/WGS84

Esim: Web Mercator (EPSG:3857) Maailmanlaajuinen koordinaatisto, joka on projisoitu WGS84 ellipsoidista tasolle Mercatorin projektiolla. Käytetään maailmanlaajuisten kartastojen esittämiseen. Koordinaatisto vääristyy sitä enemmän, mitä lähemmäs liikutaan päiväntasaajalta napa-alueille (kts: http://fi.wikipedia.org/wiki/Mercatorin_projektio#Mittakaavavirhe). Esim. Google Maps ja OpenStreetMap? käyttävät oletuksena Mercatorin projektiota.

Lisätietoa: http://fi.wikipedia.org/wiki/Mercatorin_projektio

Esim: ETRS-TM35FIN (EPSG:3067) Suomen virallinen (Julkisen hallinnon suositus) koordinaattijärjestelmä Lisätietoa: http://fi.wikipedia.org/wiki/ETRS-TM35FIN

Tasot

GIS (Geographic Information System) sovelluksissa käytetään apuna tasoja (layer) vastaavalla tavalla kuin kuvankäsittelyssä

Aineistomuodot

Rasteri: Kuvia, jotka ovat aina jossain kiinteässä mittakaavassa, koordinaatistossa ja projektiossa. Kartat koostetaan usein tasakokoisista karttaruutukuvista. Rasterit voidaan transformoida muihin projektiohiin jne, mutta operaatiot ovat raskaita

Vektori Paikkatietodata esitetään taulukkomuodossa, joka visualisoidaan ohjelmallisesti. Pikseleiden sijaan käytetään pisteitä. Aineistoja on helppo projisoida "lennossa".

Feature Karttarepresentaatio jostain reaalimaailman kohteesta. Sisältää yleensä geometrian ja siihen liittyvää attribuuttidataa. Geometria on yleensä määritelty tietotyypiksi, joka pitää sisällään tiedon geometrian tyypistä (piste, viiva, polygon jne), käytetyn koordinaattijärjestelmän, sekä itse pisteet, joista geometria muodostuu.

Perusgeometriat

Point (x,y, joskus myös z, eli korkeus)

PolyLine? (joukko pisteitä, joiden välille piirretään viiva)

Polygon (joukko pisteitä, joita pitkin piirretty viiva muodostaa suljetun polygonin)

WMS, WMTS ja WFS rajapinnat

WMS = WebMapService? Pääasiallinen käyttötarkoitus on välittää karttakuvia (esim. karttakuvia, tai kuvamuotoisia karttageometrioita). Mahdollista myös kysellä tietoa featureista. WMS tarjoaja palauttaa WMS kyselyn mukaisen karttakuvan. URL- tai XML-kyselyt WMS palvelulle.

Esim: WMS palvelun tarjoamia ominaisuuksia voi kysellä vaikkapa näin: http://tiles.kartat.kapsi.fi/taustakartta?service=WMS&request=GetCapabilities&version=1.3.0 Yksittäisen karttakuvan voi hakea esimerkiksi näin:

http://tiles.kartat.kapsi.fi/taustakartta?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=true&WIDTH=230&HEIGHT=230&CRS=EPSG%3A3857&STYLES=&MAP_RESOLUTION=80.859375&BBOX=2864248.3239021264%2C8915003.482956678%2C2864554.0720152673%2C8915309.231069818

Tällä tavalla kyselyiden laatiminen ei kuitenkaan ole usein kovin mielekästä. Usein käytetään WMS asiakasohjelmaa / kirjastoa, joka hoitaa kyselyiden tekemisen annettujen parametrien avulla.

Lisätietoa (englanniksi): http://en.wikipedia.org/wiki/Web_Map_Service

WMTS = WebMapTileService? Erityisesti karttaruutujen välittämiseen tarkoitettu rajapinta. Esim. taustakartta-aineistoja ei välitetä webissä yleensä vektoreina, koska vektoreista karttakuvien tuottaminen vaatisi liikaa prosessoritehoa. Isot kartta-aineistot on jaoteltu ruutuihin (tile), joita voi kysellä paikkatietopalvelimelta WMTS:n kautta.

WFS = WebFeatureService? Pääasiallinen käyttötarkoitus on välittää paikkatietodataa (Geometriat + attribuuttidata). Useita output formaatteja (GML, XML, JSON jne). WMS kyselyä vastaavat URL- tai XML-pohjaiset kyselyt. Lisätietoa (englanniksi): http://en.wikipedia.org/wiki/Web_Feature_Service

Paikkatietopalvelimet Tarjoavat paikkatietodataa useimmiten WMS- ja WFS-palveluina.

Esim: GeoServer?, MapServer?

Paikkatietokannat Paikkatietodatan tallentamiselle on olemassa monenlaisia implementaatioita. Esim. PostGIS laajennos PostgreSQL tietokantaan tarjoaa monipuoliset työkalut paikkatietodatan tallentamiseen, kyselemiseen ja käsittelyyn. Lisätietoa (englanniksi): http://postgis.net/

OpenLayers? 3 kirjasto

Osaa näyttää ja käsitellä paikkatietoaineistoa selaimessa Javascriptin avulla

Suomeksi kommentoituja esimerkkejä:

http://users.jyu.fi/~vaotjuha/sovellukset/ol3/

Lisää esimerkkejä:

http://ol3js.org/en/master/examples/

API:

http://ol3js.org/en/master/apidoc/

Esivalmistelut:

Mikäli käytetään joltain paikkatietopalvelimelta tulevaa aineistoa, kannattaa kokeilut tehdä jonkin webbipalvelinohjelmiston päällä, koska muuten törmätään cross-site scripting ongelmaan haettaessa tietoja ulkoiselta paikkatietopalvelimelta selaimelle. Lisätietoa http://fi.wikipedia.org/wiki/Cross_site_scripting

Esim1: OpenLayers? + OpenStreetMap?

HTML (index.html)


<!doctype html>
<html lang="en">
  <head>
      <title>OpenLayers 3 esimerkki</title>
    <link rel="stylesheet" href="http://ol3js.org/en/master/css/ol.css" type="text/css">
    <style>
      .map {
        height: 100%;
        width: 100%;
      }
    </style>
    <!-- OpenLayers3 kirjasto -->
    <script src="http://ol3js.org/en/master/build/ol.js" type="text/javascript"></script>
  </head>
  <body>
    <h2>Kartta</h2>
    <div id="map" class="map"></div>
    <script type="text/javascript" src="js/myMap.js"></script>
  </body>
</html>

JavaScript? (js/myMap.js)


// HTML elementin ID, johon kartta sijoitetaan sivustolla
var target = 'map';

// Määritetään layers muuttujaan taulukko karttatasoja
// ja luodaan taulukkoon instanssi OpenStreetMap tasosta (OSM)
// joka on kirjaston tarjoama valmis konfiguraatio,
// jossa karttakuvat haetaan (joltain) paikkatietopalvelimelta
// tile:inä 
// 
// HUOM: OpenStreetMap aineisto on EPSG:3857 koordinaatistossa
var layers = [
    new ol.layer.Tile({
        source: new ol.source.OSM()
    })
];

// Määritellään kartan näkymä.
// Näkymä on aina jossain projektiossa.
// OpenLayers 3:n näkymän oletusprojektio on EPSG:3857,
// joka on nyt sattumalta sama kuin lähtöaineisto, joten
// sitä ei tarvitse erikseen määritellä
var view = new ol.View2D({
    center: [2864895.7422, 8914363.8489], // keskitetään näkymä Mattilanniemeen
    zoom: 17 // oletuszoomaustaso
});

// Alustetaan karttainstanssi ja sijoitetaan luodut muuttujat
// kartan konfiguraatioksi
var map = new ol.Map({
    target: target,
    layers: layers,
    view: view
});

Sama homma kompaktimmassa muodossa:

var map = new ol.Map({
        target: 'map',
        layers: [
          new ol.layer.Tile({
            source: new ol.source.OSM()
          })
        ],
        view: new ol.View2D({
          center: [2864895.7422,8914363,8489],
          zoom: 17
        })
      });

Maanmittauslaitoksen tuottamasta taustakarttasarjasta koostettu WMS taustakarttapalvelu Kapsi.fi palveluntarjoajan MapServer? paikkatietopalvelimelta

HUOM: kysely suoritetaan oletuksena oletusprojektiolla EPSG:3857

    new ol.layer.Tile({
        source: new ol.source.TileWMS({
            url: 'http://tiles.kartat.kapsi.fi/taustakartta?',
            crossOrigin: 'anonymous',
            params: {
                'FORMAT': 'image/png'
            },
            serverType: 'mapserver'
        })
    })

Luodaan VectorLayer? taso, johon voidaan ladata / piirtää vektoreita

var vectorSource = new ol.source.Vector();

var vectorLayer = new ol.layer.Vector({
    source: vectorSource,

    // asetataan oletustyylejä vektoreille
    style: new ol.style.Style({
        fill: new ol.style.Fill({ // polygonin täyttöväri
            color: 'rgba(255, 255, 255, 0.7)'
        }),
        stroke: new ol.style.Stroke({
            color: 'red',
            width: 2
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color: 'red'
            })
        })
    })
});

// lisätään vectorLayer karttaan
map.addLayer(vectorLayer);

// Piirtomoodin päälle laittaminen:

draw = new ol.interaction.Draw({
    source: vectorSource,
    type: "Point" // mahdollisia arvoja: PolyLine, Polygon jne... 
});

// draw interaktio laukoo myös eventtejä, joille voidaan asettaa kuuntelijoita, kuten "drawstart" tai "drawend"
draw.on("drawend", function(event) {
    var feature = event.feature;
    // ... tee jotain piirretyllä featurella
});

// lisätään draw interaktio karttaan
map.addInteraction(draw);

// piirtomoodin laittaminen pois päältä
map.removeInteraction(draw);

// Valinta- ja muokkaustyökalut:

var select = new ol.interaction.Select();

var modify = new ol.interaction.Modify({
    features: select.getFeatures()
});


Kyseltävän (queryable) WMS-tason lisääminen

  • WMS:ltä voi kysellä featureita getFeatureInfo() metodilla
var wmsSource = new ol.source.TileWMS({
    url: 'http://demo.opengeo.org/geoserver/wms', // esimerkkidataa, tietoa maista
    params: {'LAYERS': 'ne:ne'}
});

var wmsLayer = new ol.layer.Tile({
    source: wmsSource
});

map.addLayer(wmsLayer);


// Lisätään karttaan klikkauskuuntelija
map.on('singleclick', function(evt) {
	
	// Oletetaan, että DOM:sta löytyy jokin elementti, jonka ID = "info", jossa voidaan näyttää
	// paikkatietopalvelimen palauttamat tiedot kysellystä featuresta / featureista

  document.getElementById('info').innerHTML = '';

  var viewResolution = /** @type {number} */ (view.getResolution());

  // kystyään paikkatietopalvelimalta (demo.opengeo.org geoserveri) featureita klikatun pisteen koordinaateilla
  var url = wmsSource.getGetFeatureInfoUrl(
      evt.coordinate, viewResolution, view.getProjection(),
      {'INFO_FORMAT': 'text/html'}); // voitaisiin pyytää muussakin muodossa
  if (url) {
    document.getElementById('info').innerHTML =
        '<iframe seamless src="' + url + '"></iframe>';
  }
});


GeoJSON

GeoJSON on määrämuotoista JSON:ia (http://geojson.org/geojson-spec.html) Tämä on ihan näppärä tapa välittää ja tallentaa featureita ilman paikkatietolaajennuksia tietokantaan Ainoa miinus on, että spatiaalisia operaatioita ei voida (ainakaan yleensä) tehdä geojsonille sellaisenaan, vaan featuret on transformoitava oikeiksi geometriatietotyypeiksi, jotta kaikki GIS:n hienoudet saadaan käyttöön

// Määritellään geoJSON datasource (isoja kuvioita maailmankartalle)

var geoJSONVectorSource = new ol.source.GeoJSON(
    /** @type {olx.source.GeoJSONOptions} */ ({
      object: {
        'type': 'FeatureCollection',
        'crs': {
          'type': 'name',
          'properties': {
            'name': 'EPSG:3857'
          }
        },
        'features': [
          {
            'type': 'Feature',
            'geometry': {
              'type': 'Point',
              'coordinates': [0, 0]
            }
          },
          {
            'type': 'Feature',
            'geometry': {
              'type': 'LineString',
              'coordinates': [[4e6, -2e6], [8e6, 2e6]]
            }
          },
          {
            'type': 'Feature',
            'geometry': {
              'type': 'LineString',
              'coordinates': [[4e6, 2e6], [8e6, -2e6]]
            }
          },
          {
            'type': 'Feature',
            'geometry': {
              'type': 'Polygon',
              'coordinates': [[[-5e6, -1e6], [-4e6, 1e6], [-3e6, -1e6]]]
            }
          },
          {
            'type': 'Feature',
            'geometry': {
              'type': 'MultiLineString',
              'coordinates': [
                [[-1e6, -7.5e5], [-1e6, 7.5e5]],
                [[1e6, -7.5e5], [1e6, 7.5e5]],
                [[-7.5e5, -1e6], [7.5e5, -1e6]],
                [[-7.5e5, 1e6], [7.5e5, 1e6]]
              ]
            }
          },
          {
            'type': 'Feature',
            'geometry': {
              'type': 'MultiPolygon',
              'coordinates': [
                [[[-5e6, 6e6], [-5e6, 8e6], [-3e6, 8e6], [-3e6, 6e6]]],
                [[[-2e6, 6e6], [-2e6, 8e6], [0e6, 8e6], [0e6, 6e6]]],
                [[[1e6, 6e6], [1e6, 8e6], [3e6, 8e6], [3e6, 6e6]]]
              ]
            }
          },
          {
            'type': 'Feature',
            'geometry': {
              'type': 'GeometryCollection',
              'geometries': [
                {
                  'type': 'LineString',
                  'coordinates': [[-5e6, -5e6], [0e6, -5e6]]
                },
                {
                  'type': 'Point',
                  'coordinates': [4e6, -5e6]
                },
                {
                  'type': 'Polygon',
                  'coordinates': [[[1e6, -6e6], [2e6, -4e6], [3e6, -6e6]]]
                }
              ]
            }
          }
        ]
      }
    }));

// näinkin voidaan luoda featureita
geoJSONVectorSource.addFeature(new ol.Feature(new ol.geom.Circle([5e6, 7e6], 1e6)));

geoJSONVectorLayer = new ol.layer.Vector({
  source: geoJSONVectorSource
});

map.addLayer(geoJSONVectorLayer);


GPX + transformointi

GPX on lähes kaikkien kuluttajanavigaattoreiden käyttämä tiedostomuoto. GPX:ssä käytetty koordinaattijärjestelmä on WGS84 (EPSG:4326). Mikäli WGS84 geometrioita halutaan näyttää esim OpenStreetMap:n (oletus yleensä EPSG:3857) päällä, täytyy geometriat transformoida sopivaan projektioon.

OpenLayers? 3:ssa tämä on onneksi helppoa.

// määritellään vektoritaso ja sille GPX datasource
var vector = new ol.layer.Vector({
  source: new ol.source.GPX({
  	// käsketään projektioksi OpenStreetMap:n oletusprojektio, jolloin transformaatio tehdään automaattisesti lennossa
    projection: 'EPSG:3857',
    url: 'polku/gpx/tiedostoon/tiedosto.gpx'
  })
});

// Koordinaatteja ja pisteitä voidaan transformoida myös käsin OL3:n tukemien projektioiden välillä
// tuetut projektiot: EPSG:4326, EPSG:3857, EPSG:2056, EPSG:21781

// transformoidaan EPSG:4326 (WGS84) piste EPSG:3857 projektioon
var epsg3857coords = ol.proj.transform([25.41, 64.82], 'EPSG:4326', 'EPSG:3857');

// Muitakin projektioita voidaan käyttää proj4js kirjaston avulla, mutta sen tuki OL3:ssa on vielä hyvin kokeellinen