Tipi di mappa

Seleziona la piattaforma: Android iOS JavaScript

Questo documento illustra i tipi di mappe che puoi visualizzare utilizzando API Maps JavaScript. L'API utilizza un MapType di conservare le informazioni su queste mappe. MapType è un'interfaccia che definisce la visualizzazione e l'utilizzo dei riquadri della mappa la traduzione dei sistemi di coordinate dalle coordinate sullo schermo al mondo coordinate (sulla mappa). Ogni MapType deve contenere un oggetto alcuni metodi per gestire il recupero e il rilascio di riquadri e proprietà che ne definiscono il comportamento visivo.

I meccanismi interni dei tipi di mappe all'interno dell'API Maps JavaScript è un argomento avanzato. La maggior parte degli sviluppatori può utilizzare lo tipi di mappe di base indicati di seguito. Tuttavia, puoi anche modificare la presentazione tipi di mappe esistenti utilizzando le Mappe con stile o definisci i tuoi riquadri di mappe utilizzando i tipi di mappe personalizzate. Quando fornisci tipi di mappe personalizzate, devi capire come modificare il registro dei tipi di mappe.

Tipi di mappe di base

Nell'API Maps JavaScript sono disponibili quattro tipi di mappe. Oltre al noto "dipinto" i riquadri della mappa stradale, L'API Maps JavaScript supporta anche altri tipi di mappe.

Nell'API Maps JavaScript sono disponibili i seguenti tipi di mappe:

  • roadmap mostra la visualizzazione della mappa stradale predefinita. Questo è il tipo di mappa predefinito.
  • satellite mostra il satellite di Google Earth in formato Docker.
  • hybrid mostra una combinazione di temperatura normale e satellitare visualizzazioni.
  • terrain mostra una mappa fisica basata sul rilievo informazioni.

Puoi modificare il tipo di mappa utilizzato da Map impostandone il tipo Proprietà mapTypeId, all'interno del costruttore tramite impostazione il suo oggetto Map options, oppure richiamando il metodo setMapTypeId(). La proprietà mapTypeID il valore predefinito è roadmap.

Impostazione di mapTypeId al momento della costruzione:

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

Modifica di mapTypeId in modo dinamico:

map.setMapTypeId('terrain');

Tieni presente che in realtà non imposti direttamente il tipo di mappa della mappa, ma imposta invece mapTypeId in modo che faccia riferimento a un MapType utilizzando un identificatore. L'API Maps JavaScript utilizza un registro dei tipi di mappe, come spiegato di seguito per gestire questi riferimenti.

Immagini a 45°

L'API Maps JavaScript supporta immagini speciali a 45° per determinate località. Queste immagini ad alta risoluzione offrono visualizzazioni prospettiche verso ciascuna direzione cardinale (Nord, Sud, Est, Ovest). Queste immagini sono disponibili a una livelli di zoom per i tipi di mappe supportati.

La seguente immagine mostra una vista in prospettiva a 45° di New York:

I tipi di mappe satellite e hybrid supportano la rotazione a 45° immagini ad alti livelli di zoom (12 e superiori), se disponibili. Se l'utente aumenta lo zoom su una posizione per cui esistono tali immagini, questi tipi di mappe modificare automaticamente le proprie visualizzazioni nel seguente modo:

  • Le immagini satellitari o ibride vengono sostituite con immagini con un angolo di 45°. prospettiva, centrata sulla posizione corrente. Per impostazione predefinita, orientata verso nord. Se l'utente diminuirà lo zoom, verranno visualizzati i valori vengono visualizzate di nuovo le immagini ibride. Il comportamento varia in base al livello di zoom e il valore di tilt:
    • Tra i livelli di zoom 12 e 18, viene visualizzata la mappa base dall'alto verso il basso (0°) di predefinito, a meno che tilt non sia impostato su 45.
    • A livelli di zoom pari o superiori a 18, viene visualizzata la mappa base a 45°, a meno che Il valore tilt è impostato su 0.
  • Il controllo di rotazione diventa visibile. Il controllo Ruota offre opzioni che consentono all'utente di attivare/disattivare l'inclinazione e di ruotare la vista di 90° incrementi in entrambe le direzioni. Per nascondere il controllo di rotazione, imposta Da rotateControl a false.

Diminuisci lo zoom su un tipo di mappa che mostra immagini a 45° per il ripristino ciascuna di queste modifiche, ripristinando i tipi di mappa originali.

Attivazione e disattivazione delle immagini a 45°

Puoi disattivare le immagini a 45° chiamando setTilt(0) sulla Oggetto Map. Per attivare le immagini a 45° per i tipi di mappe supportati: chiama setTilt(45). getTilt() di Map rifletterà sempre l'attuale tilt mostrato nel mappa; se imposti tilt su una mappa e poi lo rimuovi tilt (ad esempio diminuendo lo zoom della mappa), lo stato getTilt() restituirà 0.

Importante:le immagini a 45° sono supportate solo su mappe raster; queste immagini non possono essere utilizzate con le mappe vettoriali.

L'esempio seguente mostra una vista a 45° di New York:

TypeScript

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      center: { lat: 40.76, lng: -73.983 },
      zoom: 15,
      mapTypeId: "satellite",
    }
  );

  map.setTilt(45);
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.76, lng: -73.983 },
    zoom: 15,
    mapTypeId: "satellite",
  });

  map.setTilt(45);
}

window.initMap = initMap;
Visualizza esempio

Prova Sample

Visualizza esempio.

Rotazione delle immagini di 45°

Le immagini a 45° sono in realtà una raccolta di immagini per ciascuna direzione cardinale (Nord, Sud, Est, Ovest). Una volta che la mappa mostra immagini a 45°, puoi orientare a una delle sue direzioni cardinali chiamando setHeading() sull'oggetto Map, passaggio un valore numerico espresso in gradi dal nord.

L'esempio seguente mostra una mappa aerea e la rotazione automatica la mappa ogni 3 secondi quando l'utente fa clic sul pulsante:

TypeScript

let map: google.maps.Map;

function initMap(): void {
  map = new google.maps.Map(document.getElementById("map") as HTMLElement, {
    center: { lat: 40.76, lng: -73.983 },
    zoom: 15,
    mapTypeId: "satellite",
    heading: 90,
    tilt: 45,
  });

  // add listener to button
  document.getElementById("rotate")!.addEventListener("click", autoRotate);
}

function rotate90(): void {
  const heading = map.getHeading() || 0;

  map.setHeading(heading + 90);
}

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

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

let map;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 40.76, lng: -73.983 },
    zoom: 15,
    mapTypeId: "satellite",
    heading: 90,
    tilt: 45,
  });
  // add listener to button
  document.getElementById("rotate").addEventListener("click", autoRotate);
}

function rotate90() {
  const 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);
  }
}

window.initMap = initMap;
Visualizza esempio

Prova Sample

Visualizza esempio.

Modifica del registro dei tipi di mappa

Il valore mapTypeId di una mappa è un identificatore di stringa utilizzato per associare MapType a un valore univoco. Ogni oggetto Map mantiene MapTypeRegistry che contiene la raccolta MapType disponibili per quella mappa. Questo registro viene utilizzato per selezionare i tipi di mappe disponibili il controllo MapType di Map, ad esempio.

Non leggi direttamente dal registro dei tipi di mappe. Invece, puoi modificare il registro aggiungendo tipi di mappe personalizzate e associando con un identificatore di stringa di tua scelta. Non puoi modificare o modificare i tipi di mappe di base (ma puoi rimuoverli dal modificando l'aspetto degli elementi associati alla mappa mapTypeControlOptions).

Il seguente codice imposta la mappa in modo che mostri solo due tipi di mappa nell'elemento mapTypeControlOptions della mappa e modifica il registry per aggiungere l'associazione questo identificatore all'implementazione effettiva MapType.

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

var MY_MAPTYPE_ID = 'mymaps';

var mapOptions = {
  zoom: 12,
  center: brooklyn,
  mapTypeControlOptions: {
     mapTypeIds: ['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);

Mappe con stile

Il StyledMapType consente di personalizzare la presentazione le mappe base standard di Google, modificando la visualizzazione visiva di tali elementi come strade, parchi e centri abitati, per riflettere uno stile diverso. utilizzata nel tipo di mappa predefinito.

Per ulteriori informazioni sul StyledMapType, consulta la guida per mappe con stili applicati.

Tipi di mappe personalizzate

L'API Maps JavaScript supporta la visualizzazione e la gestione di tipi di mappe personalizzate, consentendoti di implementare le tue immagini di mappe o overlay di riquadri.

Esistono diverse possibili implementazioni di tipi di mappa all'interno della API Maps JavaScript:

  • Set di riquadri standard costituiti da immagini costituiscono collettivamente mappe cartografiche complete. Questi riquadri gli insiemi sono noti anche come tipi di mappe base. Questi tipi di mappe funzionano e si comportano come i tipi di mappe predefiniti esistenti: roadmap, satellite, hybrid e terrain. Puoi aggiungere un tipo di mappa personalizzato all'array mapTypes di una mappa per consenti all'interfaccia utente dell'API Maps JavaScript di Considera il tipo di mappa personalizzata come un tipo di mappa standard (includendolo nel MapType gruppo di controllo, ad esempio).
  • Overlay del riquadro dell'immagine visualizzati sopra a tipi di mappe base esistenti. In genere, questi tipi di mappe utilizzati per arricchire un tipo di mappa esistente per mostrare ulteriori informazioni e sono spesso limitati a località specifiche e/o livelli di zoom. Tieni presente che questi riquadri possono essere trasparenti, consentendoti di aggiungere elementi a mappe esistenti.
  • I tipi di mappe non immagine, che ti consentono di manipolare la visualizzazione delle informazioni sulla mappa al suo livello più fondamentale.

Ognuna di queste opzioni si basa sulla creazione di un corso implementa MapType a riga di comando. Inoltre, lo La classe ImageMapType offre alcune funzionalità per semplificare la creazione di tipi di mappe con immagini.

Interfaccia di MapType

Prima di creare corsi che implementano MapType, è importante capire in che modo Google Maps determina coordinate e decide quali parti della mappa mostrare. Devi implementare una logica simile per qualsiasi tipo di mappa di base o overlay. Leggi la guida alla mappatura e coordinate dei riquadri.

I tipi di mappe personalizzate devono implementare l'MapType a riga di comando. Questa interfaccia specifica alcune proprietà metodi che consentono all'API di avviare richieste alla tua mappa tipi quando l'API determina che deve visualizzare la mappa riquadri all'interno dell'area visibile e del livello di zoom correnti. Tu gestisci per decidere quale riquadro caricare.

Nota: puoi creare i tuoi per implementare questa interfaccia. In alternativa, se disponi immagini compatibili puoi utilizzare lo ImageMapType che implementa già questa interfaccia.

Classi che implementano l'interfaccia MapType richiedono la definizione e la compilazione delle seguenti proprietà:

  • tileSize (obbligatorio) specifica le dimensioni del riquadro (di tipo google.maps.Size). Le dimensioni devono essere rettangolari anche se non devono essere quadrati.
  • maxZoom (obbligatorio) specifica lo zoom massimo livello al quale visualizzare i riquadri di questo tipo di mappa.
  • minZoom (facoltativo) specifica lo zoom minimo livello al quale visualizzare il riquadro di questo tipo di mappa. Per impostazione predefinita, questo valore è 0 e indica che non esiste nessun valore minimo il livello di zoom esiste.
  • name (facoltativo) specifica il nome di questa mappa di testo. Questa proprietà è necessaria solo se vuoi questo tipo di mappa affinché sia selezionabile all'interno di un controllo MapType. Vedi la sezione Aggiunta di MapType controlli di seguito.
  • alt (facoltativo) specifica il testo alternativo tipo di mappa, mostrato come testo al passaggio del mouse. Questa proprietà è necessaria solo se vuoi che questo tipo di mappa sia selezionabile all'interno di un controllo MapType. Consulta la sezione Aggiungere MapType controlli below.)

Inoltre, i corsi che implementano l'interfaccia MapType devi implementare i seguenti metodi:

  • getTile() (obbligatorio) viene chiamato ogni volta che l'API determina che la mappa deve visualizzare nuovi riquadri area visibile. Il metodo getTile() deve avere quanto segue firma:

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

    L'API determina se deve chiamare getTile() in base ai tileSize di MapType, minZoom e maxZoom proprietà e l'area visibile e il livello di zoom correnti della mappa. Il gestore per questo metodo dovrebbe restituire un elemento HTML data una coordinata passata, livello di zoom ed elemento DOM a cui aggiungere l'immagine riquadro.

  • releaseTile() (facoltativo) viene chiamato ogni volta che l'API determina che la mappa deve rimuovere un riquadro quando non è più visibile. Questo metodo deve avere la seguente firma:

    releaseTile(tile:Node)

    In genere dovresti gestire la rimozione di tutti gli elementi allegati ai riquadri della mappa dopo l'aggiunta alla mappa. Ad esempio, se hai allegato un listener di eventi al riquadro della mappa. overlay, devi rimuoverli qui.

Il metodo getTile() funge da controller principale per determinare quali riquadri caricare all'interno di una determinata area visibile.

Tipi di mappe base

I tipi di mappe che costruisci in questo modo possono essere da solo o combinati con altri tipi di mappe sotto forma di overlay. Autonoma I tipi di mappe sono noti come tipi di mappe base. Ti consigliamo di impostare l'API tratta questi MapType personalizzati come tipo di mappa base (ROADMAP, TERRAIN e così via). Da fare quindi aggiungi il tuo MapType personalizzato alMap proprietà mapTypes. Questa proprietà è di tipo MapTypeRegistry.

Il seguente codice crea un MapType di base da visualizzare le coordinate dei riquadri di una mappa e disegna il contorno dei riquadri:

TypeScript

/*
 * 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.
 */

class CoordMapType {
  tileSize: google.maps.Size;
  maxZoom = 19;
  name = "Tile #s";
  alt = "Tile Coordinate Map Type";

  constructor(tileSize: google.maps.Size) {
    this.tileSize = tileSize;
  }

  getTile(
    coord: google.maps.Point,
    zoom: number,
    ownerDocument: Document
  ): HTMLElement {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(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;
  }

  releaseTile(tile: HTMLElement): void {}
}

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 10,
      center: { lat: 41.85, lng: -87.65 },
      streetViewControl: false,
      mapTypeId: "coordinate",
      mapTypeControlOptions: {
        mapTypeIds: ["coordinate", "roadmap"],
        style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
      },
    }
  );

  map.addListener("maptypeid_changed", () => {
    const showStreetViewControl =
      (map.getMapTypeId() as string) !== "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))
  );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

/*
 * 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.
 */
class CoordMapType {
  tileSize;
  maxZoom = 19;
  name = "Tile #s";
  alt = "Tile Coordinate Map Type";
  constructor(tileSize) {
    this.tileSize = tileSize;
  }
  getTile(coord, zoom, ownerDocument) {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(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;
  }
  releaseTile(tile) {}
}

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 10,
    center: { lat: 41.85, lng: -87.65 },
    streetViewControl: false,
    mapTypeId: "coordinate",
    mapTypeControlOptions: {
      mapTypeIds: ["coordinate", "roadmap"],
      style: google.maps.MapTypeControlStyle.DROPDOWN_MENU,
    },
  });

  map.addListener("maptypeid_changed", () => {
    const 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)),
  );
}

window.initMap = initMap;
Visualizza esempio

Prova Sample

Tipi di mappe overlay

Alcuni tipi di mappe sono progettati per funzionare sulla mappa esistente di testo. Questi tipi di mappe possono avere livelli trasparenti che indicano punti d'interesse o mostrando dati aggiuntivi all'utente.

In questi casi, non vuoi che il tipo di mappa venga considerato come un'entità separata, ma come un overlay. Puoi farlo aggiungendo direttamente il tipo di mappa a un MapType esistente utilizzando proprietà overlayMapTypes di Map. Questa proprietà contiene MVCArray di MapType. Tutti i tipi di mappe (di base e overlay) vengono visualizzati mapPane livello di sicurezza. I tipi di mappe di overlay verranno visualizzati sopra la mappa base sono allegati, nell'ordine in cui appaiono nel Array Map.overlayMapTypes (overlay con indice più alto vengono visualizzati davanti agli overlay con valori di indice più bassi).

L'esempio seguente è identico a quello precedente abbiamo creato un overlay riquadro MapType sopra il tipo di mappa ROADMAP:

TypeScript

/*
 * 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.
 */

class CoordMapType implements google.maps.MapType {
  tileSize: google.maps.Size;
  alt: string|null = null;
  maxZoom: number = 17;
  minZoom: number = 0;
  name: string|null = null;
  projection: google.maps.Projection|null = null;
  radius: number = 6378137;

  constructor(tileSize: google.maps.Size) {
    this.tileSize = tileSize;
  }
  getTile(
    coord: google.maps.Point,
    zoom: number,
    ownerDocument: Document
  ): HTMLElement {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(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;
  }
  releaseTile(tile: Element): void {}
}

function initMap(): void {
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      zoom: 10,
      center: { lat: 41.85, lng: -87.65 },
    }
  );

  // 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.
  const coordMapType = new CoordMapType(new google.maps.Size(256, 256))
  map.overlayMapTypes.insertAt(
    0,
    coordMapType
  );
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

/*
 * 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.
 */
class CoordMapType {
  tileSize;
  alt = null;
  maxZoom = 17;
  minZoom = 0;
  name = null;
  projection = null;
  radius = 6378137;
  constructor(tileSize) {
    this.tileSize = tileSize;
  }
  getTile(coord, zoom, ownerDocument) {
    const div = ownerDocument.createElement("div");

    div.innerHTML = String(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;
  }
  releaseTile(tile) {}
}

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    zoom: 10,
    center: { lat: 41.85, lng: -87.65 },
  });
  // 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.
  const coordMapType = new CoordMapType(new google.maps.Size(256, 256));

  map.overlayMapTypes.insertAt(0, coordMapType);
}

window.initMap = initMap;
Visualizza esempio

Prova Sample

Tipi di mappe immagine

È in corso l'implementazione di un MapType in modo che agisca come mappa base. può essere un'attività laboriosa e dispendiosa in termini di tempo. L'API fornisce una classe speciale che implementa l'MapType interfaccia per i tipi di mappe più comuni: i tipi di mappe che consistono di riquadri composti da singoli file immagine.

Questo corso, il corso ImageMapType, viene creato utilizzando un ImageMapTypeOptions che definisce le seguenti caratteristiche proprietà:

  • tileSize (obbligatorio) specifica le dimensioni del riquadro (di tipo google.maps.Size). Le dimensioni devono essere rettangolari anche se non devono essere quadrati.
  • getTileUrl (obbligatorio) specifica la funzione, solitamente fornito come valore letterale di funzione inline, per gestire del riquadro immagine appropriato in base alle informazioni fornite le coordinate del mondo e il livello di zoom.

Il seguente codice implementa un ImageMapType di base utilizzando i riquadri della luna di Google. L'esempio utilizza una funzione di normalizzazione per far sì che i riquadri si ripetano lungo l'asse x, ma non lungo sull'asse y della mappa.

TypeScript

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

  const moonMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom): string {
      const normalizedCoord = getNormalizedCoord(coord, zoom);

      if (!normalizedCoord) {
        return "";
      }

      const bound = Math.pow(2, zoom);
      return (
        "https://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,
    // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions'
    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) {
  const y = coord.y;
  let 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
  const 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 };
}

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

