Cambiar el estilo del mapa
Un paquete que aplica ajustes al estilo vectorial del mapa —como «volver blancas las carreteras», «ocultar las etiquetas», «oscurecer las áreas de agua»— de forma declarativa mediante reglas. Las mismas reglas funcionan tal cual en Android e iOS.
01 · Resumen
Las reglas son una lista de pares de «a qué capa se aplican (selector)» y «qué hacer (parche)». El selector puede escribirse por rol (carreteras, agua, etiquetas…) en lugar de por ID de capa. Los esquemas de OpenMapTiles, Shortbread y Mapbox Streets se detectan automáticamente, así que no es necesario averiguar los distintos IDs de capa de cada estilo.
El valor que devuelve createVectorStyle() se pasa como mapStyle a cualquier *MapView. En React la propiedad se llama mapStyle porque style es el CSS del propio elemento (en Android e iOS se llama style).
rasteriser con un VectorTileRasteriserSi se pasa a un mapa sin soporte vectorial sin proporcionar un rasterizador, no se queda callado sin dibujar nada: muestra en el diagnóstico «este estilo no se puede usar».
02 · Instalación
npm install @mapconductor/js-sdk-core @mapconductor/js-vectorstyle
Si también se quiere usar en mapas sin soporte vectorial, se instala react-vectortile, que incluye el rasterizador (también hace falta preparar el Service Worker descrito en Capa de mosaicos vectoriales).
npm install @mapconductor/react-vectortile
Es solo ESM. El compilador de reglas es un wasm (unos 190 KB) que se carga de forma relativa a import.meta.url. Con Vite funciona tal cual. Para servirlo desde otra ubicación, se especifica con wasmUrl.
03 · Uso básico
Si se omite document, se ajusta el estilo que el mapa está dibujando actualmente ('currentDesign'). El siguiente ejemplo convierte el diseño predeterminado de MapLibre en un mapa en blanco y negro donde solo se ven las carreteras.
import { useMemo } from 'react';
import { buildStyleRules, createVectorStyle, LayerRole } from '@mapconductor/js-vectorstyle';
import { MapLibreMapView2D, useMapLibreViewState } from '@mapconductor/react-for-maplibre';
export function RoadsOnlyMap() {
const state = useMapLibreViewState();
const mapStyle = useMemo(
() => createVectorStyle({
rules: buildStyleRules((r) => {
r.all({ color: '#000000' });
r.role(LayerRole.label, { visible: false });
r.role(LayerRole.roadCasing, { color: '#303030' });
r.role(LayerRole.road, { color: '#ffffff', widthScale: 1.4 });
}),
}),
[],
);
return (
<MapLibreMapView2D
state={state}
mapStyle={mapStyle}
onStyleDiagnostics={(messages) => console.warn(messages)}
/>
);
}Cuando usas tu propio estilo, pasa { url } o { text } en document.
04 · Cómo escribir las reglas
Las reglas se aplican de arriba hacia abajo y, como en CSS, el último elemento gana para cada propiedad. Lo básico es definir el conjunto con all primero y luego sobrescribir por rol.
buildStyleRules((r) => {
r.all({ colorFilter: { darken: 0.55 } });
r.role(LayerRole.water, { color: 'rgb(10,28,43)' });
r.role(LayerRole.road, { color: '#d0d0d0' });
r.layerId('poi-*', { visible: false });
r.kind('symbol', { opacity: 0.8 });
});* y ?.Reglas como JSON
Las reglas también son un documento JSON. Cuando las sirves desde un servidor o las guardas entre versiones de la aplicación, mantenlas en este formato y cárgalas con parseStyleRules(). El mismo documento se puede leer en Android e iOS.
{
"schemaVersion": 1,
"rules": [
{ "selector": "all", "patch": { "colorFilter": { "darken": 0.55 } } },
{ "selector": { "role": "water" }, "patch": { "color": "rgb(10,28,43)" } }
]
}import { createVectorStyle, parseStyleRules } from '@mapconductor/js-vectorstyle';
const rules = parseStyleRules(await (await fetch('/night.rules.json')).text());
const mapStyle = createVectorStyle({ rules });05 · Usarlo en mapas sin soporte de vectores
Si pasas VectorTileRasteriser como rasteriser, el estilo se dibuja sobre tiles rasterizados y se superpone. Deja el mapa propio del proveedor oculto con el diseño None.
import { useMemo } from 'react';
import { createVectorStyle } from '@mapconductor/js-vectorstyle';
import { VectorTileRasteriser } from '@mapconductor/react-vectortile';
import { GoogleMapDesign, GoogleMapView2D, useGoogleMapViewState } from '@mapconductor/react-for-googlemaps';
const state = useGoogleMapViewState({
apiKey: import.meta.env.VITE_GOOGLE_MAPS_API_KEY,
mapDesignType: GoogleMapDesign.None,
});
const rasteriser = useMemo(() => new VectorTileRasteriser(), []);
const mapStyle = useMemo(
() => createVectorStyle({
document: { url: 'https://tiles.versatiles.org/assets/styles/colorful/style.json' },
rules,
rasteriser,
}),
[rules, rasteriser],
);
<GoogleMapView2D state={state} mapStyle={mapStyle} style={{ height: 480 }} />new en cada renderizado, se considera un estilo distinto y el mapa se recrea cada vez. Mantén una única instancia con useMemo o similar.06 · Opciones principales
{ url, headers? }, { text } o 'currentDesign'.NO_STYLE_RULES, queda como está.'reload', se pasa el documento ajustado completo (correcto pero pesado).Los diagnósticos también se pueden recibir en onStyleDiagnostics de *MapView. Si se omite, se muestran en la consola. Las «reglas que no alcanzaron nada» solo indican «casi funciona» a simple vista, así que se recomienda mostrarlas en un lugar visible mientras se desarrolla.