Inicio > Código, Delphi, Ejemplos > (Google Maps – API) Codificación Geográfica – II

(Google Maps – API) Codificación Geográfica – II

Continuando con la entrada (Google Maps – API) Codificación Geográfica – I, vamos a ver cómo obtener más datos de este servicio de Google Maps.

Si habéis revisado el ejemplo sencillo que vimos en la primera entrada, os habréis fijado que hay un parámetro al final de la dirección del que no hemos hablado. Se trata del formato de salida para los datos. Los formatos que acepta el API de Google Maps son los siguientes:

  • XML: Formato extendido en XML/KLM.
  • KLM: Formato extendido en KL; Se diferencia del anterior en los tipos MIME.
  • JSON: La salida de este formato se guarda en formato de objeto JSON (Javascript Object Notation).
  • CSV: Formato comprimido separado por comas (el que se utilizó en el ejemplo).

Para utilizar un formato diferente, basta con añadir al final de la línea de petición el formato deseado:

&output=csv    &output=klm     &output=xml     &output=json

Retomando el tema inicial, vamos a utilizar uno de los formatos extendidos para obtener más información de una dirección dada, además de las coordenadas de Latitud y Longitud.
Si realizamos una petición HTTP utilizando el formato json obtenemos una respuesta como esta por parte del servidor:

{
  "name": "Barcelona,spain",
  "Status": {
    "code": 200,
    "request": "geocode"
  },
  "Placemark": [ {
    "id": "p1",
    "address": "Barcelona, España",
    "AddressDetails":
       {"Country":
        {"CountryNameCode": "ES","CountryName": "España","AdministrativeArea":
          {"AdministrativeAreaName": "CT","SubAdministrativeArea":
            {"SubAdministrativeAreaName": "Barcelona","Locality":
              {"LocalityName": "Barcelona"}}}},"Accuracy": 4},
    "ExtendedData": {
      "LatLonBox": {
        "north": 41.4682658,
        "south": 41.3199988,
        "east": 2.2261223,
        "west": 2.0524766
      }
    },
    "Point": {
      "coordinates": [ 2.1699187, 41.3879170, 0 ]
    }
  } ]
}

Utilizando un sencillo «parser» con este resultado podemos extraer la información para poder utilizarla en nuestros programas.

El ejempo que se ve en la imagen puede descargarse desde aquí.

He creado además una clase derivada de TThread que permite acceder a la imagen. Me ha parecido que en futuros usos me va a ser más útil así, aunque realmente todavía no la he probado en un entorno «multithread».

TThreadGeoCode = class(TThread)
  private
    FDireccion: string;
    FAllText: TStrings;
    FGeoStatusCode: Integer;
    FGeoAddress: string;
    FGeoCountryCode: string;
    FGeoCountryName: string;
    FGeoAdminArea: string;
    FGeoAddressLine: string;
    FGeoLocalityName: string;
    FGeoPostalCode: string;
    FGeoAccuracy: integer;
    FGeoLatitud: string;
    FGeoLongitud: string;

    procedure _ExtractResult();
    function _StatusCodeToStr(ACode:Integer):string;
    function _AccuracyToStr(ACode:integer):string;
  protected
    procedure Execute; override;
  public
    destructor Destroy; override;
    constructor Create(ADireccion:string;
                       ThreadPriority:TThreadPriority=tpNormal);

    // Direccion a buscar
    property Direccion:string read FDireccion write FDireccion;
    // Salida
    property AllText:TStrings read FAllText write FAllText;
    // propiedades de posición
    property GeoStatusCode:Integer read FGeoStatusCode write FGeoStatusCode;
    property GeoAddress:string read FGeoAddress write FGeoAddress;
    property GeoCountryName:string read FGeoCountryName write FGeoCountryName;
    property GeoCountryCode:string read FGeoCountryCode write FGeoCountryCode;
    property GeoAdminArea:string read FGeoAdminArea write FGeoAdminArea;
    property GeoAddressLine:string read FGeoAddressLine write FGeoAddressLine;
    property GeoLocalityName:string read FGeoLocalityName
       write FGeoLocalityName;
    property GeoPostalCode:string read FGeoPostalCode write FGeoPostalCode;
    property GeoAccuracy:integer read FGeoAccuracy write FGeoAccuracy;
    property GeoLatitud:string read FGeoLatitud write FGeoLatitud;
    property GeoLongitud:string read FGeoLongitud write FGeoLongitud;

  published

  end;

