Inicio > Código, Delphi, Ejemplos, Fácil, Otros, Programación > Google Maps en Delphi – II

Google Maps en Delphi – II

Share Button

En la última entrada acerca de la API de Google Maps, vimos cómo mostrar un Mapa utilizando la API en un programa Delphi, cómo centrarlo en una posición predefinida y utilizando un Zoom predeterminado.

Además como seleccionar entre los diferentes controles que podemos añadir al mapa (Zoom, Vista general, tipo de mapa…).

También cómo colocar una marca en una ubicación y cómo generar una ventana con información asociada a esa marca (NOTA1).

NOTA1: De forma similar se pueden colocar otros elementos sobre el mapa, como:

  • Líneas, polilíneas y polígonos.
  • Marcas con iconos personalizados.
  • Rutas

Una vez visto cómo mostrar el mapa, lo que nos queda es ver cómo podemos, desde nuestro programa Delphi, interactuar con él; Es decir, que el usuario pueda modificar determinadas características del mapa que tiene en pantalla, y nosotros podamos recuperar esos cambios, para utilizarlos en nuestro programa.

Vamos a continuar con el ejemplo visto en las entradas anteriores; Mostraremos al usuario un Mapa ubicado en una determinada posición. El usuario debe poder “reubicar” la vista del mapa y modificar el Zoom con que está visualizando el mapa, y esos son los valores que obtendremos para posteriormente almacenarlos y actualizarlos en nuestro programa.

  • Coordenada de Longitud
  • Coordenada de Latitud
  • Zoom actual del mapa

La forma de conseguirlo, es añadir a la página web el código necesario para capturar eventos que se produzcan en el mapa. Incluiremos controles de edición, donde se almacenan la longitud/latuitud y Zoom, que después recuperaremos desde el programa Delphi.

