== 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ää Lsiä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 Google Maps, OpenStreetMap 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 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) ---------------------------- {{{ OpenLayers 3 esimerkki

Kartta

}}} 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 = ''; } }); }}} -------------------------------- '''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 epsg3858coords = 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 }}}