Versión 3 del API de JavaScript de Google Maps

Tipos de mapas

  1. Tipos de mapas
  2. Tipos de mapas básicos
  3. Imágenes de 45°
    1. Cómo habilitar e inhabilitar imágenes de 45°
    2. Cómo girar imágenes de 45°
  4. Cómo modificar el registro del tipo de mapa
  5. Mapas con estilos
  6. Tipos de mapas personalizados
    1. Coordenadas de mapa
      1. Coordenadas mundiales
      2. Coordenadas de píxeles
      3. Coordenadas de mosaico
    2. La interfaz MapType
      1. Tipos de mapas base
      2. Tipos de mapas de superposición
      3. Tipos de mapas de imagen
  7. Proyecciones personalizadas
    1. Cómo implementar la interfaz de proyección
    2. Trasformación de coordenadas en proyecciones
    3. Selección de mosaicos en proyecciones

Tipos de mapas

En este documento se describen los tipos de mapas que puedes mostrar mediante el API de JavaScript de Google Maps. El API utiliza un objeto MapType para contener información sobre estos mapas. Un objeto MapType es una interfaz que define la visualización y el uso de mosaicos de mapas, así como el paso de sistemas de coordenadas de coordenadas de pantalla a coordenadas reales (en el mapa). Cada objeto MapType debe contener algunos métodos para gestionar la recuperación y el suministro de mosaicos y propiedades que definan su comportamiento visual.

El funcionamiento interno de los tipos de mapas en el API de Google Maps constituye un tema de nivel avanzado. La mayoría de los desarrolladores puede utilizar simplemente los tipos de mapas básicos que se describen a continuación. Sin embargo, también es posible definir mosaicos de mapas propios mediante tipos de mapas personalizados o modificar la presentación de tipos de mapas existentes a través de mapas con estilos. Para proporcionar tipos de mapas personalizados, debes saber cómo modificar el registro del tipo de mapa.

Tipos de mapas básicos

El API de Google Maps permite utilizar muchos tipos de mapas. Además de los conocidos mosaicos de mapas de carreteras "pintados", el API de Google Maps también ofrece otros tipos de mapas.

A continuación se indican los tipos de mapas que se encuentran disponibles en el API de Google Maps.

  • MapTypeId.ROADMAP muestra la vista de mapa de carretera predeterminada.
  • MapTypeId.SATELLITE muestra imágenes de satélite de Google Earth.
  • MapTypeId.HYBRID muestra una mezcla de vistas normales y de satélite.
  • MapTypeId.TERRAIN muestra un mapa físico basado en información del relieve.

Para modificar el tipo de mapa que utiliza el objeto Map, debes definir su propiedad mapTypeId configurando el objeto Map options en el constructor o ejecutando el método setMapTypeId() del mapa.

Definición de mapTypeId en el constructor:

var myLatlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
  zoom: 8,
  center: myLatlng,
  mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById("map_canvas"),
    mapOptions);

Modificación de mapTypeId de forma dinámica:

map.setMapTypeId(google.maps.MapTypeId.TERRAIN);

Ten cuenta que en realidad no configuras el tipo de mapa directamente, sino que defines su objeto mapTypeId para hacer referencia a un objeto MapType mediante un identificador. La versión 3 del API de JavaScript de Google Maps utiliza un registro del tipo de mapa, que se explica a continuación, para gestionar estas referencias.

Imágenes de 45°

El API de Google Maps admite imágenes de 45° especiales para determinadas ubicaciones. Estas imágenes de alta resolución proporcionan vistas en perspectiva de todos los puntos cardinales (Norte, Sur, Este y Oeste). Estas imágenes están disponibles a niveles de zoom elevados para los tipos de mapas admitidos.

La siguiente imagen muestra una vista en perspectiva de 45º del paseo de Santa Cruz de California:


Los tipos de mapas google.maps.MapTypeId.SATELLITE y google.maps.MapTypeId.HYBRID existentes admiten imágenes en perspectiva de 45º a niveles elevados de zoom (si están disponibles). Si se acerca el zoom a una ubicación en la que se encuentran disponibles esas imágenes, las vistas del mapa correspondiente cambian automáticamente del siguiente modo:

  • Todos los controles de desplazamiento incluidos en el mapa se modifican, y se añade un control de brújula alrededor de los controles de navegación existentes. Esta brújula permite cambiar la dirección de cualquier imagen de 45º, orientándola hacia la dirección más próxima disponible en la que existan imágenes.
  • Aparecerá un control de giro intersticial entre los controles de desplazamiento y de zoom existentes, lo que te permitirá girar en las direcciones admitidas. El control de giro solo permite rotar en el sentido de las agujas del reloj.
  • Las imágenes híbridas o de satélite se sustituyen por imágenes en perspectiva de 45º centradas en la ubicación actual. De forma predeterminada, estas vistas apuntan hacia el Norte. Si se aleja el zoom, reaparecen las imágenes híbridas o de satélite predeterminadas.
  • El control MapType activará un control que alterna entre submenús para mostrar las imágenes de 45º.

