Types de carte

Types de carte

Ce document décrit les types de carte que vous pouvez afficher en utilisant Google Maps JavaScript API. Cette API utilise un objet MapType pour conserver les informations sur les cartes. Un objet MapType est une interface qui définit l'affichage et l'utilisation des tuiles de carte ainsi que la traduction des systèmes de coordonnées, de coordonnées à l'écran en coordonnées réelles (sur la carte). Chaque objet MapType doit contenir plusieurs méthodes pour gérer la récupération et la publication des tuiles, ainsi que les propriétés qui définissent son comportement visuel.

Le fonctionnement interne des types de carte dans Maps API est un sujet complexe. La plupart des développeurs peuvent simplement utiliser les types de carte basiques indiqués ci-dessous. Néanmoins, vous pouvez également définir vos propres tuiles de carte en utilisant les types de carte personnalisés, ou modifier la présentation des types de carte existants en utilisant des cartes stylisées. Si vous souhaitez fournir des types de carte personnalisés, vous devez savoir comment modifier le registre des types de carte.

Types de carte basiques

Quatre types de carte sont disponibles dans Google Maps API. Outre les tuiles de carte routière « peintes » qui vous sont familières, Google Maps API prend également en charge d'autres types de carte.

Les types de carte suivants sont disponibles dans Google Maps API :

  • MapTypeId.ROADMAP affiche la vue de carte routière par défaut. Il s'agit du type de carte par défaut.
  • MapTypeId.SATELLITE affiche des images satellite Google Earth.
  • MapTypeId.HYBRID affiche une combinaison de vues normales et d'images satellites.
  • MapTypeId.TERRAIN affiche une carte physique basée sur les informations du terrain.

Vous pouvez modifier le type de carte utilisé par l'objet Map en définissant sa propriété mapTypeId, soit dans le constructeur en définissant son objet Map options, soit en appelant la méthode setMapTypeId() de la carte. Par défaut, la propriété mapTypeID est définie sur MapTypeId.ROADMAP.

Définir la propriété mapTypeId au moment de la construction :

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

Modifier la propriété mapTypeId de façon dynamique :

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

Notez que vous ne définissez pas directement le type de carte de la carte, mais que vous définissez sa propriété mapTypeId pour renvoyer à un objet MapType au moyen d'un identifiant. Pour gérer ces références, Maps Javascript API V3 utilise un registre de types de carte dont vous trouverez une description plus bas.

Images à 45°

Google Maps API prend en charge des images à 45° spéciales pour certains points géographiques. Ces images haute résolution fournissent des vues en perspective vers chacun des quatre points cardinaux (Nord, Sud, Est et Ouest). Elles sont également disponibles à des niveaux de zoom supérieurs pour les types de carte pris en charge.

L'image suivante montre une vue en perspective à 45° de la promenade de Santa Cruz, en Californie :

Les types de carte google.maps.MapTypeId.SATELLITE et google.maps.MapTypeId.HYBRID prennent en charge les images à 45° à des niveaux de zoom élevés, si de telles images sont disponibles. Si l'utilisateur zoome sur un point géographique pour lequel de telles images sont disponibles, ces types de carte modifient automatiquement leurs vues de la manière suivante :

  • L'image satellite ou hybride est remplacée par une image offrant une perspective à 45° centrée sur le point géographique sélectionné. Par défaut, ces vues sont orientées vers le nord. Si l'utilisateur effectue un zoom arrière, l'image satellite ou hybride par défaut s'affiche à nouveau.
  • La commande de rotation offre une combinaison d'options d'inclinaison et de rotation. Si rotateControl est défini sur true, une commande d'inclinaison s'affiche lorsqu'une image à 45° est disponible. La commande d'inclinaison permet à l'utilisateur d'incliner l'image jusqu'à un angle de 45°.
  • Lorsque l'image est inclinée, un crochet s'affiche pour permettre aux utilisateurs de faire pivoter la vue à 90° dans le sens horaire.

Lorsque l'on effectue un zoom arrière sur un type de carte affichant une image à 45°, toute modification de la vue est supprimée et le type de carte d'origine est rétabli.

Google ajoute régulièrement des images à 45° pour de nouvelles villes. Pour consulter les informations les plus récentes, reportez-vous à la liste des images à 45° sur Google Maps.

Activer et désactiver les images à 45°

Vous pouvez désactiver les images à 45° en appelant la méthode setTilt(0) sur l'objet Map. Pour activer les images à 45° avec les types de carte pris en charge, appelez la méthode setTilt(45).

La méthode getTilt() de l'objet Map reflète toujours l'inclinaison affichée sur la carte ; si vous définissez une inclinaison sur une carte puis supprimez ensuite cette inclinaison (en faisant un zoom arrière, par exemple), la méthode getTilt() de la carte renvoie la valeur 0.

L'exemple suivant affiche une vue à 45° du centre-ville de Portland, dans l'Oregon :

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 36.964, lng: -122.015},
    zoom: 18,
    mapTypeId: google.maps.MapTypeId.SATELLITE
  });
  map.setTilt(45);
}

Voir l'exemple (aerial-simple.html)

Faire pivoter des images à 45°

Les images à 45° consistent en fait en plusieurs images pour chaque point cardinal (Nord, Sud, Est, Ouest). Une fois que les images à 45° sont affichées sur votre carte, vous pouvez les orienter vers l'un des points cardinaux en appelant la méthode setHeading() sur l'objet Map, avec une valeur exprimée en degrés à partir du nord.

L'exemple suivant montre une carte aérienne qui pivote automatiquement toutes les trois secondes lorsque l'on clique sur le bouton :

var map;

function initMap() {
  map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 45.518, lng: -122.672},
    zoom: 18,
    mapTypeId: google.maps.MapTypeId.SATELLITE,
    heading: 90,
    tilt: 45
  });
}

function rotate90() {
  var heading = map.getHeading() || 0;
  map.setHeading(heading + 90);
}

function autoRotate() {
  // Determine if we're showing aerial imagery.
  if (map.getTilt() !== 0) {
    window.setInterval(rotate90, 3000);
  }
}

Voir l'exemple (aerial-rotation.html)

Modifier le registre des types de carte

Le mapTypeId d'une carte est un identifiant de chaîne utilisé pour associer un objet MapType à une valeur unique. Chaque objet Map tient à jour un registre MapTypeRegistry contenant l'intégralité des objets MapType de la carte en question. Ce registre sert à sélectionner les types de carte disponibles dans la commande MapType de l'objet Map, par exemple.

Vous n'accédez pas directement au registre des types de carte, mais vous le modifiez en y ajoutant des types de carte personnalisés et en les associant à l'identifiant de chaîne de votre choix. Vous ne pouvez pas modifier ou altérer les types de carte basiques (bien que vous puissiez les supprimer de la carte modifiant les options mapTypeControlOptions associées à la carte).

Le code suivant définit la carte pour n'afficher que deux types de carte dans les options mapTypeControlOptions de la carte et modifie le registre pour ajouter l'association avec cet identifiant à l'implémentation effective de l'interface MapType. Remarque : nous avons volontairement omis de décrire la création du type de carte personnalisé lui-même dans le code précédent. Pour plus d'informations sur la construction d'un type de carte, voir Cartes stylisées et Types de carte personnalisés ci-dessous.

// 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"),
    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);

Cartes stylisées

Le code StyledMapType vous permet de personnaliser la présentation des cartes basiques standard de Google, en modifiant le visuel des éléments tels que les routes, les parcs et les zones construites en vue de refléter un style différent du type de carte par défaut.

Des informations sur le code StyledMapType sont fournies dans la section Cartes stylisées de ce Guide du développeur.

Types de carte personnalisés

Désormais, Google Maps JavaScript API prend en charge l'affichage et la gestion des types de carte personnalisés, ce qui vous permet d'implémenter vos propres images de carte ou superpositions de tuiles.

L'API V3 permet différentes implémentations de types de carte :

  • Des jeux de tuiles standard composés d'images qui, ensemble, constituent des cartes géographiques complètes. Ces jeux de tuiles sont également appelés des types de carte de base. Ces types de carte agissent et se comportent comme les types de carte par défaut : ROADMAP, SATELLITE, HYBRID et TERRAIN. Vous pouvez ajouter votre type de carte personnalisé au tableau mapTypes d'une carte afin de permettre à l'interface utilisateur de Maps API de traiter votre type de carte personnalisé comme un type de carte standard (en l'incluant par exemple dans la commande MapType).
  • Des superpositions de tuiles d'images qui s'affichent au-dessus des types de carte basiques existants. En règle générale, ces types de carte servent à améliorer un type de carte existant en affichant des informations supplémentaires. Ils sont souvent limités à certains points géographiques et/ou niveaux de zoom spécifiques. Notez que ces tuiles peuvent être transparentes, ce qui vous permet d'ajouter des composants aux cartes existantes.
  • Des types de carte autres que des images, qui vous permettent de manipuler l'affichage des informations d'une carte à son niveau le plus fondamental.

Chacune de ces options repose sur la création d'une classe qui implémente l'interface MapType. Par ailleurs, la classe ImageMapType fournit un fonction intégrée simplifiant la création d'objets MapType d'images.

Avant d'aborder les classes qui implémentent des objets MapType, il est important de comprendre la façon dont Google Maps détermine les coordonnées et identifie les parties de la carte à afficher. Vous devrez implémenter une logique similaire pour tout objet MapType basique ou superposé.

Coordonnées de carte

Google Maps API utilise différents systèmes de coordonnées :

  • Des valeurs de latitude et de longitude qui situent un point de manière unique sur Terre. (Google utilise la norme World Geodetic System WGS84.)
  • Des coordonnées mondiales qui désignent un point de façon unique sur la carte.
  • Des coordonnées de tuile qui désignent une tuile spécifique sur la carte à un niveau de zoom donné.

Coordonnées mondiales

À chaque fois que Maps API doit traduire un lieu réel en point géographique sur une carte (l'écran), il doit d'abord traduire les valeurs de latitude et de longitude en coordonnées « mondiales ». Cette traduction se fait au moyen d'une projection de carte. Google Maps utilise à cette fin la projection de Mercator. Vous pouvez également définir votre propre projection en implémentant l'interface google.maps.Projection. (Notez que les interfaces dans V3 ne sont pas des classes que vous « sous-classez », mais de simples spécifications pour des classes que vous définissez vous-même.)

Pour simplifier le calcul des coordonnées pixels (voir ci-dessous), nous considérons qu'une carte au niveau de zoom 0 est une tuile unique de la taille de la tuile de base. Nous définissons ensuite les coordonnées mondiales relatives aux coordonnées pixels au niveau de zoom 0, en utilisant la projection pour convertir les latitudes et les longitudes en positions de pixels sur cette tuile de base. Cette coordonnée mondiale est une valeur de point flottant mesurée depuis l'origine de la projection de la carte jusqu'au point géographique donné. Notez que dans la mesure où cette valeur est une valeur de point flottant, elle peut être bien plus précise que la résolution actuelle de l'image de carte affichée. En d'autres termes, les coordonnées mondiales sont indépendantes du niveau de zoom défini.

Dans Google Maps, les coordonnées mondiales sont mesurées à partir du point d'origine de la projection de Mercator (l'angle nord-ouest de la carte à 180 degrés de longitude et environ 85 degrés de latitude). Elles augmentent à la fois dans la direction x vers l'est (la droite) et la direction y vers le sud (le bas). Étant donné que la tuile Google Maps Mercator de base fait 256 x 256 pixels, l'espace de coordonnées mondiales utilisable est de {0-256}, {0-256} (voir ci-dessous).

Notez que la projection de Mercator a une largeur finie sur le plan longitudinal, mais une hauteur infinie sur le plan latitudinal. Nous « coupons » l'image de la carte de base en utilisant la projection de Mercator à environ +/- 85 degrés pour rendre carrée la carte qui en résulte et ainsi simplifier la logique de sélection des tuiles. Notez qu'une projection peut générer des coordonnées mondiales en dehors de l'espace de coordonnées utilisables de la carte de base si vous sélectionnez des points près des pôles, par exemple.

Coordonnées pixels

Les coordonnées mondiales reflètent des points géographiques absolus sur une projection donnée, mais nous devons les traduire en coordonnées pixels pour déterminer le décalage « pixel » à un niveau de zoom donné. Ces coordonnées pixels sont calculées en utilisant la formule suivante :

pixelCoordinate = worldCoordinate * 2zoomLevel

Notez qu'à partir de l'équation ci-dessus, chaque niveau de zoom supérieur est deux fois plus grand dans les directions x et y. La résolution de chaque niveau de zoom supérieur est donc quatre fois supérieure à celle du niveau qui le précède. Par exemple, au niveau de zoom 1, la carte consiste en quatre tuiles de 256 x 256 pixels, soit un espace de pixels de 512 x 512. Au niveau de zoom 19, il est possible de définir chaque pixel x et y sur la carte en utilisant une valeur située entre 0 et 256 * 219.

Étant donné que nous avons basé les coordonnées mondiales sur la taille des tuiles de la carte, le nombre entier d'une coordonnée pixel permet d'identifier le pixel exact du point géographique en question au niveau de zoom sélectionné. Notez que pour le niveau de zoom 0, les coordonnées pixels sont égales aux coordonnées mondiales.

Nous disposons maintenant d'une méthode pour indiquer précisément chaque point géographique sur la carte, à chaque niveau de zoom. Maps API construit une fenêtre d'affichage à partir du niveau de zoom au centre de l'image (sous la forme de coordonnées LatLng) et de la taille du conteneur DOM, puis traduit cette zone de délimitation en coordonnées pixels. L'API identifie ensuite de façon logique toutes les tuiles de carte qui se trouvent à l'intérieur de ces limites en pixels. Chacune de ces tuiles de carte est référencée grâce aux coordonnées de tuile, ce qui simplifie considérablement l'affichage des images de carte.

Coordonnées de tuile

Il n'est pas possible pour Google Maps API de charger toutes les images de carte aux niveaux de zoom supérieurs, qui sont les plus utiles. À la place, Maps API divise les images à chaque niveau de zoom en un jeu de tuiles de carte, qui sont organisées de façon logique dans un ordre que comprend l'application. Lorsqu'une nouvelle zone est définie en faisant défiler la carte ou lorsque l'utilisateur modifie le niveau de zoom, Maps API détermine quelles tuiles sont nécessaires au moyen des coordonnées pixels et traduit ces valeurs en un jeu de tuiles à récupérer. Ces coordonnées de tuile sont attribuées en utilisant un schéma qui permet de déterminer plus facilement sur le plan logique quelles tuiles contiennent les images pour tout point donné.

Dans Google Maps, les tuiles sont numérotées à partir de la même origine que les pixels. Dans le cadre de l'implémentation de la projection de Mercator par Google, la tuile d'origine est toujours à l'angle nord-ouest de la carte, avec les valeurs x augmentant d'ouest en est et les valeurs y augmentant du nord au sud. Les tuiles sont indexées au moyen des coordonnées x,y à partir de cette origine. Au niveau de zoom 2, par exemple, lorsque la Terre est divisée en 16 tuiles, chaque tuile peut être désignée par une paire x,y unique :

Notez qu'en divisant les coordonnées pixels par la taille des tuiles et en conservant le nombre entier du résultat, vous générez, en tant que sous-produit, les coordonnées de la tuile au niveau de zoom actuel.

L'exemple suivant affiche les coordonnées — valeurs LatLng, coordonnées mondiales, coordonnées pixels et coordonnées des tuiles — pour Chicago, Illinois, à différents niveaux de zoom :

Voir l'exemple (map-coordinates.html)

Interface MapType

Les types de carte personnalisés doivent implémenter l'interface MapType. Cette interface spécifie certaines propriétés et méthodes qui permettent à l'API d'initier des requêtes ciblant votre ou vos types de carte lorsque l'API détermine qu'elle doit afficher des tuiles de carte dans la fenêtre d'affichage en cours et avec le niveau de zoom sélectionné. Vous gérez ces requêtes pour décider quelle tuile charger.

Remarque : Vous pouvez créer votre propre classe pour implémenter cette interface ou, si vous avez des images compatibles, vous pouvez utiliser la classe ImageMapType, qui l'implémente déjà.

Les classes qui implémentent l'interface MapType nécessitent que vous définissiez et renseigniez les propriétés suivantes :

  • tileSize (obligatoire) spécifie la taille de la tuile (de type google.maps.Size). Les tailles doivent être rectangulaires, mais pas carrées.
  • maxZoom (obligatoire) spécifie le niveau de zoom maximum auquel afficher les tuiles de ce type de carte.
  • minZoom (facultatif) spécifie le niveau de zoom minimum auquel afficher les tuiles de ce type de carte. Par défaut, cette valeur est définie sur 0, ce qui indique qu'il n'y a pas de niveau de zoom minimum.
  • name (facultatif) spécifie le nom de ce type de carte. Cette propriété n'est nécessaire que si vous souhaitez que ce type de carte soit sélectionnable au sein d'une commande MapType. (Voir Ajouter des commandes MapType ci-dessous.)
  • alt (facultatif) spécifie le texte de remplacement pour ce type de carte ; il s'affiche en tant que texte au survol. Cette propriété n'est nécessaire que si vous souhaitez que ce type de carte soit sélectionnable au sein d'une commande MapType. (Voir Ajouter des commandes MapType ci-dessous.)

Par ailleurs, les classes qui implémentent l'interface MapType doivent aussi utiliser les méthodes suivantes :

  • La méthode getTile() (obligatoire) est appelée à chaque fois que l'API détermine que la carte doit afficher de nouvelles tuiles pour la fenêtre d'affichage spécifiée. La méthode getTile() doit avoir la signature suivante :

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

    L'API détermine s'il est nécessaire d'appeler la méthode getTile() en fonction des propriétés tileSize, minZoom et maxZoom de la commande MapType, ainsi qu'en fonction de la fenêtre d'affichage actuelle et du niveau de zoom sélectionné sur la carte. Pour cette méthode, le gestionnaire (handler) doit retourner un élément HTML basé sur les coordonnées et le niveau de zoom transmis, ainsi que sur l'élément DOM auquel ajouter l'image de la tuile.

  • La méthode releaseTile() (facultative) est appelée à chaque fois que l'API détermine que la carte doit supprimer une tuile car elle est hors de l'écran. Cette méthode doit avoir la signature suivante :

    releaseTile(tile:Node)

    En général, vous devez gérer la suppression de tout élément joint aux tuiles de la carte au moment de leur ajout à la carte. Par exemple, si vous avez joint des écouteurs d'événement aux superpositions de tuiles de la carte, c'est ici que vous devez les supprimer.

La méthode getTile() sert de contrôleur principal pour déterminer quelles tuiles charger au sein d'une fenêtre d'affichage donnée.

Types de carte de base

Les types de carte que vous construisez de cette manière peuvent être soit autonomes, soit combinés à d'autres types de carte en tant que superpositions. Les types de carte autonomes sont appelés types de carte de base. Si vous le souhaitez, l'API peut traiter de tels objets MapType personnalisés comme tout autre type de carte de base existant (ROADMAP, TERRAIN, etc.). Pour ce faire, ajoutez votre MapType personnalisé à la propriété mapTypes de l'objet Map. Cette propriété est de type MapTypeRegistry.

Le code suivant crée un MapType de base pour afficher les coordonnées des tuiles de la carte et trace le contour des tuiles :

/*
 * This demo demonstrates how to replace default map tiles with custom imagery.
 * In this case, the CoordMapType displays gray tiles annotated with the tile
 * coordinates.
 *
 * Try panning and zooming the map to see how the coordinates change.
 */

/**
 * @constructor
 * @implements {google.maps.MapType}
 */
function CoordMapType(tileSize) {
  this.tileSize = tileSize;
}

CoordMapType.prototype.maxZoom = 19;
CoordMapType.prototype.name = 'Tile #s';
CoordMapType.prototype.alt = 'Tile Coordinate Map Type';

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';
  div.style.backgroundColor = '#E5E3DF';
  return div;
};

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: 41.850, lng: -87.650},
    streetViewControl: false,
    mapTypeId: 'coordinate',
    mapTypeControlOptions: {
      mapTypeIds: ['coordinate', google.maps.MapTypeId.ROADMAP],
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
    }
  });

  map.addListener('maptypeid_changed', function() {
    var showStreetViewControl = map.getMapTypeId() !== 'coordinate';
    map.setOptions({
      streetViewControl: showStreetViewControl
    });
  });

  // Now attach the coordinate map type to the map's registry.
  map.mapTypes.set('coordinate',
                   new CoordMapType(new google.maps.Size(256, 256)));
}

Voir l'exemple (maptype-base.html)

Types de carte de superposition

Certains types de carte sont conçus pour fonctionner au-dessus d'autres types de carte existants. De tels types de carte peuvent avoir des calques transparents indiquant des points d'intérêt ou affichant des données supplémentaires à l'utilisateur. (Le calque Traffic de Google est un exemple de ce type de carte.)

En pareil cas, vous ne souhaitez pas que le type de carte soit traité en tant qu'entité séparée. À la place, vous pouvez directement ajouter le type de carte à un MapType existant en utilisant la propriété overlayMapTypes de l'objet Map. Cette propriété contient un tableau MVCArray contenant les différents objets MapType. Tous les types de carte (base et superposition) sont rendus dans le calque mapPane. Les types de carte de superposition s'affichent au-dessus de toute carte de base à laquelle ils sont joints, dans l'ordre dans lequel ils figurent dans le tableau Map.overlayMapTypes.

L'exemple suivant est identique à l'exemple précédent, sauf que nous avons créé un MapType de superposition de tuiles au-dessus du type de carte ROADMAP :

/*
 * This demo illustrates the coordinate system used to display map tiles in the
 * API.
 *
 * Tiles in Google Maps are numbered from the same origin as that for
 * pixels. For Google's implementation of the Mercator projection, the origin
 * tile is always at the northwest corner of the map, with x values increasing
 * from west to east and y values increasing from north to south.
 *
 * Try panning and zooming the map to see how the coordinates change.
 */

/** @constructor */
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;
};

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 10,
    center: {lat: 41.850, lng: -87.650}
  });

  // 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)));
}

Voir l'exemple (maptype-overlay.html)

Types de carte d'image

Implémenter un MapType pour l'utiliser comme type de carte de base peut s'avérer long et fastidieux. L'API fournit une classe spéciale qui implémente l'interface MapType pour les types de carte les plus courants, c'est-à-dire les types de carte constitués de tuiles elles-mêmes composées de fichiers d'image uniques.

Cette classe, appelée ImageMapType, est construite en utilisant une spécification d'objet ImageMapTypeOptions qui définit les propriétés obligatoires suivantes :

  • tileSize (obligatoire) spécifie la taille de la tuile (de type google.maps.Size). Les tailles doivent être rectangulaires, mais pas carrées.
  • getTileUrl (obligatoire) spécifie la fonction, généralement fournie en tant que littéral fonction en ligne, pour gérer la sélection de la tuile d'image pertinente en fonction des coordonnées mondiales et du niveau de zoom.

Le code suivant implémente une classe ImageMapType basique au moyen de tuiles Google représentant la lune. Cet exemple utilise une fonction de normalisation pour veiller à ce que les tuiles se répètent le long de l'axe x, mais pas de l'axe y de votre carte.

function initMap() {
  var map = new google.maps.Map(document.getElementById('map'), {
    center: {lat: 0, lng: 0},
    zoom: 1,
    streetViewControl: false,
    mapTypeControlOptions: {
      mapTypeIds: ['moon']
    }
  });

  var moonMapType = new google.maps.ImageMapType({
    getTileUrl: function(coord, zoom) {
        var normalizedCoord = getNormalizedCoord(coord, zoom);
        if (!normalizedCoord) {
          return null;
        }
        var bound = Math.pow(2, zoom);
        return '//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'
  });

  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};
}

