Google Maps JavaScript API v3 (assignatura WEC)

De Wikijoan
Dreceres ràpides: navegació, cerca

Contingut

Introducció

Discover what you can do with the Google Maps APIs


API Documentation

Referències

Exemples

Geocoding Service

Es tracta de resoldre un problema real. A partir d'una llista de direccions reals (per exemple, les direccions dels alumnes), es tracta de visualitzar aquestes dades en un mapa. Opcionalment, podem pensar quina és la millor ruta (la ruta òptima) per recórrer tots els punts.

NOTA: en aquest codi no es necessita una key de Google Maps.

Primer de tot ficarem a la base de dades una llista de direccions:

CREATE DATABASE direccions DEFAULT CHARACTER SET utf8;
#USE direccions;

#CREATE USER alumne IDENTIFIED BY 'keiL2lai';
#GRANT ALL ON direccions.* TO alumne@localhost identified by "keiL2lai";
#flush privileges;

drop table direccions;

CREATE TABLE direccions(
direccio varchar(200) not null,
year integer
);

insert into direccions values ('Roger de Flor 254 pral 2 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Rossello 484 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Sicilia 372 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Corcega 546 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Pi i Margall 22 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Corcega 596 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Sardenya 355 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Sardenya 476 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Rossello 423 08025 Barcelona (Barcelona) (España)', 2015);
insert into direccions values ('Rossello 431 08025 Barcelona (Barcelona) (España)', 2015);

insert into direccions values ('C/Nàpols 327 08025 Barcelona (Barcelona) (España)', 2016);
insert into direccions values ('C/Almeria 30 08014 Barcelona (Barcelona) (España)', 2016);
insert into direccions values ('C/Torrent de''n Vidalet 5 08012 (Barcelona) (España)', 2016);
insert into direccions values ('C/Provença 419 08025 Barcelona (Barcelona) (España)', 2016);
insert into direccions values ('C/Navas de Tolosa 348 08027 Barcelona (Barcelona) (España)', 2016);
insert into direccions values ('C/Plaça de la Concòrdia, 2 08120 (Barcelona) (España)', 2016);
insert into direccions values ('C/Granvia 419 08015 Barcelona (Barcelona) (España)', 2016);

insert into direccions values ('C/Mas Eastornell 08389 Palfolls (Barcelona) (España)', 2016);

Farem una llista de direccions dels alumnes. Els alumnes donaran la seva adreça/direcció postal en el format:

Roger de Flor n.254 pral 2ª 08025 Barcelona (Barcelona) (España)

Els fitxers necessaris de l'aplicatiu són:

open_db_adreces_alumnes.php

<?php
$conn = mysqli_connect("localhost", "alumne", "keiL2lai");

if (!$conn) {
    $log->error('Could not connect: ' . mysql_error());
    die('Could not connect: ' . mysql_error());
}

mysqli_select_db($conn, "direccions") or die('Could not select jbalmes database.');
mysqli_set_charset('utf8',$conn);
?>

close_db_adreces_alumnes.php

<?php
mysqli_close($conn);
?>

cercar_adreces_alumnes.php:

<?php
include("open_db_adreces_alumnes.php");

$sql = "select direccio from direccions";

$result=mysqli_query($conn,$sql);

if (!$result) {
    $message  = 'Invalid query: ' . mysqli_error() . "\n";
    die($message);
}

while($row = mysqli_fetch_assoc($result)) {	
	echo utf8_encode($row['direccio']).'<br />';
}

include("close_db_adreces_alumnes.php");
?>

geocoding_service_adreces_alumnes.htm:

<!DOCTYPE html>
<html>
	<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<title>Google Maps JavaScript API v3 Example: Geocoding Simple</title>
	<link href="https://google-developers.appspot.com/maps/documentation/javascript/examples/default.css" rel="stylesheet">

	<script>
		var geocoder;
		var map;
		var adreca = [];
		var adreca_arreglada = [];
		var adreces_diferents = [];;

		function initialize() {
			geocoder = new google.maps.Geocoder();
			var latlng = new google.maps.LatLng(41.404159, 2.159929);
			var mapOptions = {
				zoom: 13,
				center: latlng,
				mapTypeId: google.maps.MapTypeId.ROADMAP
			}
			map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
		}

		function codeAddress_1() {

			var length = adreca_arreglada.length;
			for (var i = 0; i < length; i++) {
				codeAddress_2(adreca_arreglada[i]);
			}
		}

		function codeAddress_2(vaddress) {
			var address = vaddress;
			geocoder.geocode( { 'address': address}, function(results, status) {
			if (status == google.maps.GeocoderStatus.OK) {
				map.setCenter(results[0].geometry.location);

				if (!array_contains(adreces_diferents, results[0].geometry.location)) {
					//és necessari el toString() per tal de què el que es guarda en l'array sigui realment un string i no un objecte de Google Maps!
					adreces_diferents.push(results[0].geometry.location.toString()); 
					//alert(adreces_diferents.length);
					//només afegim el marker si la direcció que ha trobat el servei de geocoding és nova. El problema és que les direccions que no es resolen bé es resolen amb una direcció que es va repetint...
					var marker = new google.maps.Marker({
						map: map,
						position: results[0].geometry.location
					});
				}

			//http://stackoverflow.com/questions/9805529/geocoding-api-over-query-limit
	        } else if (status === google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {    
	            setTimeout(function() {
	                codeAddress_2(vaddress);
	            }, 200);
	        } else {
	            alert("Geocode was not successful for the following reason:" + status + ' ' + vaddress);
	        }

			});
		}

		function cercar_adreces()
		{
			var xmlhttp;
			var txt,x,xx,i;
			if (window.XMLHttpRequest)
			{// code for IE7+, Firefox, Chrome, Opera, Safari
			  xmlhttp=new XMLHttpRequest();
			}
			else
			{// code for IE6, IE5
				xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
			}

			xmlhttp.onreadystatechange=function()
			{
				if (xmlhttp.readyState==4 && xmlhttp.status==200)
				{
					txt=xmlhttp.responseText;
					//alert(txt);
					adreca=txt.split("<br />");
					adreca_arreglada = arreglar_adreces(adreca);
					codeAddress_1();
				}
			}
			xmlhttp.open("GET","cercar_adreces_alumnes.php");
			xmlhttp.send();

		}

		function array_contains(myarray,element) {
			for (var i = 0; i < myarray.length; i++) {
				if (myarray[i] == element) {
					//alert('si');
					return true;
				}
			}
		}

		function arreglar_adreces(adreces) {
			//el problema està en què s'han d'arreglar les adreces que tinc de la bd. 
			//Roger de Flor n.254 pral 2ª 08025 Barcelona (Barcelona) (España)
			//es resol incorrectament. S'ha de convertir a:
			//Roger de Flor 254 08025 Barcelona (Barcelona) (España) 
			var adreces2 = [];
			for (var i = 0; i < adreces.length; i++) {
				adreces2[i] = arreglar_adreca(adreces[i]);
			}
			return adreces2;
		}

		function arreglar_adreca(adreca) {
			var adreca2 = adreca;
			//hem de cercar on està el cp
			var poscp=adreca.indexOf("08"); //suposo que totes les adreces són de la província de Barcelona
			var adreca_temp = adreca.substr(0,poscp-1); 
			var adreca_temp2 = adreca.substr(poscp,adreca.length-1);
			var trobat_numeros = false;
			var trobat_caracter_especial = false;
			var pos_trobat_numeros = 0;
			var pos_trobat_caracter_especial;

			//el criteri per al cas particular de 'Roger de Flor n.254 pral 2ª' i similars és eliminar el 'n.' i, començant pel principi, 
			//buscar on comencen els números (en aquest cas '254') fins a trobar un caràcter especial (de moment: espai blanc, -).
			//aquesta funció és la que s'haurà de retocar en funció del format de les adreces que tingui.
			adreca_temp = adreca_temp.replace('n.','');
			//alert(adreca_temp);
			for (var i = 0; i < adreca_temp.length; i++) {
				//48: 0; ...; 57: 9; 32: espai en bland; 45: -
				if (trobat_numeros==false && (adreca_temp.charCodeAt(i)>=48 && adreca_temp.charCodeAt(i)<=57)) {
					pos_trobat_numeros = i; //trobem números
					trobat_numeros = true;
				}
				if (trobat_numeros == true && trobat_caracter_especial == false && (adreca_temp.charCodeAt(i)==32 || adreca_temp.charCodeAt(i)==45)) {
					pos_trobat_caracter_especial = i;
					trobat_caracter_especial = true;
				}

			}
			adreca_temp = adreca_temp.substr(0,pos_trobat_caracter_especial);
			adreca2 = adreca_temp.concat(" ");
			adreca2 = adreca2.concat(adreca_temp2);
			return adreca2;

		}

		function setCharAt(str,index,chr) {
			 if(index > str.length-1) return str;
			 return str.substr(0,index) + chr + str.substr(index+1);
		}

	</script>
	</head>
	<body>

	<div>
	<input type="button" value="Geocode"  onclick="cercar_adreces()" />
	</div>
	<div id="map-canvas" style="height:90%;top:30px"></div>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=*********&callback=initialize">
    </script>
	</body>
</html>

Dades GPS a Google Maps

Rutes gps.jpg

Avui en dia, amb els smartphones, tothom té a l'abast crear rutes GPS. Per exemple, el professor fa servir l'app Oruxmaps en un telèfon Android. Aquest aplicatiu pot generar fitxers de rutes GPS, que normalment tenen format XML. Un dels formats preferits és el format GPX, que no deixa de ser un fitxer XML.

D'altra banda tenim webs com ara wikiloc.com, http://ca.wikiloc.com/wikiloc/home.do, on podem descarregar i pujar rutes GPS (en format GPX entre d'altres).

