lunedì 30 novembre 2009

Visualizzazione markers su una Yahoo! Map

Complichiamo solo leggermente il codice presente nel post precedente per consentire la visualizzazione di due markers sui quali viene associata la visualizzazione di un testo se vi ci si clicca sopra.
Il marker viene visualizzato attraverso il metodo map.addOverlay(); ad esso viene associato l' l'evento MouseClick al cui verificarsi verrà elaborata la funzione openSmartWindow.

Segue la parte di codice che gestisce il tutto e naturalmente, potrete vedere il risultato cliccando qui.

// Crea il primo marker
var marker1 = new YMarker("Viale Italia, 40, la spezia, italia");
// Stringa da visualizzare cliccando sul primo marker
var contenuto1 = "

Qui ho abitato dalla nascita al 1990

";
// Apre una finestra al verificarsi dell'evento 'click' sul marker
YEvent.Capture(marker1, EventsList.MouseClick,
function() {
marker1.openSmartWindow(contenuto1);
});
// Visualizza il marker
map.addOverlay(marker1);

// Crea il secondo marker
var marker2 = new YMarker("Via pontegrande 120, la spezia, italia");
// Stringa da visualizzare cliccando sul secondo marker
var contenuto2 = "

Qui ho vissuto dal 1990 al 2000

";
// Apre una finestra al verificarsi dell'evento 'click' sul marker
YEvent.Capture(marker2, EventsList.MouseClick,
function() {
marker2.openSmartWindow(contenuto2);
});
// Visualizza il marker
map.addOverlay(marker2);


Per semplicità mi sono limitato a ripetere per ogni marker i passi necessari alla loro visualizzazione. Volendo ricercare una soluzione più raffinata, avremmo potuto includere i dati da visualizzare in un array e visualizzare il tutto tramite un ciclo iterativo. Ma questo potrebbe essere oggetto di un ulteriore post.
Alla prossima.

giovedì 26 novembre 2009

Introduzione alle Yahoo! Maps

Sempre stimolato da digitaladoptive, unico antidoto contro la cronica mancanza di tempo necessaria per riempire di contenuti questo blog, stavolta voglio introdurre ai neofiti del mashup le API di Yahoo! Maps.
Per chi ha avuto la pazienza di leggere i miei post riguardanti le API di Google Maps, si accorgerà che i metodi e le sintassi sono molto molto simili.
Il semplice obiettivo di questo post è di inserire una Yahoo! Map, centrata in un particolare punto del globo terracqueo, in una pagina web.
Per iniziare a lavorare, abbiamo bisogno di un account Yahoo! su quale chiedere una chiave ("application id"). Almeno nelle prime fasi, non avremo bisogno di uno spazio web: a differenza delle API di Google Maps, le API di Yahoo! Maps lavorano anche in locale, cioè sul proprio PC (purchè collegato alla Rete, evidentemente)

Per chiedere la chiave, come si diceva, è necessario avere un account Yahoo! e andare alla seguente pagina

Si presenterà la seguente schermata dove inserire alcuni dati:



Alcune delucidazioni:

1. Il Vostro account Yahoo! apparirà di default
2. Selezionate "Generic"
3. Potete inserire qualunque cosa
4. Potete inserire qualunque cosa
5. Non è un campo obbligatorio ma, a vostra futura memoria, suggerisco di inserire l'indirizzo della pagina web dove inserirete la mappa
6. Inserite la vostra e-mail
7. Inserite una breve descrizione

Il resto non consideratelo.

Nella pagina che segue otterrete una stringa di caratteri che copierete nel codice qui in basso dove indicato.



Il codice è diffusamente commentato, non dovreste avere problemi di comprensione (ma sono qui a vostra disposizione!)


<head>
<script type="text/javascript" src="http://api.maps.yahoo.com/ajaxymap?v=3.0&appid= INSERITE_QUI_LA_YAHOO_ID_RICHIESTA_SUL_SITO"></script>

<!-- Definizione struttura pagina: messa la mappa di dimensioni 550x450 px //-->

<style type="text/css">
#spaziomappa {
width: 550px;
height: 450px;
align: center;}
</style>

</head>

<body>
<div id="spaziomappa" align="center"></div>
<script type="text/javascript">

// centra la mappa alle coordinate indicate (lat, long)
var lat = 44.063889;
var long = 9.883333;

// definizione coppia di coordinate che identificano il Golfo della Spezia
var punto = new YGeoPoint(lat, long);
var livellozoom = 7

