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.

Nowy tryb mapy z openstreetmap.org

Ten artykuł dotyczy najnowszej wersji API

« powrót do listy poradników

API Google umożliwia dodanie innych trybów mapy niż te wbudowane (mapa fizyczna, satelitarna, hybrydowa i widok ulic). Największym problemem w dodaniu własnej mapy jest konieczność przygotowania precyzyjnych obrazków z widokiem ulic, wykalibrowanych do mapy Google. Serwis openstreetmap.org udostępnia za darmo własny zestaw map w postaci, którą bardzo łatwo zaimportować do aplikacji w API Google.

Mapy z openstreetmap.org są darmowe i wolne - w niektórych miejsach mniej a w niektórych bardziej szczegółowe niż te, dostępne w Google Maps. Przykładowo, openstreetmap.org pokazuje przebieg linii tramwajowych.

Mapa Google Maps Mapa Open Street Maps
Mapa Google Maps Mapa Open Street Maps

Konwencja nazw i mapowanie współrzędnych do obrazków

Każda mapa ma pewien określony zakres przybliżenia, na którym oferuje przygotowane, wyrenderowane wcześniej obrazki. Każdy obrazek opisany jest trzema współrzędnymi: współrzędną X (w poziomie), współrzędną Y (w pionie) oraz poziomem przybliżenia. Parametry te są liczbami całkowitymi.

W przypadku map z openstreetmap.org format URL obrazka wygląda następująco:

https://tile.openstreetmap.org/Z/X/Y.png

gdzie Z to poziom zoom (1-19) a X i Y to współrzędne (nie należy ich jednak mylić ze współrzędnymi geograficznymi). Współrzędne te są właściwe w lokalnym układzie odniesienia, gdzie punkt (0,0) to początek mapy, a kolejne całkowite wartości to kolejne numery kafelków.

Dodanie nowego trybu mapy zaczynamy od stworzenia definicji obiektu, definującego wygląd i zachowanie nowej mapy:

var mapaOpenStreetMap = {
	getTileUrl: function(wspolrzedne, zoom) {
		var znormalizowaneWspolrzedne = normalizujWspolrzedne(wspolrzedne, zoom);
		if (!znormalizowaneWspolrzedne) {
			return null;
		}
		return 'https://tile.openstreetmap.org/'+zoom+'/'+znormalizowaneWspolrzedne.x+'/'+znormalizowaneWspolrzedne.y+'.png';
	},
	tileSize: new google.maps.Size(256, 256),
	maxZoom: 19,
	name: "OpenStreetMap"
};

W przypadku własnych map, konieczne jest zaimplementowanie minimum trzech własności: getTileUrl, tileSize oraz maxZoom. Pozostałe są opcjonalne, w powyższym przykładzie zdefiniowałem nazwę tworzonej mapy. Więcej opcjonalnych właściwości porusza oficjalna dokumentacja API.

  • Parametr tileSize określa rozmiar pojedynczego kawałka mapy. Dla map z OpenStreetMaps, jest to standardowo ta sama wartość co dla oryginalnych map Google, tzn. 256 x 256 pikseli.
  • Parametr maxZoom określa maksymalny dostępny poziom przybliżenia
  • Parametr name określa nazwę mapy
  • Parametr getTileUrl to funkcja, która będzie uruchomiona za każdym razem, kiedy API chce poznać adres URL do kawałka mapy, znając współrzędną X i Y oraz poziom przybliżenia

W linii 7 zwracany jest URL na podstawie znanego schematu adresowania kawałków. Warte uwagi jest natomiast to, co dzieje się wcześniej. Aby zapewnić opływanie kawałków w poziomie (mapa będzie się wówczas zapętlać tak, jak oryginalna mapa od Google) napisałem prostę funkcję, służącą do zapętlenia numeracji w poziomie. Wygląda ona tak:

// Ta funkcja normalizuje wspolrzedne tak, by mapa sie zapetlala w poziomie.
function normalizujWspolrzedne(wspolrzedne, zoom) {
	var y = wspolrzedne.y;
	var x = wspolrzedne.x;

	var liczbaKawalkow = 1 << zoom;

	// blokada zapetlania w pionie
	if (y < 0 || y >= liczbaKawalkow) {
		return null;
	}

	// zezwolenie na zapetlanie w poziomie
	if (x < 0 || x >= liczbaKawalkow) {
		x = (x % liczbaKawalkow + liczbaKawalkow) % liczbaKawalkow;
	}

	return { x: x, y: y };
}

Mając zdefiniowane opcje mapy, dalsza część jest już bardzo prosta. Należy dodać nasz nowy tryb mapy, tworząc nową instację klasy ImageMapType, której konstruktor przyjmuje określony przez nas wcześniej parametr opcji:

mapa.mapTypes.set('openstreetmap', new google.maps.ImageMapType(mapaOpenStreetMap));

Powyższy kod dodaje powiązanie pomiędzy ID mapy (w naszym wypadku wybrałem openstreetmap) a instancją obiektu ImageMapType.

Następnie należy jeszcze wybrać domyślny tryb mapy, używając ustalonego ID:

mapa.setMapTypeId('openstreetmap');

Po uruchomieniu tak przygotowanej aplikacji, możemy cieszyć się z nowego, szczegółowego widoku map: