29 de Julio de 2014
Feb
18

.NET Tutorial 52. Geolocalización por dirección IP

Categorías: 

Alguno de vosotros me ha preguntado como desde el generador de firmas se obtenía la procedencia de una visita:

Como es de suponer la "geolocalización" de la visita se realiza mediante la dirección IP. En el caso anterior, la firma fué generada desde una visita procedente de Cagua, Venezuela

Para obtener datos de la localización uso una API que proporciona esta página: http://smart-ip.net/geoip

Esta página puede proporcionar información de la geolocalización ya bien sea un fichero XML o JSON
Se puede consultar documentación sobre esta API aquí: http://smart-ip.net/geoip-api

Como .NET dispone de una clase para manejar estructuras XML de forma muy sencilla, usaremos la opción XML en lugar de la opción JSON.

Según la documentación, se devuelve un fichero XML si se pasa la siguiente URL:

smart-ip.net/geoip-xml/direccion_ip/auto?lang=en

Tal y como se puede ver en esta captura de Firefox:


(Haz click para agrandar)

Sin embargo, eso no "parece" un fichero XML. Lo que ocurre es que Firefox interpreta el código y lo muestra como la imagen anterior. Si vemos el código fuente de la página (botón derecho sobre la página y pulsar en Ver código fuente) observamos esto:


(Haz click para agrandar)

Aquí si que vemos que efectivamente, si que se trata de un fichero XML

La lectura de ficheros XML desde .NET es tremendamente sencilla. Tendremos que agregar el siguiente NameSpace:

Imports System.Xml

La lectura se realiza más o menos así:

Dim reader As XmlTextReader = New XmlTextReader("http://smart-ip.net/geoip-xml/" & DireccionIP & "/auto?lang=en")
Dim type As XmlNodeType

reader.WhitespaceHandling = WhitespaceHandling.Significant

While reader.Read
type = reader.NodeType
  If type = XmlNodeType.Element Then

    Select Case reader.Name
      Case "countryName"
        reader.Read()
        mcountryName = reader.Value
      Case "countryCode"
        reader.Read()
        mcountryCode = reader.Value
        ...
        ...
    End Select

  End If
End While

En el código veréis que todo esto lo realiza la clase IPInfo, donde en el constructor de la clase se le pasa la dirección IP que se quiere examinar.
La clase dispone de unas propiedades de solo lectura que indican el país, el código del país estandar en dos letras, el nombre de la ciudad, la region, la latitud y la longitud

De tal forma que la llamada a dicha clase sería algo como esto:

Try
  Dim myIPinfo As New IPinfo("18.122.119.183")

  Debug.Print(myIPInfo.CountryName)
  Debug.Print(myIPInfo.CountryCode)
  Debug.Print(myIPInfo.CountryRegion)
  Debug.Print(myIPInfo.City)
  Debug.Print(myIPInfo.Latitude)
  Debug.Print(myIPInfo.Longitude)
Catch ex As Exception
  MessageBox.Show(ex.Message, "Error")
End Try

Como veís es realmente simple de usar. El resultado sería algo como esto:

Nota: el "icono" de la bandera se consigue buscando la bandera con el nombre myIPInfo.CountryCode  y con extensión gif dentro de la carpeta Flags\
Así por ejemplo si el myIPInfo.CountryCode es igual a "us" se busca este archivo : Flags\us.gif
Fácil, rápido y para todos los públicos :)

 

Bonus track: Liándola parda o como mostrar la localización en un mapa real

Aprovechando que la API de smart-ip nos proporcina la latitud y la longitud...que coño, vamos a mostrar en un mapa la ubicación de dichas coordenadas :)

Para ello vamos a utilizar una técnica que ya vimos en el Tutorial 12 En el Tutorial 12 vimos como usar un servicio web para realizar una aplicación que usaba el traductor de Bing para realizar una aplicación muy simple que permitía traducir un texto a varios idiomas.

