Google Maps API - Programmieren für Google Maps
Die folgenden Code Beispiele basieren i.d.R. auf der Google API Version3, bei der kein API Key mehr benötigt wird.
Links
Dokumentation Google Maps API
[[1]]
Google Group zu Google Maps http://groups.google.com/group/google-maps-js-api-v3
Developer Dokumentation von Apple http://developer.apple.com/webapps/docs/documentation/AppleApplications/Reference/SafariWebContent/Introduction/Introduction.html
Android Dokumentation http://developer.android.com/
API Links
Google Maps API-Familien (auf deutsch) http://code.google.com/intl/de-DE/apis/maps/
Geocodierung: http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/services.html#Geocoding
Ereignisse (Events): http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/events.html
Snippets
Weiterführende und fortgeschrittene Techniken für Google Maps
Google Maps - Benutzerdefinierte Stile
Google Maps - eigene Marker und Symbole
Hier kommen Links rein...
Position des Nutzers bestimmen
Google liefert folgendes Code Beispiel. Dabei wird zuerst getestet ob der Browser die HTML5 Geocoding Spezifikation des W3C unterstüzt (http://dev.w3.org/geo/api/spec-source.html). Wenn nicht wird Google Gears getestet und ansonsten eine Fehlermeldung ausgegeben.
// Note that using Google Gears requires loading the Javascript
// at http://code.google.com/apis/gears/gears_init.js
var initialLocation;
var siberia = new google.maps.LatLng(60, 105);
var newyork = new google.maps.LatLng(40.69847032728747, -73.9514422416687);
var browserSupportFlag = new Boolean();
function initialize() {
var myOptions = {
zoom: 6,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Try W3C Geolocation (Preferred)
if(navigator.geolocation) {
browserSupportFlag = true;
navigator.geolocation.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude);
map.setCenter(initialLocation);
}, function() {
handleNoGeolocation(browserSupportFlag);
});
// Try Google Gears Geolocation
} else if (google.gears) {
browserSupportFlag = true;
var geo = google.gears.factory.create('beta.geolocation');
geo.getCurrentPosition(function(position) {
initialLocation = new google.maps.LatLng(position.latitude,position.longitude);
map.setCenter(initialLocation);
}, function() {
handleNoGeoLocation(browserSupportFlag);
});
// Browser doesn't support Geolocation
} else {
browserSupportFlag = false;
handleNoGeolocation(browserSupportFlag);
}
function handleNoGeolocation(errorFlag) {
if (errorFlag == true) {
alert("Geolocation service failed.");
initialLocation = newyork;
} else {
alert("Your browser doesn't support geolocation. We've placed you in Siberia.");
initialLocation = siberia;
}
map.setCenter(initialLocation);
}
}
Sensorparameter einstellen
Die Anwendung muß angeben ob sie einen Sensor zur Positionsbestimmung benutzt. Z.B. der GPS Empfänger in einem Handy. Wenn nicht muß trotzdem "false" übergeben werden.
# # Example using sensor when loading the Maps JavaScript API # <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">
Optimierungen für Mobilgeräte
http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/basics.html#Mobile
Umgebender Div Container (hier mapdiv) mit width:100%. Bei älteren Desktop Browsern kann dies aber zu Schwierigkeiten führen.
Sie können iPhones und Android-Geräte anhand der navigator.userAgent-Eigenschaft im DOM erkennen:
function detectBrowser() {
var useragent = navigator.userAgent;
var mapdiv = document.getElementById("map_canvas");
if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1 ) {
mapdiv.style.width = '100%';
mapdiv.style.height = '100%';
} else {
mapdiv.style.width = '600px';
mapdiv.style.height = '800px';
}
}
Dadurch können Sie das Layout für bestimmte Geräte wie in diesem Beispiel verändern und beispielsweise den verfügbaren Platz auf dem Display für jedes Gerät anpassen.
Das iPhone akzeptiert das folgende <meta>-Tag:
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
Diese Einstellung gibt an, dass diese Karte im Vollbildmodus angezeigt werden soll und ihre Größe vom Nutzer nicht geändert werden kann. Android-Geräte mit Softwareversion 1.5 (Cupcake) unterstützen diese Parameter ebenfalls. Für den iPhone-Browser Safari muss dieses <meta>-Tag im <head>-Element der Seite enthalten sein.
Lokalisierung einer v3 App (Sprachanpassung)
Sprachlokalisierung und Anpassung der Texte - language Parameter
Normalerweise nicht notwendig weil die Sprache des Browsers verwendet wird. Wenn doch dann mit dem Language Parameter.
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false&language=de">
Gebietslokalisierung - region Parameter
Normalerweise wird die Domain der Homepage für die Regionserkennung verwendet. Manchmal möchte man die Region verändern damit Google Maps richtig gewichtet. Z.B. kann die Suche nach dem Ort Toledo den Ort in Spanien finden oder in den USA. Wenn der Region Parameter auf es steht liefert er stets den Ort in Spanien.
Beispiel
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false®ion=GB">
Richtige API Version laden - der v Parameter
http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/basics.html#Versioning
Beispiel
http://maps.google.com/maps/api/js?v=3.1&sensor=true_or_false
Kartentyp ändern
Kartentypen werden im Map options-Objekt der Karte mithilfe der mapTypeId-Eigenschaft festgelegt.
Die folgenden Kartentypen sind im Google Maps-API verfügbar:
MapTypeId.ROADMAP zeigt die Standard-Straßenkartenansicht. MapTypeId.SATELLITE zeigt Google Earth-Satellitenbilder. MapTypeId.HYBRID zeigt eine Mischung aus der normalen und der Satellitenansicht. MapTypeId.TERRAIN zeigt eine physische Karte an, die auf Geländeinformationen basiert.
Sie können den Kartentyp einer Karte ändern, indem Sie die setMapTypeId()-Methode der Karte aufrufen.
Wichtige Google Maps Objekte
Wichtige Objekte anhand von Beispiel Definitionen:
LatLng Objekt
var myLatlng = new google.maps.LatLng(-34.397, 150.644);
Options Objekt
var myOptions = {
zoom: 8,
center: myLatlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
Wird normalerweise nicht direkt erzeugt sondern als "Literalobjekt" (also als Zeichenfolge) definiert und dann direkt im Map Objekt verwendet und implizit erzeugt (siehe Map Objekt)
Wichtige Optionen
Einige oft benötigte Optionen und was sie machen:
http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/reference.html#MapOptions
- zoom - anfänglicher Zoom Level (0 = World) Erforderlich
- mapTypeId - anfängliche mapTypeId der Karte. Erforderlich
- center - anfängliches Kartenzentrum. Erforderlich
- disableDefaultUI - damit kann man die Standard Bedienelemente ausschalten (true,false). Man kann fast alles auch einzeln ein und ausschalten (Maussteuerung, Tastatursteuerung, verschieben der Karte, etc.). Siehe Link oben.
- navigationControlOptions Anfängliche Anzeigeoptionen für die Navigationssteuerung (position, style).
Map Objekt
Das Zentrale Objekt.
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
Marker Objekt
Benötigt als Parameter eine Position und optional das Map Objekt. Wenn dies nicht vorhanden ist kann man den Marker später mit setMap hinzufügen. Mit setMap(null) kann man den Marker entfernen.
Standardmäßig haben die Marker einen click Listener.
Beispiel - Marker hinzufügen
// Marker für die Achalm
var posAchalm = new google.maps.LatLng(48.493978,9.244276);
var marker = new google.maps.Marker({
position: posAchalm,
map: map,
title:"Achalm"
});
Info Window Objekt
Das folgende Beispiel definiert ein InfoWindow, welches an einen Marker ("marker") gehängt wird und sich bei Klick öffnet. Es funktioniert also mit dem obigen Marker Beispiel zusammen.
// INFOWINDOW
// Inhalt festlegen
var contentString = '<div id="content">'+
'<div id="siteNotice">'+
'</div>'+
'<h1 id="firstHeading" class="firstHeading">Achalm</h1>'+
'<div id="bodyContent">'+
'<p>Die <b>Achalm</b>, ist der Hausberg der Stadt Reutlingen, ' +
'am Rande der schwäbischen Alb gelegen. '+
'<p>Attribution: Achalm, <a href="http://de.wikipedia.org/wiki/Achalm">'+
'Achalm in der Wikipedia</a>.</p>'+
'</div>'+
'</div>';
// Fenster erzeugen...
var infowindow = new google.maps.InfoWindow({
content: contentString,
maxWidth: 280
});
// Klick-Listener an Marker hängen der das Fenster öffnet.
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map,marker);
});
Google Maps Beispiele
Komplettes Anwendungsbeispiel (Horex)
Interessant mit ein paar netten Tricks
var map, mapOptions, panoMap, resultBounds, timeout, markers = [];
function initialize() {
// MAP
//var myMapDiv = document.getElementById("map_canvas");
// or with jQuery
var myMapDiv = $("#map_canvas")[0];
var latlng = new google.maps.LatLng(51.4634, 9.5581);
// we need a ID for our new maptype
var HOREX_MAPTYPE_ID = 'HOREX';
var myOptions = {
zoom: 6,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP,
// new control button to select the maptype id
mapTypeControlOptions: {
mapTypeIds: [google.maps.MapTypeId.ROADMAP, HOREX_MAPTYPE_ID]
}
};
var map = new google.maps.Map(myMapDiv, myOptions);
// MAP STYLING
// Neue Map Style Definition
//#D1A456
//#565451
var stylez =
[
{ // Strassen
featureType: "road",
stylers: [
{ visibility: "off" }
]
},
{ //Bahn
featureType: "transit",
stylers: [
{ visibility: "off" }
]
},
{ // POI
featureType: "poi",
stylers: [
{ visibility: "off" }
]
},
{ // Landflächen
featureType: "landscape",
stylers: [
{ visibility: "on" },
{ hue: "#D1A456" },
{ saturation: 65 },
{ lightness: -33 },
{ gamma: 1 }
]
},
{ // Landflächen besiedelung
featureType: "landscape.man_made",
stylers: [
{ visibility: "off" }
]
},
{ // Landflächen natur
featureType: "landscape.natural",
stylers: [
{ visibility: "off" }
]
},
{ // Grenzen allgemein
featureType: "administrative",
elementType: "geometry",
stylers: [
{ lightness: -50},
{ saturation: 0 },
{ gamma: 1 },
{ hue: "#565451" },
{ visibility: "on" }
]
},
{ // Ländergrenzen
featureType: "administrative.country",
elementType: "geometry",
stylers: [
{ hue: "#FFFFFF" },
{ saturation: 100 },
{ lightness: 100 }
]
},
{ // Bundesländer label
featureType: "administrative.province",
elementType: "labels",
stylers: [
{
visibility: "on"
}
]
},
{ // Bundesländer label
featureType: "administrative.locality",
elementType: "labels",
stylers: [
{ visibility: "simplified" },
{ invert_lightness: true },
{ hue: "#565451" },
{ gamma: 1 },
{ saturation: 20 },
{ lightness: 25 }
]
},
{ // Wasser
featureType: "water",
stylers: [
{ visibility: "on" },
{ hue: "#cfd1d2" },
{ lightness: 50 },
{ saturation: -100 },
{ gamma: 1 }
]
}
];
// Map Zuordnung und Name des Stils
var styledMapOptions = {
map: map,
name: HOREX_MAPTYPE_ID
}
var horexMapType = new google.maps.StyledMapType(stylez,styledMapOptions);
// Style auswählen
map.mapTypes.set(HOREX_MAPTYPE_ID, horexMapType);
map.setMapTypeId(HOREX_MAPTYPE_ID);
// Zoom auf Deutschland
//geocoder = new google.maps.Geocoder();
//findAddress(map,"Germany");
// Marker setzen und in Array speichern
var markers=setMarkers(map);
}
function setMarkers(map) {
// This will hold all the markers for the clustering
// Get the JSON data that shall be mapped.
$.getJSON("http://www.horex.com/fileadmin/js/sampledata/horex.json", function(json){
//Make sure we have a markers array, holding some data.
//alert(json.markers.length);
if (json.markers && json.markers.length){
//New bounds object for the total results' bb.
var bounds = new google.maps.LatLngBounds();
//Loop through the JSON array's markers array.
$.each(json.markers, function(i){
///'this' refers to the array element of the current loop iteration index.
var data = this;
// Object position
var point = new google.maps.LatLng(data.lat,data.lng)
// New Object -> extend Bounds
bounds.extend(point);
// Data object that shall be assigned to the marker object.
var marker_data = {
"id": data.id,
"name": data.name,
"title": data.title,
"street": data.street,
"city": data.city,
"country": data.country,
"telephone":data.telephone,
"postcode":data.postcode,
"www": data.www,
"email": data.email,
"lat": data.lat,
"lng": data.lng,
"category": data.category,
"icon": data.icon,
"details": data.details
};
/**
* New google.maps.Marker object for 'this' Object.
**/
var marker = new google.maps.Marker({
map: map,
icon: 'http://www.horex.com/fileadmin/js/'+data.icon,
flat: true,
category: data.category,
title: unescape(data.title),
data: marker_data
});
// Map markers with raising timeout (just eye-catching).
//$.doTimeout(i*300, function(){
marker.setValues({
position: point,
//animation:google.maps.Animation.DROP
});
//}); i++;
// Push the marker object to the markers array.
markers.push(marker);
// Add event listener that will trigger the infoWindow.
google.maps.event.addListener(marker, "click", function(){
// panTo just looks 'nicer' than setCenter.
map.panTo(marker.position);
// Add a delay for a smoother pop-up animation.
$.doTimeout(600, function(){
// Call the custom info Window function.
showDetails(marker.data);
/**
* Workaround for an issue that loads some tiles
* in plain grey when initializing a map and on-
* screen of that map object are timed very close.
**/
google.maps.event.trigger(panoMap, 'resize');
});// End doTimeout callback function
});// end eventListener for Marker
});// End JSON Loop
// Save all markers' bounding box to a global variable.
resultBounds = bounds;
// Set the viewport to optimal fit to all results' bb.
//map.fitBounds(resultBounds);
var actZoom = map.getZoom();
map.setZoom(6);
} // end if json markers
/*
// MarkerClusterer
var markerClusterer = null;
var markerClustererStyles = [{
url: 'http://www.horex.com/fileadmin/js/images/m1.png',
height: 35,
width: 35,
textColor: '#ffffff',
textSize: 10
}, {
url: 'http://www.horex.com/fileadmin/js/images/m2.png',
height: 45,
width: 45,
textColor: '#ffffff',
textSize: 11
}, {
url: 'http://www.horex.com/fileadmin/js/images/m3.png',
height: 55,
width: 55,
textColor: '#ffffff',
textSize: 12
}]
var markerClustererOptions = {
gridSize: 35,
maxZoom: 10,
styles: markerClustererStyles
};
var markerCluster = new MarkerClusterer(map,markers,markerClustererOptions);
*/
});
return markers;
}
/**
* Function showDetails
* @author: Stephan Schmitz <eyecatchup@gmail.com>
*
* @description: Using jQueryUI modal dialogs instead of InfoWindows, to
* show the marker object's data details. Dialog overlays
* contain all custom data that have been assigned to the
* marker and also a street-view map of the markers point
* to enhance the overview. (If there is no streetview
* available, a standard map will be shown.)
**/
function showDetails(data){
// Objects position as google.maps.LatLng object.
var point = new google.maps.LatLng(data.lat,data.lng);
// Set the options for the info window map object to be created.
/*
var panoMapOptions = {
center: point,
zoom: 14,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
*/
// Initialize the info window map.
/*
panoMap = new google.maps.Map($('#panoMap')[0],
panoMapOptions);
*/
// Set the options for the google.maps.StreetViewPanorama.
/*
var panoramaOptions = {
position: point,
pov:{
heading: 34,
pitch: 10,
zoom: 0}};
*/
// Initialize the google.maps.StreetViewPanorama.
/*
var panorama = new google.maps.StreetViewPanorama(
$('#panoMap')[0],panoramaOptions);
*/
// Set the Streeview Overlay.
//panoMap.setStreetView(panorama);
/**
* The 'template' for the data, shown in the info window.
**/
var br = '<br>';
$('#data').empty()
.html(
'<div class="headerimg"><img src="http://www.horex.com/fileadmin/js/images/vertrieb_logo.gif"></div>'+
'<div class="headline">'+data.title+'</div>'+
'<div class="headline2">'+data.name+'</div>'+
'<div>'+data.postcode+' '+data.city+'</div>'+br+
'<div>'+data.street+'</div>'+
'<div>Tel.: '+data.telephone+'</div>'+
'<div>E-Mail: <a href="mailto:'+data.email+'">'+data.email+'</a></div>'+
'<div>Website: <a href="http://'+data.www+'" target="_blank">'+data.www+'</a></div>'+
'<div class="geosearch-details">'+data.details+'</div>'+
'<div class="map-printlink" style="cursor:pointer; width:21px;" onclick="window.print();"><img width="21" height="16" border="0" title="drucken" alt="drucken" style="margin-top: 20px;" src="http://www.horex.com/fileadmin/templates_v2/media/print.png"></div>'+
'<div class="route"><strong>Route finden</strong>'+br+
'<form id="routefinder" action="http://maps.google.de" method="GET" target="_blank">'+
'<input type="text" id="saddr" name="saddr" value="Abfahrtsort" onclick="if(this.value==\'Abfahrtsort\')this.value=\'\';"/>'+
'<input type="hidden" id="daddr" name="daddr" value="'+data.city+','+data.street+'"/>'+br+
'<input type="submit" class="route_button" value="Absenden"></form></div>'
);
/**
* Set the dialog options for the info windows.
**/
$('#dialog').dialog({
width: 675,
modal: true,
position: ['center','center'],
title: " ",
autoOpen: true,
closeOnEscape:true,
draggable: true,
show: "slide",
hide: "slide"
});
}
// Zoom auf Adresse Funktion (mit geocoder siehe init)
function findAddress(map,address) {
if (!address)
var address=document.getElementById("countryselect").value;
if ((address != '') && geocoder) {
geocoder.geocode( { 'address': address}, function(results, status) {
if (status == google.maps.GeocoderStatus.OK) {
if (status != google.maps.GeocoderStatus.ZERO_RESULTS) {
if (results && results[0] && results[0].geometry && results[0].geometry.viewport)
map.fitBounds(results[0].geometry.viewport);
} else {
alert("No results found");
}
} else {
alert("Geocode was not successful for the following reason: " + status);
}
});
}
}
/**
* jQuery doTimeout: Like setTimeout, but better! - v1.0 - 3/3/2010
* http://benalman.com/projects/jquery-dotimeout-plugin/
*
* Copyright (c) 2010 "Cowboy" Ben Alman
* Dual licensed under the MIT and GPL licenses.
* http://benalman.com/about/license/
**/
(function($){var a={},c="doTimeout",d=Array.prototype.slice;$[c]=function(){return b.apply(window,[0].concat(d.call(arguments)))};$.fn[c]=function(){var f=d.call(arguments),e=b.apply(this,[c+f[0]].concat(f));return typeof f[0]==="number"||typeof f[1]==="number"?this:e};function b(l){var m=this,h,k={},g=l?$.fn:$,n=arguments,i=4,f=n[1],j=n[2],p=n[3];if(typeof f!=="string"){i--;f=l=0;j=n[1];p=n[2]}if(l){h=m.eq(0);h.data(l,k=h.data(l)||{})}else{if(f){k=a[f]||(a[f]={})}}k.id&&clearTimeout(k.id);delete k.id;function e(){if(l){h.removeData(l)}else{if(f){delete a[f]}}}function o(){k.id=setTimeout(function(){k.fn()},j)}if(p){k.fn=function(q){if(typeof p==="string"){p=g[p]}p.apply(m,d.call(n,i))===true&&!q?o():e()};o()}else{if(k.fn){j===undefined?e():k.fn(j===false);return true}else{e()}}}})(jQuery);
Beispiele auf Google: http://code.google.com/intl/de-DE/apis/maps/documentation/javascript/examples/index.html
Simple Map
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=set_to_true_or_false"></script>
<script type="text/javascript">
function initialize() {
var latlng = new google.maps.LatLng(-34.397, 150.644);
var myOptions = {
zoom: 8,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
}
</script>
</head>
<body onload="initialize()">
<div id="map_canvas" style="width:100%; height:100%"></div>
</body>
</html>