function initMap() {
  const map = new google.maps.Map(document.getElementById("map"), {
    center: { lat: 0, lng: 0 },
    zoom: 1,
    streetViewControl: false,
    mapTypeControlOptions: {
      mapTypeIds: ["moon"],
    },
  });
  const moonMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
      const normalizedCoord = getNormalizedCoord(coord, zoom);

      if (!normalizedCoord) {
        return "";
      }

      const bound = Math.pow(2, zoom);
      return (
        "https://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,
    // @ts-ignore TODO 'radius' does not exist in type 'ImageMapTypeOptions'
    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) {
  const y = coord.y;
  let 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
  const 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 };
}

window.initMap = initMap;
Visualizza esempio

Prova Sample

Proiezioni

La Terra è una sfera tridimensionale (approssimativamente), mentre una è una superficie piatta bidimensionale. La mappa visualizzata all'interno l'API Maps JavaScript, come qualsiasi mappa piana della Terra, è una proiezione della sfera su una superficie piana. Nella sua termini, una proiezione può essere definita come una mappatura valori di latitudine/longitudine in coordinate sulla mappa della proiezione.

Le proiezioni nell'API Maps JavaScript devono implementare il parametro interfaccia di Projection. Projection l'implementazione deve fornire non solo una mappatura da una coordinata da un sistema all'altro, ma una mappatura bidirezionale. Vale a dire che definisci come traslare dalle coordinate di Earth (LatLng oggetti) al corso Projection mondo di coordinamento e viceversa. Google Maps utilizza la proiezione di Mercatore per creare le sue mappe dai dati geografici e convertire gli eventi sulla mappa in coordinate geografiche. Puoi ottenere questa proiezione chiamata getProjection() su Map (o qualsiasi tipo di MapType base standard). Per la maggior parte degli utilizzi, questo Projection standard è sufficiente, ma puoi anche per definire e usare proiezioni personalizzate.