// Definisce l'oggetto map che caricherà una mappa nell'elemento "spaziomappa" della pagina web
var map = new YMap(document.getElementById('spaziomappa'));

// Aggiunge la barra di controllo che consente tre tipi di visualizzazione:
// cartina (REG), satellite (SAT) e ibrida (HYB)
map.addTypeControl();

// Aggiunge il controllo per lo zoom
map.addZoomLong();

// Imposta il tipo di mappa, in questo caso ibrida; per altri tipi di visualizzazione
// Si può usare SAT (satellite) o REG (cartina)
map.setMapType(YAHOO_MAP_HYB);

// Mostra la mappa centrata alle coordinate definite dalla variabile 'punto'al
// livello 7 di zoom
map.drawZoomAndCenter(punto, livellozoom);

</script>
</body>

Il risultato lo potete trovare qui.
Nelle prossime puntate cercheremo di fare qualcosa di più, per adesso mi limito a suggerirvi i links alla documentazione ufficiale di Yahoo! Maps API (inglese):

martedì 28 aprile 2009

La febbre suina vista da Google Maps, API e mashups

Riprendo a scrivere su questo blog, fermo da un po', non per scopi didattici ma per documentare i preziosi contributi che Google Maps e API possono avere nella nostra vita quotidiana.
La triste vicenda è quella della febbre suina. Diversi ricercatori hanno scelto di creare mappe dove geolocalizzare i casi di febbre suina dando un quadro della diffusione del virus. Ecco i principale esempi:

Google Map di Niman (Biomedical Research Pittsburgh, USA)

Mibazaar
Interessante mashup tra Google Maps e Twitter: sulla mappa vengono visualizzati in tempo reale i tweets le cui keywords riguardano la febbre suina

Mapa de Influenza

2009 Swine Flu (H1N1) Outbreak Map

Human swine flu map
Mashup tra Google Maps e The Guardian

Segnalo infine il Google Doc Swine flu case by case.

mercoledì 11 febbraio 2009

Geocoding, ovvero come ottenere coordinate geografiche da un indirizzo

In attesa di tornare a parlare di API, prendo spunto da una domanda fatta da un utente di questo blog e che suppongo possa essere utile a molti di voi. Abbiamo visto come visualizzare su una Google Map una serie di indirizzi e relative coordinate, caricati direttamente sul database MySQL o importati da un file con estensione .CSV (di fatto da qualsiasi foglio eletttonico tramite opportuna trasformazione).
Può capitare di avere una serie di indirizzi ma non le relative coordinate geografiche. Esiste allora la possibilità di elaborare automaticamente una lista di indirizzi aggiungendo le coordinate di cui abbiamo bisogno?
Una delle soluzioni ci viene offerta da questo servizio che utilizza le Yahoo Maps.

Come si procede per la nostra attività di geocoding? E' molto semplice