Aquest aplicatiu que aquí presentem fa el següent:

No és un projecte especialment difícil, se't facilita el codi per tal de què el provis.

rutes_gps.php (llegeix el contingut de la carpeta rutes_gps/):

<?php

if ($handle = opendir('rutes_gps/')) {

    /* This is the correct way to loop over the directory. */
    while (false !== ($entry = readdir($handle))) {
	//if (strstr($entry, '.gpx')) {
	if (strstr($entry, '.xml')) {
			echo "<p>";
        	//echo "<a href='rutes_gps/$entry'>$entry</a><br />";
			echo "<a href=\"#\" onclick=\"pintar_ruta('rutes_gps/$entry')\">$entry</a><br />";
		//SimpleXML functions are part of the PHP core
		$xml = simplexml_load_file('rutes_gps/'.$entry)
			or die("Error: Cannot create object");
		

		foreach($xml->children() as $child)
			{
				if (!strstr($child->getName(),'trk')) {
				echo $child->getName() . ": " . $child . "<br>";
				}
			}
		echo "</p>";

	}
    }
    closedir($handle);
}
?>

Pots descarregar-te una carpeta amb rutes GPS:

rutes_gps.htm: és la pàgina principal i el punt d'entrada: http://localhost/rutes_gps.htm

<!DOCTYPE html>
<html>
	<head>
	<meta name="viewport" content="initial-scale=1.0, user-scalable=no">
	<meta charset="utf-8">
	<title>Rutes GPS</title>
	<link rel="stylesheet" href="rutes_gps.css" type="text/css" />		


	<script>
	function carregar_rutes() {
		var xmlhttp;
		var txt,x,xx,i;
                xmlhttp=new XMLHttpRequest();

		xmlhttp.onreadystatechange=function() {
			if (xmlhttp.readyState==4 && xmlhttp.status==200) {
				txt=xmlhttp.responseText;
				document.getElementById('rutes').innerHTML=txt;
			}
		}
		xmlhttp.open("GET","rutes_gps.php",true);
		xmlhttp.send();
	}

	function pintar_ruta(url) {
		var xmlhttp;
		var txt,x,xx,i;
		if (window.XMLHttpRequest)
		  {// code for IE7+, Firefox, Chrome, Opera, Safari
		  xmlhttp=new XMLHttpRequest();
		  }
		else
		  {// code for IE6, IE5
		  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
		  }

			xmlhttp.onreadystatechange=function()
			  {
			  if (xmlhttp.readyState==4 && xmlhttp.status==200)
				 {
				 x=xmlhttp.responseXML.documentElement.getElementsByTagName("trkpt");
			  	var coordenades = new Array(x.length);
				var coordenadeslat_min=1000, coordenadeslat_max=0, coordenadeslat_total, coordenadeslat_mig;
				var coordenadeslong_min=1000, coordenadeslong_max=0, coordenadeslong_total, coordenadeslong_mig;

				for (var i = 0; i < x.length; i++) {
					coordenades[i] = new Array(2);
				}
				 for (i=0;i<x.length;i++) {
					//omplim una matriu
					coordenades[i][0] = x[i].attributes[0].value;
					coordenades[i][1] = x[i].attributes[1].value;

					if (coordenadeslat_min > coordenades[i][0]) coordenadeslat_min = coordenades[i][0];
					if (coordenadeslat_max < coordenades[i][0]) coordenadeslat_max = coordenades[i][0];
					if (coordenadeslong_min > coordenades[i][1]) coordenadeslong_min = coordenades[i][1];
					if (coordenadeslong_max < coordenades[i][1]) coordenadeslong_max = coordenades[i][1];
				}

				var bounds = new google.maps.LatLngBounds();
				var latlng = new google.maps.LatLng(coordenadeslat_min, coordenadeslong_min);
				bounds.extend(latlng);
				var latlng = new google.maps.LatLng(coordenadeslat_max, coordenadeslong_max);
				bounds.extend(latlng);

				var myLatLng_puntmig = bounds.getCenter();

				var mapOptions = {
					center: myLatLng_puntmig,
					mapTypeId: google.maps.MapTypeId.HYBRID
				};
				
				var map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
				map.fitBounds(bounds); //ajustem el mapa al contorn de les 4 cantonades, i podem conèixer el zoom.
				//alert(map.getZoom());

				var lineCoordinates = new Array(x.length);
				for (var i = 0; i < x.length; i++) {
					lineCoordinates[i] = new google.maps.LatLng(coordenades[i][0],coordenades[i][1]);
				}

				var line = new google.maps.Polyline({
					path: lineCoordinates,
					map: map
				});

			}
		}

		xmlhttp.open("GET",url,true);
		xmlhttp.send();
	}
	</script>

	</head>
	<body>
	<h1>Rutes GPS</h1>
	<div id="rutes">
	</div>
	<div id="map_canvas">
	Selecciona una ruta
	</div>
    <script async defer
    src="https://maps.googleapis.com/maps/api/js?key=*******&callback=carregar_rutes">
    </script>
	</body>
</html>

rutes_gps.css: un full d'estils adequat (adapta les mides de les capes a la resolució de la teva pantalla)

html, body {
	margin:0;
	padding:0;
}
body{
	color: #fff;
	font-family: "Trebuchet MS", "Lucida Grande", Arial, Helvetica, sans-serif;
	background: #222;
	margin: 0 40px;
	padding: 0;
	font-size: 0.8em;
	position: relative;
	text-align: left;

}

div#rutes
{
	position: absolute;
	top: 60px;
	left: 20px;
	width: 200px;
	padding: 10px;
	margin: 10px;
	font-size: 1em;
	background-color: #333;
}

div#map_canvas
{
	position: absolute;
	top: 60px;
	left: 260px;
	width: 1000px;
	height: 800px;
	padding: 10px;
	margin: 10px;
	background-color: #444;
}

a{
	color: #ff9000;
	text-decoration: none;
}

creat per Joan Quintana Compte, abril 2018

Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
Institut Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines