oct 092010
 

Buenas,

Una vez visto cómo mostrar un mapa de Google Maps, cómo centrarlo y cómo poner marcas, ahora toca el momento de personalizarlo.

En la versión 3 del API de Google Maps, hay que tener en cuenta que no se permite añadir o eliminar controles de forma dinámica, éstos deben de establecerse en la creación del mapa.

El objeto MapOptions

Este objeto será el encargado de dar la forma inicial a nuestro mapa. Para ver todas sus propiedades, te aconsejo una visita a la API de Google Maps ya que aquí sólo veremos los más interesantes (o al menos desde mi punto de vista).

Obligatorias
  • center: propiedad que determina dónde se centrará el mapa al mostrarlo. Es obligatoria y es de tipo LatLng.
  • mapTypeId: propiedad de tipo MapTypeId obligatoria y que es cómo se mostrará inicialmente el mapa.
  • zoom: entero obligatorio con el zoom aplicado al mapa.
Visuales
  • disableDefaultUI: booleano para mostrar o no todos los controles del mapa. Por defecto están habilitados.
  • mapTypeControl: booleano para mostrar o no el tipo de mapa. Por defecto habilitado.
  • mapTypeControlOptions: propiedad del tipo MapTypeControlOptions para configuración del control del tipo de mapa cuando éste se muestra.
    • mapTypeIds: array con los tipos de mapa a mostrar. Ver MapTypeId.
    • position: propiedad de tipo ControlPosition para especificar dónde se mostrará el control. Por defecto TOP_RIGHT. Las constantes posibles son:
      • BOTTOM
      • BOTTOM_LEFT
      • BOTTOM_RIGHT
      • LEFT
      • RIGHT
      • TOP
      • TOP_LEFT
      • TOP_RIGHT
    • style: propiedad de tipo MapTypeControlStyle para determinar el estilo del control. Los posibles valores son:
      • DEFAULT
      • DROPDOWN_MENU
      • HORIZONTAL_BAR
  • navigationControl: booleano para mostrar o no el control de navegación.
  • navigationControlOptions: propiedad de tipo NavigationControlOptions con las propiedades del control de navegación.
    • position: propiedad de tipo ControlPosition.
    • style: propiedad de tipo NavigationControlStyle para especificar el tipo de navegador. Las constantes posibles son:
      • ANDROID
      • DEFAULT
      • SMALL
      • ZOOM_PAN
  • scaleControl: booleano para mostrar o no el control de escala.
  • scaleControlOptions: propiedad de tipo ScaleControlOptions con las opciones del control de escala.
No visuales
  • disableDoubleClickZoom: booleano para des/habilitar el zoom con el clic de ratón.
  • draggable: booleano para des/habilitar el poder mover el mapa. Por defecto se puede.
  • keyboardShortcuts: booleano para des/habilitar el control del mapa con el teclado. Por defecto habilitado.
  • scrollwheel: booleano para des/habilitar el control de la rueda del ratón. Habilitado por defecto.

Aplicando lo visto a Delphi

Una vez vistas las configuraciones posibles del mapa, nos queda ver cómo hacerlo desde Delphi.

