Archivo para Marzo, 2009

Obtener la latitud y longitud de una dirección con Google Maps y C#

20 de Marzo de 2009

Cuando trabajamos con Google Maps usamos las latitudes y longitudes para definir los puntos, el centro del mapa, etc… Si no conocemos esos datos, pero sí la dirección de la ubicación, podemos “geolocalizar“, es decir obtener las coordenadas con el objecto “geocoder“.

Para poder obtener las coordenadas directamente vía C# y no geolocalizar con javascript usaremos el objeto de C# WebRequest y WebResponse para obtener directamente desde Google los datos que necesitamos y poder tratarlos en nuestra aplicación.

La idea es hacer las petiticiones a la URL de geolocalización de Google que es la siguiente: http://maps.google.com/maps/geo?q=Direccion

A esta url, se le deben especificar los siguientes parámetros:

q -> es la dirección que queremos geolocalizar
output -> es como queremos obtener la información del servicio. Puede ser xml, kml, csv o json
key -> nuestra key de la api de google.

En resumidas cuentas, nos queda una URL así, vamos a usar el formato CSV, así que lo especifico ya en el ejemplo:

http://maps.google.com/maps/geo?q=Mataro&output=csv&key=MI-KEY-API

La url anterior debería mostrar en nuestros navegadores algo así:

200,4,41.5375002,2.4452776

Esos son los datos que necesitamos, una tira de valores separados por comas para poder trabajar con ellos.

El primer valor es el código de respuesta de la petición. Existen diferentes códigos en función de si todo ha ido bien, si se ha producido un error o si simplemente, la dirección no se puede encontrar. Aquí hay una tabla que relaciona estos códigos:

  • 200: No se han producido errores, la dirección se analizó correctamente y se devolvió su código geográfico.
  • 400: No se ha podido analizar correctamente la solicitud de ruta
  • 500: No se ha podido procesar correctamente la solicitud de ruta o de códigos geográficos, sin saberse el motivo exacto del fallo.
  • 601: Falta el parámetro HTTP q o no tiene valor alguno. En las solicitudes de códigos geográficos, esto significa que se ha especificado una dirección vacía. En las solicitudes de ruta, esto significa que no se ha especificado ninguna consulta.
  • 602: No se ha encontrado una ubicación geográfica que se corresponda con la dirección especificada. Esto puede deberse a que la dirección sea relativamente nueva o a que no sea correcta.
  • 603: El código geográfico de la dirección indicada o de la ruta para la consulta de ruta proporcionada no puede devolverse por motivos jurídicos o contractuales.
  • 604: El objeto GDirections no pudo calcular la ruta entre los puntos mencionados en la consulta. Esto suele deberse a que no hay ninguna ruta disponible entre los dos puntos o a que no tenemos datos para extraer rutas en la región en cuestión.
  • 610: La clave proporcionada no es válida o no coincide con el dominio para el cual se ha indicado
  • 620: La clave proporcionada ha sobrepasado el límite de solicitudes en un período de 24 horas.

El segundo grupo, es el 4 en el ejemplo, nos indica la precisión del resultado, de nuevo, hay una tabla para relacionar todo esto:

  • 0 Ubicación desconocida.
  • 1 Precisión a nivel de país.
  • 2 Precisión a nivel de región (estado, provincia, prefectura, etc.). 3 Precisión a nivel de subregión (condado, municipalidad, etc.).
  • 4 Precisión a nivel de ciudad o pueblo.
  • 5 Precisión a nivel de código postal.
  • 6 Precisión a nivel de calle.
  • 7 Precisión a nivel de intersección.
  • 8 Precisión a nivel de dirección.

Y por último, los 2 restantes valores, lo que realmente queremos saber, la latitud y la longitud.

Ahora solo nos queda hacer que nuestra aplicación recoja esos valores con un par de funciones simples:

string constructuirGeoURL(string direccion){
	string geoURL = "";

	if(direccion != ""){
		direccion = direccion.Trim();
		direccion = direccion.Replace(" ", "+");

		geoURL = @"http://maps.google.com/maps/geo?
                q=###ADDRESS###&output=###OUTPUT###&key=###KEY###";

		//Sustitución de las variables
		geoURL = geoURL.Replace("###ADDRESS###", direccion);
		geoURL = geoURL.Replace("###OUTPUT###","csv");
		geoURL = geoURL.Replace("###KEY###", ApiGoogle);
	}

return geoURL;
}

Con la función construirGeoURL(), vamos ha obtener la URL que después vamos a usar en la función cargarLatitudLatitud() que nos va a dar la latitud, longitud y el código de respuesta de la petición.

 void cargarLatitudLatitud(string geoURL){
   string csvValues = "";
   string Latitud = "";
   string Longitud = "";
   string Respuesta_geo = "";
	try
	{
	 WebRequest objWebRequest = WebRequest.Create(geoURL);
	 WebResponse objWebResponse = objWebRequest.GetResponse();
	 Stream objWebStream = objWebResponse.GetResponseStream();

         using (StreamReader objStreamReader = new StreamReader(objWebStream))
	 {
	  csvValues = objStreamReader.ReadToEnd();
	 }

	if (csvValues != null)
	{
	 string[] geoValues = csvValues.Split(new char[] { ',' });
	 if (geoValues.Length > 0)
	  {
	   Respuesta_geo = geoValues[0].ToString();
	   Latitud = geoValues[2].ToString();
	   Longitud = geoValues[3].ToString();
	  }
	}

        }
	catch (Exception exp){
	 Response.Write(exp.Message);
	}
}

