Kartentypen

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.
Plattform auswählen: Android iOS JavaScript

In diesem Dokument werden die Kartentypen erläutert, die Sie mit der Maps JavaScript API anzeigen lassen können. Die API verwendet ein MapType-Objekt, um Informationen zu diesen Karten zu speichern. Ein MapType ist eine Schnittstelle, die die Anzeige und Nutzung der Kartenkacheln und die Umwandlung der Koordinatensysteme von Bildschirmkoordinaten in Weltkoordinaten (auf der Karte) definiert. Jedes MapType-Objekt muss einige Methoden enthalten, um den Abruf und die Freigabe von Kacheln durchzuführen, sowie Properties, die ihr visuelles Verhalten definieren.

Die Funktionsweise von Kartentypen in der Maps JavaScript API ist ein fortgeschrittenes Thema. Die meisten Entwickler können die unten aufgeführten grundlegenden Kartentypen verwenden. Sie können aber auch die Darstellung vorhandener Kartentypen mit Karten mit benutzerdefinierten Stilen ändern oder eigene Kartenkacheln mithilfe von benutzerdefinierten Kartentypen definieren. Wenn Sie benutzerdefinierte Kartentypen bereitstellen, müssen Sie wissen, wie Sie die Kartentypregistrierung ändern.

Basiskartentypen

In der Maps JavaScript API sind vier Kartentypen verfügbar. Neben den bekannten „gezeichneten“ Straßenkartenkacheln unterstützt die Maps JavaScript API auch andere Kartentypen.

Die folgenden Kartentypen sind in der Maps JavaScript API verfügbar:

  • roadmap zeigt die Standard-Straßenkartenansicht an. Dies ist der Standardkartentyp.
  • satellite zeigt Google Earth-Satellitenbilder an.
  • hybrid zeigt eine Mischung aus der normalen und der Satellitenansicht.
  • terrain zeigt eine physische Karte, die auf Geländeinformationen basiert.

Du kannst den von Map verwendeten Kartentyp ändern, indem du die Property mapTypeId entweder im Konstruktor durch Festlegen des Map options-Objekts oder durch Aufrufen der setMapTypeId()-Methode der Karte festlegst. Die Property mapTypeID ist standardmäßig auf roadmap gesetzt.

mapTypeId wird beim Erstellen festgelegt:

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

mapTypeId dynamisch ändern:

map.setMapTypeId('terrain');

Beachten Sie, dass Sie den Kartentyp nicht direkt festlegen, sondern mithilfe einer ID mit dem mapTypeId auf einen MapType verweisen. Die Maps JavaScript API verwendet eine Kartentypregistrierung, wie unten erläutert, um diese Referenzen zu verwalten.

45 °-Bilder

Die Maps JavaScript API unterstützt spezielle 45°-Bilder für bestimmte Standorte. Diese hochauflösenden Bilder bieten perspektivische Ansichten der einzelnen Himmelsrichtungen (Norden, Süden, Osten, Westen). Für unterstützte Kartentypen sind diese Bilder in höheren Zoomstufen verfügbar.

Die folgende Abbildung zeigt eine perspektivische 45°-Ansicht von New York City:

Die Kartentypen satellite und hybrid unterstützen 45°-Bilder bei hohen Zoomstufen (12 und höher), sofern verfügbar. Zoomt der Nutzer einen Ort, für den solche Bilder vorhanden sind, vergrößert sich die Ansicht automatisch durch die folgenden Kartentypen:

  • Das Satelliten- oder Hybridbild wird durch Bilder mit einer 45°-Perspektive in der Mitte des aktuellen Standorts ersetzt. Diese Ansichten sind standardmäßig nach Norden ausgerichtet. Wenn der Nutzer herauszoomt, erscheinen wieder die Standard-Satelliten- oder Hybridbilder. Das Verhalten variiert je nach Zoomstufe und dem Wert von tilt:
    • Zwischen den Zoomstufen 12 und 18 wird die Top-down-Basiskarte (0°) standardmäßig angezeigt, sofern tilt nicht auf 45 festgelegt ist.
    • Bei Zoomstufen 18 oder größer wird die 45°-Basiskarte angezeigt, sofern tilt nicht auf 0 gesetzt ist.
  • Das Steuerelement zum Drehen wird sichtbar. Das Drehsteuerelement bietet Optionen, mit denen der Nutzer die Neigung ein- und ausschalten kann und die Ansicht in 90°-Schritten gedreht werden kann. Setzen Sie rotateControl auf false, um das Rotationssteuerelement auszublenden.