Al alejar el zoom en los mapas que muestran imágenes de 45º, se deshacen los cambios aplicados y se restablecen los tipos de mapas originales.

Google añade constantemente imágenes de 45º de ciudades nuevas. Puedes consultar la lista de imágenes de 45º de Google Maps para obtener la información más actualizada.

Cómo habilitar e inhabilitar imágenes de 45º

Puedes inhabilitar imágenes de 45° ejecutando setTilt(0) en el objeto Map. Para habilitar imágenes con perspectiva de 45º para los tipos de mapas admitidos, ejecuta setTilt(45).

El método getTilt() de Map siempre reflejará la inclinación actual que se muestra en el mapa; si configuras una inclinación en un mapa y, a continuación, eliminas esa inclinación (alejando el mapa, por ejemplo), el método getTilt() del mapa devolverá 0.

En el siguiente ejemplo se muestra una vista de 45º del centro de Portland (Oregón, EE.UU.):

var mapOptions = {
  center: new google.maps.LatLng(37.339085, -121.8914807),
  zoom: 18,
  mapTypeId: 'satellite'
};
map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
map.setTilt(45);

Ver ejemplo (aerial-simple.html)

Cómo girar imágenes de 45°

Las imágenes de 45º están formadas por un conjunto de imágenes para cada punto cardinal (Norte, Sur, Este y Oeste). Una vez que aparecen imágenes de 45º en un mapa, esas imágenes se pueden orientar hacia uno de los cuatro puntos cardinales ejecutando setHeading() en el objeto Map y especificando un valor numérico expresado en grados respecto al Norte.

El código del siguiente permite mostrar un mapa aéreo que gira automáticamente cada tres segundos cuando se hace clic en el botón:

var map;
function initialize() {

  var mapOptions = {
    center: new google.maps.LatLng(45.518970, -122.672899),
    zoom: 18,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  };
  map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  map.setTilt(45);
  map.setHeading(90);
}

function autoRotate() {
  // Determine if we're showing aerial imagery
  if (map.getTilt() != 0) {
    map.setHeading(180);
    setTimeout('map.setHeading(270)',3000);
    setTimeout('map.setHeading(0)',6000);
    setTimeout('map.setHeading(90)',9000);
  }
}

Ver ejemplo (aerial-rotation.html)

Cómo modificar el registro del tipo de mapa

El objeto mapTypeId de un mapa es un identificador de cadena que se utiliza para asociar un objeto MapType a un único valor. Cada objeto Map mantiene un elemento MapTypeRegistry que contiene el conjunto de objetos MapType disponibles para un mapa. Este registro se utiliza para seleccionar los tipos de mapas que se encuentran disponibles en el control MapType, por ejemplo.

No se puede interpretar directamente a partir del registro del tipo de mapa. En su lugar, debes modificar el registro añadiendo tipos de mapas personalizados y asociándolos a un identificador de cadena que elijas. No puedes modificar o alterar los tipos de mapas básicos (aunque puedes eliminarlos del mapa modificando la apariencia del objeto mapTypeControlOptions asociado del mapa).

En el siguiente código, el mapa se configura para que muestre únicamente dos tipos de mapas en su objeto mapTypeControlOptions y se modifica el registro para añadir la asociación con este identificador a la implementación real de la interfaz MapType. Nota: en el código anterior, se ha omitido intencionadamente la creación del propio tipo de mapa personalizado. Para obtener información sobre cómo crear un tipo de mapa, consulta las secciones Mapas con estilos o Tipos de mapas personalizados que se indican a continuación.

// Modify the control to only display two maptypes, the
// default ROADMAP and the custom 'mymap'.
// Note that because this is simply an association, we
// don't need to modify the MapTypeRegistry beforehand.

var MY_MAPTYPE_ID = 'mymaps';

var mapOptions = {
  zoom: 12,
  center: brooklyn,
  mapTypeControlOptions: {
     mapTypeIds: [google.maps.MapTypeId.ROADMAP, MY_MAPTYPE_ID]
  },
  mapTypeId: MY_MAPTYPE_ID
};

// Create our map. This creation will implicitly create a
// map type registry.
map = new google.maps.Map(document.getElementById("map_canvas"),
    mapOptions);

// Create your custom map type using your own code.
// (See below.)
var myMapType = new MyMapType();

// Set the registry to associate 'mymap' with the
// custom map type we created, and set the map to
// show that map type.
map.mapTypes.set(MY_MAPTYPE_ID, myMapType);

Mapas con estilos

StyledMapType permite personalizar la presentación de mapas base de Google estándar, cambiando la visualización de elementos tales como carreteras, parques y áreas urbanizadas para que reflejen un estilo diferente al utilizado en el tipo de mapa predeterminado.

En la sección Mapas con estilos de esta Guía para desarrolladores se incluye información sobre el tipo de mapa StyledMapType.

Tipos de mapas personalizados

La versión 3 del API de JavaScript de Google Maps admite ahora la visualización y administración de tipos de mapas personalizados, lo que te permite implementar tus propias superposiciones de mosaicos o imágenes de mapas.

La versión 3 incluye varias implementaciones de tipos de mapas posibles:

  • Conjuntos de mosaicos estándar, que incluyen imágenes que, en su conjunto, constituyen mapas cartográficos completos. Estos conjuntos de mosaicos también se conocen como tipos de mapas base. Estos tipos de mapa actúan y se comportan como los tipos de mapas predeterminados: ROADMAP, SATELLITE, HYBRID y TERRAIN. Puedes añadir tu propio tipo de mapa personalizado a un conjunto mapTypes de un mapa para permitir que la interfaz de usuario del API de Google Maps considere el tipo de mapa personalizado como un tipo de mapa estándar (incluyéndolo en el control MapType, por ejemplo).
  • Superposiciones de mosaicos de imágenes que se muestran sobre tipos de mapas base existentes. En general, estos tipos de mapas se utilizan para ampliar un tipo de mapa existente con el fin de mostrar información adicional y, a menudo, se limitan a ubicaciones específicas o niveles de zoom concretos. Ten en cuenta que estos mosaicos pueden ser transparentes, lo que permite añadir elementos a los mapas existentes.
  • Tipos de mapas que no son imágenes, que permiten manipular la visualización de la información del mapa en el nivel más básico

Cada una de estas opciones se basa en la creación de una clase que implementa la interfaz MapType. Además, la clase ImageMapType proporciona algunos comportamientos integrados para simplificar la creación de MapType de imágenes.

Antes de explicar las clases encargadas de la implementación de MapType, conviene comprender la forma en que Google Maps determina las coordenadas y decide las partes del mapa que se mostrarán. Deberás implementar una lógica similar para cualquier MapType de superposición o base.

Coordenadas de mapa

El API de Google Maps utiliza diversos sistemas de coordenadas:

  • valores de latitud y longitud que hacen referencia a un punto único en el mundo (Google utiliza el estándar WGS84 o Sistema Geodésico Mundial),
  • coordenadas mundiales que hacen referencia a un punto único en el mapa,
  • coordenadas de mosaico que hacen referencia a un mosaico específico del mapa en el nivel de zoom aplicado.

Coordenadas mundiales

Siempre que el API de Google Maps necesite convertir una ubicación del mundo en una ubicación del mapa (la pantalla), primero deberá convertir los valores de latitud y longitud en una coordenada "mundial". Esta conversión se realiza mediante una proyección cartográfica. Google Maps utiliza la proyección de Mercator con este propósito. También puedes definir tu propia proyección mediante la implementación de la interfaz google.maps.Projection. (Ten en cuenta que las interfaces de la versión 3 no son clases que puedas "subclasificar", sino que son especificaciones sencillas para las clases que tú mismo defines).

Para una mayor comodidad en el cálculo de las coordenadas en píxeles (podrás encontrar más información al respecto a continuación), asumimos que un mapa en el nivel de zoom 0 es un único mosaico del tamaño de mosaico base. A continuación, definimos las coordenadas mundiales de acuerdo con el sistema de coordenadas en píxeles en el nivel de zoom 0, utilizando la proyección para convertir latitudes y longitudes en posiciones de píxel en este mosaico base. Esta coordenada mundial es un valor de punto flotante medido desde el origen de la proyección del mapa hasta la ubicación específica. Ten en cuenta que como este valor es un valor de punto flotante, puede ser mucho más preciso que la resolución actual de la imagen de mapa que se muestre. En otras palabras, una coordenada mundial es independiente del nivel de zoom actual.

Las coordenadas mundiales de Google Maps se miden a partir del origen de la proyección de Mercator (la esquina noroccidental del mapa a 180 grados de longitud y 85 grados de latitud aproximadamente) y se incrementan a lo largo del eje x en dirección este (derecha) y a lo largo del eje y en dirección sur (abajo). Dado que el mosaico base de una proyección de Mercator en Google Maps es de 256 x 256 píxeles, el espacio de coordenadas mundiales que se puede utilizar equivale a {0-256}, {0-256} (encontrarás más información a continuación).