Voir l'exemple (maptype-image.html)

Projections

La Terre est une sphère (ou presque) tridimensionnelle, tandis qu'une carte est une surface plane bidimensionnelle. Comme toute autre carte plane de la Terre, la carte que vous voyez dans Google Maps API est une projection de cette sphère sur une surface plane. Pour faire simple, une projection consiste à transformer des valeurs de latitude/longitude en coordonnées sur la carte de la projection.

Dans Google Maps API, les projections doivent implémenter l'interface Projection. Une implémentation de l'interface Projection doit fournir non seulement la traduction d'un système de coordonnées dans un autre, mais également un mappage bidirectionnel. En d'autres termes, vous devez définir comment traduire les coordonnées de la Terre (LatLng) dans le système des coordonnées mondiales de la Projection, et vice versa. Google Maps utilise la projection de Mercator pour créer ses cartes à partir de données géographiques et convertir les événements sur la carte en coordonnées géographiques. Vous pouvez obtenir cette projection en appelant la méthode getProjection() sur l'objet Map (ou toute autre interface MapType de base standard). Pour la plupart des utilisations, cette Projection standard est suffisante. Vous pouvez toutefois définir et utiliser vos propres projections personnalisées.

Implémenter une projection

Lorsque vous implémentez une projection personnalisée, vous devez définir plusieurs paramètres :

  • La formule pour traduire des coordonnées de latitude et de longitude en un plan cartésien, et vice versa. (L'interface Projection ne prend en charge que les transformations en coordonnées rectilignes.)
  • La taille des tuiles de base. Toutes les tuiles doivent être rectangulaires.
  • La « taille mondiale » de la carte au moyen des tuiles de base définies au niveau de zoom 0. Notez que pour les cartes qui consistent en une seule tuile au niveau de zoom 0, la taille mondiale et la taille de la tuile de base sont identiques.

Transformation des coordonnées en projections

Chaque projection fournit deux méthodes pour convertir des coordonnées géographiques en coordonnées mondiales :

  • La méthode Projection.fromLatLngToPoint() convertit une valeur LatLng en une coordonnée mondiale. Cette méthode sert à positionner des superpositions sur la carte (et à positionner la carte elle-même).
  • La méthode Projection.fromPointToLatLng() convertit une coordonnée mondiale en une valeur LatLng. Cette méthode sert à convertir des événements tels que des clics sur la carte en coordonnées géographiques.

Google Maps suppose que les projections sont rectilignes.

En règle générale, vous pouvez utiliser une projection dans deux cas : pour créer une carte du monde ou pour créer une carte d'une zone locale. Dans le premier cas, vous devez veiller à ce que votre projection soit également rectiligne et normale à toutes les longitudes. Certaines projections (en particulier les projections coniques) peuvent être « localement normales » (p. ex. au point nord), mais dévier du nord géographique, notamment lorsque l'on positionne la carte de plus en plus loin de sa longitude de référence. Vous pouvez utiliser une telle projection localement, mais sachez qu'elle manque naturellement de précision et que les erreurs de transformation sont de plus en plus visibles à mesure que vous vous éloignez de la longitude de référence à partir de laquelle vous déviez.

Sélection du type de tuile dans les projections

Les projections ne sont pas seulement utiles pour déterminer la position des points géographiques ou des superpositions, elles permettent également de positionner les tuiles de carte elles-mêmes. Maps API effectue le rendu des cartes de base en utilisant une interface MapType, qui doit déclarer à la fois la propriété projection pour identifier la projection de la carte et une méthode getTile() pour récupérer les tuiles de carte en fonction des valeurs de coordonnées des tuiles. Les coordonnées des tuiles sont basées à la fois sur la taille de vos tuiles basiques (qui doivent être rectangulaires) et la « taille mondiale » de votre carte, c'est-à-dire la taille en pixels de votre carte mondiale au niveau de zoom 0. (Pour les cartes qui consistent en une seule tuile au niveau de zoom 0, la taille de la tuile et la taille mondiale sont identiques.)

Vous définissez la taille de la tuile de base avec la propriété tileSize de votre interface MapType. Vous définissez la taille mondiale de manière implicite avec les méthodes fromLatLngToPoint() et fromPointToLatLng() de votre projection.

Étant donné que la sélection des images dépend des valeurs transmises, il s'avère utile de nommer les images qui peuvent être sélectionnées par programmation en fonction de ces valeurs. Par exemple, en utilisant le format map_zoom_tileX_tileY.png.

L'exemple suivant définit la classe ImageMapType en utilisant la projection de Gall-Peters :

// This example defines an image map type using the Gall-Peters projection.
// https://en.wikipedia.org/wiki/Gall%E2%80%93Peters_projection

function initMap() {
  // Create a map. Use the Gall-Peters map type.
  var map = new google.maps.Map(document.getElementById('map'), {
    zoom: 0,
    center: {lat: 0, lng: 0},
    mapTypeControl: false
  });

  initGallPeters();
  map.mapTypes.set('gallPeters', gallPetersMapType);
  map.setMapTypeId('gallPeters');

  // Show the lat and lng under the mouse cursor.
  var coordsDiv = document.getElementById('coords');
  map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv);
  map.addListener('mousemove', function(event) {
    coordsDiv.textContent =
        'lat: ' + Math.round(event.latLng.lat()) + ', ' +
        'lng: ' + Math.round(event.latLng.lng());
  });

  // Add some markers to the map.
  map.data.setStyle(function(feature) {
    return {
      title: feature.getProperty('name'),
      optimized: false
    };
  });
  map.data.addGeoJson(cities);
}

