Documentación / Vista de mapa / Cambiar el estilo del mapa

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.

REACT
@mapconductor/js-vectorstyle
PROP
mapStyle
ESM / CJS
Solo ESM

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

Mapa
Cómo funciona
Qué se necesita
MapLibre / Mapbox / MapTiler
El propio mapa lee el estilo. Al cambiar las reglas, solo se aplican las diferencias y no se vuelven a cargar los mosaicos.
Solo este paquete
Otros (Google Maps, Leaflet, OpenLayers, ArcGIS, Cesium, HERE, MapKit, deck.gl…)
Dibuja el estilo sobre mosaicos ráster y los superpone.
rasteriser con un VectorTileRasteriser

Si 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

terminalnpm
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).

terminalnpm
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.

RoadsOnlyMap.tsxTypeScript · React
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.

TypeScriptTypeScript
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 });
});
Selector
Constructor
Descripción
all
r.all(patch)
Todas las capas.
{ role }
r.role(LayerRole.road, patch)
Rol. background, water, waterway, land, landuse, park, building, road, road-casing, rail, transit, boundary, aeroway, label, poi.
{ layerId }
r.layerId('poi-*', patch)
ID de la capa. Se pueden usar * y ?.
{ sourceLayer }
r.sourceLayer('water', patch)
Nombre del source-layer del tile.
{ kind }
r.kind('symbol', patch)
Tipo de capa. background, fill, line, circle, symbol, other.
anyOf / allOf / not
r.where(selector, patch)
Combinaciones.
Parche
Tipo
Descripción
visible
boolean
Visibilidad.
color
string
Color según el tipo de capa (relleno, línea, texto e iconos, fondo).
colorFilter
{ desaturate } | { darken } | { lighten } | { invertLightness } | { mix }
Transformación sobre el color original.
opacity
0–1
Opacidad.
widthScale
number
Multiplicador del ancho de línea o del radio del círculo.
filter
Expresiones de MapLibre
Reemplaza el filtro de la capa.
minZoom / maxZoom
number
Rango de zoom en el que se muestra.
properties
Record<string, unknown>
Propiedad de la especificación de estilo directamente por nombre. Se aplica al final.

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.

night.rules.jsonJSON
{
  "schemaVersion": 1,
  "rules": [
    { "selector": "all", "patch": { "colorFilter": { "darken": 0.55 } } },
    { "selector": { "role": "water" }, "patch": { "color": "rgb(10,28,43)" } }
  ]
}
TypeScriptTypeScript
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.

TypeScriptTypeScript · React
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 }} />
PRECAUCIÓN
El rasterizador se compara por igualdad. Si haces 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

Opción
Valor predeterminado
Descripción
document
'currentDesign'
Estilo a ajustar. { url, headers? }, { text } o 'currentDesign'.
rules
—
Regla a aplicar. Si es NO_STYLE_RULES, queda como está.
rasteriser
—
Es para dibujar en mapas que no admiten vectores.
onUnsupported
'report'
Cuando el mapa no acepta un diff. Si es 'reload', se pasa el documento ajustado completo (correcto pero pesado).
onDiagnostics
—
La cantidad de capas alcanzadas, las reglas que no alcanzaron nada y los ajustes que el mapa rechazó.
wasmUrl
—
Ubicación del wasm del compilador.

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.

Páginas relacionadas