Wenn Sie aus einem Kartentyp herauszoomen, der 45°-Bilder enthält, werden alle diese Änderungen rückgängig gemacht und die ursprünglichen Kartentypen wiederhergestellt.

45 °-Bilder aktivieren und deaktivieren

Du kannst 45°-Bilder deaktivieren, indem du setTilt(0) für das Map-Objekt aufrufst. Rufen Sie setTilt(45) auf, um 45°-Bilder für unterstützte Kartentypen zu aktivieren. Die Methode getTilt() von Map gibt immer die aktuelle tilt wieder, die auf der Karte angezeigt wird. Wenn du eine tilt auf einer Karte festlegst und diese tilt später entfernst (z. B. durch Herauszoomen aus der Karte), gibt die Methode getTilt() der Karte 0 zurück.

Wichtig: 45°-Bilder werden nur auf Rasterkarten unterstützt und können nicht mit Vektorkarten verwendet werden.

Im folgenden Beispiel sehen Sie eine 45°-Ansicht von New York City:

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;
Beispiel ansehen

Beispiel ausprobieren

Beispiel ansehen

45 °-Bilder drehen

Die 45°-Bilder bestehen eigentlich aus einer Sammlung von Bildern für jede Himmelsrichtung (Norden, Süden, Osten, Westen). Sobald auf der Karte 45°-Bilder angezeigt werden, können Sie das Bildmaterial an einer Himmelsrichtung ausrichten, indem Sie setHeading() für das Objekt Map aufrufen und einen Zahlenwert übergeben, der in Graden relativ zum Norden ausgedrückt wird.

Das folgende Beispiel zeigt eine Luftaufnahme. Die Karte wird automatisch alle drei Sekunden gedreht, wenn auf die Schaltfläche geklickt wird:

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;
Beispiel ansehen

Beispiel ausprobieren

Beispiel ansehen

Map Type Registry bearbeiten

Ein mapTypeId einer Zuordnung ist eine String-ID, mit der ein MapType einem eindeutigen Wert zugeordnet wird. Jedes Map-Objekt verwaltet ein MapTypeRegistry, das die Sammlung der verfügbaren MapTypes für diese Karte enthält. Mit dieser Registry werden beispielsweise die Kartentypen ausgewählt, die im Karten-Kartensteuerelement verfügbar sind.

Sie können keine Daten direkt aus der Map Type Registry beziehen. Stattdessen können Sie die Registry ändern, indem Sie benutzerdefinierte Kartentypen hinzufügen und mit einer String-ID Ihrer Wahl verknüpfen. Sie können die grundlegenden Kartentypen nicht ändern, aber Sie können sie von der Karte entfernen, indem Sie die Darstellung der mit mapTypeControlOptions verknüpften Karten ändern.

Mit dem folgenden Code wird festgelegt, dass die Karte nur zwei Kartentypen in der Karte mapTypeControlOptions anzeigt und die Registry so ändert, dass die Verknüpfung mit dieser Kennung der tatsächlichen Implementierung der Schnittstelle MapType hinzugefügt wird.

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

Formatierte Karten

Mit StyledMapType können Sie die Darstellung von standardmäßigen grundlegenden Google-Karten anpassen, indem Sie Elemente wie Straßen, Parks und bebaute Flächen in einem anderen visuellen Stil anzeigen als beim Standardkartentyp.

Weitere Informationen zu StyledMapType findest du in der Anleitung zu Karten mit benutzerdefinierten Stilen.

Benutzerdefinierte Kartentypen

Die Maps JavaScript API unterstützt die Anzeige und Verwaltung benutzerdefinierter Kartentypen, sodass Sie Ihre eigenen Kartenbilder oder Kachel-Overlays implementieren können.

In der Maps JavaScript API gibt es mehrere mögliche Kartentypimplementierungen:

  • Standardkachelsätze, die aus Bildern bestehen, die zusammen vollständige kartografische Karten ergeben. Diese Kachelsätze werden auch als Basiskartentypen bezeichnet. Die folgenden Kartentypen verhalten sich wie die vorhandenen Standardkartentypen: roadmap, satellite, hybrid und terrain. Du kannst deinen benutzerdefinierten Kartentyp zu einem mapTypes-Array hinzufügen, damit er von der UI der Maps JavaScript API als Standardkartentyp behandelt werden kann (z. B. durch Einbindung in das Kartentyp-Steuerelement).
  • Bildkachel-Overlays, die über vorhandenen Basiskartentypen angezeigt werden. Im Allgemeinen werden diese Kartentypen verwendet, um einen vorhandenen Kartentyp zu ergänzen und so zusätzliche Informationen anzuzeigen. Sie sind oft auf bestimmte Standorte und/oder Zoomstufen beschränkt. Beachten Sie, dass diese Kacheln transparent sein können, sodass Sie vorhandenen Karten Elemente hinzufügen können.
  • Kartentypen ohne Bild, mit denen Sie die Anzeige von Karteninformationen auf der grundlegendsten Ebene bearbeiten können