Y aun podemos extraer más, ya que si la dirección es ambigua (pero correcta), google puede devolver más de un resultado. De esta forma, con una dirección tipo:

Obtendremos por parte de Google la lista de direcciones correcta que pueden corresponder a esta calle. Cada una de ellas presenta la estructura mostrada anteriormente variando el identificador (id):

  "Placemark": [ {
    "id": "p1",
...
    "id": "p2",
...

Sucesivamente para las distintas direcciones correctas y posibles para esa combinación: Alava, Burgos, Ciudad Real, Cuenca,…

A partir de aquí, no costaría mucho para modificar el ejemplo anterior de forma que se puedan extraer y mostrar los datos, no sólo de la primera dirección, sino de todas las devueltas en la petición.

Hasta aquí estos dos artículos (I y II), que sirven a modo de introducción y prefacio del próximo que estoy preparando.

Está claro, que la idea final y el objetivo que persigo es poder integrar en un programa Delphi las características de Google Maps. El problema actual es, que en nuestras Base de Datos/programas normalmente no tenemos codificadas nuestras direcciones con Latitud/Longitud, así aque para llegar a nueastro objetivo antes tenemos que conseguir estos dos parámetros. Ahí es donde nos és útil el concepto de «Codificación geográfica».

Una vez que tenemos Latitud y Longitud para nuestra dirección, ya podemos avanzar un paso más…

5/5 - (1 voto)
  1. Scott Cannon
    martes, 11 de agosto de 2009 a las 22:37 | #1

    I was using the GeoCoding examples that you posted on Torry.net and I have a question about the text that is returned for STR_Address when you put in Tokyo Japan. The returned data is Ansi but looks like this «T\U014Dky\U014D Metropolis, Japan» for T?ky? Metropolis Japan. I want the data to be coverted to Tokyo Metropolis, Japan. Do you know how I would go about converting the Unicode Escape chartater?

  2. wesbrrantes
    jueves, 22 de octubre de 2009 a las 17:35 | #2

    me tira error en la linea de codigo:
    Self.AllText.Text := Stream.DataString;

    y se pega el programa, no he podido revisar a profundidad el programa pues se pega y no permite el debugger…

    otra pregunta…
    estoy trabajando en la oficina y existen muchos puertos cerrados, eso no afecta la conectividad de el programa?

    digo si quisiera revisar el programa, a cuales puertos debo tener acceso desde mi equipo, pues imagino que eso debe afectar…

  3. Neftalí
    viernes, 23 de octubre de 2009 a las 11:26 | #3

    @wesbrrantes
    Hola wesbrrantes.
    El error tiene pinta de que estás trabajando con una versión diferente de las Indy a al que tengo yo.
    En mi caso he utilizado Delphi6 y Indy 10.

    En cuanto a la otra pregunta, el acesso se hace como si lo hicieras directamente a la página web, así que si desde tu ordenador tienes acceso a internet y a las páginas de Google Maps, no debería haber problemas para que el programa accediera también.

    Un saludo.

  4. viernes, 9 de abril de 2010 a las 23:57 | #4

    muy buena pagina,
    he estado leyendo el articulo y mi pregunta es si tambien se puede capturar las coordenadas de las esquinas,
    en el ejmplo he visto que aparece: «ExtendedData»:

    es posible obtenerlo con: getSouthWest() y getNorthEast() ???

  1. Sin trackbacks aún.