Ten en cuenta que una proyección de Mercator tiene un ancho longitudinalmente finito, pero un alto latitudinalmente infinito. "Cortamos" la imagen del mapa base que utiliza una proyección de Mercator en +/- 85 grados aproximadamente para que el mapa resultante tenga forma rectangular, con lo que la selección de mosaicos presenta una lógica mucho más sencilla. Ten en cuenta que es posible que una proyección genere coordenadas mundiales que se sitúen fuera del espacio de coordenadas utilizables del mapa base (por ejemplo, al acercarse demasiado a los polos).

Coordenadas de píxeles

Las coordenadas mundiales representan ubicaciones absolutas en una proyección determinada, pero necesitamos convertirlas en coordenadas de píxeles para determinar la desviación en "píxeles" en un nivel de zoom concreto. Estas coordenadas de píxeles se calculan mediante la fórmula siguiente:

pixelCoordinate = worldCoordinate * 2zoomLevel

En la ecuación anterior, fíjate en que cada nivel de zoom creciente equivale al doble en las direcciones x y y. Por tanto, cada nivel de zoom superior presenta una resolución que cuadruplica la resolución del nivel precedente. Por ejemplo, en el nivel de zoom 1, el mapa consta de cuatro mosaicos de 256 x 256 píxeles, lo que equivale a un espacio en píxeles de 512 x 512. En el nivel de zoom 19, se puede hacer referencia a cada píxel x e y del mapa utilizando un valor entre 0 y 256 * 219.

Dado que basamos las coordenadas mundiales en el tamaño de mosaico del mapa, la parte entera de las coordenadas de píxeles permite identificar el píxel exacto en dicha ubicación en el nivel de zoom actual. Ten en cuenta que en el nivel de zoom 0, las coordenadas de píxeles equivalen a las coordenadas mundiales.

Ahora ya disponemos de un método para representar con precisión todas las ubicaciones del mapa en todos los niveles de zoom. El API de Google Maps crea una ventana gráfica a partir del centro del nivel de zoom del mapa (como LatLng) y el tamaño del elemento DOM que lo contiene y convierte este cuadro delimitador en coordenadas de píxeles. A continuación, el API determina de forma lógica todos los mosaicos de mapas incluidos dentro de los límites de los píxeles especificados. Se hace referencia a cada uno de estos mosaicos de mapas mediante coordenadas de mosaico, que simplifican enormemente la visualización de las imágenes del mapa.

Coordenadas de mosaico

Lo más probable es que el API de Google Maps no pueda cargar todas las imágenes del mapa en los niveles de zoom superiores que resultan de mayor utilidad; en su lugar, el API de Google Maps descompone las imágenes de cada nivel de zoom en un conjunto de mosaicos de mapa organizados de forma lógica en el orden que comprende la aplicación. Cuando se desplaza un mapa a una nueva ubicación o a un nuevo nivel de zoom, el API de Google Maps determina los mosaicos necesarios mediante las coordenadas de píxeles y convierte estos valores en un conjunto de mosaicos para su recuperación. Estas coordenadas de mosaico se asignan mediante un esquema que hace que resulte fácil determinar desde un punto de vista lógico el mosaico que contiene las imágenes correspondientes a un punto específico.

En Google Maps, los mosaicos se numeran desde el mismo origen que los píxeles. Para la implementación en Google de la proyección de Mercator, el mosaico de origen se encuentra siempre en la esquina noroccidental del mapa; los valores del eje x aumentan de oeste a este y los del eje y aumentan de norte a sur. Los mosaicos se indexan utilizando las coordenadas x,y de ese origen. Por ejemplo, en el nivel de zoom 2, cuando la Tierra se divide en 16 mosaicos, se puede hacer referencia a cada uno de ellos mediante un par x,y único:

Ten en cuenta que, al dividir las coordenadas de píxeles entre el tamaño de mosaico y tomar la parte entera del resultado, se obtiene como resultado la coordenada de mosaico en el nivel de zoom actual.

En el ejemplo siguiente se muestran las coordenadas (valores LatLng, coordenadas mundiales, coordenadas de píxeles y coordenadas de mosaico) de Chicago (Illinois, EE.UU.) en diferentes niveles de zoom:

Ver ejemplo (map-coordinates.html)

La interfaz MapType

