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 über diese Karten zu speichern. Ein MapType
ist eine Schnittstelle, die die Anzeige und Nutzung von Kartenkacheln und die Umwandlung von Bildschirmkoordinaten in Weltkoordinaten (auf der Karte) definiert. Jeder MapType
muss Methoden zum Abrufen und Freigeben von Kacheln sowie Eigenschaften zum Definieren des visuellen Verhaltens enthalten.
Die Funktionsweise von Kartentypen in der Maps JavaScript API ist ein komplexes Thema. Die meisten Entwickler können einfach die unten aufgeführten Basiskartentypen verwenden. Es ist aber auch möglich, die Darstellung vorhandener Kartentypen mithilfe von Karten mit benutzerdefinierten Stilen anzupassen oder eigene Kartenkacheln mithilfe von benutzerdefinierten Kartentypen zu definieren. Wenn Sie benutzerdefinierte Kartentypen bereitstellen möchten, müssen Sie die Registry für Kartentypen ändern können.
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
ist der Standardkartentyp und zeigt die standardmäßige Straßenkartenansicht an.satellite
zeigt Google Earth-Satellitenbilder an.hybrid
zeigt eine Mischung aus normalen und Satellitenbildern an.terrain
zeigt eine physische Karte an, die auf Geländedaten beruht.
Um den Kartentyp zu ändern, der von der Map
verwendet wird, legen Sie die mapTypeId
-Eigenschaft fest. Dazu müssen Sie entweder im Konstruktor das Map options
-Objekt festlegen oder die Methode setMapTypeId()
der Karte aufrufen. Die Eigenschaft mapTypeID
ist standardmäßig auf roadmap
gesetzt.
mapTypeId
beim Erstellen festlegen:
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');
Hinweis: Sie legen den Kartentyp der Karte nicht direkt fest. Stattdessen verweisen Sie mit der mapTypeId
auf einen MapType
.
Die Maps JavaScript API nutzt eine Registry (siehe unten), um diese Verweise zu verwalten.
45°-Bilder
Für bestimmte Orte unterstützt die Maps JavaScript API spezielle 45°-Bilder. Diese hochauflösenden Bilder ermöglichen perspektivische Ansichten für alle Himmelsrichtungen (Norden, Süden, Osten, Westen). Sie sind in höheren Zoomstufen für unterstützte Kartentypen 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. Sind entsprechende Bilder verfügbar wird die Ansicht dieser Kartentypen beim Heranzoomen automatisch so angepasst:
- Die Satelliten- oder Hybridbilder werden durch 45°-Bilder ersetzt, die auf den aktuellen Ort zentriert sind. Standardmäßig sind diese Bilder nach Norden ausgerichtet. Zoomt der Nutzer heraus, werden wieder die standardmäßigen Satelliten- oder Hybridbilder angezeigt. Das Verhalten variiert je nach Zoomstufe und dem Wert von
tilt
: - Zwischen den Zoomstufen 12 und 18 wird standardmäßig die Draufsichtbasiskarte (0°) angezeigt, außer
tilt
ist auf „45“ gesetzt. - Bei höheren Zoomstufen wird die 45°-Basiskarte angezeigt, außer
tilt
ist auf „0“ gesetzt. - Die Steuerung für die Rotation wird eingeblendet. Sie enthält Optionen, mit denen der Nutzer die Neigung aktivieren bzw. deaktivieren und die Ansicht in 90°-Schritten in beide Richtungen drehen kann. Wenn die Steuerung ausgeblendet werden soll, setzen Sie
rotateControl
auffalse
.
Beim Herauszoomen aus einem Kartentyp mit 45°-Bildern werden alle diese Änderungen rückgängig gemacht und die ursprünglichen Kartentypen wiederhergestellt.
45°-Bilder aktivieren und deaktivieren
Um 45°-Bilder zu deaktivieren, rufen Sie setTilt(0)
im Map
-Objekt auf. Um 45°-Bilder für unterstützte Kartentypen zu aktivieren, müssen Sie setTilt(45)
aufrufen. Die getTilt()
-Methode der Map
spiegelt immer die aktuelle Neigung der Karte wider. Wenn Sie eine tilt
für eine Karte festlegen und später entfernen (z. B. durch Herauszoomen aus der Karte), gibt die getTilt()
-Methode der Karte 0
zurück.
Wichtig: 45°-Bilder werden nur auf Rasterkarten unterstützt. Sie können nicht für Vektorkarten verwendet werden.
Mit folgendem Beispiel wird eine 45°-Ansicht von New York City angezeigt:
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;
Testbeispiel
45°-Bilder drehen
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 die Bilder an einer Himmelsrichtung ausrichten. Dazu rufen Sie setHeading()
für das Map
-Objekt auf und übergeben dabei einen Zahlenwert, der in Grad relativ zum Norden ausgedrückt wird.
Mit folgendem Beispiel wird eine Luftaufnahme angezeigt. 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;
Testbeispiel
Registry für Kartentypen ändern
Die mapTypeId
einer Karte ist eine String-ID, mit der einem MapType
ein eindeutiger Wert zugeordnet wird. Jedes Map
-Objekt enthält eine MapTypeRegistry
mit der Sammlung der verfügbaren MapType
s für die Karte. Mit dieser Registry werden beispielsweise die Kartentypen ausgewählt, die im Steuerelement „MapType“ der Karte verfügbar sind.
Sie können Daten nicht direkt aus der Registry auslesen. Stattdessen bearbeiten Sie die Registry, indem Sie benutzerdefinierte Kartentypen hinzufügen und ihnen eine String-ID Ihrer Wahl zuweisen. Sie können die grundlegenden Kartentypen nicht anpassen oder ändern, haben aber die Möglichkeit, sie aus der Karte zu entfernen. Dazu passen Sie die Darstellung der zugehörigen mapTypeControlOptions
der Karte an.
Mit dem folgenden Code wird festgelegt, dass nur zwei Kartentypen in den mapTypeControlOptions
der Karte angezeigt werden. Außerdem wird die Registry so geändert, dass die Verknüpfung mit dieser ID der eigentlichen Implementierung der MapType
-Schnittstelle 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);
Karten mit benutzerdefinierten Stilen
Mit dem StyledMapType
können Sie die Darstellung der standardmäßigen Google-Basiskarten anpassen. Dazu ändern Sie die visuelle Darstellung von Elementen wie Straßen, Parks und bebauten Gebieten, um einen anderen Stil als den des Standardkartentyps zu verwenden.
Weitere Informationen zu StyledMapType
finden Sie unter Eingebettete JSON-Stildeklarationen verwenden.
Benutzerdefinierte Kartentypen
Die Maps JavaScript API unterstützt die Anzeige und Verwaltung benutzerdefinierter Kartentypen, sodass Sie eigene Kartenbilder oder Kachel-Overlays implementieren können.
In der Maps JavaScript API gibt es mehrere Implementierungsmöglichkeiten für Kartentypen:
- Standardkachelsätze, die aus Bildern bestehen, die zusammen vollständige kartografische Karten ergeben. Diese Kachelsätze werden auch als Basiskartentypen bezeichnet. Sie verhalten sich wie die vorhandenen Standardkartentypen *
roadmap
,satellite
,hybrid
undterrain
. Sie können Ihren benutzerdefinierten Kartentyp zummapTypes
-Array einer Karte hinzufügen, damit er von der UI innerhalb der Maps JavaScript API als Standardkartentyp verarbeitet und z. B. in das Steuerelement „MapType“ für den Kartentyp aufgenommen wird. - Bildkachel-Overlays, die über vorhandenen Basiskartentypen angezeigt werden. Im Allgemeinen werden diese Kartentypen verwendet, um einen bestehenden Kartentyp zu ergänzen und zusätzliche Informationen anzuzeigen. Sie sind oft auf bestimmte Orte und/oder Zoomstufen beschränkt. Diese Kacheln können transparent sein, damit Sie bestehenden Karten Features hinzufügen können.
- Kartentypen ohne Bild, mit denen Sie die Anzeige von Karteninformationen auf der Grundebene steuern können.
Für jede dieser Optionen muss eine Klasse erstellt werden, die die MapType
-Schnittstelle implementiert. Darüber hinaus bietet die Klasse ImageMapType
einige integrierte Verhaltensweisen, um das Erstellen von Imagemap-Typen zu vereinfachen.
Die MapType
-Schnittstelle
Bevor Sie Klassen erstellen, die MapType
implementieren, müssen Sie verstehen, wie Google Maps Koordinaten berechnet und entscheidet, welche Teile der Karte angezeigt werden sollen. Für alle Basis- oder Overlay-Kartentypen muss eine ähnliche Logik implementiert werden.
Weitere Informationen finden Sie im Leitfaden zu Karten- und Kachelkoordinaten.
Benutzerdefinierte Kartentypen müssen die MapType
-Schnittstelle implementieren. Über diese Schnittstelle werden bestimmte Eigenschaften und Methoden festgelegt, mit denen die API Anfragen an Ihre Kartentypen initiieren kann, wenn Kartenkacheln im aktuellen Darstellungsbereich und mit der aktuellen Zoomstufe angezeigt werden müssen. Sie verarbeiten diese Anfragen, um zu entscheiden, welche Kachel geladen werden soll.
Hinweis: Sie können eine eigene Klasse erstellen, um die Schnittstelle zu implementieren. Falls Sie kompatible Bilder haben, können Sie alternativ die Klasse ImageMapType
verwenden, die diese Schnittstelle bereits implementiert.
Bei Klassen, die die Schnittstelle MapType
implementieren, müssen Sie die folgenden Eigenschaften definieren und Werte dafür angeben:
tileSize
(erforderlich) gibt die Größe der Kachel vom Typgoogle.maps.Size
an. Sie muss rechteckig, aber nicht zwangsläufig quadratisch sein.maxZoom
(erforderlich) gibt die maximale Zoomstufe für die Anzeige von Kacheln dieses Kartentyps an.minZoom
(optional) gibt die minimale Zoomstufe für die Anzeige von Kacheln dieses Kartentyps an. Standardmäßig ist der Wert auf0
gesetzt. Das bedeutet, dass keine minimale Zoomstufe vorhanden ist.name
(optional) gibt den Namen des Kartentyps an. Diese Eigenschaft ist nur erforderlich, wenn Nutzer den Kartentyp über das entsprechende Steuerelement auswählen können sollen. Weitere Informationen finden Sie unter Steueroptionen.alt
(optional) gibt den alternativen Text für diesen Kartentyp an. Er wird als Hover-Text angezeigt. Diese Eigenschaft ist nur erforderlich, wenn Nutzer den Kartentyp über das entsprechende Steuerelement auswählen können sollen. Weitere Informationen finden Sie unter Steueroptionen.
Außerdem müssen Klassen zur Implementierung der MapType
-Schnittstelle die folgenden Methoden implementieren:
-
getTile()
(erforderlich) wird immer dann aufgerufen, wenn die API ermittelt, dass die Karte neue Kacheln für den Darstellungsbereich anzeigen muss. Die MethodegetTile()
muss folgende Signatur haben:getTile(tileCoord:Point,zoom:number,ownerDocument:Document):Node
Anhand der Eigenschaften
tileSize
,minZoom
undmaxZoom
derMapType
, des aktuellen Darstellungsbereichs und der aktuellen Zoomstufe ermittelt die API, ob siegetTile()
aufrufen 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()
(optional) wird immer dann aufgerufen, wenn die API ermittelt, dass eine Kachel entfernt werden muss, da sie nicht mehr im Darstellungsbereich sichtbar ist. Die Methode muss folgende Signatur haben: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.
Mit der Methode getTile()
wird bestimmt, welche Kacheln in einem bestimmten Darstellungsbereich zu laden sind.
Basiskartentypen
Kartentypen, die Sie auf diese Weise erstellen, können entweder allein oder in Verbindung mit anderen Kartentypen als Overlays eingesetzt werden. Eigenständige Kartentypen werden als Basiskartentypen bezeichnet. Wenn Sie möchten, dass die API solche benutzerdefinierten MapType
s genauso behandelt wie die vorhandenen Basiskartentypen (ROADMAP
, TERRAIN
usw.), müssen Sie den benutzerdefinierten MapType
der mapTypes
-Eigenschaft der Map
hinzufügen. Das ist eine Eigenschaft des Typs MapTypeRegistry
.
Mit dem folgenden Code wird ein Basis-MapType
erstellt, mit dem die Kachelkoordinaten einer Karte angezeigt werden und ein Umriss der Kacheln gezeichnet wird:
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;
Testbeispiel
Overlay-Kartentypen
Einige Kartentypen sind dazu vorgesehen, über vorhandenen Kartentypen verwendet zu werden. Sie können transparente Ebenen haben, die POIs anzeigen oder dem Nutzer zusätzliche Informationen zur Verfügung stellen.
In diesen Fällen sollte der Kartentyp nicht als separate Einheit, sondern als Overlay eingesetzt werden.
Dazu fügen Sie den Kartentyp über die Eigenschaft overlayMapTypes
der Map
direkt einem vorhandenen MapType
hinzu. Diese Eigenschaft enthält ein MVCArray
mit MapType
s. Alle Kartentypen (Basis- und Overlay-Karten) werden innerhalb der mapPane
-Ebene gerendert. Overlay-Kartentypen werden über der Basiskarte angezeigt, der sie zugeordnet sind, und zwar in der Reihenfolge, in der sie im Map.overlayMapTypes
-Array erscheinen. Overlays mit höheren Indexwerten werden vor Overlays mit niedrigeren Indexwerten angezeigt.
Das folgende Beispiel ist mit dem letzten Beispiel identisch, aber es wurde ein Kachel-Overlay-MapType
über dem ROADMAP
-Kartentyp 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;
Testbeispiel
Imagemap-Typen
Die Implementierung eines MapType
als Basiskartentyp kann zeit- und arbeitsintensiv sein. In der API ist eine besondere Klasse verfügbar, mit der die MapType
-Schnittstelle für die gängigsten Kartentypen implementiert wird: Kartentypen, die aus Kacheln bestehen, die wiederum aus einzelnen Bilddateien zusammengesetzt sind.
Diese Klasse, die ImageMapType
-Klasse, wird mithilfe einer ImageMapTypeOptions
-Objektspezifikation erstellt, die die folgenden erforderlichen Properties definiert:
tileSize
(erforderlich) gibt die Größe der Kachel vom Typgoogle.maps.Size
an. Sie muss rechteckig, aber nicht zwangsläufig quadratisch sein.getTileUrl
(erforderlich) gibt die Funktion an, normalerweise als Inline-Funktionsliteral, mit der die Auswahl der richtigen Bildkachel anhand der übergebenen Weltkoordinaten und Zoomstufe verarbeitet wird.
Mit folgendem Code wird ein Basis-ImageMapType
implementiert, der die Mondkacheln von Google verwendet. In diesem Beispiel wird eine Normalisierungsfunktion verwendet, damit sich die Kacheln auf der X-Achse, aber nicht auf der Y-Achse der Karte wiederholen.
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;
Testbeispiel
Projektionen
Die Erde ist eine (annähernd) dreidimensionale Kugel, während eine Karte eine flache, zweidimensionale Fläche ist. Die Maps JavaScript API projiziert diese Kugel (wie jede andere flache Karte der Erde) auf eine flache Oberfläche. Stark vereinfacht kann man eine Projektion als Zuordnung von Breiten- und Längengradwerten zu den Koordinaten der projizierten Karte definieren.
Für Projektionen in der Maps JavaScript API muss die Schnittstelle Projection
implementiert werden. Die Projection
-Implementierung muss nicht nur eine Abbildung eines Koordinatensystems auf ein anderes bieten, sondern auch eine bidirektionale Zuordnung. Sie müssen also definieren, wie die Erdkoordinaten (LatLng
-Objekte) in das Weltkoordinatensystem der Projection
-Klasse übersetzt werden sollen und umgekehrt.
In Google Maps wird die Mercator-Projektion verwendet, um Karten aus geografischen Daten zu erstellen und Ereignisse auf der Karte in geografische Koordinaten umzuwandeln. Um die Projektion abzurufen, müssen Sie getProjection()
für die Map
(oder einen der standardmäßigen Basis-MapType
s) aufrufen. In den meisten Fällen reicht diese Standard-Projection
aus. Sie können aber auch eigene benutzerdefinierte Projektionen definieren und verwenden.
Projektionen implementieren
Wenn Sie eine benutzerdefinierte Projektion implementieren, müssen Sie einige Dinge definieren:
- Die Formeln für die Abbildung von Breiten- und Längenkoordinaten auf einer kartesischen Ebene und die entsprechenden Formeln für die Abbildung von einer kartesischen Ebene auf Breiten- und Längenkoordinaten. Die
Projection
-Schnittstelle unterstützt nur Umrechnungen in geradlinige Koordinaten. - Die Basiskachelgröße. Alle Kacheln müssen rechteckig sein.
- Die „Weltgröße“ einer Karte unter Verwendung des Basiskachelsatzes bei Zoomstufe 0. Bei Karten, die bei Zoomstufe 0 aus einer Kachel bestehen, sind Weltgröße und Basiskachelgröße identisch.
Umwandlung von Koordinaten in Projektionen
Für jede Projektion gibt es zwei Methoden zur Umrechnung zwischen geografischen und Weltkoordinaten:
- Bei der
Projection.fromLatLngToPoint()
-Methode wird einLatLng
-Wert in eine Weltkoordinate umgewandelt. Diese Methode wird verwendet, um Overlays auf der Karte sowie die Karte selbst zu positionieren. - Die
Projection.fromPointToLatLng()
-Methode wandelt eine Weltkoordinate in einenLatLng
-Wert um. Sie wird verwendet, um Ereignisse auf der Karte (z. B. Klicks) in geografische Koordinaten umzuwandeln.
Google Maps geht davon aus, dass Projektionen geradlinig sind.
Im Allgemeinen können Sie eine Projektion für zwei Zwecke verwenden: um eine Weltkarte zu erstellen oder um eine Karte eines lokalen Gebiets zu erstellen. Für die Weltkarte muss die Projektion für alle Längengrade geradlinig und normal sein. Einige Projektionen, insbesondere konische Projektionen, können „lokal normal“ sein (also nach Norden zeigen), aber vom geografischen Norden abweichen. Das ist z. B. der Fall, wenn die Karte weiter relativ zu einem Referenzlängenpunkt positioniert ist. Sie können eine solche Projektion lokal verwenden, müssen sich aber bewusst sein, dass die Projektion zwangsläufig ungenau ist und Umwandlungsfehler immer offensichtlicher werden, je weiter Sie sich vom Referenzlängengrad entfernen.
Auswahl von Kartenkacheln in Projektionen
Mit Projektionen lassen sich nicht nur die Positionen von Orten oder Overlays bestimmen, sondern auch die Kartenkacheln selbst positionieren.
Die Maps JavaScript API rendert Basiskarten über eine MapType
-Schnittstelle, die sowohl eine projection
-Eigenschaft zum Identifizieren der Kartenprojektion als auch eine getTile()
-Methode zum Abrufen der Kartenkacheln anhand der Kachelkoordinatenwerte deklarieren muss. Kachelkoordinaten basieren auf der Größe der Basiskachel (die rechteckig sein muss) und der „Weltgröße“ Ihrer Karte (entspricht der Größe in Pixeln Ihrer Kartenwelt bei Zoomstufe 0). Bei Karten, die bei Zoomstufe 0 aus einer Kachel bestehen, sind Weltgröße und Kachelgröße identisch.
Sie legen die Basiskachelgröße in der tileSize
-Eigenschaft des MapType
fest. Die Weltgröße wird implizit in den fromLatLngToPoint()
- und fromPointToLatLng()
-Methoden Ihrer Projektion definiert.
Da die Bildauswahl auf diesen übergebenen Werten beruht, ist es empfehlenswert, Bilder so zu benennen, dass sie programmatisch ausgewählt werden können, z. B. map_zoom_tileX_tileY.png
.
Im folgenden Beispiel wird mithilfe der Peters-Projektion ein 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") 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;