Für jede dieser Optionen muss eine Klasse erstellt werden, die die Schnittstelle MapType implementiert. Außerdem bietet die Klasse ImageMapType einige integrierte Verhaltensweisen, um das Erstellen von Bildkartentypen zu vereinfachen.

Schnittstelle MapType

Bevor Sie Klassen zum Implementieren von MapType erstellen, sollten Sie wissen, wie Google Maps Koordinaten bestimmt und entscheidet, welche Teile der Karte angezeigt werden. Für alle Basis- oder Overlay-Kartentypen muss eine ähnliche Logik implementiert werden. Lesen Sie den Leitfaden zu Karten- und Kachelkoordinaten.

Benutzerdefinierte Kartentypen müssen die Schnittstelle MapType implementieren. Über diese Schnittstelle werden bestimmte Properties und Methoden angegeben, mit denen die API Anfragen an deine Kartentypen initiieren kann, wenn die API feststellt, dass Kartenkacheln für den aktuellen Darstellungsbereich und die aktuelle Zoomstufe angezeigt werden müssen. Sie verwalten diese Anfragen, um zu entscheiden, welche Kachel geladen werden soll.

Hinweis: Sie können zur Implementierung dieser Schnittstelle eine eigene Klasse erstellen. Wenn du kompatible Bilder hast, kannst du alternativ die Klasse ImageMapType verwenden, mit der diese Schnittstelle bereits implementiert ist.

Bei Klassen zur Implementierung der Schnittstelle MapType müssen Sie die folgenden Properties definieren und angeben:

  • tileSize (erforderlich) gibt die Größe der Kachel vom Typ google.maps.Size an. Die Größen müssen rechteckig sein, müssen aber nicht quadratisch sein.
  • maxZoom (erforderlich) gibt die maximale Zoomstufe für die Anzeige von Kacheln dieses Kartentyps an.
  • minZoom ist optional und gibt die minimale Zoomstufe für die Anzeige von Kacheln dieses Kartentyps an. Standardmäßig ist dieser Wert 0. Dies bedeutet, dass keine minimale Zoomstufe vorhanden ist.
  • name ist optional und gibt den Namen für diesen Kartentyp an. Dieses Attribut ist nur erforderlich, wenn dieser Kartentyp innerhalb eines Kartentyp-Steuerelements auswählbar sein soll. Weitere Informationen finden Sie unter MapType-Steuerelemente hinzufügen.
  • alt ist optional und gibt den alternativen Text für diesen Kartentyp an, der als Hover-Text angezeigt wird. Diese Eigenschaft ist nur erforderlich, wenn dieser Kartentyp innerhalb eines Kartentyp-Steuerelements auswählbar sein soll. Weitere Informationen finden Sie unter MapType-Steuerelemente hinzufügen.

Außerdem müssen Klassen zur Implementierung der Schnittstelle MapType die folgenden Methoden implementieren:

  • getTile() (erforderlich) wird immer dann aufgerufen, wenn die API feststellt, dass die Karte neue Kacheln für den gegebenen Darstellungsbereich anzeigen muss. Die Methode getTile() muss die folgende Signatur haben:

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

    Die API bestimmt anhand der Eigenschaften tileSize, minZoom und maxZoom sowie des aktuellen Darstellungsbereichs und der Zoomstufe, ob getTile() aufgerufen werden muss. Der Handler für diese Methode sollte ein HTML-Element mit den übergebenen Koordinaten, der Zoomstufe und dem DOM-Element zurückgeben, an das das Kachelbild angefügt wird.

  • releaseTile() wird (optional) immer dann aufgerufen, wenn die API ermittelt, dass die Karte eine Kachel entfernen muss, wenn sie nicht mehr sichtbar ist. Die Methode muss folgende Signatur aufweisen:

    releaseTile(tile:Node)

    Normalerweise sollten Sie alle Elemente entfernen, die nach dem Hinzufügen zur Karte an die Kartenkacheln angehängt wurden. Wenn Sie beispielsweise Ereignis-Listener an Kartenkachel-Overlays angehängt haben, sollten Sie sie hier entfernen.