Los tipos de mapas personalizados deben implementar la interfaz MapType. Esta interfaz especifica determinadas propiedades y métodos que permiten que el API inicie solicitudes para los tipos de mapas cuando determine que necesita mostrar mosaicos de mapas en la ventana gráfica y en el nivel de zoom actuales. Estas solicitudes permiten determinar el mosaico que se cargará.

(Nota: puedes crear tu propia clase para implementar esta interfaz; o bien, si dispones de imágenes compatibles, utilizar la clase ImageMapType que ya implementa esta interfaz).

Las clases que implementan la interfaz MapType requieren que definas y completes las siguientes propiedades:

  • tileSize (obligatoria) especifica el tamaño del mosaico (de tipo google.maps.Size). Deben tener forma rectangular, aunque no tienen que ser necesariamente cuadrados.
  • maxZoom (obligatoria) especifica el nivel de zoom máximo al que se mostrarán los mosaicos de este tipo de mapa.
  • minZoom (obligatoria) especifica el nivel de zoom mínimo al que se mostrarán los mosaicos de este tipo de mapa. De forma predeterminada, este valor es 0, lo que indica que no existe ningún nivel de zoom mínimo.
  • name (opcional) especifica el nombre de este tipo de mapa. Esta propiedad solo es necesaria si deseas que este tipo de mapa se pueda seleccionar en el control MapType. (Consulta la sección sobre cómo añadir controles MapType que se indica a continuación).
  • alt (opcional) especifica el texto alternativo para este tipo de mapa, mostrado en forma de texto que aparece al colocar el cursor del ratón sobre un determinado elemento. Esta propiedad solo es necesaria si deseas que este tipo de mapa se pueda seleccionar en el control MapType. (Consulta la sección sobre cómo añadir controles MapType que se indica a continuación).

Además, las clases que implementan la interfaz MapType necesitan que implementes los siguientes métodos:

  • getTile() (obligatorio) se ejecuta siempre que el API determina que es necesario mostrar en el mapa mosaicos nuevos en la ventana gráfica correspondiente. El método getTile() debe incluir la siguiente firma:

    getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node

    El API determina si es necesario ejecutar getTile() en función de las propiedades tileSize, minZoom y maxZoom de MapType y de la ventana gráfica y del nivel de zoom actuales del mapa. El controlador de este método debe devolver un elemento HTML en función de una coordenada transmitida, del nivel de zoom y del elemento DOM en el que se debe añadir la imagen de mosaico.

  • releaseTile() (opcional) se ejecuta siempre que el API determina que es necesario eliminar un mosaico del mapa porque queda fuera del área de visión. Este método debe tener la siguiente firma:

    releaseTile(tile:Node)

    Normalmente, la eliminación de cualquier elemento asociado a los mosaicos de mapas se realiza después de añadirlos a este. Por ejemplo, si has asociado detectores de eventos a las superposiciones de mosaicos de mapa, deberás eliminarlos aquí.

El método getTile() funciona como el principal controlador para determinar los mosaicos que se cargarán en una ventana gráfica concreta.

Tipos de mapas base

Los tipos de mapas que se crean de esta forma pueden ser independientes o combinarse con otros tipos de mapas en forma de superposiciones. Los tipos de mapas independientes se denominan tipos de mapas base. Te recomendamos que el API trate estos tipos de mapa (MapType) personalizados como cualquier otro tipo de mapa base ya existente (ROADMAP, TERRAIN, etc.). Para ello, añade el objeto MapType personalizado a la propiedad mapTypes de Map. Esta propiedad es de tipo MapTypeRegistry.

El siguiente código crea un tipo de mapa (MapType) base para mostrar las coordenadas de mosaico de un mapa y traza un contorno de los mosaicos:

function CoordMapType() {
}

CoordMapType.prototype.tileSize = new google.maps.Size(256,256);
CoordMapType.prototype.maxZoom = 19;

CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
  var div = ownerDocument.createElement('div');
  div.innerHTML = coord;
  div.style.width = this.tileSize.width + 'px';
  div.style.height = this.tileSize.height + 'px';
  div.style.fontSize = '10';
  div.style.borderStyle = 'solid';
  div.style.borderWidth = '1px';
  div.style.borderColor = '#AAAAAA';
  return div;
};

CoordMapType.prototype.name = "Tile #s";
CoordMapType.prototype.alt = "Tile Coordinate Map Type";

var map;
var chicago = new google.maps.LatLng(41.850033,-87.6500523);
var coordinateMapType = new CoordMapType();

function initialize() {
  var mapOptions = {
    zoom: 10,
    center: chicago,
    mapTypeControlOptions: {
      mapTypeIds: ['coordinate', google.maps.MapTypeId.ROADMAP],
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    }
  };
  map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  // Now attach the coordinate map type to the map's registry.
  map.mapTypes.set('coordinate',coordinateMapType);

  // We can now set the map to use the 'coordinate' map type.
  map.setMapTypeId('coordinate');
}