Implementazione di una proiezione

Quando implementi una proiezione personalizzata, devi definire alcune cose:

  • Le formule per mappare le coordinate di latitudine e longitudine su un piano cartesiano e viceversa. (Interfaccia di Projection supporta solo trasformazioni in coordinate rettilinee.)
  • Le dimensioni del riquadro di base. Tutti i riquadri devono essere rettangolari.
  • La "dimensione mondiale" di una mappa utilizzando il riquadro base impostato a livello di zoom 0. Tieni presente che, per le mappe costituite da un riquadro con zoom pari a 0, le dimensioni del mondo e le dimensioni del riquadro di base sono identiche.

Coordina le trasformazioni in Proiezioni

Ogni proiezione fornisce due metodi che traducono sistemi di coordinate, che consentono di convertire tra regioni coordinate mondiali:

  • Il metodo Projection.fromLatLngToPoint() converte un LatLng in una coordinata mondiale. Questo metodo è utilizzato per posizionare gli overlay sulla mappa (e per posizionare la mappa stessa).
  • Il metodo Projection.fromPointToLatLng() converte una coordinata mondiale in un valore LatLng. Questo viene utilizzato per convertire eventi come i clic che si verificano mappato in coordinate geografiche.

Google Maps presuppone che le proiezioni siano rettilinee.

In genere, puoi utilizzare una proiezione per due casi: per creare un mappa del mondo o per creare una mappa di un'area locale. Nel primo caso, dovresti assicurarti che la proiezione sia anche rettilinea e normale a tutte le longitudini. Alcune proiezioni (in particolare quelle coniche) può essere "localmente normale" (ovvero puntare a nord), ma deviare dal vero nord; Ad esempio, più la mappa è posizionata rispetto ad alcuni longitudine di riferimento. Puoi usare questa proiezione localmente, ma consapevoli che la proiezione è necessariamente imprecisa e che gli errori diventeranno sempre più apparentemente la longitudine di riferimento della deviazione.

Selezione dei riquadri della mappa nelle proiezioni

Le proiezioni non sono utili solo per determinare le posizioni dei luoghi o overlay, ma per il posizionamento dei riquadri della mappa stessi. L'API Maps JavaScript esegue il rendering delle mappe base utilizzando un'istruzione MapType che deve dichiarare sia una proprietà projection per identificando la proiezione della mappa e un getTile() per recuperare i riquadri della mappa in base a riquadro di Google Cloud. Le coordinate dei riquadri sono basate su sia la dimensione base della casella (che deve essere rettangolare) sia il "mondo dimensione" della tua mappa, che è la dimensione in pixel del tuo mondo a un livello di zoom pari a 0. (per le mappe costituite da un riquadro con zoom pari a 0, il riquadro dimensione e dimensione del mondo sono identiche.)

Sei tu a definire le dimensioni del riquadro di base all'interno del campoMapType proprietà tileSize. La dimensione del mondo viene definita implicitamente in modo implicito all'interno dell'intervallo fromLatLngToPoint() della proiezione e fromPointToLatLng().