Pues bien, aquí se realizará algo parecido, por no decir prácticamente lo mismo. Se usará un servicio de Bing Maps para realizar esta representación en un mapa.

Lo primero que hay que realizar es obtener una "clave" para poder usar el servicio de Bing Maps desde nuestro código.

Para ello deberémos ir a https://www.bingmapsportal.com  
Al logear con nuestro Live ID accederemos a esta pantalla:


(Haz click para agrandar)

Para crear nuevas "keys" usaremos la opción del menú de la izquierda

Una vez que tengamos nuestra key procederemos de la siguiente forma:

En nuestro proyecto agregaremos una referencia de servicio: 


(Haz click para agrandar)

Existen 4 referencias para trabajar con Bing Maps, tal y como se comenta en http://msdn.microsoft.com/en-us/library/dd221354.aspx

En este ejemplo solo se usará la referencia del servicio "ImageryService" cuya dirección tal y como indica la página anterior es:

http://dev.virtualearth.net/webservices/v1/imageryservice/im ageryservice.svc?wsdl

Pues bien, pondremos dicha dirección en "Agregar referencia de servicio" y pulsaremos el botón Ir:


(Haz click para agrandar)

Una vez cargada la referencia veremos los métodos disponibles


(Haz click para agrandar)

En mi caso he cambiado el espacio de nombres a BingMapsImageService tal y como puede verse en la imagen

Una vez acepta la referencia observamos esto en nuestro explorador de soluciones:

Pues bien, ahora solo nos queda hacer esto en nuestro código

Imports Tutorial52.BingMapsImageryService

De este modo  tendremos acceso a los datos del servicio de Bing Maps en nuestro código

Sólo dos apuntes finales:

1) El ejemplo que hay en http://msdn.microsoft.com/en-us/library/dd221354.aspx está basado para una aplicación WPF. Observaréis que este tutorial sigue siendo una aplicación de Windows Forms, en lugar de WPF. 

Se cambiado el método BitmatImage del ejemplo por un MemoryStream tal y como veréis en el código

2) En el mismo ejemplo de la MSDN esto no es correcto (sí, aunque parezca mentira los tios de la MSDN tambien la cagan):

Dim imageryService As New ImageryServiceClient()

debería ser:

Dim imageryService As New ImageryServiceClient("BasicHttpBinding_IImageryService")

3) De nuevo en el ejemplo de la MSDN, la conversión de la latitud y longitud en el método GetImagery no es correcto, aunque esto creo que tiene que ver con la configuración regional del equipo.
En mi caso, hay que pasar como caracter decimal la coma, no el punto, ya que este valor:
40.452 la rutina GetImagery la transforma a 40452, que es un valor incorrecto para la latitud o longitud

Bueno, despues de estas correcciones en el ejemplo de la MSDN obtenemos algo tal que así:   


(Haz click para agrandar)

Se puede cambiar el nivel de Zoom y el tipo de mapa:
(los tipos de mapa del estilo "birdeye" no me han funcionado)


(Haz click para agrandar)


 

Tags: geolocation, geolocalización, ip location, ip geolocation, get ip address location, bing maps, gps

 

Saludos.
mov eax,ollydbg; Int 13h    

 

Descargar proyecto .NET Tutorial 52
(170 KB. Visual Studio 2008 Professional)
(requiere Bing Maps key)

 

5
Valoración media: 5 (3 votos)

2 Comentarios:

Thank you for sharing this

Thank you for sharing this Ollydbg, great job! If your pleasure, I was added a link to your article at examples block of Smart-IP.net Geo-IP API Documentation page. I'd like also to translate this to Russian and publish at my blog, if you accept this. Please, let me know. Best regards, Mike

Hi Mike First i wanted to

Hi Mike
First i wanted to thank you for your great geo-API
It would be an honor for me if you translate this post into Russian in your personal blog

Даже я не могу поверить, я посещений матушки-России :)

Flipándolo me hayo como este payo traducirá liándola parda al idioma de Tolstói :D

Saludos.
mov eax,ollydbg; Int 13h