Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/vhosts/cadetill.com/domains/cadetill.com/public_html/wp-content/plugins/qtranslate-x/qtranslate_frontend.php on line 497

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/vhosts/cadetill.com/domains/cadetill.com/public_html/wp-content/themes/suffusion/functions/media.php on line 666

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/vhosts/cadetill.com/domains/cadetill.com/public_html/wp-content/themes/suffusion/functions/media.php on line 671

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/vhosts/cadetill.com/domains/cadetill.com/public_html/wp-content/themes/suffusion/functions/media.php on line 684

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/vhosts/cadetill.com/domains/cadetill.com/public_html/wp-content/themes/suffusion/functions/media.php on line 689

Warning: "continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in /var/www/vhosts/cadetill.com/domains/cadetill.com/public_html/wp-content/themes/suffusion/functions/media.php on line 694
delphi – Página 8 – El blog de cadetill
ago 312010
 

Buenas,

Vimos en un mensaje anterior qué era y cómo obtener las coordenadas geográficas de una determinada dirección mediante la API de GeoCodificación de Google Maps. También vimos que la API podía devolver el resultado en dos formatos diferentes, JSON y XML. Me he decidido a explicar el JSON dado que es lo recomendado por Google. Para quien no sepa qué es el JSON, les recomiendo una visita a su web o en la wiki.

La estructura JSON

Cuando realizamos una búsqueda, ésta puede contener una dirección exacta de lo que buscamos (ej: Plaza de España, 5, Barcelona, España) o bien una parte de la misma (Ej: Plaza de España, 5). Como bien nos podemos imaginar, de «Plaza de España» hay muchas, por lo que la API de Google Maps nos devolverá todas las coincidencias que encuentre hasta un máximo de 10 (esta cantidad no la he visto reflejada en la documentación de Google Maps pero por las pruebas que he realizado parece que es así, no obstante, ésto no quiere decir que no salga dicha cantidad en la documentación).

Así pues, la estructura JSON devuelta por el API tendrá una parte común a todos los resultados (el estado de la consulta) y un array que contendrá todos los resultados.

Ésta sería una estructura base para 1 resultado de la llamada a la API:

{
  "status": "OK",
  "results": [ {
    "types": [ "street_address" ],
    "formatted_address": "Plaça d'Espanya, 5, 08014 Barcelona, Spain",
    "address_components": [ {
      "long_name": "5",
      "short_name": "5",
      "types": [ "street_number" ]
    }, {
      "long_name": "Plaça d'Espanya",
      "short_name": "Plaça d'Espanya",
      "types": [ "route" ]
    }, {
      "long_name": "Barcelona",
      "short_name": "Barcelona",
      "types": [ "locality", "political" ]
    }, {
      "long_name": "Barcelona",
      "short_name": "B",
      "types": [ "administrative_area_level_2", "political" ]
    }, {
      "long_name": "Catalonia",
      "short_name": "CT",
      "types": [ "administrative_area_level_1", "political" ]
    }, {
      "long_name": "Spain",
      "short_name": "ES",
      "types": [ "country", "political" ]
    }, {
      "long_name": "08014",
      "short_name": "08014",
      "types": [ "postal_code" ]
    } ],
    "geometry": {
      "location": {
        "lat": 41.3749536,
        "lng": 2.1485485
      },
      "location_type": "RANGE_INTERPOLATED",
      "viewport": {
        "southwest": {
          "lat": 41.3718069,
          "lng": 2.1454125
        },
        "northeast": {
          "lat": 41.3781022,
          "lng": 2.1517078
        }
      },
      "bounds": {
        "southwest": {
          "lat": 41.3749536,
          "lng": 2.1485485
        },
        "northeast": {
          "lat": 41.3749555,
          "lng": 2.1485718
        }
      }
    }
  } ]
}

Veamos cada una de las partes de este resultado:

  • status: estado de la consulta. Hay varios estados, ver la API para consultarlos. A nosotros nos interesa el estado «OK» devuelto cuando la consulta se realiza correctamente y sin errores.
  • results: array con los resultados devueltos por el API. Si no hay resultados a mostrar, devolverá un array vacío.
    • types: array con uno o más tags indicando el tipo de resultado. Ver en el API los diferentes tipos posibles.
    • formatted_address: dirección en formato «legible» devuelta por el API de Google Maps
    • address_components: array que contiene de forma desglosada el contenido de formatted_address. Éste suele tener la siguiente información:
      • types: array con el tipo de componente
      • long_name: todo el texto descriptivo del componente
      • short_name: abreviatura del componente si existiera.
    • geometry: lista con datos de localización
      • location: lista que contiene las coordenadas geográficas
        • lat: latitud
        • lng: longitud
      • location_type: información extra sobre la localización. Ver en el API los diferentes valores.
      • viewport: lista que contiene la ventana recomendada para la visualización del resultado.
        • southwest: lista con las coordenadas suroeste de la ventana.
          • lat: latitud
          • lng: longitud
        • northeast: lista con las coordenada noreste de la ventana.
          • lat: latitud
          • lng: longitud
      • bounds: (opcional) lista con la ventana que contiene la totalidad del resultado. Destacar que no tiene porque coincidir con el viewport.
        • southwest: lista con las coordenadas suroeste de la ventana.
          • lat: latitud
          • lng: longitud
        • northeast: lista con las coordenada noreste de la ventana.
          • lat: latitud
          • lng: longitud
    • partial_match: indica la exactitud del resultado devuelto. Aunque la documentación del API de Google Maps no lo marca como opcional, en las pruebas que he realizado no siempre ha devuelto este parámetro.

Continuará…

Nos leemos

ago 312010
 

Buenas,

Pasando el rato por internet, yendo de página en página para pasar el rato, me topé con el blog de un viejo conocido, Neftalí. En él vi que, en cuatro muy buenos mensajes, explicaba cómo se consultaba y mostraba en un programa Delphi información de Google Maps.

La verdad es que me gustó mucho el tema y nunca se me hubiera pasado por la cabeza el usar Google Maps en una aplicación Delphi. Desde aquí le doy las gracias por abrirme los ojos, jejeje

Interesado en el tema, empecé a investigarlo y me di cuenta que lo explicado por Neftalí (y otras webs consultadas) nos mostraban el uso de la v2 de la API de Google Maps la cual, actualmente está marcada en desuso. Así que decidí dedicar algo de tiempo a actualizar estas demos encontradas a la nueva versión de la API, la v3.

La GeoCodificación

Como la propia web del API de Google Maps dice, «la GeoCodificación es el proceso de convertir una dirección (como «1600 Amphitheatre Parkway, Mountain View, CA») en coordenadas geográficas (como latitud 37.423021 y longitud -122.083739), que pueden usarse para poner marcas o posiciones en el mapa«.

Aunque podemos encontrar toda la documentación sobre la API de GeoCodificación aquí y su uso no sea demasiado complejo, vamos a explicar cómo funciona.

La idea es sencilla: se realiza una llamada a una determinada URL con una serie de parámetros y Google Maps nos devuelve un resultado formateado como le hayamos indicado.

Aquí tenemos la primera diferencia entre la V2 y la V3. En la primera, el formato devuelto era un parámetro más de la llamada y tenía 4 formatos posibles. En cambio, en la V3 el formato no es una parámetro y sólo tiene dos posibles salidas, o JSON o XML.

La url a la que se tiene que realizar la llamada es la siguiente:
http://maps.google.com/maps/api/geocode/output?parameters

Donde output define el formato de salida pudiendo ser json o xml quedando url como estas:
http://maps.google.com/maps/api/geocode/json?parameters
http://maps.google.com/maps/api/geocode/xml?parameters

Y los parámetros son los siguientes:

  • address o latlng: obligatorio. Es la dirección que queremos GeoCodificar (no puede contener espacios, hay que sustituirlos por un «+») o bien las coordenadas geográficas directamente. Ej: ?address=1600+Amphitheatre+Parkway,+Mountain+View,+CA
  • sensor: obligatorio. Indica si el dispositivo desde el que se hace la petición dispone de sensor de localización. Ej: &sensor=false
  • language: opcional. Determina el idioma de salida. Si no se indica, se intentará usar el idioma del dominio que realiza la petición (si es posible), sino se tomará el inglés. Ej: &language=es. Lista de idiomas soportados.
  • region: opcional. Código de la región en formato ccTLD (country code top-level domain). La mayoría de códigos ccTLD corresponden a los códigos ISO 3166-1, aunque hay exepciones. Ej: &region=es
  • bounds: opcional. Especifica una zona geográfica en la que buscar de forma preferida. Se realiza mediante la definición de un cuadro especificando sus lados noreste y suroeste separados por la barra vertical (|). Ej: &bounds=34.172684,-118.604794|34.236144,-118.500938

Una vez explicada la teoría, el implementar ésto en Delphi no resulta complicado. Bastará con tener un TEdit donde introducir la dirección a buscar, un TButton donde pondremos el código de la llamada, un TIdHTTP con el que realizar la petición web y un TMemo en el que mostrar el resultado obtenido. El código del TButton debería de ser algo así:

const
  CHAR_SPACE = ' ';
  CHAR_PLUS = '+';
  STR_WEB = 'http://maps.google.com/maps/api/geocode/json?address=';
  STR_SENSOR = '&sensor=false';
  STR_REGION = '&region=es';
var
  Str: string;
  Stream: TStringStream;
begin
  Stream := TStringStream.Create('');
  try
    // sustituimos blancos por signo +
    Str := AnsiReplaceStr(Edit1.Text, CHAR_SPACE, CHAR_PLUS);
    // generamos url con parámetros
    Str := STR_WEB + Str + STR_SENSOR + STR_REGION;
    // hacemos petición a la API de Google
    IdHTTP.Get(Str, Stream);
    // pasamos de UTF8 a string
    Memo1.Lines.Text := UTF8ToString(Stream.DataString);
  finally
    if Assigned(Stream) then FreeAndNil(Stream);
  end;
end;

No olvidemos de incluir en la cláusula uses la unit StrUtils.

Continuará……

Nos leemos