Vektor-Tile-Layer
Ein Paket, das Vektorstile im MapLibre-Format (style.json) im Browser in Raster-Tiles rendert, sodass sie über jeden Kartenanbieter gelegt werden können. Karten, die Vektorstile nicht selbst lesen können — wie Google Maps, MapKit, HERE, ArcGIS oder Cesium — sehen damit genauso aus.
01 · Übersicht
Das Rendering erfolgt durch einen in Rust geschriebenen Renderer, der zu wasm kompiliert wurde, und läuft in einem Web Worker. Die gerenderten Tiles werden vom lokalen Tile-Server des SDK (Service Worker) ausgeliefert und erscheinen auf der Karte als gewöhnlicher RasterLayer. Aus Sicht der Karte ist es einfach nur ein Raster-Layer. Daher spielt der Anbieter keine Rolle.
Der Layer wird in zwei Ebenen aufgeteilt: ein „Boden“ aus Füllungen, Linien und Kreisen sowie ein transparenter „Label“-Layer darüber. Wenn die Fonts ankommen, wird nur die Label-Ebene neu gezeichnet; dadurch verschwindet die Karte nicht kurz, sobald der Text erscheint. Die Quellenangabe des Stils (z. B. OpenStreetMap) wird ebenfalls automatisch hinzugefügt.
02 · Installation
npm install @mapconductor/js-sdk-core @mapconductor/js-sdk-react \
@mapconductor/react-vectortile@mapconductor/js-vectorstyle wird als Abhängigkeit mitinstalliert. Das Paket ist nur als ESM verfügbar.
Service Worker für die Tiles platzieren
Die Tiles werden von /tile-sw.js ausgeliefert. Die Anforderungen sind dieselben wie bei der Heatmap. Kopieren Sie die Datei aus @mapconductor/js-sdk-core in das öffentliche Verzeichnis Ihrer App.
{
"scripts": {
"postinstall": "cp node_modules/@mapconductor/js-sdk-core/dist/tile-sw.js public/tile-sw.js"
}
}Im Produktions-Build von Vite ist eine Konfiguration erforderlich, die Worker als ES-Module ausgibt (im Dev-Server ist das nicht nötig).
import { defineConfig } from 'vite';
export default defineConfig({
worker: { format: 'es' },
});localhost genügt HTTP, beim Öffnen von einem anderen Gerät im LAN ist jedoch HTTPS erforderlich.03 · Grundlegende Verwendung
Kann in jedem *MapView platziert werden. An style kann eine URL zu einer style.json, deren Zeichenkette oder ein bereits geparstes Objekt übergeben werden. Das Beispiel unten blendet die eigene Karte von Google Maps aus (GoogleMapDesign.None) und zeichnet darüber den Vektorstil.
import { createGeoPoint, createMapCameraPosition } from '@mapconductor/js-sdk-core';
import { GoogleMapDesign, GoogleMapView2D, useGoogleMapViewState } from '@mapconductor/react-for-googlemaps';
import { VectorTileLayer } from '@mapconductor/react-vectortile';
const TOKYO = createGeoPoint({ latitude: 35.6812, longitude: 139.7671 });
const STYLE_URL = 'https://tiles.versatiles.org/assets/styles/colorful/style.json';
export function VectorTileMap() {
const state = useGoogleMapViewState({
apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
mapDesignType: GoogleMapDesign.None,
cameraPosition: createMapCameraPosition({ position: TOKYO, zoom: 12 }),
});
return (
<GoogleMapView2D state={state} style={{ height: 480 }}>
<VectorTileLayer style={STYLE_URL} onDiagnostics={(messages) => console.warn(messages)} />
</GoogleMapView2D>
);
}style wird inhaltlich verglichen. Bei gleichem Inhalt entsteht keine Neuberechnung, auch wenn jedes Mal ein neues Objekt erstellt und übergeben wird.
04 · Das Aussehen ändern
rules übergibt die Regeln, wie sie unter Kartenstil anpassen beschrieben sind, und zeichnet mit Anpassungen wie Farbänderungen oder dem Ausblenden von Layern. Ausgeblendete Rollen (Gebäude, Beschriftungen usw.) werden gar nicht erst gezeichnet.
import { useMemo } from 'react';
import { buildStyleRules, LayerRole } from '@mapconductor/js-vectorstyle';
import { VectorTileLayer } from '@mapconductor/react-vectortile';
const rules = useMemo(
() => buildStyleRules((r) => {
r.role(LayerRole.building, { visible: false });
r.role(LayerRole.water, { colorFilter: { mix: { color: '#3a7ca5', amount: 0.6 } } });
r.role(LayerRole.label, { opacity: 0.6 });
}),
[],
);
<VectorTileLayer style={STYLE_URL} rules={rules} />Ändert man Regeln oder den Stil, werden nur die im Speicher vorhandenen Vektor-Tiles neu gezeichnet; es wird nicht aufs Netzwerk zugegriffen. Die Formen sind ja unverändert, nur die Art der Darstellung ändert sich. Auch ein Einsatz wie das Verschieben von Farben per Slider erhöht den Datenverkehr nicht. Lässt man rules weg, wird der Regel-Compiler (wasm) nicht geladen.
05 · Als Basemap verwenden
Mit asBasemap wird bei MapLibre, Mapbox und MapTiler kein Raster erzeugt, sondern der Stil direkt an die Karte übergeben und das Karten-Design ersetzt. Diese drei können selbst Vektorstile zeichnen, daher ist das schneller und schöner. In diesem Fall wirkt opacity nicht.
import { MapLibreMapView2D, useMapLibreViewState } from '@mapconductor/react-for-maplibre';
import { VectorTileLayer } from '@mapconductor/react-vectortile';
<MapLibreMapView2D state={state}>
<VectorTileLayer style={STYLE_URL} rules={rules} asBasemap />
</MapLibreMapView2D>Bei allen anderen Providern ändert asBasemap nichts. Blenden Sie die eigene Karte des Providers app-seitig aus, indem Sie das Design auf None setzen.
06 · Die wichtigsten Eigenschaften
Tiles mit Schlüssel verwenden
<VectorTileLayer
style="https://tiles.example.com/styles/basic/style.json"
headers={{ Authorization: `Bearer ${token}` }}
/>07 · Aktuelle Einschränkungen
imports von Mapbox und einige Layer-Typen werden nicht gezeichnet. Dies erscheint in onDiagnostics.*MapView platziert werden. Außerhalb der Karte funktioniert es nicht.