Basándonos en los ejemplos anteriores, crearemos una constante (MAPA_CODE) que contendrá el código html y JavaScript necesario. En éste, destacar la creación de una nueva función JavaScript que será llamada desde Delphi y será la encargada de generar el mapa con la configuración que hayamos especificado en el programa. La función es esta:

  function DoWeb(Lat,Lon,TMap,aZoom,ZClick,MoveMap,Keyb,Wheel,ShowTM,
                 PosTM,StyleTM,ShowNav,PosNav,StyleNav,ShowScale,PosScale) {
    switch (TMap) {
      case "HYBRID": aTMap = google.maps.MapTypeId.HYBRID; break;
      case "ROADMAP": aTMap = google.maps.MapTypeId.ROADMAP; break;
      case "SATELLITE": aTMap = google.maps.MapTypeId.SATELLITE; break;
      default: aTMap = google.maps.MapTypeId.TERRAIN;
    } 

    switch (PosTM) {
      case "BOTTOM": aPosTM = google.maps.ControlPosition.BOTTOM; break;
      case "BOTTOM_LEFT": aPosTM = google.maps.ControlPosition.BOTTOM_LEFT; break;
      case "BOTTOM_RIGHT": aPosTM = google.maps.ControlPosition.BOTTOM_RIGHT; break;
      case "LEFT": aPosTM = google.maps.ControlPosition.LEFT; break;
      case "RIGHT": aPosTM = google.maps.ControlPosition.RIGHT; break;
      case "TOP": aPosTM = google.maps.ControlPosition.TOP; break;
      case "TOP_LEFT": aPosTM = google.maps.ControlPosition.TOP_LEFT; break;
      default: aPosTM = google.maps.ControlPosition.TOP_RIGHT;
    } 

    switch (StyleTM) {
      case "DROPDOWN_MENU": aStyleTM = google.maps.MapTypeControlStyle.DROPDOWN_MENU; break;
      case "HORIZONTAL_BAR": aStyleTM = google.maps.MapTypeControlStyle.HORIZONTAL_BAR; break;
      default: aStyleTM = google.maps.MapTypeControlStyle.DEFAULT;
    } 

    switch (PosNav) {
      case "BOTTOM": aPosNav = google.maps.ControlPosition.BOTTOM; break;
      case "BOTTOM_LEFT": aPosNav = google.maps.ControlPosition.BOTTOM_LEFT; break;
      case "BOTTOM_RIGHT": aPosNav = google.maps.ControlPosition.BOTTOM_RIGHT; break;
      case "LEFT": aPosNav = google.maps.ControlPosition.LEFT; break;
      case "RIGHT": aPosNav = google.maps.ControlPosition.RIGHT; break;
      case "TOP": aPosNav = google.maps.ControlPosition.TOP; break;
      case "TOP_LEFT": aPosNav = google.maps.ControlPosition.TOP_LEFT; break;
      default: aPosNav = google.maps.ControlPosition.TOP_RIGHT;
    } 

    switch (StyleNav) {
      case "ANDROID": aStyleNav = google.maps.NavigationControlStyle.ANDROID; break;
      case "SMALL": aStyleNav = google.maps.NavigationControlStyle.SMALL; break;
      case "ZOOM_PAN": aStyleNav = google.maps.NavigationControlStyle.ZOOM_PAN; break;
      default: aStyleNav = google.maps.NavigationControlStyle.DEFAULT;
    } 

    switch (PosScale) {
      case "BOTTOM": aPosScale = google.maps.ControlPosition.BOTTOM; break;
      case "BOTTOM_LEFT": aPosScale = google.maps.ControlPosition.BOTTOM_LEFT; break;
      case "BOTTOM_RIGHT": aPosScale = google.maps.ControlPosition.BOTTOM_RIGHT; break;
      case "LEFT": aPosScale = google.maps.ControlPosition.LEFT; break;
      case "RIGHT": aPosScale = google.maps.ControlPosition.RIGHT; break;
      case "TOP": aPosScale = google.maps.ControlPosition.TOP; break;
      case "TOP_LEFT": aPosScale = google.maps.ControlPosition.TOP_LEFT; break;
      default: aPosScale = google.maps.ControlPosition.TOP_RIGHT;
    } 

    var latlng = new google.maps.LatLng(Lat,Lon);
    var myOptions = {
      center: latlng,
      mapTypeId: aTMap,
      zoom: aZoom, 

      disableDoubleClickZoom: ZClick,
      draggable: MoveMap,
      keyboardShortcuts: Keyb,
      scrollwheel: Wheel, 

      mapTypeControl: ShowTM,
      mapTypeControlOptions: {position: aPosTM, style: aStyleTM},
      navigationControl: ShowNav,
      navigationControlOptions: {position: aPosNav, style: aStyleNav},
      scaleControl: ShowScale,
      scaleControlOptions: {position: aPosScale} 

    };
    map = null;
    map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
  }
Las constantes posibles son:

Como podemos ver, la función recibe tantos parámetros como posibles configuraciones tengamos. Lo primero que hace es coger el valor de las constantes necesarias según los parámetros recibidos (los 6 switch). Luego creamos el objeto que contendrá la longitud y latitud y el que contendrá todas las opciones del mapa. Para terminar, liberamos el objeto map por si existía y lo volvemos a crear con las características nuevas.

A nivel de código Delphi, pues queda hacer la llamada cómo ya hemos visto en anterioridad:

const
  StrParams = '%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s';
var
  Doc2: IHTMLDocument2;
  Win2: IHTMLWindow2;
  Params: String;
begin
  Doc2 := wbWeb.Document as IHTMLDocument2;
  Win2 := Doc2.parentWindow;

  Params := Format(StrParams, [eLong.Text,
                               eLat.Text,
                               QuotedStr(cbTypMap.Text),
                               IntToStr(tbZoom.Position),
                               LowerCase(BoolToStr(not chZoomClick.Checked, True)),
                               LowerCase(BoolToStr(chDrag.Checked, True)),
                               LowerCase(BoolToStr(chTeclado.Checked, True)),
                               LowerCase(BoolToStr(chWheel.Checked, True)),
                               LowerCase(BoolToStr(chShowTypeMap.Checked, True)),
                               QuotedStr(cbTMPosition.Text),
                               QuotedStr(cbTMStyle.Text),
                               LowerCase(BoolToStr(chNavigation.Checked, True)),
                               QuotedStr(cbNPosition.Text),
                               QuotedStr(cbNStyle.Text),
                               LowerCase(BoolToStr(chScale.Checked, True)),
                               QuotedStr(cbSPosition.Text)
                               ]);

  Win2.execScript('DoWeb(' + Params + ')', 'JavaScript');
end;

Aquí os dejo un ejemplo de la pantalla.

