Phonegap - odczyt gpx

W artykule pokażę jak zrobić prostą aplikację do odczytywania trasy szlaku w formacie gpx. Przykładowe trasy zaczerpnę ze strony mapa-turystyczna.pl. Swoją drogą jest to naprawdę świetna strona do planowania wycieczek górskich. Utwórzmy najpierw nowy projekt Phonegap (Minimal Phonegap project). Tak jak to ma miejsce w artykule Phonegap od podstaw.

Przerabiamy plik assets/www/index.html tak jak poniżej.
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<meta name="viewport" content="width=device-width,initial-scale=1">
	<title>Read gpx in google maps api</title>
	<meta name="description" content="">
	<link rel="stylesheet" type="text/css" href="css/main.css">
	<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
	<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.9.1/jquery-ui.min.js"></script>
	<script type="text/javascript" src="cordova.js"></script>
	<script type="text/javascript" src="js/main.js"></script>
</head>
<body>
	<input type="text" id="gpx_url"><button id="show_trail">Show</button><br>
	<button id="my_pos">Show my position on the map</button>
	<div id="map"></div>
</body>
</html>
Jak widać jest to prosty dokument html, w którym załączamy odpowiednie skrypty (w pliku main.js będzie właściwy kod aplikacji), styl css oraz mamy div o id map do wyświetlenia mapy ze szlakiem, input do wprowadzenia urla do pliku gpx oraz przycisk do pokazania szlaku na mapie. Ponadto dodatkowo umieściliśmy button, po kliknięciu którego będziemy pokazywać naszą aktualną pozycję na mapie.
W pliku res/xml/config.xml należy dodać wpis, aby można było łączyć się do pliku gpx z podanej domeny.
<access origin="mapa-turystyczna.pl" />
Teraz czas na napisanie właściwego skryptu javascript (main.js). W aplikacji podajemy adres do pliku gpx w polu tekstowym. Po kliknięciu na button "Show" pokazujemy szlak na mapie. Dodatkowy button służy do pokazania markera z naszą aktualną pozycją na mapie. Cały kod z pliku main.js poniżej.
/*global google,$,window,document*/
document.addEventListener("deviceready", onDeviceReady, false);
function onDeviceReady() {
	var lat = 52.229676, lon = 21.012229, rozmiar = new google.maps.Size(34,47), 
	punkt_startowy = new google.maps.Point(0,0), 
	punkt_zaczepienia = new google.maps.Point(17,47),
	map,mapOptions,icon1,icon2;
	var markers_array = [];
	mapOptions = {
		center: new google.maps.LatLng(lat, lon),
		zoom: 3,
		mapTypeId: google.maps.MapTypeId.TERRAIN
	};
	map = new google.maps.Map(document.getElementById("map"), mapOptions);

	function addMarker(lat,lon) {
			var marker = new google.maps.Marker({
			position: new google.maps.LatLng(lat, lon)
		});
		markers_array.push(marker);
		marker.setMap(map);
		map.panTo(marker.getPosition());
	}
	
	$('#my_pos').click(function() {
		if (navigator.geolocation) {
	        navigator.geolocation.getCurrentPosition(showPosition, onError, {maximumAge: 300000, timeout:10000, enableHighAccuracy : true});
	    } else {
	        alert("Geolocation is not supported by this browser.");
	    }
	});
	function showPosition(position) {
		clearOverlays();
		addMarker(position.coords.latitude,position.coords.longitude);
	}
	function onError(error) {
        alert('code: '    + error.code    + '\n' +
              'message: ' + error.message + '\n');
    }

	$('#show_trail').click(function() {
		$.ajax({
			type: "GET",
			url: $('#gpx_url').val(),
			dataType: "xml",
			crossDomain: true,
			success: function(xml) {
				var points = [];
				var bounds = new google.maps.LatLngBounds();
				$(xml).find("trkpt").each(function() {
					var lat = $(this).attr("lat");
					var lon = $(this).attr("lon");
					var p = new google.maps.LatLng(lat, lon);
					points.push(p);
					bounds.extend(p);
				});

				var poly = new google.maps.Polyline({
					// use your own style here
					path: points,
					strokeColor: "#FF00AA",
					strokeOpacity: .7,
					strokeWeight: 4
				});

				poly.setMap(map);
				// fit bounds to track
				map.fitBounds(bounds);
			}
		});
	});

	function clearOverlays() {
	  for (var i = 0; i < markers_array.length; i++ ) {
		  markers_array[i].setMap(null);
	  }
	  markers_array.length = 0;
	}
}
Cały kod uruchamiamy gdy urządzenie jest gotowe (deviceready). Na początku generujemy mapę wycentrowaną w dowolnym startowym punkcie. Za wyświetlenie szlaku na mapie odpowiada kod.
$('#show_trail').click(function() {
	$.ajax({
		type: "GET",
		url: $('#gpx_url').val(),
		dataType: "xml",
		crossDomain: true,
		success: function(xml) {
			var points = [];
			var bounds = new google.maps.LatLngBounds();
			$(xml).find("trkpt").each(function() {
				var lat = $(this).attr("lat");
				var lon = $(this).attr("lon");
				var p = new google.maps.LatLng(lat, lon);
				points.push(p);
				bounds.extend(p);
			});

			var poly = new google.maps.Polyline({
				// use your own style here
				path: points,
				strokeColor: "#FF00AA",
				strokeOpacity: .7,
				strokeWeight: 4
			});

			poly.setMap(map);
			// fit bounds to track
			map.fitBounds(bounds);
		}
	});
});
Pobieramy ajaxem dane z adresu podanego w polu tekstowym, a następnie budujemy odpowiednią polilinię. Poza wyświetleniem szlaku na mapie kod zawiera również następującą funkcjonalność wykorzystującą geolokalizację. Po kliknięciu w odpowiedni przycisk na mapie pokazuje się marker z naszą aktualną pozycją (funkcja addMarker).
Jeśli chcesz dowiedzieć się więcej na temat Phonegap i Androida polecam zapoznanie się z ebookiem Phonegap dla Androida od podstaw.

Komentarze 1

manx

04.02.2015 10:47

Witam:). Trafiłem na tą stronę podczas szukania informacji na temat phonegap i zastanawiam się nad ebookiem. Programista ze mnie żaden, zajmuję się projektowaniem stron www, opieram je o system joomla. I mam, pytanie. Czy za pomocą phonegap można napisać aplikację, która by wyświetlała daną stronę www? Czyli defacto byłaby to zwykła przeglądarka, ale bez okna do wpisywania adresu. Po prostu aplikacja miałaby wyświetlać tylko jeden adres www :)

Dodaj komentarz