Hola de nuevo.
En esta entrega vamos a ver como acceder al servicio de geoposicionamiento de Google Geocoding.
Tal y como indica en las especificaciones de Geocoding, se puede acceder de dos formas diferentes. Una usando XML y otra usando JSON.
La primera seria invocando la dirección directamente a la URL http://maps.google.com/maps/api/geocode/xml?address=Puerta+del+sol,1+Madrid+Spain®ion=sp&sensor=false.
En este caso, nos devuelve la lista de posibles direcciones, junto a cada una de sus posiciones geográficas.
Menudo chorizo!!
Pero, como podemos usar la opción de JSON, vamos a creare un WCF para recuperar este resultado.
Así, que lo primero que necesitamos crear es un DataContract para almacenar los resultados.
Si ejecutamos la sentencia anterior, sustituyendo XML por JSON, te puedes hacer una idea de como tiene que ser nuestro interface.
En esta entrega vamos a ver como acceder al servicio de geoposicionamiento de Google Geocoding.
Tal y como indica en las especificaciones de Geocoding, se puede acceder de dos formas diferentes. Una usando XML y otra usando JSON.
La primera seria invocando la dirección directamente a la URL http://maps.google.com/maps/api/geocode/xml?address=Puerta+del+sol,1+Madrid+Spain®ion=sp&sensor=false.
En este caso, nos devuelve la lista de posibles direcciones, junto a cada una de sus posiciones geográficas.
<GeocodeResponse>
<status>OK</status>
<result>
<type>street_address</type>
<formatted_address>Callede Peña del Sol, 1, 28034 Madrid, España</formatted_address>
<address_component>
<long_name>1</long_name>
<short_name>1</short_name>
<type>street_number</type>
</address_component>
<address_component>
<long_name>Calle dePeña del Sol</long_name>
<short_name>Calle dePeña del Sol</short_name>
<type>route</type>
</address_component>
<address_component>
<long_name>Madrid</long_name>
<short_name>Madrid</short_name>
<type>locality</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Madrid</long_name>
<short_name>M</short_name>
<type>administrative_area_level_2</type>
<type>political</type>
</address_component>
<address_component>
<long_name>Comunidadde Madrid</long_name>
<short_name>Comunidadde Madrid</short_name>
<type>administrative_area_level_1</type>
<type>political</type>
</address_component>
<address_component>
<long_name>España</long_name>
<short_name>ES</short_name>
<type>country</type>
<type>political</type>
</address_component>
<address_component>
<long_name>28034</long_name>
<short_name>28034</short_name>
<type>postal_code</type>
</address_component>
<geometry>
<location>
<lat>40.4884395</lat>
<lng>-3.7027410</lng>
</location>
<location_type>RANGE_INTERPOLATED</location_type>
<viewport>
<southwest>
<lat>40.4874340</lat>
<lng>-3.7043715</lng>
</southwest>
<northeast>
<lat>40.4901319</lat>
<lng>-3.7016736</lng>
</northeast>
</viewport>
<bounds>
<southwest>
<lat>40.4883964</lat>
<lng>-3.7034958</lng>
</southwest>
<northeast>
<lat>40.4891695</lat>
<lng>-3.7025493</lng>
</northeast>
</bounds>
</geometry>
<partial_match>true</partial_match>
</result>
</GeocodeResponse>
Menudo chorizo!!
Pero, como podemos usar la opción de JSON, vamos a creare un WCF para recuperar este resultado.
Así, que lo primero que necesitamos crear es un DataContract para almacenar los resultados.
Si ejecutamos la sentencia anterior, sustituyendo XML por JSON, te puedes hacer una idea de como tiene que ser nuestro interface.
[DataContract]
public class GeoResponse
{
[DataMember(Name= "status")]
public string Status { get; set; }
[DataMember(Name= "results")]
public CResult[] Results { get;set; }
[DataContract]
public class CResult
{
[DataMember(Name= "formatted_address")]
publicstring formatted_address { get; set; }
[DataMember(Name= "address_components")]
publicGeocodeAddressComponent[] AddressComponents{ get; set; }
[DataContract]
publicclass GeocodeAddressComponent
{
[DataMember(Name= "long_name")]
publicstring LongName { get;set; }
[DataMember(Name= "short_name")]
publicstring ShortName { get;set; }
[DataMember(Name= "types")]
publicstring[] Type { get;set; }
}
[DataMember(Name= "geometry")]
publicCGeometry Geometry { get; set; }
[DataContract]
publicclass CGeometry
{
[DataMember(Name= "location")]
publicCLocation Location { get; set; }
[DataContract]
publicclass CLocation
{
[DataMember(Name= "lat")]
publicdouble Latitude { get;set; }
[DataMember(Name= "lng")]
publicdouble Longitude { get;set; }
}
}
}
}
Ahora, definimos la función que usaremos para llamar al Geocoding.
[OperationContract]
GeoResponseCallGeoWS(string address);
Ahora, a crear la clase que implementa este interface.
public class Geocoding : IGeocoding
{
public GeoResponse CallGeoWS(stringaddress)
{
{
stringurl = string.Format(
"http://maps.google.com/maps/api/geocode/json?address={0}®ion=sp&sensor=false",
HttpUtility.UrlEncode(address)
);
varrequest = (HttpWebRequest)HttpWebRequest.Create(url);
request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip,deflate");
request.AutomaticDecompression= DecompressionMethods.GZip | DecompressionMethods.Deflate;
DataContractJsonSerializerserializer = new DataContractJsonSerializer(typeof(GeoResponse));
varres = (GeoResponse)serializer.ReadObject(request.GetResponse().GetResponseStream());
return res;
}
}
}
Como veréis, la URL usada es la de Geocode, este nos devolverá el bloque en ZIP y lo descomprimimos automáticamente, a la par que hacemos la deseralización del resultado usando el contract que hemos creado antes.
Como ves, es muy sencillo.
Solo a tener en cuenta una cosa.. La librería de JSON la puedes encontrar en C:\Program Files\Reference Assemblies\Microsoft\Framework\v3.0\System.Runtime.Serialization.dll
Bueno... y después de todo esto, ¿Qué se puede hacer
Pues vamos a usarlo para mostrar información de direcciones y mostrarlo en un mapa de Google Maps.
En este caso, vamos a utilizar la opción de mapas staticos de Google.
http://maps.google.com/maps/api/staticmap?center=latitud,longitud
Geocoding.Geocodinggc = new Geocoding.Geocoding();
GeoResponse gr;
String address = "Paseodel Prado,1,Madrid,Spain";
GeoResponse geocodingResponse = gc.CallGeoWS(address);
Nos devuelve un objeto del tipo GeoResponse, que vamos a recorrer para montar un ListView.
listViewResult.Items.Clear();
foreach(GeoResponse.CResultresult in _geocodingResponse.Results)
{
ListViewItem lv = new ListViewItem(result.formatted_address,0);
lv.SubItems.Add(Coordenates_ToString(Functions.Convert2DegressMinutesSeconds(result.Geometry.Location.Longitude,true)));
lv.SubItems.Add(Coordenates_ToString(Functions.Convert2DegressMinutesSeconds(result.Geometry.Location.Latitude)));
listViewResult.Items.Add(lv);
}
Como habrás notado, estoy usando la función de conversión de Grados Minutos y segundos que se ha comentado anteriormente, para mostrar la posición geográfica en unidades de GPS.
La función Coordenates_ToString es para formatear nuestras coordenadas.
privateString Coordenates_ToString(Functions.Coordenatescoordenates)
{
return(coordenates.Geo + " " +coordenates.Degress.ToString() + "º "+
coordenates.Minutes.ToString() + "' " +
coordenates.Seconds.ToString() + "'' ");
}
Si quieres ver todo esto en funcionamiento, descárgate el código y el TestHarness para probarlo.
Comentarios
Publicar un comentario
Si quieres comentar, criticar, aportar mas informacion o simplemente felicitar, inserta tu comentario a continuacion. Entre todos podemos hacer cosas grandes.