var gallPetersMapType;
function initGallPeters() {
  var GALL_PETERS_RANGE_X = 800;
  var GALL_PETERS_RANGE_Y = 512;

  // Fetch Gall-Peters tiles stored locally on our server.
  gallPetersMapType = new google.maps.ImageMapType({
    getTileUrl: function(coord, zoom) {
      var scale = 1 << zoom;

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

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

      return 'images/gall-peters_' + zoom + '_' + x + '_' + y + '.png';
    },
    tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y),
    isPng: true,
    minZoom: 0,
    maxZoom: 1,
    name: 'Gall-Peters'
  });

  // Describe the Gall-Peters projection used by these tiles.
  gallPetersMapType.projection = {
    fromLatLngToPoint: function(latLng) {
      var latRadians = latLng.lat() * Math.PI / 180;
      return new google.maps.Point(
          GALL_PETERS_RANGE_X * (0.5 + latLng.lng() / 360),
          GALL_PETERS_RANGE_Y * (0.5 - 0.5 * Math.sin(latRadians)));
    },
    fromPointToLatLng: function(point, noWrap) {
      var x = point.x / GALL_PETERS_RANGE_X;
      var y = Math.max(0, Math.min(1, point.y / GALL_PETERS_RANGE_Y));

      return new google.maps.LatLng(
          Math.asin(1 - 2 * y) * 180 / Math.PI,
          -180 + 360 * x,
          noWrap);
    }
  };
}

// GeoJSON, describing the locations and names of some cities.
var cities = {
  type: 'FeatureCollection',
  features: [{
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [-87.650, 41.850]},
    properties: {name: 'Chicago'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [-149.900, 61.218]},
    properties: {name: 'Anchorage'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [-99.127, 19.427]},
    properties: {name: 'Mexico City'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [-0.126, 51.500]},
    properties: {name: 'London'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [28.045, -26.201]},
    properties: {name: 'Johannesburg'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [15.322, -4.325]},
    properties: {name: 'Kinshasa'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [151.207, -33.867]},
    properties: {name: 'Sydney'}
  }, {
    type: 'Feature',
    geometry: {type: 'Point', coordinates: [0, 0]},
    properties: {name: '0°N 0°E'}
  }]
};

Voir l'exemple (map-projection-simple.html)

Envoyer des commentaires concernant…

Google Maps JavaScript API
Google Maps JavaScript API
Besoin d'aide ? Consultez notre page d'assistance.