Ver ejemplo (maptype-base.html)

Tipos de mapas de superposición

Algunos tipos de mapas se diseñan para mostrarse sobre otros tipos de mapas ya existentes. Estos tipos de mapas pueden incluir capas transparentes que muestren puntos de interés o datos adicionales para el usuario. (La capa de tráfico de Google es un ejemplo de este tipo de mapa).

En tales casos, lo normal es que no quieras que el tipo de mapa sea considerado como una entidad independiente. Por el contrario, puedes añadir directamente el tipo de mapa a un objeto MapType ya existente mediante la propiedad overlayMapTypes de Map. Esta propiedad contiene un conjunto MVCArray del objeto MapType. Todos los tipos de mapas (base y superposición) se representan en la capa mapPane. Los tipos de mapas de superposición se muestran sobre cualquier mapa base al que se encuentren asociados, en el mismo orden en el que aparecen en el conjunto Map.overlayMapTypes.

El siguiente ejemplo es idéntico al anterior, con la excepción de que hemos creado una superposición de mosaicos MapType sobre el tipo de mapa ROADMAP:

function CoordMapType(tileSize) {
  this.tileSize = tileSize;
}

CoordMapType.prototype.getTile = function(coord, zoom, ownerDocument) {
  var div = ownerDocument.createElement('div');
  div.innerHTML = coord;
  div.style.width = this.tileSize.width + 'px';
  div.style.height = this.tileSize.height + 'px';
  div.style.fontSize = '10';
  div.style.borderStyle = 'solid';
  div.style.borderWidth = '1px';
  div.style.borderColor = '#AAAAAA';
  return div;
};

var map;
var chicago = new google.maps.LatLng(41.850033,-87.6500523);

function initialize() {
  var mapOptions = {
    zoom: 10,
    center: chicago,
    mapTypeId: google.maps.MapTypeId.ROADMAP
  };
  map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);

  // Insert this overlay map type as the first overlay map type at
  // position 0. Note that all overlay map types appear on top of
  // their parent base map.
  map.overlayMapTypes.insertAt(0, new CoordMapType(new google.maps.Size(256, 256)));
}

Ver ejemplo (maptype-overlay.html)

Tipos de mapas de imagen

La implementación de un tipo de mapa (MapType) para que sirva de tipo de mapa base puede ser una tarea laboriosa que requiere una gran cantidad de tiempo. El API proporciona una clase especial que implementa la interfaz MapType para los tipos de mapas más utilizados: tipos de mapas que constan de mosaicos compuestos de archivos de una sola imagen.

Esta clase, la clase ImageMapType, se construye a través de una especificación de objeto ImageMapTypeOptions que define las siguientes propiedades obligatorias:

  • tileSize (obligatoria) especifica el tamaño del mosaico (de tipo google.maps.Size). Deben tener forma rectangular, aunque no tienen que ser necesariamente cuadrados.
  • getTileUrl (obligatoria) especifica la función, normalmente proporcionada como un literal de función insertado, para procesar la selección del mosaico de imagen adecuado en el nivel de zoom y las coordenadas mundiales que se han proporcionado.

El siguiente código implementa un tipo ImageMapType básico mediante los mosaicos de luna de Google. El ejemplo utiliza una función de normalización para garantizar que los mosaicos se repitan a lo largo del eje X, pero no a lo largo del eje Y, de tu mapa.

var moonTypeOptions = {
  getTileUrl: function(coord, zoom) {
      var normalizedCoord = getNormalizedCoord(coord, zoom);
      if (!normalizedCoord) {
        return null;
      }
      var bound = Math.pow(2, zoom);
      return "http://mw1.google.com/mw-planetary/lunar/lunarmaps_v1/clem_bw" +
          "/" + zoom + "/" + normalizedCoord.x + "/" +
          (bound - normalizedCoord.y - 1) + ".jpg";
  },
  tileSize: new google.maps.Size(256, 256),
  maxZoom: 9,
  minZoom: 0,
  radius: 1738000,
  name: "Moon"
};

var moonMapType = new google.maps.ImageMapType(moonTypeOptions);

function initialize() {
  var myLatlng = new google.maps.LatLng(0, 0);
  var mapOptions = {
    center: myLatlng,
    zoom: 1,
    streetViewControl: false,
    mapTypeControlOptions: {
      mapTypeIds: ["moon"]
    }
  };

  var map = new google.maps.Map(document.getElementById("map_canvas"),
      mapOptions);
  map.mapTypes.set('moon', moonMapType);
  map.setMapTypeId('moon');
}