Para poder usar la función cargarLatitudLatitud(), hay que importar los espacios de nombres siguientes:

<%@ import Namespace="System.Net" %>
<%@ import Namespace="System.IO" %>

Como podéis ver, el uso del objecto WebRequest y WebResponse es sencillo y nos permite trabajar con el servicio de Google Maps para geolocalizar directamente desde nuestras aplicaciones C#.

¿Se os ocurre alguna forma de aprovechar otra característica de Google Maps sobre C#?

.NET Framework 1.1 y Windows Vista

13 de Marzo de 2009

Windows Vista viene preparado para dar soporte a las aplicaciones que utilizan .NET Framework 2.0 y el novedoso .NET Framework 3.0, pero los chicos de Microsoft no dan soporte para las abundantes aplicaciones .NET Framework 1.1 tales como VS.NET 2003, InstallShield 11.5 y muchas otras.

Para poder instalar el Framework 1.1 bajo Vista, es necesario obtener el dotnet.exe desde Microsoft: http://download.microsoft.com/download/a/a/c/aac39226-8825-44ce-90e3-bf8203e74006/dotnetfx.exe

Cuando ejecutamos una aplicacion basada en .NET Framework 1.1 bajo Windows Vista, automáticamente el sistema nos propone obtener dicho Framework, pero en nuestro caso no funcionó correctamente y tuvimos que echar mano del ejecutable anterior.

Una vez instalado y después de reiniciar el equipo, la aplicación basada en .NET Framework 1.1 debería volver a funcionar correctamente.

Carga Google Analytics y Google Maps asincronamente

13 de Marzo de 2009

Seguramente tanto Google Analytics cómo Google Maps sean usadas por muchas de las aplicaciones Web de hoy en día.

Precisamente estas dos aplicaciones pueden provocar, en muchas situaciones, retrasos en los tiempos de carga o lo que es peor, que no se cargue el contenido de forma correcta.

Google Analytics

Analytics es el gestor de estadísticas gratuito de Google, es usado por muchísimos sitios Web y quizás debido a eso, se suele producir un retraso en la carga de la página, para evitar este retraso simplemente hay que dejarle la carga al evento onload del navegador. Con jQuery esto se traduce así:

  $(document).ready(function(){
      $.getScript('http://www.google-analytics.com/ga.js',function(){
         if (typeof(_gat) == 'object'){
            var pageTracker = _gat._getTracker('UA-XXXXXXX-Y');
            pageTracker._initData();
            pageTracker._trackPageview();
         }
      });
   });

Pero si no estamos usando jQuery podemos usar la función como addLoadEvent() que nos permite añadir funcionalidades al evento onload con compatibilidad en todos los navegadores, sería algo así:

addLoadEvent(function(){
 // Insertamos el Código que Google Analytics
 var analyticsCode = 'UA-XXXXXXX-Y';
 var s = document.createElement("script");
 s.type = "text/javascript";
 s.src = "http://www.google-analytics.com/ga.js";
 s.onload = s.onreadystatechange = function() {
	if (typeof _gat  == 'object'){
            var pageTracker = _gat._getTracker(analyticsCode);
            pageTracker._initData();
            pageTracker._trackPageView();
         }
 }
 document.getElementsByTagName("head")[0].appendChild(s);
});

En ambos casos se debe reemplazar (UA-XXXXXXX-Y) por el código que Google Analytics nos asigna.

Google Maps

La mayor y posiblemente mejor aplicación de mapas de Internet y de dónde la gran mayoría de sitios Web obtienen la información sobre mapas, es sin duda la que más problemas produce. Las largas esperas producen, por ejemplo, en Internet Explorer 6 que el tiempo de carga de las imágenes nos desesperen antes de poder visualizarlas….

Para solucionar el problema basándonos en una solución sobre jQuery podemos usar:

function cargarMapa(){
   if (GBrowserIsCompatible()) {
      var map = new GMap2(document.getElementById("MAPA"));
      map.setCenter(new GLatLng(39.578678,2.646021), 16);
   }
};
$(document).ready(function(){
   var api='AQUI TU GOOGLE MAPS API KEY';
   $.getScript('http://maps.google.com/maps?file=api
&amp;v=2.x&amp;key='+api+'&amp;async=2&amp;callback=cargarMapa');
});

Si se prefiere, también podemos usar el ya conocido addLoadEvent()

addLoadEvent(function(){
	var api='AQUI TU GOOGLE MAPS API KEY';
	function cargarMapa(){
	   if (GBrowserIsCompatible()) {
	      var map = new GMap2(document.getElementById("MAPA"));
	      map.setCenter(new GLatLng(39.578678,2.646021), 16);
	   }
	};
	var s = document.createElement("script");
	s.type = "text/javascript";
	s.src = 'http://maps.google.com/maps?file=api
        &amp;v=2.x&amp;key='+api+'&amp;async=2&amp;callback=cargarMapa';

         document.getElementsByTagName("head")[0].appendChild(s);
})

Fuente: anieto2k

¿Habéis tenido problemas antes con los tiempos de carga usando estos servicios de Google en vuestras aplicaciones Web?