GEvent.addListener(map, "click", function (overlay,point)
GEvent.addListener(map, "zoomend", function (oldLevel, newLevel)
GEvent.addListener(map, "mousemove", function(latlng)

Aunque uno no esté muy familiarizado con el tema (yo mismo no lo estoy mucho  ;-D ), no hacen falta muchas explicaciones para comprender los eventos; “Capturaremos” en OnClick, OnZoomEnd y OnMouseMove sobre el mapa. Aquí se puede acceder a la lista de eventos, métodos y propiedades de la clase Gmap.

En el caso del evento OnClick, por ejemplo, utilizaremos un código como este:

GEvent.addListener(map, "click", function (overlay,point){
if (point){
document.posicion.x.value=point.x
document.posicion.y.value=point.y
document.posicion.z.value=map.getZoom()
TipoMapa = map.getCurrentMapType().getName()
document.posicion.t.value=TipoMapa
}

Obtenemos información del punto actual (utilizando un parámetro) y el Zoom actual y el tipo de Mapa utilizando métodos de la clase GMap. Todos ellos se almacenan (como hemos comentado antes) en componentes de tipo Text, que nos sirven como “paso intermedio” para luego capturar esos valores de la página Web desde nuestro programa.

Como resultado final, os dejo el ejemplo que se adjunta con esta entrada. En él he incluído/integrado la parte de Geocodificación (visto en las entradas I y II), y el código y modificaciones necesarias para recuperar posición, Zoom y tipo de Mapa (este incluído a última hora) que el usuario selecciona en un Mapa.

Información capturada

La información de los lugares puede ser guardada y recuperada de un fichero de texto; La estructura es bastante simple y no hace falta mayor explicación. Se almacena en el mismo directorio de la aplicación y recibe el nombre de “Lugares.txt”.

Recuperar y Guardar ubicaciones

La información que podemos capturar del Mapa (utilizando la clase GMap) y de otros elementos que estén incluíds en el mapa (imágenes, líneas, marcas,…) es muy extensa y está detallada en las referencias de la API de Google Maps.

Personalmente, creo que las posibilidades de ampliación son muy grandes y bastantes más sencillas de lo que a priori puede parecer.

Se puede descargar el ejemplo completo desde aquí.
<DESCARGAR EJEMPLO>

Espero que estas entradas hayan sido de utilidad. Como siempre cualquier comentario, corrección, sugerencia,… es bienvenida. ;-D

Un saludo.

ACTUALIZACIÓN (10 Febrero 2012): Dado el cambio de política de Google, ahora es necesario (obligatorio) colocar la key que se proporciona desde Google para poder utilizar la API. Es necesario modificar el fichero _mapa.txt del recurso y  recompilarlo utilizando RC.CMD.

 

5/5 - (1 voto)
  1. lunes, 29 de junio de 2009 a las 11:48 | #1

    Buen final a esta serie de entradas. Hay detalles que desconocía y que me van a ser muy útiles.
    Gracias.

  2. Alfredo Angulo
    viernes, 3 de julio de 2009 a las 16:58 | #2

    Me entro la curiosidad de meter esta herramienta a mi aplicación para buscar mapas, todo va bien hasta el momento de pulsar el boton buscar me salta el siguiente error:

    ERROR NO SE ENCUENTRA EL RECURSO

    Precisamente marca error en el siguiente codigo:

    // Se trata de seguridad de Visualizacion?
    resName := RES_HTML_PAGEMAP;

    // Llamar a la búsqueda de recurso
    b := FindInstanceOfResource(resName, RT_RCDATA, HInstance);

    // NO ENCUENTRA EL RECURSO Y MARCA EL ERROR
    if not b then begin
    // Error de recurso no encontrado
    raise Exception.Create(EMAP_MSG_ERRORGETRES);
    Application.Terminate;
    end;

    Agradezco tus comentarios….

  3. Alfredo Angulo
    viernes, 3 de julio de 2009 a las 17:00 | #3

    Me falto informarte que ya copie el archivo MapaRES.res en la ruta donde se encuentra el .pas y en diferentes rutas haber si eso es el problema pero no doy :)….

  4. Neftalí
    lunes, 6 de julio de 2009 a las 10:35 | #4

    @Alfredo Angulo
    Hola Alfredo.
    Acabo de actualizar el link del ejemplo. Prueba a compilarlo ahora y a ejecutarlo.
    http://neftali.clubdelphi.com/ejemplos_files/Ej1_googlemaps.zip

  5. Neftalí
    lunes, 6 de julio de 2009 a las 10:38 | #5

    @Alfredo Angulo
    Te acabo de subir una versión “extraoficial” que carga la página desde el fichero TXT directamente, por si sigue sin funcionarte.

    http://neftali.clubdelphi.com/ejemplos_files/Ej1_googlemaps_bis.zip

    Un saludo.

  6. Alfredo Angulo
    lunes, 6 de julio de 2009 a las 17:53 | #6

    Gracias por tus respuestas, pero haz la prueba con un nuevo proyecto, agregas un boton y alli mandas llamar el formulario FVerMapa.pas de la siguiente forma :

    [DELPHI]

    try
    Application.CreateForm(tFormVerMapa,FormVerMapa);
    FormVerMapa.ShowModal;
    finally
    FormVerMapa.Free;
    end;

    [/DELPHI]

    Corres el programa, presionas el boton y te saldrá el formulario par buscar un lugar, le escribes algun lugar y presionas enter y te marca el error de que no se encuentra el recurso, lo que trato de decir es que el ejemplo no funciona cuando es llamada de otro proyecto, si yo lo corro asi como viene el ejemplo después de descomprimir el archivo que subistes ese no marca error todo jala muy bien, pero si intentas añadirlo a un formulario de algun programa no funciona…. me explico ???

  7. Alfredo Angulo
    lunes, 6 de julio de 2009 a las 18:28 | #7

    Añadi el recurso .rc, y se me agrego en el .dpr ( proyecto ) una linea nueva:

    {$R ‘..\..\Utilerias\GoogleMaps\MapaRes.res’ ‘..\..\Utilerias\GoogleMaps\MapaRes.rc’}

    Al compilar me marca ahora el sigu

  8. Alfredo Angulo
    lunes, 6 de julio de 2009 a las 18:29 | #8

    siguiente error de compilación:
    [Error] Warning . Duplicate Resource(s)

  9. Alfredo Angulo
    lunes, 6 de julio de 2009 a las 18:37 | #9

    Disculpa Neftalli por tanto mensaje, lo que pasa es que es la 1er vez que añado un archivo .res al proyecto, ya logre que funcionará, quite la linea donde toma todos los archivos de recursos y puse el nuevo, por eso marcaba error:

    //{$R *.res}
    {$R ‘..\..\Utilerias\GoogleMaps\MapaRes.res’ ‘..\..\Utilerias\GoogleMaps\MapaRes.rc’}

    Gracias que tengas buen día, y te reconozco que te quedo muy bien tu aplicacion de google maps, muy bueno, solo una ultima pregunta, como se puede dejar por default la opción del mapa HIBRIDO ???? ya vez que cuando buscar un lugar te sale el mapa y en la parte superior derecha hay 3 opciones: 1.- MAPA 2.- SATELITE 3.- HIBRIDO, sale por default MAPA….

  10. Neftalí
    lunes, 6 de julio de 2009 a las 22:45 | #10

    @Alfredo Angulo

    Hay un procedimiento llamado:

    procedure _ChangeMapType();

    Que es donde se configura el tipo de mapa;

    Se busca la línea:
    STR_PREFIX_TYPE = ‘##MAPTYPE##’;

    Y se sustituye por esta otra configurada segun el tipo de mapa:
    STR_TYPE = ‘ map.setMapType(%s);’;

    Si cambias ese procedimiento por este, aparecerá siempre el mapa híbrido:

    //············································································
    procedure _ChangeMapType();
    const
    STR_PREFIX_TYPE = ‘##MAPTYPE##’;
    STR_TYPE = ‘ map.setMapType(%s);’;
    var
    i, j:Integer;
    str, line:string;
    begin

    // Buscar la cadena
    for i := 0 to (TSWeb.Count – 1) do begin
    line := Self.TSWeb[i];
    j := AnsiPos(STR_PREFIX_TYPE, line);
    // Es la línea
    if (j > 0) then begin
    Str := Format(STR_TYPE,[G_HYBRID_MAP]);
    Self.TSWeb[i] := Str;
    Self.TSWeb.SaveToFile(Self.FNameWeb);

    Break;
    end;
    end;
    end;
    //············································································

  11. Alfredo Angulo
    martes, 7 de julio de 2009 a las 01:14 | #11

    Gracias, neftalli, te quedo muy bien, hay lugares que no salen los nombres de las calles, es porque en google todavia no las actualiza ????

  12. Alfredo Angulo
    martes, 7 de julio de 2009 a las 01:18 | #12

    por darte un ejemplo MORELIA, MICHOACAN acercas el mapa y no salen los nombres de las calles solo las carreteras, y si buscas GUADALAJARA, JALISCO si te salen las calles si lo acercas….

  13. Alfredo Angulo
    martes, 7 de julio de 2009 a las 01:32 | #13

    Ultima pregunta Neftalli, entre a esta pagina http://maps.google.es/ y si busco alli por ejemplo MORELIA, MICHOACAN salen 4 opciones en la parte superior derecha la primera es para agregar fotos que caracterizan al lugar, la 4ta se llama RELIEVE, alli si lo presiono empiezan a salir los NOMBRES de las calles del lugar, veo que estas usando la misma dirección http://maps.google.es/maps?&q=%s,%s&z=15 pero no entiendo porque no aparece lo mismo en la aplicación de delphi que en la pagina de maps.google ??

  14. Alfredo Angulo
    martes, 7 de julio de 2009 a las 03:00 | #14

    otra cosa, lo que pasa es que pienso meter esta herramienta en 2 aplicaciones y dichas aplicaciones usan diferentes imagenes de icono en el .exe y me los cambia, si es algo molesto estar cambiando el nombre del icono para que tome el que le corresponde, porque mejor que habilite el boton “LOAD ICON” del Menu Project-Options-Aplication, estoy buscando donde le da la orden de que se deshabilite ese boton :)

  15. Neftalí
    martes, 7 de julio de 2009 a las 08:46 | #15

    @Alfredo Angulo

    Lo de las calles es normal. No todas las ciudades tienen igual de actualizados mapa e imágenes.

  16. Neftalí
    martes, 7 de julio de 2009 a las 08:47 | #16

    @Alfredo Angulo

    Si encuentra un fichero de recurso con un icono llamado MAINICON, creo que por defecto toma este en lugar de el configurado en las opciones del proyecto.

    Un saludo.

  17. Neftalí
    martes, 7 de julio de 2009 a las 13:35 | #17

    @Alfredo Angulo
    En esa dirección que comentas (http://maps.google.es/maps?&q=%s,%s&z=15) lo que hace la aplicación es sustituir los %s por las coordenadas de longitud y Latitud.

  18. Alfredo Angulo
    miércoles, 8 de julio de 2009 a las 01:00 | #18

    Como defines los botones que aparecen arriba a la derecha, si entro al http://maps.google.com/ y busco LOS MOCHIS, SINALOA alli si muestra los nombres de las calles presionando el boton RELIEVE ..

  19. Neftalí
    miércoles, 8 de julio de 2009 a las 09:40 | #19

    @Alfredo Angulo

    Para el tipo de Mapa RELIEVE puedes utilizar como constante de Tipo de mapa: G_PHYSICAL_MAP

    Para obtener más información puedes mirar la API de Google Maps y hacer pruebas modificando el fichero de recurso.

    Donde aparece esta línea:
    map.addControl(new GLargeMapControl());

    Añade debajo estas dos.
    map.addMapType(G_PHYSICAL_MAP);
    map.setMapType(G_PHYSICAL_MAP);

  20. Alfredo Angulo
    jueves, 9 de julio de 2009 a las 02:15 | #20

    gracias neftalli, ya le agarre el rollo a esto…. :)

  21. Xabi
    jueves, 9 de julio de 2009 a las 09:14 | #21

    Fantástico trabajo! Muchas gracias por dedicar tu tiempo a compartir estos recursos :)

  22. Marco
    sábado, 8 de agosto de 2009 a las 05:30 | #22

    Muchas gracias por el ejemplo, gran trabajo.
    Deseo poder colocar otros objetos (polilineas) sobre los mapas, pero no se por donde empezar, puedes explicarme que debo hacer para trazar una sola linea, ya lei el tutor de la API de Google, pero no tengo idea en que parte de delphi debo encajar el codigo, por ejemplo.

    var polyline = new GPolyline([
    new GLatLng(37.4419, -122.1419),
    new GLatLng(37.4519, -122.1519)
    ], “#ff0000”, 10);
    map.addOverlay(polyline);

    Muchas gracias

  23. socger
    lunes, 10 de agosto de 2009 a las 09:34 | #23

    Estoy trabajando todavía con Delphi 5, sabríais decirme si las Indy para esta versión funcionan con este ejemplo?.

    Y por cierto, no encuentro las Indy para esta versión de Delphi. Podríais decirme de donde bajarlas.

    Gracias.

  24. Neftalí
    lunes, 10 de agosto de 2009 a las 11:45 | #24

    @Marco

    Hola Marco.
    Revisa el código de la página Web que se usa en el ejemplo y añade en la página el código para la poliliea.

    Lo más sencillo es que primero lo pruebes con una página web estática y luego lo integres en el ejemplo.

    Un saludo.

  25. Neftalí
    lunes, 10 de agosto de 2009 a las 11:45 | #25

    @socger

    Hola socger.
    La verdad es que no lo he probado con Delphi 5.
    Puedes descargar el último paquete de las indy desde aquí:
    http://www.indyproject.org/Sockets/Download/Files/Indy10.DE.aspx

  26. socger
    viernes, 14 de agosto de 2009 a las 12:02 | #26

    Gracias, he conseguido instalar las Indy 10 en Delphi 5, pero ahora al abrir tu código me doy cuenta que no tenemos la misma versión de Delphi (cosa lógica). ¿Te importaría decirme que versión es con la que trabajas para probar tus ejemplos?.

    Esto lo necesito porque por ejemplo el ejemplo 2 de geoCodificacion no lo puedo ni abrir. El primero lo pude abrir y modificar para que funcionara en Delphi 5

    Mi cuenta de correo es socger@hotmail.com por si podrías decirme esto por correo privado.

    Saludos y gracias de antemano.

  27. Marco
    jueves, 27 de agosto de 2009 a las 06:57 | #27

    @Neftalí
    Logre hacer las polilineas, y la integracion con los ejemplos de Google, gracias a tus instrucciones y ejemplos (no estaba leyendo los casos anteriores) MUCHAS GRACIAS.

  28. Yordan
    jueves, 15 de octubre de 2009 a las 12:12 | #28

    Hello Nefali.
    Great work !

    But , is there a way to get the coordinates of a marker – from google maps, back to delphi ?

  29. Neftalí
    viernes, 16 de octubre de 2009 a las 11:49 | #29

    Hello. Something is changed on Google.

    This error is describes here.

    I’am reading for a solution.

    =============================
    Hola.
    Parece que algo ha cambiado recientemente en cómo Google responde las peticoines (relacionado con la API).

    Este post parece que explica el problema.

  30. Neftalí
    viernes, 16 de octubre de 2009 a las 12:06 | #30

    Ok.
    Parece que basta con obtener una API Key aquí:
    http://code.google.com/intl/es-ES/apis/maps/signup.html

    Y añadir a la llamada el parámetro con la Key obtenida.

    Por ejemplo:
    &key=AWEAGB98698….. (vuestra key)

    Un saludo.

  31. Neftalí
    viernes, 16 de octubre de 2009 a las 12:42 | #31

    SOLUCIÓN: Utilizando una API key válida todo funciona correctamente.
    He subido los ejemplos actualizados.

    Un saludo.

  32. Gustavo Enriquez
    viernes, 3 de junio de 2011 a las 14:10 | #32

    Felicitaciones, muy bien explicado y muy práctico.

    Voy a utilizarlo dentro de mi aplicación.

    Saludos.

  33. Carlos Rocha
    jueves, 9 de febrero de 2012 a las 21:40 | #33

    Buenas Tardes Neftali disculpa en el codigo ya modifique el parametro &hey y me sigue marcando el error que no poporciona el codigo

    esto Tengo en mi codigo

    const
    STR_WEB = ‘http://maps.google.com/maps/geo?q=’;
    STR_KEY = ‘&key=ABQIAAAAFVb255bTSpn4DC0nkcIz3hTgmueMIh62ahlPS2dC-DIXqzciAxRZItsH3Fy4UcBpz0Q4D8XHzbxt3A’;

    Y cuando hace el Html pone esto

  34. Neftalí
    viernes, 10 de febrero de 2012 a las 11:16 | #34

    @Carlos Rocha
    Hola Carlos.

    La key de Google debes colocarla en el HTML. HE subido el ejemplo actualizado.
    Fíjate que hay un fichero de recursos (_mapa.txt) que tiene el código necesario para añadir la key. En ese lugar es donde se debe añadir la key que proporciona Google.

    Una vez actualizado el recurso, generamos el fichero .RES compilado (para ello utiliza RC.CMD).

    Con el fichero de recursos regenerado correctamente (MAPA.RES), vuelve a recompilar el proyecto y a ver qué tal.

    Un saludo.

  35. Mike
    martes, 3 de abril de 2012 a las 18:17 | #35

    SON UNOS EJEMPLOS GRANDIOSOS SR. NEFTALI
    ME HAN AYUDADO DEMACIADO AL IR COMPRENDIENDO
    DELPHI

  36. viernes, 21 de julio de 2023 a las 13:38 | #36

    Hola Neftali.
    Estoy probando los ejemplos de mapas, para implementar en un sistema de logistica.

    Uso la version 10.3.3 de Delphi. Y al intentar ejecutar el ejemplo me sale este error.

    [dcc32 Error] FVerMapa.pas(210): E2250 There is no overloaded version of ‘EnumResourceModules’ that can be called with these arguments

  37. viernes, 4 de agosto de 2023 a las 11:58 | #37

    @Francisco

    Hola Francisco.
    Perdona que no haya contestado antes, pero a veces se me van los comentarios al SPAM y tardo en verlos.

    Para que compile, bastaría que cambies el parámetro de la función _MyEnumResourceModules, de un Longint a un HINST.
    Con eso debería bastar.

    Otra cosa es que posiblemente no llegue a mostrarse, porque han cambiado la APIs de Google. Deberás revisarlas y mirar el tema de la APIKEY.

  1. miércoles, 2 de marzo de 2011 a las 13:17 | #1