// Normalizes the coords that tiles repeat across the x axis (horizontally)
// like the standard Google map tiles.
function getNormalizedCoord(coord, zoom) {
  var y = coord.y;
  var x = coord.x;

  // tile range in one direction range is dependent on zoom level
  // 0 = 1 tile, 1 = 2 tiles, 2 = 4 tiles, 3 = 8 tiles, etc
  var tileRange = 1 << zoom;

  // don't repeat across y-axis (vertically)
  if (y < 0 || y >= tileRange) {
    return null;
  }

  // repeat across x-axis
  if (x < 0 || x >= tileRange) {
    x = (x % tileRange + tileRange) % tileRange;
  }

  return {
    x: x,
    y: y
  };
}

Ver ejemplo (maptype-image.html)

Proyecciones

La Tierra es una esfera tridimensional (aproximadamente), mientras que un mapa es una representación en dos dimensiones. El mapa que visualizas en el API de Google Maps, al igual que cualquier representación plana de la Tierra, es una proyección de esa esfera en una superficie plana. En sus términos más básicos, una proyección se puede definir como una asignación de valores de latitud y longitud a las coordenadas del mapa de la proyección.

En el API de Google Maps, las proyecciones deben implementar la interfaz Projection. La implementación de un objeto Projection debe proporcionar no solo una asignación de un sistema de coordenadas a otro, sino también una asignación bidireccional. Es decir, debes definir cómo pasar de las coordenadas de la Tierra (LatLng) al sistema de coordenadas mundiales de la proyección (Projection), y viceversa. Google Maps utiliza la proyección de Mercator para crear sus mapas a partir de datos geográficos y convertir eventos del mapa en coordenadas geográficas. Puedes obtener esta proyección ejecutando getProjection() en el mapa (Map) (o cualquiera de los tipos de mapas (MapType) base estándar). Para la mayoría de usos, bastará con esta proyección estándar (Projection), aunque también podrás definir y utilizar tu propias proyecciones personalizadas.

Cómo implementar una proyección

A la hora de implementar una proyección personalizada, deberás definir los siguientes elementos:

  • Las fórmulas para asignar coordenadas de latitud y longitud a un plano cartesiano y viceversa. (La interfaz Projection solo admite transformaciones en coordenadas rectilíneas).
  • El tamaño del mosaico base. Todos los mosaicos deben ser rectangulares.
  • El "tamaño del mundo" de un mapa utilizando el conjunto de mosaicos base a un nivel de zoom 0. Ten en cuenta que, en los mapas que se componen de un mosaico a nivel de zoom 0, el tamaño del mundo coincide con el tamaño del mosaico base.

Transformaciones de coordenadas en proyecciones

Cada proyección proporciona dos métodos que realizan conversiones entre estos dos sistemas de coordenadas, lo que te permite convertir coordenadas geográficas en mundiales y viceversa:

  • El método Projection.fromLatLngToPoint() convierte un valor LatLng en una coordenada mundial. Este método se utiliza para posicionar superposiciones en el mapa (y para posicionar el propio mapa).
  • El método Projection.fromPointToLatLng() convierte una coordenada mundial en un valor LatLng. Este método se utiliza para convertir eventos, como los clics que se registran en el mapa, en coordenadas geográficas.

Google Maps asume que las proyecciones son rectilíneas.

Generalmente, puedes utilizar una proyección con dos fines: crear un mapa del mundo o crear un mapa de un área local. En el primer caso, debes asegurarte de que todas las longitudes de tu proyección también sean rectilíneas y normales. Algunas proyecciones (especialmente, las proyecciones cónicas) pueden ser "localmente normales" (es decir, apuntan al norte), aunque se desvían del norte absoluto; por ejemplo, cuanto más alejado se coloque el mapa con respecto a alguna longitud de referencia. Puedes utilizar localmente una proyección de este tipo, pero debes tener en cuenta que la proyección es necesariamente imprecisa y que los errores de transformación serán mayores cuanto más te desvíes de la longitud de referencia.

Selección de mosaicos de mapas en proyecciones

Además de ser útiles para determinar posiciones de ubicaciones o superposiciones, las proyecciones permiten posicionar los propios mosaicos de mapas. El API de Google Maps representa mapas base mediante una interfaz MapType, que debe declarar una propiedad projection para identificar la proyección del mapa y un método getTile() para recuperar mosaicos de mapas en función de los valores de las coordenadas de mosaico. Las coordenadas de mosaico se basan en el tamaño del mosaico básico (que debe ser rectangular) y en el "tamaño del mundo" de tu mapa, que es el tamaño de píxel de tu mapa del mundo a un nivel de zoom 0. (En el caso de mapas compuestos por un mosaico a un nivel de zoom 0, el mosaico y el mundo tienen el mismo tamaño).