Die Methode getTile() dient als Hauptcontroller zum Bestimmen der Kacheln, die innerhalb eines bestimmten Darstellungsbereichs geladen werden sollen.

Basiskartentypen

Auf diese Weise konstruierte Kartentypen können entweder eigenständig sein oder mit anderen Kartentypen als Overlays kombiniert werden. Eigenständige Kartentypen werden als Basiskartentypen bezeichnet. Eventuell möchtest du, dass die API solche benutzerdefinierten MapTypes wie jeden anderen vorhandenen Basiskartentyp (ROADMAP, TERRAIN usw.) behandelt. Füge dazu das benutzerdefinierte MapType-Attribut der MapmapTypes hinzu. Dieses Attribut ist vom Typ MapTypeRegistry.

Mit dem folgenden Code wird ein grundlegender MapType erstellt, um die Kachelkoordinaten einer Karte darzustellen und einen Umriss der Kacheln zu zeichnen:

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;
Beispiel ansehen

Beispiel ausprobieren

Überlagerungskartentypen

Einige Kartentypen sind so konzipiert, dass sie über vorhandenen Kartentypen stehen. Solche Kartentypen können transparente Ebenen haben, die POIs oder zusätzliche Daten für den Nutzer enthalten.

In diesen Fällen soll der Kartentyp nicht als separate Entität, sondern als Overlay behandelt werden. Füge dazu den Kartentyp mithilfe der overlayMapTypes-Property von Map direkt einer vorhandenen MapType hinzu. Dieses Attribut enthält ein MVCArray von MapTypes. Alle Kartentypen (Basis- und Overlay-Karten) werden innerhalb der Ebene mapPane gerendert. Overlay-Kartentypen werden auf der Basiskarte, an die sie angehängt sind, in der Reihenfolge angezeigt, in der sie im Array Map.overlayMapTypes vorkommen. Overlays mit höheren Indexwerten werden vor Overlays mit niedrigeren Indexwerten angezeigt.

Das folgende Beispiel ist mit dem vorherigen Beispiel identisch, nur haben wir hier ein Kachel-Overlay MapType über dem Kartentyp ROADMAP erstellt:

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;
Beispiel ansehen

Beispiel ausprobieren

Bildkartentypen

Die Implementierung von MapType als Basiskartentyp kann zeit- und arbeitsaufwändig sein. Die API bietet eine spezielle Klasse, mit der die Schnittstelle MapType für die gängigsten Kartentypen implementiert wird: Kartentypen, die aus Kacheln bestehen, die wiederum aus einzelnen Bilddateien zusammengesetzt sind.

Diese Klasse, die Klasse ImageMapType, wird mit einer ImageMapTypeOptions-Objektspezifikation erstellt, die die folgenden erforderlichen Properties definiert:

  • tileSize (erforderlich) gibt die Größe der Kachel vom Typ google.maps.Size an. Die Größen müssen rechteckig sein, müssen aber nicht quadratisch sein.
  • getTileUrl (erforderlich): Gibt die Funktion an, normalerweise als Inline-Funktionsliteral, mit der die Auswahl der korrekten Bildkacheln basierend auf den angegebenen Weltkoordinaten und der Zoomstufe verarbeitet werden soll.

Mit dem folgenden Code wird ein einfacher ImageMapType mithilfe von Google-Kacheln implementiert. Im Beispiel wird eine Normalisierungsfunktion verwendet, damit Kacheln auf der x-Achse, aber nicht auf der y-Achse der Karte wiederholt werden.

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;
Beispiel ansehen

Beispiel ausprobieren

Projektionen

Die Erde ist eine dreidimensionale Kugel (annähernd), eine Karte dagegen eine flache, zweidimensionale Oberfläche. Die in der Maps JavaScript API angezeigte Karte ist wie jede flache Karte der Erde eine Projektion dieser Kugel auf eine flache Oberfläche. Einfach ausgedrückt kann eine Projektion als Zuordnung von Breiten- und Längengradwerten zu Koordinaten auf der Karte der Projektion definiert werden.