También podéis descargaros los fuentes y el binario del programa desde aquí.

Otro día más.

Nos leemos

  13 Responses to “Jugando con la API de Google Maps (VIII) – personalizar el mapa”

  1. Simplemente genial.

    Me parece una idea increíble lo de mezclar javascript con delphi para así aprovechar la API de google.

    Saludos

    • Gracias amigo

      La verdad es que sí, es genial y divertido a la vez 🙂

      Te adelanto en primicia, y ahora que no nos lee nadie, que en las próximas entregas miraré de mostrar cómo usar el StreetView (muy sencillo), el uso de polígonos y calcular rutas entre dos puntos.

      También investigaré cómo recoger información devuelta por el API y si me sale, también lo mostraré 🙂

      Espero que tenga tiempo para todo jejejeje

      Nos leemos

      PD: prácticamente no se JavaScript, así que si veis alguna estupidez en el código, espero me lo digáis 🙂

  2. Estoy comenzando con google maps, y solo quiero agradecer por tus explicaciones. Realmente son muy buenas y de gran ayuda.

    Estare a la espera de tus avances.

    Saludos.

  3. Te adelanto en primicia, y ahora que no nos lee nadie, que en las próximas entregas miraré de mostrar cómo usar el StreetView (muy sencillo), el uso de polígonos y calcular rutas entre dos puntos.

    Eso crees tu 😀

    Muy interesante este asunto, estoy esperado ver el StreetView 😉

    Saludos

  4. Lovely sharp post. Never thought that it was this easy. Extolment to you!

  5. que tal esta muy bueno tu blog estoy tratando de crear un mapa donde pongo varias coordenadas dentro de un array y verlas en el mapa con sus respectivas marca o crear una linea que los junte no se si me puedes ayudar te lo agardeceria musho

  6. bueno antes que nada cambie el javascript del makemarker por este

    ‘ function MakeMarker(Lat, Lng) { ‘ +
    ‘ var lugares = [ ‘+
    ‘[19.31144, -99.04433],’+
    ‘[19.31144, -99.04453],’+
    ‘[19.31144, -99.04473]’+
    ‘];’+
    ‘ for ( i = 0; i < lugares.length; i++) { '+
    ' var coord = lugares[i];'+
    ' var myLatLng = new google.maps.LatLng(coord[0], coord[1]);'+
    ' var marker = new google.maps.Marker({ '+
    ' position: myLatLng,'+
    ' map: map , ' +
    ' icon: ''http://google-maps-icons.googlecode.com/files/factory.png'&#039; '+
    ' }); '+
    '} ' +
    ' } '+

    cuando le das buscar si te manda todas las marcas pero solo lo hace con coordenadas
    que yo puse necesito llenar un tipo array con una consulta que seria algo asi

    procedure TForm1.Coor;
    begin
    ssql:= 'select Latitud, Longitud from fabricas Where Idfabricas = ' + inttostr(cbtFab.GetDato(cbtFab.ItemIndex)); '';
    query.SQL.Add(ssql);
    query.Open;
    if not query.Eof then
    begin
    while not query.Eof do
    begin
    idLat := Trim(query.fields[0].AsString);
    idLon := Trim(query.fields[1].AsString);
    Idlatitud [query.RecNo-1]:= QuotedStr(idLat);
    Idlongitud [query.RecNo-1]:= QuotedStr(idLong);
    query.Next;
    end;
    end;
    query.Close;
    end;
    el problema es que necesito hablar este array que se crea al javascript y cambiar las coordenadas en lugares por las del array no se si me explique espero me puedas ayudar de antemano mushas gracias

    • Buenas,

      Bueno, si te fijas en el ejemplo del artículo anterior, verás que necesitas un Array de markets global a todo el JS

          
       
            var map = null; 
            var markerArray = [];
      ......
      

      Y luego necesitarás dos funciones JS, una para el rellenado y otra para el borrado de markets

            
      function DeleteMarkers() { 
              for (i = 0; i < markerArray.length; i++) { 
                markerArray[i].setMap(null); 
              }
              markerArray = []; 
            } 
           
            function MakeMarker(Lat, Lng, titulo) { 
              var latlng = new google.maps.LatLng(Lat,Lng);
              var aMarker = new google.maps.Marker({ 
                  position: latlng, 
                  map: map, 
                  title: titulo 
                  }); 
              markerArray[markerArray.length] = aMarker; 
            } 
      

      Ahora sólo te queda hacer una llamada a estas funciones desde Delphi para tener las markets que quieras en cada momento. Primero haces una llamada a DeleteMarkers para quitar todas las marcas y luego, mediante un bucle, las llamadas necesarias a MakeMarker.

      Espero que te sirva

      Nos leemos
      cadetill

  7. ps mushas gracias si me sirvio de esho tan facil que era la solucion y yo complicandome la vida pero bueno es entretenido estar jugando con estas aplicaciones de nuevo gracias y felicitarte por tu blog
    Saludos

Leave a Reply to sonic Cancel 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)

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.