Poiché la selezione delle immagini dipende da questi valori passati, è utile assegnare un nome alle immagini che possono essere selezionate in modo programmatico i valori passati, come map_zoom_tileX_tileY.png.

L'esempio seguente definisce un ImageMapType utilizzando Proiezione di Gall-Peters:

TypeScript

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

function initMap(): void {
  // Create a map. Use the Gall-Peters map type.
  const map = new google.maps.Map(
    document.getElementById("map") as HTMLElement,
    {
      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.
  const coordsDiv = document.getElementById("coords") as HTMLElement;

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv);
  map.addListener("mousemove", (event: google.maps.MapMouseEvent) => {
    coordsDiv.textContent =
      "lat: " +
      Math.round(event.latLng!.lat()) +
      ", " +
      "lng: " +
      Math.round(event.latLng!.lng());
  });

  // Add some markers to the map.
  map.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name") as string,
      optimized: false,
    };
  });
  map.data.addGeoJson(cities);
}

let gallPetersMapType;

function initGallPeters() {
  const GALL_PETERS_RANGE_X = 800;
  const GALL_PETERS_RANGE_Y = 512;

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

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

      // Don't wrap tiles vertically.
      const y = coord.y;

      if (y < 0 || y >= scale) return "";

      return (
        "https://developers.google.com/maps/documentation/" +
        "javascript/examples/full/images/gall-peters_" +
        zoom +
        "_" +
        x +
        "_" +
        y +
        ".png"
      );
    },
    tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y),
    minZoom: 0,
    maxZoom: 1,
    name: "Gall-Peters",
  });

  // Describe the Gall-Peters projection used by these tiles.
  gallPetersMapType.projection = {
    fromLatLngToPoint: function (latLng) {
      const 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) {
      const x = point.x / GALL_PETERS_RANGE_X;
      const 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.
const cities = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-87.65, 41.85] },
      properties: { name: "Chicago" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-149.9, 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.5] },
      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" },
    },
  ],
};

declare global {
  interface Window {
    initMap: () => void;
  }
}
window.initMap = initMap;

JavaScript

// 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.
  const 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.
  const coordsDiv = document.getElementById("coords");

  map.controls[google.maps.ControlPosition.TOP_CENTER].push(coordsDiv);
  map.addListener("mousemove", (event) => {
    coordsDiv.textContent =
      "lat: " +
      Math.round(event.latLng.lat()) +
      ", " +
      "lng: " +
      Math.round(event.latLng.lng());
  });
  // Add some markers to the map.
  map.data.setStyle((feature) => {
    return {
      title: feature.getProperty("name"),
      optimized: false,
    };
  });
  map.data.addGeoJson(cities);
}

let gallPetersMapType;

function initGallPeters() {
  const GALL_PETERS_RANGE_X = 800;
  const GALL_PETERS_RANGE_Y = 512;

  // Fetch Gall-Peters tiles stored locally on our server.
  gallPetersMapType = new google.maps.ImageMapType({
    getTileUrl: function (coord, zoom) {
      const scale = 1 << zoom;
      // Wrap tiles horizontally.
      const x = ((coord.x % scale) + scale) % scale;
      // Don't wrap tiles vertically.
      const y = coord.y;

      if (y < 0 || y >= scale) return "";
      return (
        "https://developers.google.com/maps/documentation/" +
        "javascript/examples/full/images/gall-peters_" +
        zoom +
        "_" +
        x +
        "_" +
        y +
        ".png"
      );
    },
    tileSize: new google.maps.Size(GALL_PETERS_RANGE_X, GALL_PETERS_RANGE_Y),
    minZoom: 0,
    maxZoom: 1,
    name: "Gall-Peters",
  });
  // Describe the Gall-Peters projection used by these tiles.
  gallPetersMapType.projection = {
    fromLatLngToPoint: function (latLng) {
      const 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) {
      const x = point.x / GALL_PETERS_RANGE_X;
      const 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.
const cities = {
  type: "FeatureCollection",
  features: [
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-87.65, 41.85] },
      properties: { name: "Chicago" },
    },
    {
      type: "Feature",
      geometry: { type: "Point", coordinates: [-149.9, 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.5] },
      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" },
    },
  ],
};

window.initMap = initMap;
Visualizza esempio

Prova Sample