sep 022010
 

Buenas,

Una vez visto cómo funcionan nuestras clases, ha llegado el momento de mostrar la información en un mapa.

Si le damos un vistazo al tutorial del API de JavaScript de Google Maps nos podemos dar cuenta que es muy sencillo el mostrar un mapa con los datos que queramos mostrar. Vasta con montar una pequeña página web, que ésta ejecute un script y mostrarla en un TWebBrowser.

La página web

Lo primero es ver y comprender qué hace esta sencilla página web que, incluso para gente que no está familiarizada con la programación web, llega a entenderlo fácilmente. Para todo el que quiera verla, les remito a dicho tutorial.

La parte qué realmente nos interesa es el JavaScript que hay. Lo primero es  incluir el API de Google mediante la línea

<script type="text/javascript"
   src="http://maps.google.com/maps/api/js?sensor=false"></script>

Recordad lo que explicamos en un artículo anterior sobre el parámetro sensor.

Y ahora se crea una función que será llamada en el evento OnLoad del tag body la cual realizará los siguientes pasos.

  • Crear un objeto para almacenar las coodenadas (latlng).
  • Crear un objeto de tipo map options que contenga todas las características del mapa
  • Crear un objeto “mapa” con los parámetros de dónde se mostrará y qué características tendrá

El resultado, éste:

<script type="text/javascript">
  function initialize() {
    var latlng = new google.maps.LatLng(-34.397, 150.644);
    var myOptions = {
      zoom: 8,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(document.getElementById("map_canvas"),
        myOptions);
  }

</script>

A nivel de características del mapa, decir que puede especificarse el zoom (zoom), la longitud y latitud en la que debe centrarse (center) y el tipo de mapa que se quiere visualizar (mapTypeId) que puede ser:

  • ROADMAP: mapa normal 2D
  • SATELLITE: muestra las fotografías de satélite
  • HYBRID: mixto entre ROADMAP y SATELLITE
  • TERRAIN: relieve físico del terreno

Esta es otra deferencia con la versión 2 del API. En la v2 existe una visión del mapa por defecto. En esta versión hay que especificarla. Si quieres saber más acerca de los tipos de mapa, te recomiendo una visita a Google Map Javascript API V3 – Map Types.

Ahora que se ha entendido lo que hace el código de la página, llega el momento de mostrarlo en nuestra aplicación Delphi. Lo primero que tendremos que decidir es dónde almacenaremos esta web, si en un archivo en disco y cargarlo en ejecución, si en un archivo de recursos o bien en una constante en el mismo código (o alguna otra manera que no se me ocurre ahora, jejeje). La del archivo físico en disco yo la descartaría de entrada por el simple motivo de que puede ser borrada por error, no copiada si se cambia de carpeta el contenido,….. Vamos, que es más fácil perder el archivo que otra cosa.

Y entre archivo de recursos o constante, pues ya depende de la manera en que nos guste programar. Si nos gusta un código más limpio, sin duda en un archivo de recursos. Pero si queremos poder ver en todo momento todo lo que afecta al programa y queremos tener un código algo más sencillo (no es que sea complicado usar un fichero de recursos), sin duda en una constante dentro del código. En este ejemplo, lo haremos mediante una constante (a la que llamaremos MAPA_CODE) en el código Delphi.

El objeto TWebBrowser

Para cargar nuestro mapa en el objeto TWebBroser dependerá de cómo lo hayamos guardado. Si lo hemos guardado como un archivo en disco, bastará con hacer una llamada al método Navigate pasándole como parámetro la ruta exacta de dónde se encuentra dicho fichero.

Y si lo que hemos hecho es almacenarlo en un fichero de recursos o en una constante, el proceder será algo diferente. La idea es conseguir tener un TStringStream que contenga el código fuente de la página web. Dado que nosotros almacenamos la página en una constante, bastará con crear una variable de éste tipo pasándole como parámetro la constante.

var
  StringStream: TStringStream;
begin
  StringStream := TStringStream.Create(MAPA_CODE);

Luego tenemos que asegurarnos que el objeto Document del TWebBrowser tiene “algo”. Para ello basta con hacer una llamada a Navigate con la típica página de inicio.

    if not Assigned(wbWeb.Document) then wbWeb.Navigate('about:blank');

Ahora ya nos encontramos en la disposición de poder cargar nuestra página almacenada en el TStringStream. Para ello tenemos que coger la interfaz IPersistStreamInit del objeto Document, borrar el documento actual mediante una llamada al método InitNew del IPersistStreamInit, crear un objeto IStream con los datos del TStringStream y cargar este objeto IStream en el documento mediante el método Load del objeto IPersistStreamInit. Todo esto que parece una comida de olla, se resume en esta función:

procedure CargaWeb;
var
  StringStream: TStringStream;
  PersistStreamInit: IPersistStreamInit;
  StreamAdapter: IStream;
begin
  // creación del TStringStream con el string que contiene la página web
  StringStream := TStringStream.Create(MAPA_CODE);
  try
    // nos aseguramos de tener algún contenido en Document
    if not Assigned(wbWeb.Document) then wbWeb.Navigate('about:blank');

    // acceder a la interfaz IPersistStreamInit de Document
    if wbWeb.Document.QueryInterface(IPersistStreamInit, PersistStreamInit) = S_OK then
    begin
      // borrar datos actuales
      if PersistStreamInit.InitNew = S_OK then
      begin
        // creación y inicialización del IStream
        StreamAdapter:= TStreamAdapter.Create(StringStream);
        try
          Screen.Cursor := crHourGlass;
          // carga de la página web mediante IPersistStreamInit
          PersistStreamInit.Load(StreamAdapter);
        finally
          Screen.Cursor := crDefault;
        end;
      end;
    end;
  finally
    StringStream.Free;
  end;
end;

Si en el OnShow de un formulario hiciéramos una llamada a esta función, veríamos que en nuestro TWebBrowser se visualiza el mapa de Google en las coordenadas que trae por defecto (las que contiene nuestra constante).

Pero ésto no es lo que nosotros queremos. Lo que queremos es poder posicionar el mapa en un punto determinado y, ésto ya será parte del siguiente artículo.

Continuará….

Nos leemos

  13 Responses to “Jugando con la API de Google Maps (V) – mi primer mapa”

  1. Ahora me sale un error en

    IPersistStreamInit

    es porque tengo delphi 7 verdad??’

    que hago

    mejor me consigo delphi 2010

    con que version de delphi estan estos ejemplo?

    Gracias

    de nuevo

  2. dejando los ejemplos

    al agregar a un formulario un gmmap en delphi 7 y correr el programa me marca

    [Error] File not found: ‘UAboutFrm.dfm’

    a que se debe esto?

  3. Encontre que no me instalo algunas dcu como por ejemplo gmbase

    en delphi 7

    porque puede haber pasado esto?
    Gracias

  4. 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); // el error es aqui ya que uso delphi 7
    finally
    if Assigned(Stream) then FreeAndNil(Stream);
    end;
    end;

  5. hola buenas tardes, primero que nada una felicitación tienes muy buen contenido el de esta pagina de verdad me ha ayudado.
    solo tengo una pregunta ¿y si se quiere buscar por latitud y longitud? he intentado ejecutar el script del maps (MakeMarker) y por alguna razón no pinta el marcador

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)