A térképek felbontását a nagyítási (zoom) fokozat (z) határozza meg. A legkisebb, z = 0 nagyításnál az egész világ egy 256*256 pixeles négyzetre képeződik le:
Magasabb nagyítási fokozatokban 2z * 2z darab mozaikdarabból (ún. tile-okból) áll össze a térkép. z = 1 esetén pl.:
![]() | ![]() |
![]() | ![]() |
A Google Maps felhasználói felület lényege tehát, hogy ezekből a tile-okból mindig a megfelelő darabokat jeleníti meg.
Ezen felül természetesen számos további szolgáltatása van: a térképhez saját vektoros vagy raszteres tartalmat adhatunk, eseménykezelőket definiálhatunk stb.
A Google Maps API segítségével a saját weboldalunkba ágyazhatunk egy Google Maps térképet, és azzal különféle dolgokat művelhetünk.
Az API folyamatos fejlesztés alatt van. Ez az anyag a 3. verzió használatát mutatja be.
Az API használatához részletes útmutató és referencia található a Google Code oldalain.
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"> </script> <script type="text/javascript"> function initialize() { var latlng = new google.maps.LatLng(47.475, 19.062); var myOptions = { zoom: 13, center: latlng, mapTypeId: google.maps.MapTypeId.HYBRID }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); } </script> ... <body onload='initialize();'> <div id="map_canvas" style="width:700px; height:500px"></div> </body>
Ennek eredménye: 1. példa - térkép beágyazás
Lássuk mi is történik:
A térképet kezelő JavaScript kódokat letöltjük a Google szerveréről az első <script>
elemmel. Ezután készítünk egy egyszerű függvényt, ami az oldal betöltése után (<body>
elem onload
eseménye) hívódik majd meg.
Ez a függvény fogja a "map_canvas"
azonosítójú div
-be betölteni a megfelelően beállított térképet. Ehhez először létrehozunk "map" néven egy google.maps.Map
objektum példányt, melynek konstruktorát a térképet tartalmazó div
objektumával hívjuk meg.
A beállítások változtatásával egyszerűen alakíthatunk a térkép kinézetén, kezelőszervein. Ha a műholdképre vetített úthálózat helyett mást szeretnénk látni, akkor használhatjuk az alábbi előre definiált konstansokat a mapTypeId
értékeként:
google.maps.MapTypeId.ROADMAP
- autótérkép
google.maps.MapTypeId.SATELLITE
- műholdkép
google.maps.MapTypeId.TERRAIN
- domborzati térkép + fedettség
google.maps.MapTypeId.HYBRID
- műholdkép úthálózattal és egyebekkel
... var myOptions = { zoom: 13, center: latlng, panControl: false, streetViewControl: false, mapTypeControl: true, mapTypeControlOptions: { mapTypeIds: [google.maps.MapTypeId.ROADMAP,google.maps.MapTypeId.TERRAIN] }, zoomControl: true, scaleControl: true, mapTypeId: google.maps.MapTypeId.ROADMAP }; ...
1/a. példa - egyszerű térkép, módosított beállításokkal
A google.maps.event.addListener()
függvénnyel egyszerűen definiálhatunk a térkép egyes objektumaihoz eseménykezelőt:
... google.maps.event.addListener(map, 'click', function(event) { with(event.latLng) alert("fi="+lat()+"° lambda="+lng()+"°"); }); ...
google.maps.Marker
objektum egy példányának létrehozásával tudunk definiálni.
A következő példában a térképre kattintva egy új pont jön létre az adott helyen. Ehhez az előbbi példa eseménykezelőjét kell átírnunk:
... var marker = new google.maps.Marker({ position: event.latLng, map: map, title: (++markerCnt)+". pont" }); ...
3. példa - eseménykezelés; pont (marker) hozzáadása
Ha egy markernél beállítjuk a draggable: true
tulajdonságot, akkor az az egérrel áthelyezhető lesz. Az előző példa ezzel kiegészítve:
3.b példa - áthelyezhető markerek hozzáadása
A google.maps.InfoWindow
objektum segítségével "információs buborékot" hozhatunk létre.
A konstruktornak paraméterként adott objektum legfontosabb eleme a "content" mező, melyben a buborék tartalmát határozhatjuk meg.
A buborékot az objektum open()
metódusával nyithatjuk meg. Ha itt nem csak a térképet adjuk paraméternek, hanem pl. egy markert, úgy ahhoz lesz kötve a buborék.
Az előző példát továbbfejlesztve a markerekve kattintva jelenjen meg egy hozzájuk kapcsolt InfoWindow:
... var marker = new google.maps.Marker({ position: event.latLng, map: map, title: (++markerCnt)+". pont" }); var infowindow = new google.maps.InfoWindow({ content: "<b>"+markerCnt+". pont</b><br>"+ "φ="+event.latLng.lat()+"<br>λ="+event.latLng.lng() }); google.maps.event.addListener(marker, 'click', function() { infowindow.open(map,marker); }); ...
4. példa - eseménykezelés; pont hozzáadása információs buborékkal
A térképre felvehetünk töröttvonalat is. Ehhez létre kell hoznunk egy google.maps.Polyline
objektumot, megadni a pontjait, és az objektum setMap()
metódusával hozzárendelni a térképet, amin meg akarjuk jeleníteni.
A töréspontokat egy tömb (illetve egy ahhoz hasonlító objektumtípus, az MVCArray
) tartalmazza, amelyre a getPath()
ad referenciát.
Az alábbi példában töröttvonalat rajzolhatunk a térképre: minden kattintás egy újabb szakaszt ad a vonalhoz. A kódban kihasználjuk, hogy az MVCArray push()
metódusa automatikusan a tömb végére tesz be egy új elemet.
... var polyOptions = { strokeColor: '#ff0000', strokeOpacity: 0.6, strokeWeight: 5 } poly = new google.maps.Polyline(polyOptions); poly.setMap(map); google.maps.event.addListener(map, 'click', function(event) { var path=poly.getPath(); path.push(event.latLng); }); ...
5. példa - eseménykezelés; töröttvonal rajzolása
Teljesen hasonlóan lehet sokszöget is definiálni a google.maps.Polygon
objektummal. Az előző példát kicsit módosítva így zárt poligont is rajzolhatunk.
6. példa - eseménykezelés; poligon rajzolása
Téglalapot a google.maps.Rectangle
, kört pedig a google.maps.Circle
objektumokkal tudunk létrehozni.
A téglalapnál a délnyugati és az északkeleti sarok koordinátáit kell megadnunk google.maps.LatLng
objektumokkal, míg a körnél a középpontot, valamint a méterben kifejezett sugarat.
Amennyiben az objektumoknál beállítjuk az editable: true
tulajdonságot, akkor az alakzatok szerkeszthetők is lesznek. A következő példában a megfelelő gombok megnyomásakor létrejön egy kör vagy téglalap az aktuális nézet közepén, úgy, hogy mkérete fele lesz a térkép méretének.
... példa - Méretezhető/áthelyezhető téglalap vagy kör rajzolása
A google.maps.Geocoder
objektum segítségével geokódolási kéréseket küldhetünk, melyek segítségével teljes vagy részleges címekhez, településnevekhez rendelhetünk földrajzi koordinátákat, vagy fordítva: egy koordinátákkal adott ponthoz a címet.
A geokódolás aszinkron folyamat: mikor elküldjük a kérést, a script futása folytatódik. Ha megérkezett a kérésre a válasz, az eredményt paraméterként megkapja egy általunk definiált függvény.
Ezzel a függvénnyel lehet aztán feldolgozni az eredményt.
A kérést a Geocoder objektum geocode()
metódusával küldhetjük el. A szükséges adatokat az első paraméterként adott objektumban adjuk át.
Ha címből indulunk ki, akkor azt az address
mezőben tároljuk; ha a földrajzi koordinátákból, akkor a latLng
értékét állítjuk be.
A következő példában a geocode() függvény a paraméterként kapott címet elhelyezi a térképen. A függvényt egy szövegdoboz onclick eseménye aktiválja.
... var map,geocoder; function initialize() { var latlng = new google.maps.LatLng(47.475, 19.062); var myOptions = { zoom: 13, center: latlng, mapTypeId: google.maps.MapTypeId.HYBRID }; map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); geocoder = new google.maps.Geocoder(); } function geocode(addr) { geocoder.geocode( { address: addr }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location, title: addr }); } else { alert("A geokódolás nem sikerült. A hiba oka: " + status); } }); } ... Írj be egy címet: <input type=text onchange='geocode(this.value)' /> ...
Ehhez teljesen hasonlóan valósítható meg az inverz geokódolás is (koordináták alapján cím meghatározása).
... function inverseGeocode(loc) { geocoder.geocode( { latLng: loc }, function(results, status) { if (status == google.maps.GeocoderStatus.OK) { alert(results[0].formatted_address); } else { alert("A geokódolás nem sikerült. A hiba oka: " + status); } }); } ...
A google.maps.DirectionsService
objektummal útvonalat is terveztethetünk. A geokódoláshoz hasonlóan az útvonaltervezés is aszinkron folyamat. A szervernek küldött kérés tartalmazza a kezdőpontot, a célt, az utazás módját (DRIVING=autózás, WALKING=gyaloglás és BICYCLING=kerékpározás).
Bonyolultabb esetben köztes útpontokat is megadhatunk. A pontokat megadhatjuk koordinátáikkal, vagy címükkel.
... var directionsService = new google.maps.DirectionsService(); ... var request = { origin: 'kiindulópont', destination: 'célpont', travelMode: google.maps.DirectionsTravelMode.DRIVING }; directionsService.route(request, function(result, status) { if (status == google.maps.DirectionsStatus.OK) { // ide jöhet az eredményt feldolgozó kód } else alert('Nem sikerült az útvonaltervezés.\n'+status); }); ...
Ha sikerült az útvonaltervezés, akkor a válaszként kapott result
objektum routes[]
eleme tartalmazza a lehetséges útvonalakat. Minden útvonal útszakaszokból (leg) áll.
Ha csak a kezdő és a végpontot adtuk meg, akkor cak egy ilyen leg van, ha köztes pontokat is, akkor minden két útpont közti útvonalrész egy-egy külön leget alkot. Ezek az útvonalakon belül a legs[]
tömbben vannak.
Például az első lehetséges útvonal első szakasza: result.routes[0].legs[0]
.
Az útszakaszok az előzőekhez hasonlóan további rövidebb szakaszokra oszlanak (steps[]
), amelyekben a path[]
tömb már ténylegesen az adott útszakaszt reprezentáló töröttvonal pontjait tartalmazza.
Látható, hogy az útvonalterv egy meglehetősen összetett objektum. Szerencsére van egy olyan eszköz, melynek segítségével minimális kódolással megjeleníthetjük az eredményt, ez pedig a google.maps.DirectionsRenderer
objektum.
Az objektum egy példányához egyszerűen hozzárendeljük a megjelenítéshez használt térkép objektumot és az útvonalat, ezen felül semmi dolgunk nincs.
... var directionsDisplay = new google.maps.DirectionsRenderer(); directionsDisplay.setMap(map); ... if (status == google.maps.DirectionsStatus.OK) { directionsDisplay.setDirections(result); alert(result.routes[0].legs[0].distance.text+' - '+result.routes[0].legs[0].duration.text); } ...
Lehetőségünk van arra is, hogy lekérdezzük a földfelszín egy vagy több pontjának (vagy akár egy töröttvonal mentén pontok sorozatának) tengerszint feletti magasságát. Erre a google.maps.ElevationService
objektumot kell használnunk. A megoldás a geokódoláshoz meglehetősen hasonló.
Fontos megjegyezni, hogy a kapott értékek nem a valós magassági adatok, hanem egy digitális domborzatmodell alapjány számított magasságok. Emiatt az értékek többszörösen is hibákkal terheltek:
Egy egyszerű, egy pontra vonatkozó magasságiadat-kérés a következőképp néz ki:
... var elev = new google.maps.ElevationService(); ... google.maps.event.addListener(map, 'click', function(event) { elev.getElevationForLocations({ locations: [event.latLng] }, function(results, status) { if (status == google.maps.ElevationStatus.OK) with(event.latLng) alert("fi="+lat()+"°\n lambda="+lng()+"°\n h="+results[0].elevation+"m"); }); }); ...
10. példa - magasság lekérdezése
Ha akarunk, saját raszteres térképet is megjeleníthetünk a Google Maps API segítségével. A legegyszerűbb megoldás az, ha ún. lefedő képként adjuk a saját raszteres képet a térképhez:
... // a foktrapéz, ahova a GroundOverlay kerül var hely=new google.maps.LatLngBounds(new google.maps.LatLng(47.3456, 18.6086),new google.maps.LatLng(47.8550, 19.2015)); // GroundOverlay definiálása ovl = new google.maps.GroundOverlay("bp_kornyek.jpg", hely); ovl.setMap(map); ...
11. példa - lefedő kép (GroundOverlay)
A lefedő képet egy, a délnyugati és az északkeleti sarkának koordinátáival definiált foktrapézra illesztjük. A foktrapéz egy google.maps.LatLngBounds
objektum, a lefedő kép pedig egy google.maps.GroundOverlay
.
A létrehozott GroundOverlay objektum átlátszósága is állítható annak setOpacity()
metódusával; a paraméter értéke 0 (teljesen átlátszó) és 1 (teljesen átlátszatlan) között változhat.
Ez az oldal is GroundOverlay-t használ a Curiosity rover által megtett út szemléltetésére.
Lefedő képet csak kisebb méretű raszteres térképből érdemes készíteni, mivel a túl nagy méretű kép megjelenítése esetleg akadozóvá teszi a weboldalt. A nagyobb képeket célszerűbb feldarabolni. Ilyenkor le kell gyártanunk azokat a mozaikdarabokat, amelyekből a különböző nagyítási fokozatokon felépül a kép. Ha azt szeretnénk, hogy térképünk a Google saját térképeivel kombinálva is látható legyen, nagyon fontos, hogy ugyanazt a vetületet és szelvényezést alkalmazzuk.
A Google Maps-féle vetület a következő:
Szerencsére vannak olyan programok, amik a mozaikdarabolást és az egyéb kulimunkát elvégzik helyettünk. Talán a legkényelmesebb a Global Mapper alkalmazása. Ebben a programban még a vetülettel sem kell foglalkoznunk; bármilyen korrekt georeferenciával rendelkező anyagból gombnyomásra legyártja a Google Maps mozaikkészletet.
A mozaikdarabokat úgy kell elnevezni, hogy a zoom és a mozaiksorszámok ismeretében egyszerűen meghatározható legyen az adott kép fájlneve.
Ha megvannak a mozaikdarabok, akkor definiálnunk kell egy saját térképtípust. Itt a legfontosabb annak a függvénynek az elkészítése, ami adott x, y, zoom paraméterekre megadja a megfelelő tile URL-jét:
... var globuszOpts = { getTileUrl: function(coord, zoom) { return "nemet_gomb/n_"+zoom+"_"+coord.y+"_"+coord.x+".png"; }, tileSize: new google.maps.Size(256, 256), isPng: true minZoom: 0, maxZoom: 4, name: "Földgömb" }; var globuszMapType = new google.maps.ImageMapType(globuszOpts); ...
Az így elkészített térképtípussal két dolgot tehetünk. Egyszerűbb esetben fedvényként a Google térkép fölé helyezhetjük. Ez különösen előnyös akkor, ha térképünk háttere átlátszó, mivel így az alatta lévő tartalom is látható.
... map.overlayMapTypes.insertAt(0, globuszMapType); ...
11a. példa - saját térképmozaik, mint fedvény
A másik esetben a térképtípust felvesszük a kiválasztható önálló térképtípusok közé. Ezután ugyanúgy kiválasztható lesz, mint a beépített típusok:
... var myOptions = { zoom: 2, center: latlng, mapTypeControl: true, mapTypeControlOptions: { mapTypeIds: ['gömb',google.maps.MapTypeId.SATELLITE]}, }; var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); map.mapTypes.set('gömb', globuszMapType); map.setMapTypeId(google.maps.MapTypeId.SATELLITE); ...
11b. példa - saját térképmozaik, mint térképtípus
11c. példa - térképmozaik, mint térképtípus - Google Sky és Moon
KML vagy KMZ formátumú fájlokat is megjeleníthetünk a térképünkön. Ehhez mindössze be kell töltenünk a megfelelő fájlt a google.maps.KmlLayer
függvény segítségével, majd az így létrehozott objektumhoz hozzá kell rendelnünk a térképet, amin megjelenítjük:
... var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); var kml = new google.maps.KmlLayer('http://mercator.elte.hu/~saman/hu/okt/gmaps3/hochschwab.kmz'); kml.setMap(map); ...
12. példa - KML/KMZ fájl megjelenítése
Fontos megjegyezni, hogy ebben az esetben nem használhatunk lokális fájlneveket, sem relatív URL-t. Minden esetben meg kell adnunk az abszolút URL-t. Ennek az az oka, hogy a KML/KMZ fájl raszteres képpé alakítása nem a böngészőben történik, hanem a Google egyik szerverén.