Recupero delle coordinate geografiche in una pagina WEB
E' possibile ottenere le coordinate geografiche, in javascript, utilizzando le API di geolocalizzazione(http://dev.w3.org/geo/api/spec-source.html).
Le coordinate possono essere recuperate dal disposito host se questo ha un GPS integrato, oppure possono essere dedotte dall'indirizzo IP o dalla cella GSM.
L'oggetto navigator.geolocation si occupa del recupero delle informazioni geografiche dal dispositivo host.
Nell'esempio che segue viene chiamata la funziona getCurrentPosition a cui vengono passate callback in caso successo e quella in caso di errore,
Nel caso di successo il parametro position contiene le informazioni di latitudine e longitudine.
if (navigator.geolocation != null) {
navigator.geolocation.getCurrentPosition(foundLocation, noLocation);
}
else {
noLocation();
}
function foundLocation(position) {
var lat = position.coords.latitude;
var lng = position.coords.longitude;
SetCoordinate(lat, lng);
//..
}
function SetCoordinate(lat, lng) {
$('.coord-latitude').val(lat);
$('.coord-longitude').val(lng);
}
function noLocation() {
//..
}
Ottenute le coordinate si possono effettuare delle operazioni di ricerca geolocalizzate, ad esempio trovare il negozio più vicino in quel momento.
Se si hanno a disposizione un elenco di indirizzi da geolocalizzare si vogliono ottenere le coordinate si può leggere il mio post precedente:
http://www.devland.it/cs/blogs/alessio-vecchi/archive/2009/11/16/geolocalizzazione-con-google-HTTP-service.aspx
Ottenute le coordinate dal dispositivo si può fare una chiamata POST a un WebService, che per comodità ho messo nel code behind della pagina, che restituisce la lista dei negozi ordinate per distanza decrescente.
function StartSearch() {
var lat = $('.coord-latitude').val();
var lng = $('.coord-longitude').val();
$.ajax({
type: "POST",
url: "/index.aspx/SearchStore",
data: "{'lat': " + lat + ", 'lng':" + lng + " }",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(stores) {
ApplyTemplate(stores);
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus + ' ' + errorThrown);
}
});
}
Se la chiamata ha successo viene fatta una callback alla funzione ApplyTemplate:
function ApplyTemplate(stores) {
//alert(stores.d);
$('#results').setTemplateURL('template/stores-result.html');
$('#results').processTemplate(stores);
}
che utilizza il motore jTemplate per renderizzare i dati che ci vengono restituiti in formato json.
Il file template stores-result.html è una listing semplicissimo:
{#foreach $T.d as store}
<div class="store-item">
<p>(#{$T.store.store.ID}) - {$T.store.store.Name}</p>
<p>{$T.store.store.Address}</p>
<p>{#if $T.store.distance<1 }
{($T.store.distance*1000).toFixed(0)} metri
{#else} {$T.store.distance.toFixed(0)} km {#/if}</p>
</div>
{#/for}
Ecco invece il codice della pagina e il code behind:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="index.aspx.cs" Inherits="index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="http://maps.google.com/maps/api/js?sensor=false" type="text/javascript"></script>
<script src="script/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="script/jquery-jtemplates.js" type="text/javascript"></script>
<script src="index.js" type="text/javascript"></script>
<style type="text/css">
.address
{
width:400px;
}
.store-item
{
background-color:#f0f0f0;
width:400px;
border-bottom:1px solid gray;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div class="content">
Cerca lo store più vicino a te:<br />
<div id="div-searching">
ricerca in corso...
</div>
<br />
<asp:TextBox ID="tbAddress" runat="server" CssClass="address" />
<input type="text" id="tbLatitude" class="coord-latitude" runat="server" />
<input type="text" id="tbLongitude" class="coord-longitude" runat="server" />
<asp:HyperLink ID="hlSearch" runat="server" NavigateUrl="#" Text="cerca"
CssClass="but-cerca search-button" />
</div>
<div id="results">
</div>
</form>
</body>
</html>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Services;
using System.Collections;
using System.Xml;
using System.Xml.Linq;
using System.Globalization;
public partial class index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
Draw();
}
private void Draw()
{
tbAddress.Text = "";
}
private const double RAD = 57.295779513082323;
private static double Distance(double lat1, double lng1, double lat2, double lng2)
{
var a = Math.Sin(lat1 / RAD) * Math.Sin(lat2 / RAD);
var b = Math.Cos(lat1 / RAD) * Math.Cos(lat2 / RAD) * Math.Cos((lng2 - lng1) / RAD);
var distance = 6377.830272 * Math.Acos(a + b);
return distance;
}
[WebMethod()]
public static IEnumerable SearchStore(double lat, double lng)
{
return Store.Stores.
OrderBy(s => Distance(s.Latitude, s.Longitude, lat, lng)).
Select(s => new { store = s, distance = Distance(s.Latitude, s.Longitude, lat, lng) });
}
}