1. Scaricate sul vostro PC il template excel (Step #1)
2. Compilate il template coi dati in vostro possesso (non è necessario valorizzare tutti i campi)
3. Copiate e incollate nell'apposito riquadro (Step #2)
4. Cliccate sul tasto "Validate" (Step #3)
5. Cliccate sul tasto "Run geocode" (Step #5)
6. Apparirà una "nuova" lista (Step #6), comprensiva di coordinate, pronta da copiare (basterà cliccare col tasto destro del mouse, selezionare tutto e copiare negli appunti)
7. Incollate la selezione su Excel o Open Office.

Dopo questa semplicissima procedura, potrete salvare il vostro file in formato csv ed essere importato nella tabella MySQL, per poi continuare il nostro lavoro come come abbiamo visto in questo articolo.

Questa è una delle soluzioni già pronte, in realtà potremmo crearci una applicazione personale che utilizzi il Servizio Geocoding delle Google Maps API. Si fà cioè una request al servizio (in formato REST) e la risposta può avvenire in formato JSON, KML, XML e anche CSV. Il discorso però è abbastanza complesso e, forse, potrebbe essere oggetto di un apposito post.
La cosa da sottolineare assolutamente è che non si può utilizzare il servizio per qualcosa che sia diverso dal mostrare i risultati su una Google Map.

sabato 31 gennaio 2009

Caricare markers da un database con MySQL e PHP (seconda parte)

Con quanto svolto nel precedente articolo abbiamo di fatto concluso il nostro lavoro. Si tratterà infatti di includere in una pagina html il codice che legga il file XML prodotto dallo script PHP e valorizzi i parametri dei vari metodi javascript per la visualizzazione.
Nell'esempio viene utilizzato il metodo statico


GEvent.addListener
(marker, 'mouseover', function() {marker.openInfoWindowHtml(html)});


che attiva la visualizzazione, al passaggio del mouse, di una finestra di dialogo di una stringa (variabile html) contenente denominazione e descrizione del marker

Non credo ci siano ulteriori commenti da fare se non dare una occhiata al codice. Il risultato del progetto lo potete trovare qui.



<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Visualizzazione markers su Google Map tramite MySQL e PHP</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=LAVOSTRAAPIKEY"
type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[

function load() {
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(44.0750963, 10.700323), 8);

GDownloadUrl("creaxml.php", function(data) {
var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");
for (var i = 0; i < markers.length; i++) {
var denom = markers[i].getAttribute("denom");
var indirizzo = markers[i].getAttribute("indirizzo");
var tipomarker = markers[i].getAttribute("tipomarker");
var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")),
parseFloat(markers[i].getAttribute("long")));
var marker = createMarker(point, denom, indirizzo, tipomarker);
map.addOverlay(marker);
}
});
}
}

function createMarker(point, denom, indirizzo, tipomarker) {
var marker = new GMarker(point);
var html = "("+tipomarker+")<br/><b>" + denom + "</b> <br/>" + indirizzo;
GEvent.addListener(marker, 'mouseover', function() {
marker.openInfoWindowHtml(html);
});
return marker;
}
//]]>
</script>
</head>

<body onload="load()" onunload="GUnload()">

</body>
</html>




Volendo raffinare l'applicazione, si potrebbe ad esempio visualizzare un marker di colore diverso per ogni tipologia di punto (nel nostro caso lavoro oppure studio). Il codice relativo non è molto più complicato di quanto abbiamo visto, potete fare rierimento alla già citata guida su Google Code. Oppure ci torneremo in uno dei prossimi articoli.

giovedì 29 gennaio 2009

Caricare markers da un database con MySQL e PHP (prima parte)

Una possibilità davvero interessante è quella di poter visualizzare su una Google Map dei markers le cui coordinate ed altri elementi siano caricati da un database esterno.
Questo ci consente di poter utilizzare insiemi molto grandi di coordinate lasciando sempre inalterato il codice javascript di richiamo della mappa.
In questo articolo non concluderemo il nostro lavoro, ci limiteremo a capire come costruire il nostro database, popolarlo e creare scripts Php per l'interrogazione dei dati e la realizzazione di un output XML. Ci ritroveremo dunque nella stessa situazione del precedente post: un file XML da dare "in pasto" al codice javascript affinchè i markers vengano visualizzati sulla mappa.

Questo post e il successivo fanno ampio riferimento al materiale, opportunamente semplificato e integrato nella parte divulgativa, contenuto nel bellissimo articolo (in inglese) che trovate su Google Code.

Definiamo il progetto da realizzare: una sorta di "curriculum geografico", cioè una Google Map dove vengono visualizzati tutti i luoghi dove ho studiato o lavorato, le cui informazioni sono contenute in un database.

Essendo un progetto didattico, i dati in realtà sono molto pochi. Le potenzialità invece sono infinite, poichè potremmo inserire nel database grandi quantità di dati realizzate da terze parti e, con le opportune conoscenze tecniche, filtrarli nella maniera che più ci interessa.

Di cosa abbiamo bisogno:
1) Uno spazio web con supporto MySQL e PHP
2) Alcuni cenni su come si costruisce un database relazionale
3) Piccole conoscenze di PHP e Javascript


PUNTO 1
Ci sono due possibilità: la prima è quella di registrarsi su Internet ad un servizio di spazio web gratuito con le caratteristiche cui sopra. Vi ho già citato ilbello.com hosting, ma i servizi di questo tipo sono innumerevoli. Una selezione ai altri servizi gratuiti e ad free potete trovarla in questo post.

La seconda possibilità è lavorare in locale, cioè utilizzare il proprio PC come fosse un server web. A questo scopo potete utilizzare pacchetti software come XAMPP o EasyPHP. Per la corretta installazione potete far riferimento ai link in calce all'articolo.

PUNTO 2
Ci affideremo a un database relazionale, strutturato in tabelle (a noi ne serve solo una). Il nostro spazio web, sia esso reale o virtuale, ci consentirà di creare e popolare (inserire dati) un database attraverso il linguaggio di amministrazione PhpMyAdmin.

Per quanto riguarda il servizio ilbello.com si accederà all'interfaccia PhpMyAdmin all'indirizzo http://sql.ilbello.com/, inserendo username e password fornitici al momento della registrazione. Per gli altri servizi, cambierà ovviamente l'indirizzo di accesso ma le modalità saranno identiche.




Per creare e popolare la tabella del database si posono utilizzare diversi metodi:

1) Inserendo ciascun elemento attraverso l'interfaccia di PhpMyAdmin
2) Importando in PhpMyAdmin opportuni files sql come ad esempio questo:


CREATE TABLE `markers`(
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`denom` VARCHAR( 60 ) NOT NULL ,
`indirizzo` VARCHAR( 60 ) NOT NULL ,
`lat` FLOAT( 10, 6 ) NOT NULL ,
`long` FLOAT( 10, 6 ) NOT NULL,
`tipomarker` VARCHAR( 30 ) NOT NULL ,
) ENGINE = MYISAM ;

Cosa dico attraverso questo set di istruzioni?

crea una tabella con 6 campi: il campo id è un indice che si autoincremente; il secondo campo, denom, ha al massimo 60 caratteri; lo stesso dicasi per il campo indirizzo; lat e long sono campi numerici, al massimo di 10 cifre di cui 6 decimali; tipomarker ha al massimo 30 caratteri; MYISAM è il motore di indicizzazione del database.


3) Importando opportuni files in formato CSV (ottenuti da terze parti o dal nostro foglio elettronico).



PUNTO 3
Attingiamo adesso ad alcuni elementi di PHP per accedere ai dati del database ed elaborarli in modo da formare un documento XML. Per motivi di sicurezza si sceglie di creare due script distinti, uno con le credenziali di autenticazione e l'altro che riceve le credenziali, accede al database e forma il documento XML. Ecco i listati dei due file, credenziali.php e creaxml.php. Notate che cliccando su quest'ultimo link non viene visualizzato lo script bensì il suo risultato, cioè il file XML con i dati che visualizzeremo sulla mappa.


<?
//Ovviamente $username, $password e $database conterranno i valori comunicati dal
vostro fornitore del servizio di hosting o scelti a piacere se utilizzate un server
web in locale
$host="localhost";
$username="vostrousername";
$password="vostrapassword";
$database="vostrodatabase";
?>



<?php

// richiede i dati di accesso contenuti in credenziali.php
require("credenziali.php");

