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.

Wyświetlenie profilu trasy

Ten artykuł dotyczy najnowszej wersji API

« powrót do listy poradników

W API3 premierę miała nowa usługa, pozwalająca szybko wyznaczyć wysokość nad poziomem morza dowolnego punktu na Ziemi, określonego współrzędnymi LatLng. Wskazywana wysokość jest aproksymowana poprzez interpolację z sąsiednimi punktami o znanej, zmierzonej wysokości. Nie należy traktować jej jako wartości idealnej z dokładnością do centrymetrów, ale w większości wypadków jej dokładność jest na tyle dobra, że pozwala na orientacyjne wyobrażenie o wysokości terenu w danym punkcie.

W tym poradniku pokazany zostanie sposób na stworzenie aplikacji, która wyświetli na wykresie profil wysokościowy wybranej przez użytkownika trasy. Efekt ma być następujący:

Profil wysokościowy trasy

Zarys sposobu działania i wymagania

Do wyświetlenia trasy przejazdu z punktu A do punktu B użyjemy standardowych funkcji, dostępnych w APIv3 - DirectionsService(). W odpowiedzi na zadane zapytanie o wskazówki przejazdu otrzymamy polilinię, którą automatycznie narysujemy na mapie (DirectionsRenderer(). Uproszczony kształt polilinii wykorzystamy do zapytania wsadowego o wysokości punktów. Użyjemy do tego klasy ElevationService(). W odpowiedzi uzyskamy tablicę ze współrzędnymi i odpowiadającymi im wysokościami nad poziomem morza. Za pomocą funkcji computeLength() w bibliotece GeometryLibrary stworzymy oddzielną tablicę, zawierającą odległość wybranego punktu od początku trasy. Otrzymane odległości oraz uzyskane wcześniej wysokości narysujemy na wykresie, wykorzystując do tego interaktywne wykresy, dostępne w chartAPI od Google.

Tyle teorii, czas na omówienie szczegółów implementacji.

Uzyskanie wskazówek dojazdu

Konieczne jest stworzenie globalnych obiektów:

var trasa  		 = new google.maps.DirectionsService();
var trasa_render = new google.maps.DirectionsRenderer({suppressInfoWindows: true});

Pierwszy z nich będzie przetwarzał zapytania i zwracał odpowiedzi, drugi natomiast będzie służył do automatycznego wstawienia uzyskanej polilinii ma mapę (opcjonalny parametr suppresInfoWindows ustawiony na true oznacza, że nie będą wyświetlane dymki po kliknięciu na punkt początkowy i końcowy trasy).

Kiedy mapa zostanie zainicjowana, metodą setMap() obiektu renderującego ustawiamy odniesienie do docelowej mapy:

mapa = new google.maps.Map(document.getElementById("mapka"), opcjeMapy); 			
trasa_render.setMap(mapa);

Aby zadać zapytanie, stworzymy literalny obiekt o następującej strukturze:

var dane_trasy = 
{
	origin: 'Kraków',
	destination: 'Zakopane',
	travelMode: google.maps.DirectionsTravelMode.DRIVING
}

Taki zapis oznacza, że zapytanie będzie polegać na znalezieniu trasy dojazdu z Krakowa do Zakopanego, zakładając podróż samochodem.

Zadajemy zapytanie:

trasa.route(dane_trasy, obsluga_wskazowek);

Do obsługi odpowiedzi posłuży funkcja obsluga_wskazowek():

function obsluga_wskazowek(wynik, status)
{
	if(status != google.maps.DirectionsStatus.OK || !wynik.routes[0])
	{
		alert('Wystąpił błąd!');
		return;
	}
	
	trasa_render.setDirections(wynik);
	poziom.getElevationAlongPath({path: wynik.routes[0].overview_path, samples: 100}, obsluga_wysokosci);
}

Po początkowym sprawdzeniu poprawności odpowiedzi, w linii 9 nakazujemy wyrenderowanie uzyskanej polilinii. Następnie w linii 10 zadajemy wsadowe zapytanie o wysokości nad poziomem morza.

Wsadowe zapytanie o wysokość nad poziomem morza

poziom.getElevationAlongPath({path: wynik.routes[0].overview_path, samples: 100}, obsluga_wysokosci);

W prezentowanej konfiguracji, odpowiedź API składa się z jednej trasy. Punkty, odpowiadające uproszczonej polilinii zawarte są we własności overview_path pierwszego elementu routes. Tę ścieżkę w postaci tablicy współrzędnych podajemy jako parametr path, natomiast jako parametr samples wstawiamy dowolną liczbę, oznaczającą, jak dyskretyzowana będzie dana ścieżka. Przykładowo, wartość 100 oznacza, że w odpowiedzi uzyskamy 100 równo rozłożonych punktów, każdy z odpowiadającą mu wysokością nad poziomem morza. Wyniki będą interpetowane za pomocą funkcji obsluga_wysokosci().

Interpetacja wysokości nad poziomem morza, stworzenie wykresu

Do stworzenia wykresu skorzystamy z Google ChartAPI. Należy dołączyć do strony skrypt ładujący API:

<script src="http://www.google.com/jsapi" type="text/javascript"></script>    

oraz nakazać wczytanie odpowiedniego pakietu. W tym przykładzie będziemy korzystać wyłącznie ze standardowego wykresu typu scatter, wystarczy więc wczytać pakiet core.

google.load("visualization", "1", {packages: ["corechart"]});

Obiekt globalny, odpowiadający za wykres:

var wykres;
/* wycięty kod */
wykres = new google.visualization.ScatterChart(document.getElementById('obraz'));

Taki zapis oznacza, że wykresy będą rysowane w elemencie DOM o ID obraz - należy do wcześniej utworzyć (może to być zwykły, pusty DIV).

Ponieważ będziemy korzystać z biblioteki GeometryLibrary, nie wolno zapomnieć o drobnej modyfikacji adresu skryptu API:

<script src="http://maps.google.com/maps/api/js?sensor=false&libraries=geometry" type="text/javascript"></script>    

Wszystkie wymagane rzeczy zostały zadeklarowane, czas na analizę funkcji obsluga_wysokosci():

function obsluga_wysokosci(wyniki, status)
{
	if(status != google.maps.ElevationStatus.OK)
	{
		alert('Wystąpił błąd!');
		return;
	}
	
	var dane = new google.visualization.DataTable();
	dane.addColumn('number', 'Odległość');
	dane.addColumn('number', 'Wysokość');
	
	var odleglosci = [];
	var wysokosci = [];
	var sciezka = [];
	
	var min_wys = 0;
	var max_wys = 0;
	
	for(var i=0; i<wyniki.length; i++)
	{
		wysokosci.push(wyniki[i].elevation);
		sciezka.push(wyniki[i].location);
		odleglosci.push(google.maps.geometry.spherical.computeLength(sciezka)/1000);
		
		// uaktualnienie wartości min/max
		if(wyniki[i].elevation > max_wys)
			max_wys = wyniki[i].elevation;
			
		if(wyniki[i].elevation < min_wys)
		{
			min_wys = wyniki[i].elevation;
		}
	}
	
	dane.addRows(odleglosci.length);

	for(var i=0; i<odleglosci.length; i++)
	{
		dane.setValue(i,0,odleglosci[i]);
		dane.setValue(i,1,wysokosci[i]);
	}
	
	wykres.draw(dane,
	{
		width: 700,
		height: 400,
		vAxis: {title: 'Wysokość [m]', min: min_wys, max: max_wys},
		hAxis: {title: 'Odległość [km]', min: 0, max: odleglosci[odleglosci.length-1]},
		legend: 'none',
		lineWidth: 1,
		curveType: 'function',
		pointSize: 0,
		title: 'Profil pokonanej trasy',
		chartArea:
			{
				left: 50,
				top: 50,
				width: 600,
				height: 300
			}
	});
}

Większość kodu służy do rysowania wykresu - API do tego służące jest bardzo obszerne, więc kod ten nie będzie szczegółowo omawiany w tych fragmentach. Istotne są linie 13-34. W nich tworzymy tablicę wysokosci reprezentującą wartości w osia Y, oraz tablicę odleglosci, odpowiadającą za wartości na osi X. Dystans od punktu startowego do wybranego punktu obliczamy iteracyjnie w pętli w liniach 20-34. Dodatkowo, znajdujemy minimalną i maksymalną wartość wysokości nad poziomem morza, co pozwoli wyskalować wykres na osi Y. Maksymalną wartością na osi X będzie ostatnia wartość z tablicy odleglosci, natomiast wartością minimalną będzie oczywiście 0. Aby wykres wyglądał odpowiednio do naszych zamierzeń, należy:

  • Wyłączyć pokazywanie punktów (pointSize: 0),
  • Włączyć pokazywanie estymowanej regresji (lineWidth: 1),
  • Włączyć zaokrąglanie krzywej regresji (curveType: 'function'),
  • Wyskalować osie,
  • Zdefiniować parametry wizualne (szerokość, wysokość, odległość wykresu od lewej i górnej krawędzi, szerokość i wysokość właściwego wykresu,
  • Nazwać osie i dodać tytuł wykresu.

Przykład jest gotowy do działania: przykład 1pokaż kod przykładu

Dodanie interakcji

Oczywiście, wybór trasy można pozostawić użytkownikowi. Dodamy formularz:

<form name="geokoder" action="#" onsubmit="pokazProfil(); return false;">
Skąd: <input type="text" name="skad" id="skad" value="Zakopane" /><br />
Dokąd: <input type="text" name="dokad" id="dokad" value="Poznań" /><br />
<input type="submit" value="POKAŻ PROFIL TRASY!" />
</form>

Po wysłaniu formularza wywołana ma być funkcja pokazProfil(), a dalsze akcje mają zostać zaprzestane poprzez zwrócenie wartości false.

function pokazProfil()
{
	var skad = document.getElementById('skad').value;
	var dokad = document.getElementById('dokad').value;
	document.getElementById('obraz').style.display = 'block';
	
	var dane_trasy = 
	{
		origin: skad,
		destination: dokad,
		travelMode: google.maps.DirectionsTravelMode.DRIVING
	}
	
	trasa.route(dane_trasy, obsluga_wskazowek);
}

Wcześniej zapytanie o trasę było wysyłane w ramach funkcji mapaStart() - teraz nie jest już to potrzebne, toteż wygląda ona następująco:

function mapaStart()  
{  
	wykres = new google.visualization.ScatterChart(document.getElementById('obraz'));
	
	var wspolrzedne = new google.maps.LatLng(53.41935400090768,14.58160400390625);
	var opcjeMapy = {
		zoom: 10,
		center: wspolrzedne,
		mapTypeId: google.maps.MapTypeId.SATELLITE,
		disableDefaultUI: true
	};
	mapa = new google.maps.Map(document.getElementById("mapka"), opcjeMapy); 			
	trasa_render.setMap(mapa);
}  

Sprawdź profil wysokościowy wybranej przez siebie trasy: przykład 2pokaż kod przykładu

Polecane artykuły

Dodaj stronę do ulubionego serwisu społecznościowego

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

Kategorie markerów i polilinii

API v3

Stwórz markery/polilinie w kilku kategoriach, a następnie ukrywaj i pokazuj wybrane kategorie


Geokodowanie adresów

API v3

Kurs podstaw cz. XI: Proste i szybkie geokodowanie adresów (zamiana adresu na współrzędne)


Dostosowanie powiększenia do markerów

API v3

Kurs pokazuje, jak wyświetlić mapę tak, by wszystkie markery były widoczne


Wbudowane kontrolki i sterowanie

API v3

Kurs podstaw cz. VI: Dodawanie wbudowanych kontrolek i definiowanie sterowania mapy