www.gmapsapi.com

Kompleksowy kurs podstaw API, po którym mapowianie nie będzie miało przed Tobą żadnych tajemnic!

Setki przykładów, kursów i poradników z kodem gotowym do skopiowania i korzystania.

Największa strona o Google Maps API w Polsce, największe źródło informacji w języku polskim.

Pamiętanie danych między sesjami

Ten artykuł dotyczy API w wersji 2

« powrót do listy poradników

Jeśli Twój użytkownik ma zwyczaj pracować w ściśle określonym obszarze na mapie, wygodne może być udostępnienie możliwości pamiętania jej parametrów pomiędzy poszczególnymi sesjami. W tym poradniku pokażę dwie podstawowe metody, które możesz wykorzystać w swojej aplikacji.

Metoda 1: Link stały

Pierwszym sposobem na zapamiętanie danych między sesją jest udostępnienie możliwości generowania tzw. linku stałego (ang. permalink) do aktualnie wyświetlanego widoku na mapie. Można go skopiować do schowka lub zapisać do zakładek - kiedy adres strony zostanie wywołany z tego specjalnie przygotowanego adresu, mapa ustawi się w sprecyzowanych parametrami adresu ustawieniach.

Przykładowy adres linku stałego może wyglądać następująco:
http://gmapsapi.com/przyklady/029/02.html?lat=53.41935400090768&lng=14.58160400390625&zoom=8&typmapy=mapa
Można odczytać z niego informację o położeniu mapy (punkt GLatLng(53.41935400090768,14.58160400390625)), poziom przybliżenia = 8, oraz typ mapy normalnej.

Generowanie linku stałego

Pod mapą dodamy link o tytule "pokaż link stały". Po jego kliknięciu wyświetli się małe okienko, w którym napisany będzie adres. W celu realizacji takiego interfejsu napiszemy właną klasę LinkStaly, odpowiedzialną za wyświetlenie okna i wygenerowanie linku. Globalny obiekt kontrolka tworzymy i dodajemy do mapy:

kontrolka = new LinkStaly();
kontrolka.dodajDoMapy(mapa);

Klasa LinkStaly:

function LinkStaly() {}
LinkStaly.prototype.dodajDoMapy = function(mapa)
{
	var kontener	= document.createElement("div");
	kontener.id = 'linkstaly'; // id diva z linkiem to linkstaly
	kontener.style.display = 'none'; // na początku kontrolka ma być ukryta
	kontener.appendChild(document.createTextNode('Link stały do tego widoku:'));
	
	var linkurl = document.createElement('textarea');
	linkurl.className = 'link';
	linkurl.id = 'url'; // id pola tekstowego to url
	kontener.appendChild(linkurl);
	
	var przycisk = document.createElement('input');
	przycisk.type = 'button';
	przycisk.value = 'OK';
	przycisk.onclick = function() { kontrolka.ukryj(); };
	kontener.appendChild(przycisk);
	
	this.mapa = mapa;
	this.wlaczony = false;
	mapa.getContainer().appendChild(kontener);
}

Dzięki metodzie dodajDoMapy utworzone okno (blokowy element div o id linkstaly) zostanie dołączone do mapy. Okienko zawierać będzie tekst "Link stały do tego widoku", pole typu textarea, do którego będzie wpisany adres URL, oraz przycisk OK, dzięki któremu okienko zostanie ukryte.

LinkStaly.prototype.ukryj = function()
{
	document.getElementById('linkstaly').style.display = 'none';
	this.wlaczony = false;
}

Własność wlaczony ma być ustawiana na false, gdy okienko nie jest widoczne, a gdy jest to wartość tej własności ma wynosić true. W tym przykładzie nie będzie ona wykorzystana, ale w następnym zrobimy z niej użytek. Mamy już kontrolkę dodaną do mapy, czas napisać kod, który wygeneruje link stały:

LinkStaly.prototype.wyswietl = function()
{
	// pobieramy odpowiednie parametry mapy
	var lat 	= this.mapa.getCenter().lat();
	var lng 	= this.mapa.getCenter().lng();
	var zoom 	= this.mapa.getZoom();
	switch(this.mapa.getCurrentMapType())
	{
		case G_HYBRID_MAP: 		var typ = 'hybryda'; break;
		case G_SATELLITE_MAP: 	var typ = 'satelita'; break;
		case G_PHYSICAL_MAP: 	var typ = 'teren'; break;
		default: 				var typ = 'mapa';
	}
	
	// to jest bazowy adres tego przykładu
	var adres 	 = 'http://gmapsapi.com/przyklady/029/01.html';
	
	// a to dodatkowe parametry mapy
	adres 		+= '?lat='+lat;
	adres 		+= '&lng='+lng;
	adres 		+= '&zoom='+zoom;
	adres 		+= '&typmapy='+typ;
	
	// wyświetlamy link i pokazujemy okno
	document.getElementById('url').value = adres;
	document.getElementById('linkstaly').style.display = 'block';
	this.wlaczony = true;
}

Kod w powyższym listingu jest skomentowany, więc dalsze uwagi nie są już potrzebne. Aby wygenerować link stały, skorzystamy z funkcji:

function pobierzLinkStaly()
{
	if(!kontrolka)
		return;
	kontrolka.wyswietl();
}

Ponieważ link pod mapą będzie wyświetlany zanim mapa się załaduje, sprawdzamy najpierw czy stworzona została już kontrolka, i jeśli tak to wyświetlamy adres stały.

Wczytywanie danych z linku stałego

OK, link został wygenerowany. Jak jednak odczytać dane, zapisane jako parametry w adresie? Można to zrobić albo po stronie serwera (PHP), albo po stronie klienta. Ja zaprezentuję to drugie rozwiązanie (jako trudniejsze)

function pobierzParametrZAdresu(nazwa)
{
	nazwa = nazwa.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
	var regexS = "[\\?&]"+nazwa+"=([^&#]*)";
	var regex = new RegExp(regexS);
	var wyniki = regex.exec(window.location.href);
	if(wyniki == null)
		return false;
	else
		return wyniki[1];
}

Ta funkcja dzięki wyrażenion regularnym szuka w parametrach w adresie nazwy poszukiwanej przez nas (jej nazwa jest przekazana w argumencie funkcji), i zwraca odpowiadającą jej wartość, lub false jeśli takiego parametru nie znaleziono. Dzięki tej funkcji możliwe staje się pobranie wartości, które można obsłużyć następująco:

// odczytujemy parametry z adresu
var lat 	= pobierzParametrZAdresu('lat') || 53.41935400090768;
var lng 	= pobierzParametrZAdresu('lng') || 14.58160400390625;
var zoom	= pobierzParametrZAdresu('zoom') || 8;

zoom 	= parseInt(zoom);
lat 	= parseFloat(lat);
lng 	= parseFloat(lng);

switch(pobierzParametrZAdresu('typmapy'))
{
	case 'satelita': 	var typ = G_SATELLITE_MAP; break;
	case 'typ': 		var typ = G_PHYSICAL_MAP; break;
	case 'hybryda': 	var typ = G_HYBRID_MAP; break;
	default: 			var typ = G_NORMAL_MAP; break;
}

Wycentrowanie mapy jest już w tym momencie czystą formalnością. Pamiętaj, by zapewnić alternatywne dane w sytuacji, gdy w adresie parametrów nie podano (w kodzie powyżej są to liczby po dwóch pionowych kreskach ||).

Jak to działa? Sprawdż przykład: przykład 1pokaż kod przykładu

Modyfikacja

Przykład 1 ma jedną wadę. Gdy okno z linkiem stałym jest otworzone, przesuwanie mapy nie powoduje odświeżania adresu. Można to bardzo szybko naprawić, dodając taki kod:

GEvent.addListener(mapa,'moveend',function()
{
	if(kontrolka.wlaczony)
		kontrolka.wyswietl();
});

W tym momencie użyteczna jest własność wlaczony - po zakończeniu przesuwania/przybliżania lub zmiany typu mapy sprawdzamy, czy kontrolka jest włączona, a jeśli tak, to zwyczajnie nakazujemy wyświetlić nowy link stały. Oto przykład, demonstrujący działanie: przykład 2pokaż kod przykładu

Metoda 2: Pamiętanie danych w cookies

Drugim sposobem na pamiętanie danych między sesjami jest zapis do ciasteczek, przechowywanych po stronie klienta. W tym przykładzie pokażę, jak obsłużyć zapis i odczyt z ciasteczek za pomocą JavaScript.

Potrzebna będą specjalne funkcje napisane w tym celu - JavaScript nie posiada prostej, gotowej funkcji do obsługi ciasteczek. W przykładzie wykorzystałem kod ze strony http://techpatterns.com/downloads/javascript_cookies.php - wygląda on tak:

function Set_Cookie( name, value, expires, path, domain, secure ) 
{
	// set time, it's in milliseconds
	var today = new Date();
	today.setTime( today.getTime() );

	/*
	if the expires variable is set, make the correct 
	expires time, the current script below will set 
	it for x number of days, to make it for hours, 
	delete * 24, for minutes, delete * 60 * 24
	*/
	if ( expires )
	{
		expires = expires * 1000 * 60 * 60 * 24;
	}
	var expires_date = new Date( today.getTime() + (expires) );

	document.cookie = name + "=" +escape( value ) +
	( ( expires ) ? ";expires=" + expires_date.toGMTString() : "" ) + 
	( ( path ) ? ";path=" + path : "" ) + 
	( ( domain ) ? ";domain=" + domain : "" ) +
	( ( secure ) ? ";secure" : "" );
}

// this fixes an issue with the old method, ambiguous values 
// with this test document.cookie.indexOf( name + "=" );
function Get_Cookie( check_name ) {
	// first we'll split this cookie up into name/value pairs
	// note: document.cookie only returns name=value, not the other components
	var a_all_cookies = document.cookie.split( ';' );
	var a_temp_cookie = '';
	var cookie_name = '';
	var cookie_value = '';
	var b_cookie_found = false; // set boolean t/f default f
	
	for ( i = 0; i < a_all_cookies.length; i++ )
	{
		// now we'll split apart each name=value pair
		a_temp_cookie = a_all_cookies[i].split( '=' );
		
		
		// and trim left/right whitespace while we're at it
		cookie_name = a_temp_cookie[0].replace(/^\s+|\s+$/g, '');
	
		// if the extracted name matches passed check_name
		if ( cookie_name == check_name )
		{
			b_cookie_found = true;
			// we need to handle case where cookie has no value but exists (no = sign, that is):
			if ( a_temp_cookie.length > 1 )
			{
				cookie_value = unescape( a_temp_cookie[1].replace(/^\s+|\s+$/g, '') );
			}
			// note that in cases where cookie is initialized but no value, null is returned
			return cookie_value;
			break;
		}
		a_temp_cookie = null;
		cookie_name = '';
	}
	if ( !b_cookie_found )
	{
		return null;
	}
}		

// this deletes the cookie when called
function Delete_Cookie( name, path, domain )
{
	if ( Get_Cookie( name ) ) document.cookie = name + "=" +
	( ( path ) ? ";path=" + path : "") +
	( ( domain ) ? ";domain=" + domain : "" ) +
	";expires=Thu, 01-Jan-1970 00:00:01 GMT";
}

Powyższy kod zapisałem w oddzielnym pliku, który podłącze później do przykładu: http://gmapsapi.com/examples/029/cookies.js.

Zapis do ciasteczek przeprowadzać będziemy przy kończeniu pracy z mapą, odpowiednią funkcję dołączymy do tagu body w atrybucie onunload:

<body onload='mapaStart()' onunload='zapisz(); GUnload()'> 

GUnload() musi być ciągle obecne, funkcje muszą być wywoływane w tej kolejności. Funkcja zapisz() będzie zapisywać dane do cookies:

function zapisz()
{
	var lat 	= mapa.getCenter().lat();
	var lng 	= mapa.getCenter().lng();
	var zoom 	= mapa.getZoom();
	switch(mapa.getCurrentMapType())
	{
		case G_HYBRID_MAP:		var typ = 'hybryda'; break;
		case G_SATELLITE_MAP:	var typ = 'satelita'; break;
		case G_PHYSICAL_MAP:	var typ = 'teren'; break;
		default:				var typ = 'mapa'; break;
	}
	var wartosc = lat+'@'+lng+'@'+zoom+'@'+typ;
	Set_Cookie('parametryMapy', wartosc, 14);
}

Dane będą przechowywane w jednym ciasteczku w postaci długość@szerokość@zoom@typ_mapy. Trzeci argument funkcji Set_Cookie oznacza, że ciasteczko będzie przechowywane maksymalnie przez 14 dni od daty zapisu lub ostatniego nadpisania.

Aby odczytać dane z ciasteczka można posłużyć się takim skryptem:

var parametry = Get_Cookie('parametryMapy');
if(parametry)
{
	var tablica = parametry.split("@");
	var lat = parseFloat(tablica[0]);
	var lng = parseFloat(tablica[1]);
	var zoom = parseInt(tablica[2]);
	switch(tablica[3])
	{
		case 'hybryda': var typ = G_HYBRID_MAP; break;
		case 'satelita': var typ = G_SATELLITE_MAP; break;
		case 'teren': var typ = G_PHYSICAL_MAP; break;
		default: var typ = G_NORMAL_MAP;
	}
}
else
{
	var lat 	= 53.41935400090768;
	var lng 	= 14.58160400390625;
	var zoom	= 8;
	var typ 	= G_NORMAL_MAP;
}

mapa.setCenter(new GLatLng(lat,lng),zoom,typ);

W skrócie, ta funkcja ma działanie odwrotne do poprzedniej, dodaliśmy też obsługę wartości domyślnych w przypadku, gdy ciasteczko nie istnieje.

przykład 3pokaż kod przykładu

Uwagi i spostrzeżenia

  • Część użytkowników może mieć zablokowaną obsługę ciasteczek. Niestety nie istnieje obejście tego problemu, w grę wchodzi wówczas jedynie pierwsza z przedstawionych metod.
  • Ciasteczko będą mogły odczytać jedynie skrypty, znajdujące się w tej samej domenie co skrypt, który ciasteczko ustawił.
  • Dane z ciasteczek są w postaci stringa. Należy je przekonwertować na liczby zmiennoprzecinkowe (parseFloat()) lub na całkowite (parseInt()) w przypadku współrzędnych i poziomu przybliżenia. Zaniechanie tego kroku doprowadzi do niewyświetlenia się mapy

Polecane artykuły

Dodaj stronę do ulubionego serwisu społecznościowego

Oto, co najczęściej czytają internauci, którzy przeczytali ten artykuł:

Dodawanie markerów przez użytkownika

API v2

Poradnik pokazuje, w jaki sposób stworzyć formularz, pozwalający na dodawanie markerów


Wczytywanie danych z programu MS Excel

API v2

W tym przykładzie pokazane zostało, w jaki sposób wyświetlić markery z arkusza kalkulacyjnego


Własna mapa w Google Maps API

API v2

Przygotowanie i sposób stworzenia własnej mapy, na przykładzie mapy z gry GTA3


Warstwa zdjęć z Panoramio

API v2

Dodaj na swoją mapę eleganckie miniaturki zdjęć okolicy z serwisu Panoramio