Debes definir el tamaño del mosaico base en la propiedad tileSize de MapType. Debes definir el tamaño del mundo implícitamente en los métodos fromLatLngToPoint() y fromPointToLatLng() de tu proyección.

Debido a que la selección de las imágenes depende de estos valores transmitidos, es útil establecer un nombre para las imágenes que se puedan seleccionar automáticamente en función de estos valores transmitidos como, por ejemplo, map_zoom_tileX_tileY.png.

El siguiente ejemplo define un objeto ImageMapType con la proyección de Gall-Peters:

// Note: this value is exact as the map projects a full
// 360 degrees of longitude.
var GALL_PETERS_RANGE_X = 800;

// Note: this value is inexact as the map is cut off at ~ +/- 83 degrees.
// However, the polar regions produce very little increase in Y range, so
// we will use the tile size.
var GALL_PETERS_RANGE_Y = 510;

function degreesToRadians(deg) {
  return deg * (Math.PI / 180);
}

function radiansToDegrees(rad) {
  return rad / (Math.PI / 180);
}

function GallPetersProjection() {

  // Using the base map tile, denote the lat/lon of the equatorial origin.
  this.worldOrigin_ = new google.maps.Point(GALL_PETERS_RANGE_X * 400 / 800,
      GALL_PETERS_RANGE_Y / 2);

  // This projection has equidistant meridians, so each longitude
  // degree is a linear mapping.
  this.worldCoordinatePerLonDegree_ = GALL_PETERS_RANGE_X / 360;

  // This constant merely reflects that latitudes
  // vary from +90 to -90 degrees.
  this.worldCoordinateLatRange = GALL_PETERS_RANGE_Y / 2;
};

GallPetersProjection.prototype.fromLatLngToPoint = function(latLng) {

  var origin = this.worldOrigin_;
  var x = origin.x + this.worldCoordinatePerLonDegree_ * latLng.lng();

  // Note that latitude is measured from the world coordinate origin
  // at the top left of the map.
  var latRadians = degreesToRadians(latLng.lat());
  var y = origin.y - this.worldCoordinateLatRange * Math.sin(latRadians);

  return new google.maps.Point(x, y);
};

GallPetersProjection.prototype.fromPointToLatLng = function(point, noWrap) {

  var y = point.y;
  var x = point.x;

  if (y < 0) {
    y = 0;
  }
  if (y >= GALL_PETERS_RANGE_Y) {
    y = GALL_PETERS_RANGE_Y;
  }

  var origin = this.worldOrigin_;
  var lng = (x - origin.x) / this.worldCoordinatePerLonDegree_;
  var latRadians = Math.asin((origin.y - y) / this.worldCoordinateLatRange);
  var lat = radiansToDegrees(latRadians);
  return new google.maps.LatLng(lat, lng, noWrap);
};

function initialize() {
  var gallPetersMap;

  var gallPetersMapType = new google.maps.ImageMapType({
    getTileUrl: function(coord, zoom) {
      var numTiles = 1 << zoom;

      // Don't wrap tiles vertically.
      if (coord.y < 0 || coord.y >= numTiles) {
        return null;
      }

      // Wrap tiles horizontally.
      var x = ((coord.x % numTiles) + numTiles) % numTiles;

      // For simplicity, we use a tileset consisting of 1 tile at zoom level 0
      // and 4 tiles at zoom level 1.
      var baseURL = 'images/';
      baseURL += 'gall-peters_' + zoom + '_' + x + '_' + coord.y + '.png';
      return baseURL;
    },
    tileSize: new google.maps.Size(800, 512),
    minZoom: 0,
    maxZoom: 1,
    name: 'Gall-Peters'
  });

  gallPetersMapType.projection = new GallPetersProjection();

  var mapOptions = {
    zoom: 0,
    center: new google.maps.LatLng(0,0)
  };
  gallPetersMap = new google.maps.Map(document.getElementById("gallPetersMap"),
      mapOptions);

  gallPetersMap.mapTypes.set('gallPetersMap', gallPetersMapType);
  gallPetersMap.setMapTypeId('gallPetersMap');
  gallPetersMap.overlayMapTypes.insertAt(0, gallPetersMapType);
}

Ver ejemplo (map-projection-simple.html)

Autenticación obligatoria

Tienes que acceder a Google+ para realizar esta acción.

Acceder a...

Desarrolladores de Google necesita tu permiso para realizar esta acción.