Devland

from developers to developers
Welcome to Devland Sign in | Join | Help
in Search

Alessio Vecchi blog

Utilizzo delle Geolocation API per calcolare le distanze

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) });
    }

}

 

Comments

No Comments

Leave a Comment

(required) 
(optional)
(required) 
Submit
Powered by Community Server (Commercial Edition), by Telligent Systems