Az OpenLayers egy nyílt forráskódú kliens oldali JavaScript függvénykönyvtár, melynek segítségével különféle forrásokból származó térképi adatok jeleníthetők meg interaktív térképként weboldalakon. Az OpenLayers első változatát a MetaCarta nevű amerikai cég fejlesztette ki 2006-ban. 2007 novemberétől a projektet átvette az Open Source Geospatial Foundation (OSGeo).
Az alábbi segédlet feltételezi, hogy az olvasónak vannak legalább minimális JavaScript ismeretei.
Fontos megjegyezni, hogy az OpenLayers csak az adatok megjelenítését végzi, ezért önmagában nem sokat ér: mindenképpen szükség van a háttérben valamilyen adatforrásra. Ez utóbbi rendkívül sokféle lehet: egy egyszerű raszteres képtől kezdve különféle WMS, TMS szervereken keresztül különféle vektoros adatszolgáltatókig rengeteg lehetőség akad.
Az OpenLayers weboldala, dokumentációval, és letölthető anyagokkal
Az OpenLayers kódjait kétféleképpen használhatjuk: vagy letöltjük a szükséges fájlokat szerverünkre, vagy csak linkeljük az openlayers.org-on található script fájlt. Ez utóbbinak előnye, hogy mindig a legfirssebb változattal fogunk dolgozni, hátránya viszont, hogy az oldalaink lassabban töltődnek be, illetve, hogy a térképünk teljesen használhatatlan lesz, ha valami miatt az openlayers.org nem elérhető.
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>OpenLayers térkép</title>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
function init() // az oldal betöltésekor végrehajtandó függvény
{
// létrehozzuk a térképet a 'terkep_helye' azonosítójú div elemben
var map = new OpenLayers.Map('terkep_helye', {});
// létrehozunk egy OSM réteget és hozzáadjuk a térképhez
map.addLayer(new OpenLayers.Layer.OSM());
// kb. Magyarországra nagyítunk
map.zoomToExtent(new OpenLayers.Bounds(1790000,5730000,2560000,6210000));
}
</script>
</head>
<body onload="init()">
<h1>OpenLayers térkép</h1>
<div style="width:650px; height:400px" id="terkep_helye"></div>
</body>
</html>
0. példa - OSM térkép OpenLayers kezelőfelülettel.
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>OpenLayers - egyszerű térkép</title>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
function init() // az oldal betöltésekor végrehajtandó függvény
{
// létrehozzuk a térképet a 'terkep_helye' azonosítójú div elemben
var map = new OpenLayers.Map('terkep_helye', {} );
// létrehozunk egy WMS réteget
var wms = new OpenLayers.Layer.WMS( "OSGeo WMS",
'http://vmap0.tiles.osgeo.org/wms/vmap0',
{layers: ['basic','priroad','secroad']},
{});
// hozzáadjuk a réteget a térképhez
map.addLayer(wms);
// kb. Magyarországra nagyítunk
map.zoomToExtent(new OpenLayers.Bounds(17,46,22,49));
}
</script>
</head>
<body onload="init()">
<h1>OpenLayers - egyszerű térkép</h1>
<div style="width:600px; height:400px" id="terkep_helye"></div>
</body>
</html>
A térképet a weboldalon egy <div> elem fogja tartalmazni.
Ezt definiálnunk kell a html dokumentumban. Fontos megadnunk a térkép méretét (a style tulajdonságban) és az elem azonosítóját (id), ami jelen esetben "terkep_helye".
A térképes weboldal lelke a térképet megjelenítő JavaScript kód lesz, ami két részből áll:
http://openlayers.org/api/OpenLayers.js címről linkelünk be; init() nevű függvényben helyezünk el,
amely függvényt a weboldal betöltésekor automatikusan végrehajt a böngésző, a <body> tagben elhelyezett onload="init()" eseménykezelő miatt.
Az init() függvényben először létrehozunk egy OpenLayers.Map objektumot; ez lesz maga a térkép.
Az objektumkonstruktor két paramétert vár: a térképet tartalmazó <div> elem id-jét, valamint egy objektumot, amelyben különféle kulcs:érték párokkal a térkép működését befolyásoló további paramétereket lehet megadni. (Ebben a példában ez az objektum üres.)
Ha a térképszolgáltató szerver ezt lehetővé teszi, a térképünk vetületét is meghatározhatjuk. A következő példában a térképet MapServer adja, vektoros alapanyagból dolgozva. Így semmi akadálya annak, hogy a legkülönfélébb vetületekben készüljön az általa küldött raszteres kép.
...
function init() // az oldal betöltésekor végrehajtandó függvény
{
// létrehozzuk a térképet a 'terkep_helye' azonosítójú div elemben
var map = new OpenLayers.Map('terkep_helye',
{
projection: "EPSG:23700", // Az EPSG:23700 az EOV kódja
maxExtent: new OpenLayers.Bounds(400000,45000,950000,380000), // Nem földrajzi, hanem vetületi koordinátákat használunk
maxResolution: 1000, // zoom=0 esetén 1 pixel 1000 méter legyen.
units: "m"
} );
// létrehozunk egy WMS réteget
var wms = new OpenLayers.Layer.WMS( "MapServer mintatérkép",
'http://wms.elte.hu/cgi-bin/mapserv?map=/home/saman/mapserver/p1.map',
{
layers: ['megye'],
format: 'image/png'
},
{ singleTile: true });
// hozzáadjuk a réteget a térképhez
map.addLayer(wms);
// kb. Magyarországra nagyítunk
map.zoomToMaxExtent();
}
...
1a. példa - egyszerű térkép, más vetületben
Lehetőségünk van arra is, hogy több, különféle forrásból származó réteget jelenítsünk meg egy térképen.
Ekkor fontos elkülöníteni a "base layer" típusú rétegeket, melyekből egyszerre csak egy jeleníthető meg (az, hogy melyik, azt interaktívan is kiválaszthatjuk pl. egy LayerSwitcher control segítségével), és a "overlay" rétegeket.
Egy réteg akkor lehet "overlay", ha az isBaseLayer tulajdonsága false és a transparent tulajdonsága true.
Természetesen csak akkor kerülhet egymésra két réteg, ha azonos a vetületük.
Az alábbi példában egy OSM típusú réteget is létrehozunk, mely az OpenStreetMap térképét tartalmazza. Ennek vetülete az ún. Spherical Mercator. Mivel ez a réteg csak ebben a vetületben jeleníthető meg, a vele együtt használt többi rétegnek is ebben kell lennie.
Figyeljük meg ezen kívül a LayerSwitcher control hozzáadásának módját.
...
function init() // az oldal betöltésekor végrehajtandó függvény
{
// létrehozzuk a térképet a 'terkep_helye' azonosítójú div elemben
var map = new OpenLayers.Map('terkep_helye',
{
projection: "EPSG:3857", // EPSG:3857 = Spherical Mercator
maxExtent: new OpenLayers.Bounds(1800000,5700000,2600000,6300000)
});
// hozáadunk egy OSM réteget
map.addLayer(new OpenLayers.Layer.OSM());
// létrehozunk egy WMS réteget
var wms = new OpenLayers.Layer.WMS( "vasutak",
'http://mercator.elte.hu/cgi-bin/mapserv?map=/home/oktatok/saman/public_html/mapserver/vonat/mo.map',
{
layers: ['vasut'],
isBaseLayer: false,
transparent: true
},
{});
// hozzáadjuk a réteget a térképhez
map.addLayer(wms);
// a LayerSwitcher kezelőszerv segítsével kapcsolgathajuk a rétegeket
map.addControl(new OpenLayers.Control.LayerSwitcher);
// kb. Magyarországra nagyítunk
map.zoomToExtent(new OpenLayers.Bounds(1800000,5700000,2600000,6300000));
}
...
2. példa - több réteg egy térképen
Használhatjuk az OpenLayersben a Google Mapsből ismert különféle rétegeket is. Ehhez azonban be kell linkelnünk a Google Maps JS API-t is.
...
<!-- Google Maps 3 JS API - ez is kell, ha Google térképi rétegeket akarunk használni -->
<script src="http://maps.google.com/maps/api/js?v=3.2&sensor=false"></script>
<script type="text/javascript">
function init() // az oldal betöltésekor végrehajtandó függvény
{
// létrehozzuk a térképet a 'terkep_helye' azonosítójú div elemben
var map = new OpenLayers.Map('terkep_helye', {});
// rétegek hozzáadása
// Google hybrid
map.addLayer(new OpenLayers.Layer.Google("Google Hybrid",{type: google.maps.MapTypeId.HYBRID, numZoomLevels: 22}));
// Google satellite
map.addLayer(new OpenLayers.Layer.Google("Google Satellite",{type: google.maps.MapTypeId.SATELLITE, numZoomLevels: 22}));
// Google roadmap
map.addLayer(new OpenLayers.Layer.Google("Google Road Map",{type: google.maps.MapTypeId.ROADMAP, numZoomLevels: 22}));
// Google terrain
map.addLayer(new OpenLayers.Layer.Google("Google Terrain",{type: google.maps.MapTypeId.TERRAIN, numZoomLevels: 22}));
// OSM réteg
map.addLayer(new OpenLayers.Layer.OSM());
// egyebek
// a LayerSwitcher kezelőszerv segítsével kapcsolgathajuk a rétegeket
map.addControl(new OpenLayers.Control.LayerSwitcher());
// kb. Magyarországra nagyítunk
map.zoomToExtent(new OpenLayers.Bounds(1790000,5730000,2560000,6210000));
}
</script>
...
2/g. példa - Google rétegek a térképen
Egy érdekes rétegtípus a GeoRSS. Ennek segítségével nagyon egyszerűen megjeleníthetünk GeoRSS forrásból származó információkat.
A GeoRSS megjelenítéséhez a JavaScriptnek egy másik szerveren lévő XML fájlt kellene olvasnia, amit biztonsági okokból nem tehet meg.
Ennek kiküszöbölésére a saját szerverünkön el kell helyezni egy egyszerű proxy-t, ami közvetíti majd az információt.
A proxy címét az OpenLayers.ProxyHost változóban adhatjuk meg.
...
// ha külső forrásból (nem az oldalt tartalmazó szerverről) akarunk XML vagy egyéb fájlt beolvasni, akkor proxyra van szükség
OpenLayers.ProxyHost = "/ol/xmlproxy.php?url=";
...
// létrehozunk egy GeoRSS réteget
georss = new OpenLayers.Layer.GeoRSS(
'',
'http://earthquake.usgs.gov/earthquakes/catalogs/1day-M0.xml',
{
icon: new OpenLayers.Icon('img/earthquake.png',{w:32,h:32},{x:-16,y:-16}),
popupSize: new OpenLayers.Size(180,300)
});
// hozzáadjuk a réteget a térképhez
map.addLayer(georss);
...
2/b. példa - több réteg egy térképen - GeoRSS réteggel
Ha a szerverünkön van php értelmező, akkor a proxy nagyon egyszerűen megoldható. Esetünkben az xmlproxy.php fájl tartalma ennyi:
<?php print file_get_contents($_GET['url']); ?>
Az eseménykezelés lényege, hogy bizonyos események megtörténtekor (pl. egérkattintás, nagyítási fokozat megváltozása, stb.) végrehajtódik egy erre a célra emgírt függvény. A függvény rendszerint megkapja paraméterként az esemény részleteit leíró adatokat (általában egy ún. esemény-objektum formájában).
A egyes OpenLayers objektumokhoz azok events.register() metódusával tudunk eseménykezelőt rendelni.
Fontos megjegyezni, hogy amennyiben az eseményhez pozícióadat is tartozik (egér események), az mindig a térképet tartalmazó div elem koordinátarendszerében értendő.
Ezt a térkép getLonLatFromPixel() metódusával számíthatjuk át a térkép aktuális vetületének rendszerébe.
A különböző vetületi és/vagy földrajzi koordináta-rendszerek közti átszámításhoz létre kell hoznunk egy-egy OpenLayers.Projection objektumpéldányt, a forrás és a cél rendszer beállításaival.
Ha a Spherical Mercator (EPSG:3857) és WGS84 lat/lon (EPSG:4326) közöttt számítunk át, másra nincs is szükség. Más vetületek esetén a proj4.js függvénykönyvtárt használhatjuk, vagy akár saját kezűleg is definiálhatjuk a transzformációs függvényeket.
...
var wgs84=new OpenLayers.Projection('EPSG:4326');
var merc=new OpenLayers.Projection('EPSG:3857');
...
map.events.register("click", map, function(e)
{
// a kattintás helye a térképet tartalmazó div-ben
var pxPos=map.events.getMousePosition(e);
// átszámítva az aktuális vetületi rendszerbe
var projPos=map.getLonLatFromPixel(pxPos);
// átszámítva földrajzi koordinátákra
var geoPos=projPos.clone().transform(merc,wgs84);
alert("A kattintás helye\n - A dobozban: "+pxPos+"\n - Mercator-vetületben: "+projPos+"\n - WGS-84-ben: "+geoPos);
});
...
3. példa - kattintásra koordináták kiírása
A különféle objektumok más és más eseményeket tudnak kiváltani. Ezek közül a leggyakrabban használtak a következők:
Egér események: ezek szinte minden, a képernyőn megjelenő elemhez hozzárendelhetők.
A különböző rétegekhez tartozó események:
A Marker layer az egyik legegyszerűbb rétegtípus: pontokat helyezhetünk el rajta, melyeket valamilyen ikon jelöl.
A Marker layer konstruktorának első paraméter a réteg neve. Ezen kívül lehet még egy második paraméter is, ami egy objektum a kezdeti beállításokkal.
A réteg addMarker() függvénye sgítségével helyezhetünk el pontokat. A következő példában minden egérkattintással lerakunk egy markert:
...
// csinálunk egy marker layert
var markers=new OpenLayers.Layer.Markers("pontok");
map.addLayer(markers);
...
map.events.register("click", map, function(e)
{
// a kattintás helye a térképet tartalmazó div-ben
var pxPos=map.events.getMousePosition(e);
// átszámítva az aktuális vetületi rendszerbe
var projPos=map.getLonLatFromPixel(pxPos);
// új marker
var m=new OpenLayers.Marker(projPos);
markers.addMarker(m);
});
...
4. példa - kattintásra marker elhelyezése
A Marker layer lehetőségei meglehetősen korlátozottak (nem jeleníthetünk meg neveket a jelzők mellett, stb.), emiatt a legtöbb esetben célszerűbb a Vector layer alkalmazása pontszerű elemekkel.
A Vector layeren bármilyen vektoros rajz elhelyezhető. A rajzi elemek lehetnek pontok, vonalak, felületek is.
A layer elemei OpenLayers.Feature.Vector objektumok.
Ezek az elemek a geometriai adatokon kívül attribútumokat és stílusadatokat is tartalmazhatnak.
A következő példában ismét pontokat helyezhetünk el az egérrel, ezeknek a pontoknak azonban címkéjük is van,
és a DragFeature control segítségével azok át is helyezhetők.
...
// csinálunk egy vector layert
var pontok=new OpenLayers.Layer.Vector("pontok");
var dragControl=new OpenLayers.Control.DragFeature(pontok);
map.addControl(dragControl);
dragControl.activate();
map.addLayer(pontok);
// kb. Magyarországra nagyítunk
map.zoomToExtent(new OpenLayers.Bounds(1800000,5700000,2600000,6300000));
map.events.register("click", map, function(e)
{
// a kattintás helye a térképet tartalmazó div-ben
var pxPos=map.events.getMousePosition(e);
// átszámítva az aktuális vetületi rendszerbe
var projPos=map.getLonLatFromPixel(pxPos);
// új point feature létrehozása a kattintás helyére
var m=new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.Point(projPos.lon, projPos.lat),
{},
{
externalGraphic: 'http://openlayers.org/api/img/marker.png',
graphicHeight: 21,
graphicWidth: 16,
graphicYOffset: -21,
label: ++markerCnt+'. pont',
labelAlign: 'lb',
fontWeight: 'bold',
fontColor: 'purple',
labelXOffset: 6
});
pontok.addFeatures(m);
});
...
5. példa - áthelyezhető pontok elhelyezése kattintásra egy Vector layeren
OpenLayers.Feature.Vector objektumok szerkezeteAz OpenLayers.Feature.Vector objektum vektoros elemek leírására szolgál. Ennek megfelelően a következő fő részei vannak:
geometry | Az elem geometriája, egy OpenLayers.Geometry objektum, vagy annak valameyik "származéka". |
|
attributes | Az elem attribútumai, JavaScript objektumként. (pl.: { nev: "Érd", ir_szam: 2030} ) |
|
style | Az elem stílusa, egy OpenLayers.Style objektum |
Egy vector réteget feltölthetünk különböző forrásokból származó elemekkel is.
Ehhez meg kell adnunk a réteg protocol tulajdonságát. Ennek értéke egy OpenLayers.Protocol.* objektum
(a * helyén a használt forrástól függően más és más állhat), amelyben meghatározzuk a vector rétegre kerülő elemek forrását, és a szükséges paramétereket.
A protokollon kívül meg kell még adni a strategies tulajdonságot is, mely egy tömb; a tömb minden eleme egy OpenLayers.Strategy.* objektum.
Ez határozza meg, hogy milyen szabályok szerint kérjen az OpenLayers elemeket a rétegre.
A Vector layert benépesíthetjük pl. WFS szolgáltatás adataival. Ekkor az OpenLayers.Protocol.WFS-t kell használnunk.
Ebben megadjuk a WFS szolgáltató URL-jét, a kért elemek típusát (a MapServer által szolgáltatott WFS esetében ez valamelyik LAYER neve), a vetületet, valamint azt, hogy milyen attribútumadatokat várunk az egyes elemekhez.
Itt MapServer használatakor az msGeometry jelenti magát az elemet.
A következő példában ezen kívül alkalmazzuk a SelectFeature controlt is,
melynek segítségével egyszerűen kijelölhetők elemek egy vector layeren, és a kijelöléshez eseménykezelőket is definiálhatunk.
Ebben a példában egy kis segédfüggvény (dump()) segítségével kiíratjuk a kijelölt elem attribútumait.
...
// csinálunk egy wfs layert...
var wfs=new OpenLayers.Layer.Vector(
"WFS próba",
{
isBaseLayer: true,
strategies: [new OpenLayers.Strategy.BBOX()],
protocol: new OpenLayers.Protocol.WFS(
{
version: "1.0.0",
url: "http://wms.elte.hu/cgi-bin/mapserv?map=/home/saman/mapserver/p2wfs.map",
featureType: "Megye_nepesseg",
srsName: "EPSG:23700",
propertyNames: ['msGeometry','Nev','Nepesseg','Gyermek','Felnott','Idos']
})
});
// és hozzáadjuk a térképhez
map.addLayer(wfs);
// hozzáadunk egy SelectFeature controlt. Ezzel egyszerűen kijelölhetők elemek a vektoros rétegen
var sfc=new OpenLayers.Control.SelectFeature(wfs,
{
toggle: true, // az elemre kattintás ki-be kapcsolja a kijelölést
onSelect: function(feature) { dump(feature.attributes); } // eseménykezelő - kiiratjuk az elem tulajdonságait
});
map.addControl(sfc);
// aktiváljuk a SelectFeature controlt
sfc.activate();
...
...
function dump(o) // a paraméterként kapott objektum tulajdonságait kiírja az 'info' nevű divben
{
var d=document.getElementById('info');
var s='';
for(i in o)
s+=i+': '+o[i]+'; ';
d.innerHTML=s;
}
...
6. példa - Vector layer WFS adatokkal
6c. példa - Vector layer WFS adatokkal feljavítva
MÁV vasútvonalak WFS adatokkal
Ebben a példában az OpenLayers.Protocol.HTTP-t használjuk az OpenLayers.Format.KML-lel.
Míg az előbbi a HTTP-n keresztül való fájlbetöltést, az utóbbi a KML adatok értelmezését végzi:
...
// csinálunk egy vector layert...
kml=new OpenLayers.Layer.Vector(
"Túraútvonal",
{
isBaseLayer: false,
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP(
{
url: "data/utvonal.kml",
format: new OpenLayers.Format.KML()
}),
style: { strokeWidth: 3, strokeColor: "#FF0000" }
});
// és hozzáadjuk a térképhez
map.addLayer(kml);
map.addControl(new OpenLayers.Control.LayerSwitcher());
// kb. a célterületre nagyítunk
map.zoomToExtent(new OpenLayers.Bounds(2108000,6020000,2115000,6025000));
...
6/x. példa - Vector layer KML adatokkal
A fenti példában nem vesszük át a KML fájlban található stílusbeállításokat, hanem egy egységes vonalstílust definiálunk az egész rétegnek.
Ha inkább a KML fájl stílusait szeretnénk használni, akkor állítsuk be a extractStyles: true opciót a KML formátum objektumnál, és ne írjuk felül a stílusokat:
...
kml=new OpenLayers.Layer.Vector(
"Túraútvonal",
{
isBaseLayer: false,
strategies: [new OpenLayers.Strategy.Fixed()],
protocol: new OpenLayers.Protocol.HTTP(
{
url: "data/utvonal.kml",
format: new OpenLayers.Format.KML({ extractStyles: true } )
})
});
...
Az Image layer az egyik legegyszerűbb rétegtípus: egy raszteres képet helyezünk el egy téglalap alakú területen. A kép valamilyen szabványos webes formátumban legyen (jpg, png vagy gif).
Az OpenLayers.Layer.Image konstruktorfüggvény paraméterei sorban:
a réteg neve, a képfájl URL-je, a kép kiterjedése annak vetületi koordináta-rendszerében, a kép mérete pixelekben, és az esetleges további beállítások.
...
var img = new OpenLayers.Layer.Image(
"Raszteres térkép",
'http://mercator.elte.hu/~saman/webglobes/globe_greenwich.jpg',
new OpenLayers.Bounds(-180, -90, 180, 90),
new OpenLayers.Size(3600,1800),
{
numZoomLevels: 6,
maxResolution: 0.4
});
...
Bár az OpenLayers lehetőséget ad arra, hogy a különféle objektumoknál megadjuk azok vetületét, jelenleg csak az alapértelmezett WGS84 lat/lon és a Google-féle gömbi Mercator-vetület van képletekkel is definiálva.
Ez akkor okoz problémát, ha a különféle vetültetek között koordináta-átszámítást kell végeznünk.
Ilyenkor két lehetőségünk van: felhasználjuk a proj4.js függvénykönyvtárat, vagy sajátkezűleg definiálunk vetületet, az átszámítási függvények megírásával.
A proj4.js használatához először le kell töltenünk és el kell helyeznünk a használandó JavaScript fájlt a szerverünkön.
Emellett szükségünk lesz a használandó vetületek proj.4 formátumú definíciójára, és már használhatjuk is őket.
A következő példában WGS84-es földrajzi, gömbi Mercator és EOV koordináták között lehet átszámítani:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
<title>proj4.js - vetületi átszámítások</title>
<script src="proj4js/lib/proj4js.js"></script>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
// EOV vetület proj4-es definíciója. Figyelem: az EPSG adatbázisban hibásan szerepel, a dátumtranszformáció hiányzik belőle!
Proj4js.defs["EPSG:23700"] = "+title=Hungarian EOV EPSG:23700 +proj=somerc +lat_0=47.14439372222222 +lon_0=19.04857177777778 +x_0=650000 +y_0=200000 +ellps=GRS67 +datum=HD72 +towgs84=57.01,-69.97,-9.29 +units=m +no_defs"
// létrehozunk egy-egy vetület objektum példányt a használandó vetületekhez
var w=new OpenLayers.Projection("EPSG:4326");
var g=new OpenLayers.Projection("EPSG:900913");
var e=new OpenLayers.Projection("EPSG:23700");
// az átszámítást irányító függvény
function szamit(form,p)
{
if (p=='wgs84')
{
var pt=new OpenLayers.Geometry.Point(form.la.value,form.fi.value);
var proj=w;
}
else if (p=='google')
{
var pt=new OpenLayers.Geometry.Point(form.gx.value,form.gy.value);
var proj=g;
}
else
{
var pt=new OpenLayers.Geometry.Point(form.ex.value,form.ey.value);
var proj=e;
}
var p1=pt.clone().transform(proj,w);
var p2=pt.clone().transform(proj,g);
var p3=pt.clone().transform(proj,e);
with(form)
{
fi.value=p1.y.toFixed(6);la.value=p1.x.toFixed(6);
gx.value=p2.x.toFixed(1);gy.value=p2.y.toFixed(1);
ex.value=p3.x.toFixed(1);ey.value=p3.y.toFixed(1);
}
}
</script>
</head>
<body>
<h1>proj4.js - vetületi átszámítások</h1>
<form>
<table>
<tr>
<td>
WGS84 latlon<br/>
Φ: <input type="text" name="fi"/>
Λ: <input type="text" name="la"/><br/>
<input type="button" value="Átszámít" onclick="szamit(this.form,'wgs84')" />
</td>
<td>
Google Mercator<br/>
x: <input type="text" name="gx"/>
y: <input type="text" name="gy"/><br/>
<input type="button" value="Átszámít" onclick="szamit(this.form,'google')" />
</td>
<td>
EOV<br/>
x: <input type="text" name="ex"/>
y: <input type="text" name="ey"/><br/>
<input type="button" value="Átszámít" onclick="szamit(this.form,'eov')" />
</td>
</tr>
</table>
</form>
</body>
</html>
Ha a vetületi egyenletet saját magunk akarjuk definiálni, akkor meg kell adnunk egy másik (általában WGS84 latlon) rendszerbe való átszámítás oda-vissza egyenleteit a OpenLayers.Projection.addTransform függvény segítségével.
Az átszámításokat egy-egy függvény végzi, melynek egyetlen paramétere egy point objektum, mely az átszámítandó koordinátákat tartalmazza.
A http://www.sat24.com/image2.ashx?region=hu címen található műholdkép vetülete például a meteorológiában gyakran használt metsző sztereografikus vetület, 60°-os metsző szélességgel és 10°-os kezdőmeridiánnal.
Az ehhez való átszámítás definíciója:
...
var rad=Math.PI/180; // fok/radián váltószám
var R=6378137; // közepes földsugár
var c=1+Math.sqrt(3)/2; // c=1+sin(60°)
...
// vetületi transzformáció definiálása a metsző sztereografikus vetülethez (la0=10)
OpenLayers.Projection.addTransform("EPSG:4326","meteo_stereo",
function (point)
{
var fi=point.y;
var la=point.x-10;
var ro,x,y;
with(Math)
{
ro=c*tan(PI/4-fi*rad/2);
point.x=R*ro*sin(la*rad);
point.y=-R*ro*cos(la*rad);
}
return point;
});
// inverz vetületi transzformáció definiálása a metsző sztereografikus vetülethez (la0=10)
OpenLayers.Projection.addTransform("meteo_stereo","EPSG:4326",
function (point)
{
var x=point.x,y=point.y;
with(Math)
{
ro=sqrt(x*x+y*y);
if (ro==0)
la=0;
else
la=acos(-y/ro)*sign(x)/rad;
la+=10;
if (la>180)
la-=360;
point.x=la;
point.y=(PI/4-atan(ro/R/c))/rad*2;
}
return point;
});
...
Az OpenStreetMap Nominatim nevű szolgáltatásával egyszerűen geokódolhatunk bármilyen címet, vagy rendelhetünk címet egy koordinátapárhoz. Mindkét irányú művelet http-kérés kiadásával történik.
Az szolgáltatást kétféleképpen tudjuk használni JavaScriptben:
XMLHttpRequest objektumával egyszerűen kiadhatunk http-kéréseket és fogadhatjuk az arra kapott választ.
Biztonsági okokból azonban ilyen kéréseket mindig csak a helyi szervernek küldhetünk, emiatt szükség van egy proxy-ra a szerveren, mely továbbítja a kéréseket külső szerver felé.
Erre a célra is alkalmazható pl. a http://mercator.elte.hu/~saman/hu/okt/ol/xmlproxy.php?url= egyszerű php-proxy.
A válasz feldolgozása történhet szinkron vagy aszinkron módon (azaz a script futása leáll, amíg meg nem jön a válasz, vagy egy callback függvény hívódik meg a válasz befutásakor).
...
var xmlhttp; // a http-kérésekhez
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
function geokodol(hely) // geokódoló kérést küldünk a Nominatimnak
{
if (hely=='')
return;
xmlhttp.open("GET",'/~saman/hu/okt/ol/xmlproxy.php?url=http://nominatim.openstreetmap.org/search?q='+hely+'%26format=json',false);
xmlhttp.send();
var valasz=eval('('+xmlhttp.responseText+')');
if (valasz[0]) // ha van legalább egy eredmény...
alert(valasz[0].display_name)
else // ha nincs eredmény
alert('Nincs találat.');
}
...
script node-ot, amilynek src tulajdonságának a geokódoló kérés URL-jét állítjuk be.
Ebben az esetben fontos, hogy a választ JSON formában kérjük, és állítsuk be a json_callback paraméterben a callback függvény nevét.
Ezzel a módszerrel kikerülhető az előbb említett biztonsági korlát, viszont csak aszinkron módon dolgozható fel a válasz.
...
function geokodol(hely) // geokódoló kérést küldünk a Nominatimnak
{
if (hely=='')
return;
var s=document.createElement('script');
s.src='http://nominatim.openstreetmap.org/search?q='+hely+'&format=json&json_callback=helyetMutat';
document.body.appendChild(s);
}
function helyetMutat(valasz)
{
if (valasz[0])
alert(valasz[0].display_name)
else // ha nincs eredmény
alert('Nincs találat.');
}
...
A térképünkhöz rengeteg, előre definiált eszközt adhatunk. Ezek közös neve Control. A leggyakrabban használt eszközök a következők:
Az OpenLayers.Control.LayerSwitcher segítségével ki-be kapcsolgathatjuk a térkép rétegeit. Példa
Ha egy réteget nem akarunk látni a LayerSwitcherben, akkor az adott réteg tulajdonságainál szerepeljen a következő: displayInLayerSwitcher: false
A kezelőszerv "Base Layer" és "Overlays" szövegeit kicserélhetjük a létrehozott LayerSwitcher objektum baseLbl.innerHTML és layerSwitcher.dataLbl.innerHTML elemeinek átállításával.
Ezek, és további beállítások is láthatók ebben a példában.
kiírja a térkép sarkában az egérmutató koordinátáit Példa
Fontosabb beállítható tulajdonságok:
prefix, separator, suffix: az első koordináta elé, a kettő közé és a második után kerülő szövegek.
Pl. a { prefix:'Lon:', separator:'°, lat:', suffix:'°' } beállítás eredményeképpen a megjelenített formátum: Lon: 19.1°, lat: 47.5°.numDigits: tizedesjegyek számaemptyString: szöveg, ami akor jelenik meg, ha "lemegyünk a térképről"displayProjection: a koordináták vetülete (OpenLayers.Projection objektum). Ha nincs megadva, akkor a térkép vetülete az alapértelmezett.kiírja a térkép aktuális méretarányát. Példa
dinamikus mértéklécet helyez el a térképen
a térképre kattintva megkapjuk egy WMS rétegen az adott helyen lévő elem adatait.Példa
Ha a WMSGetFeatureInfo controlt MapServer szolgáltatáson használjuk, akkor a következő dolgok legyenek beállítva a mapfile-ban a helyes működéshez:
... WEB # a MAP objekumon belüli WEB objektum METADATA ... "wms_srs" "EPSG:4326 EPSG:3857" # itt szerepeljen az a vetület, amiben az OpenLayers kéri a térképet "wms_enable_request" "*""ows_encoding" "WINDOWS-1250" # itt az alapanyag (pl. shapefájl) karakterkódolását adjuk meg END END ... LAYER ... METADATA "wms_enable_request" "*""gml_include_items" "all" # enélkül nem kapjuk meg az attribútumadatokat ENDDUMP true # enélkül nem megy a getfeatureinfo kérés TEMPLATE "template.html" # nem kell létező fájlnévnek lennie, hacsak nem html formátumú featureinfo-t várunk ...
egy Vector réteg elemeit áthelyezhetővé teszi. Példa
egy Vector rétegen rajzolhatunk vele új elemeket. Példa
segítségével méréseket (hossz, terület stb.) végezhetünk a térképen
segítségével kijelölhetjük egy Vector réteg elemeit, és a kijelöléshez eseménykezelőt definiálhatunk