//Sostituisce alcuni caratteri speciali con il relativo codice entita'
function parseToXML($htmlStr)
{
$xmlStr=str_replace('<','<',$htmlStr);
$xmlStr=str_replace('>','>',$xmlStr);
$xmlStr=str_replace('"','"',$xmlStr);
$xmlStr=str_replace("'",''',$xmlStr);
$xmlStr=str_replace("&",'&',$xmlStr);
return $xmlStr;
}

// Si connette al database
$connection=mysql_connect (localhost, $username, $password);
if (!$connection) {
die('Non connesso : ' . mysql_error());
}

$db_selected = mysql_select_db($database, $connection);
if (!$db_selected) {
die ('database non selezionato : ' . mysql_error());
}

// Seleziona tutte le righe della tabella con i markers
$query = "SELECT * FROM markers WHERE 1";
$result = mysql_query($query);
if (!$result) {
die('Query invalida: ' . mysql_error());
}

header("Content-type: text/xml");

// Genera il nodo principale del file XML
echo '<markers>';

// Ciclo che crea il resto del documento XML sulla base dei dati della tabella
while ($row = @mysql_fetch_assoc($result)){
// ADD TO XML DOCUMENT NODE
echo '<marker ';
echo 'denom="' . parseToXML($row['denom']) . '" ';
echo 'indirizzo="' . parseToXML($row['indirizzo']) . '" ';
echo 'lat="' . $row['lat'] . '" ';
echo 'long="' . $row['long'] . '" ';
echo 'tipomarker="' . $row['tipomarker'] . '" ';
echo '/>';
}

// Genera il tag di chiusura del nodo principale
echo '</markers>';

?>

Per adesso abbiamo finito, nel prossimo articolo vedremo come integrare il tutto all'interno nella Google Map, utilizzando istruzioni di cui ormai conosciamo il significato.


Linkografia per chi desidera installare un server in locale

Per installare XAMPP
@ Corso Joomla su Second Life (consultare le slide dalla 6 alla 22)
@ Slideshare (consultare le slide dalla 6 alla 22)
@ XAMPP step by step
@ Installare XAMPP su Windows

Per installare Easy PHP
@ Guida PHP su Windows
@ Installare e configurare Php e MySQL

lunedì 19 gennaio 2009

Visualizzare markers contenuti in un file XML

Come anticipato nel post precedente, cominciamo a "raffinare" il procedimento per la visualizzazione sulla nostra mappa di particolari markers.
Il nostro obiettivo è di rendere dinamica la visualizzazione dei markers importandone le coordinate ed altre informazioni da un file esterno alla nostra pagina di visualizzazione della Google Map.
In particolare, i dati che andremo a visualizzare sono stati precedentemente inclusi in un file XML. Non è il luogo adatto per disquisire sull'utilizzo di questo metalinguaggio, ci basti sapere che in un file xml le informazioni sono contenute in particolari elementi detti tags.
Nel nostro esempio il file xml è costituito da un solo tag (marker) con tre attributi, la latitudine (lat), la longitudine (long) e una breve descrizione (descr). Il file si chiama scuole.xml ed è il seguente


<markers>
<marker lat="44.111508" long="9.835831" descriz="Qui ho frequentato le scuole superiori">
<marker lat="44.113902" long="9.834570" descriz="Qui ho frequentato le scuole elementari">
<marker lat="44.113715" long="9.833441" descriz="Qui ho frequentato le scuole medie">
<marker lat="44.111206" long="9.834749" descriz="Qui abitavo molti anni fa">
</markers>



Il vantaggio di questa soluzione diventa evidente nel momento in cui avessimo l'esigenza di aggiungere altri markers. In quel caso, basterebbe inserire i nuovi dati a partire dalla penultima riga, rispettando la medesima sintassi, senza necessità di modificare la pagina web di visualizzazione della mappa.
Per gestire il file XML e "passare" i dati alla nostra pagina web sono però necessari alcuni step:

1. Caricare in memoria il contenuto del file
Per fare ciò, utilizzeremo il metodo

GDownloadUrl("scuole.xml", function(data, responseCode));

Il file scuole.xml viene caricato nella variabile data; in responseCode viene caricato con un codice di elaborazione il cui valore ci permette di capire se ci sono stati problemi nel caricamento (es. un file xml non valido o con errori nei dati) e quindi di gestire la cosa senza che l'elaborazione si interrompa (argomento che tralasciamo per ora per semplicità).

N.B. E' necessario che il documento XML sia contenuto nel medesimo server che ospita il codice javascript e quindi la pagina che richiede la Google Map.

2. Capire il tipo di documento contenuto nel file (XML)
Affinchè il codice javascript "capisca" che il file caricato sia xml viene utilizzato il namespace GXml, che fornisce metodi statici per gestire documenti XML. Il metodo

GXml.parse(data);
infatti, non è altro che un parser XML.

3. Gestire i dati in maniera corretta
I dati vengono caricati sotto forma di stringa mentre le coordinate geografiche devono essere in formato numerico. La funzione

parseFloat()
ha appunto come argomento la stringa corrispondente agli attributi lat e long e produce in uscita un numero in floating point.

Dopo tanto scrivere, passiamo alla visualizzazione del codice, opportunamente commentato per facilitarne la comprensione.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>

<title>Visualizzazione markers da file XML</title>

<script src="http://maps.google.com/maps?file=api&v=2 &key=LAVOSTRAGOOGLEAPIKEY" type="text/javascript">
</script>

<script type="text/javascript">

function initialize() {

if (GBrowserIsCompatible()) {

var map = new GMap2(document.getElementById("map_canvas"));
map.addControl(new GSmallMapControl());
map.addControl(new GMapTypeControl());

//Aggiunge la scala
map.addControl(new GScaleControl());

//Centra la mappa in un punto particolare
map.setCenter(new GLatLng(44.112909 , 9.835415), 16);

GDownloadUrl("scuole.xml", function(data, responseCode) {

var xml = GXml.parse(data);
var markers = xml.documentElement.getElementsByTagName("marker");

for (var i = 0; i < markers.length; i++) {

var punto = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("long")));

var titolo = (markers[i].getAttribute("descriz"));
map.addOverlay(new GMarker(punto, {title: titolo}));

}
});

}

}

</script>

</head>

<body onload="initialize()" onunload="GUnload()">
<div id="map_canvas" style="width: 500px; height: 400px"></div>

</body>
</html>

Il risultato lo potete apprezzare qui.

Una volta capito questo meccanismo, nei prossimi post tenteremo di realizzare una applicazione ancora più raffinata. Invece di movimentare un file XML statico, potremmo infatti crearlo in maniera dinamica, prelevando ad esempio l'elenco delle coordinate e le descrizioni da un database.