Projektionen in der Maps JavaScript API müssen die Schnittstelle Projection implementieren. Eine Projection-Implementierung muss nicht nur eine Zuordnung von einem Koordinatensystem zu einem anderen bereitstellen, sondern auch eine bidirektionale Zuordnung. Das heißt, Sie müssen die Übertragung der Erdkoordinaten (LatLng-Objekte) in das Weltkoordinatensystem der Klasse Projection und umgekehrt definieren. In Google Maps wird die Mercator-Projektion verwendet, um Karten aus geografischen Daten zu erstellen und Ereignisse auf der Karte in geografische Koordinaten umzuwandeln. Sie erhalten diese Projektion, indem Sie getProjection() für Map oder einen der Standardbasistypen MapType aufrufen. Für die meisten Anwendungsfälle reicht dieser Standard-Projection aus, aber du kannst auch eigene benutzerdefinierte Projektionen definieren und verwenden.

Projektionen implementieren

Wenn Sie eine benutzerdefinierte Projektion implementieren, müssen Sie einige Dinge definieren:

  • Die Formel zum Zuordnen von Breiten- und Längengraden zu einer kartesischen Ebene und umgekehrt. Die Schnittstelle Projection unterstützt nur Transformationen in geradlinige Koordinaten.
  • Die Basiskachelgröße. Alle Kacheln müssen rechteckig sein.
  • Die "Weltgröße" einer Karte unter Verwendung der grundlegenden Kachel mit der Zoomstufe 0. Bei Karten, die aus einer Kachel bei Zoom 0 bestehen, sind Weltgröße und Basiskachelgröße identisch.

Transformationen in Projektionen koordinieren

Jede Projektion bietet zwei Methoden, die zwischen diesen beiden Koordinatensystemen übersetzen, sodass Sie zwischen geografischen und Weltkoordinaten konvertieren können:

  • Die Methode Projection.fromLatLngToPoint() konvertiert einen LatLng-Wert in eine Weltkoordinate. Diese Methode wird verwendet, um Overlays auf der Karte zu positionieren und um die Karte selbst zu positionieren.
  • Die Methode Projection.fromPointToLatLng() wandelt eine Weltkoordinate in einen LatLng-Wert um. Mit dieser Methode werden Ereignisse wie Klicks auf der Karte in geografische Koordinaten umgewandelt.

In Google Maps wird vorausgesetzt, dass Projektionen geradlinig sind.

Im Allgemeinen können Sie eine Projektion in zwei Fällen verwenden: zum Erstellen einer Karte der Welt oder einer Karte eines lokalen Gebiets. Im ersten Fall sollten Sie darauf achten, dass Ihre Projektion bei allen Längengraden auch geradlinig und normal ist. Einige Projektionen (insbesondere konische Projektionen) können lokal zurückgegeben werden (d.h. nach Norden zeigen), aber vom geografischen Norden abweichen; zum Beispiel, wenn die Karte weiter relativ zu einem Referenzlängenpunkt positioniert ist. Sie können eine solche Projektion lokal verwenden. Beachten Sie jedoch, dass die Projektion unpräzise sein wird und Transformationsfehler immer deutlicher werden, je weiter sie vom abweichenden Referenzlängenwert abweichen.

Auswahl von Kartenkacheln in Projektionen

Projektionen sind nicht nur nützlich, um die Positionen von Standorten oder Overlays zu bestimmen, sondern auch für die Positionierung der Kartenkacheln selbst. Die Maps JavaScript API rendert Basiskarten mithilfe einer MapType-Schnittstelle, die sowohl die Property projection zum Identifizieren der Kartenprojektion als auch die Methode getTile() zum Abrufen der Kartenkacheln basierend auf Kachelkoordinaten-Werten deklarieren muss. Die Kachelkoordinaten basieren auf der grundlegenden Kachelgröße (die rechteckig sein muss) und auf der Weltgröße deiner Karte (entspricht der Pixelgröße deiner Kartenwelt bei Zoomstufe 0). Bei Karten, die aus einer Kachel bei Zoom 0 bestehen, sind die Kachelgröße und die Weltgröße identisch.

Die grundlegende Kachelgröße legst du in der Property tileSize des MapTypes fest. Die Weltgröße definieren Sie implizit in den Methoden fromLatLngToPoint() und fromPointToLatLng() Ihrer Projektion.

Da die Bildauswahl auf diesen übergebenen Werten beruht, empfiehlt es sich, Bilder zu benennen, die programmatisch ausgewählt werden können und denen Werte übergeben werden, z. B. map_zoom_tileX_tileY.png.

Im folgenden Beispiel wird mithilfe der Projektion Gall-Peters eine ImageMapType definiert:

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

Beispiel ausprobieren