Adaptador MapLibre¶
geoworld-maplibre en npm:
helpers que ponen un nivel del cliente JavaScript en un mapa
MapLibre GL JS. Cero dependencias en runtime;
maplibre-gl (≥ 2) y geoworld son peers. El código vive en
packages/js/geoworld-maplibre.
Una llamada por nivel¶
import { createClient } from "geoworld";
import { addBoundaries } from "geoworld-maplibre";
const world = createClient({ version: "1.0.0" });
const regions = await addBoundaries(map, world, "CHL", "ADM1", { fit: true });
regions.source; // "geoworld-CHL-ADM1"
regions.layers; // ["geoworld-CHL-ADM1-fill", "geoworld-CHL-ADM1-line"]
regions.bbox; // del índice, sin descarga
regions.remove(); // las capas y luego el source
addBoundaries falla pronto si el territorio o el nivel no existen, encuadra
el mapa con el bbox del índice cuando se pide (antes de que lleguen los
datos), descarga el nivel a través del cliente (verificado, cacheado), espera
a que el estilo admita un source y añade un source GeoJSON más una capa de
relleno y otra de línea. Lanza si el id del source ya está en el mapa: llama
a remove() en el handle anterior en vez de confiar en un reemplazo
silencioso.
| Opción | Por defecto | Significado |
|---|---|---|
part |
— | Una parte de un nivel dividido ("US-CA", "unassigned") |
preview |
false |
El preview simplificado en vez del archivo completo |
source |
geoworld-{ISO3}-{NIVEL}[-{parte}][-preview] |
Id del source |
fill |
{ "fill-color": "#00695c", "fill-opacity": 0.15 } |
Paint del relleno, o false para no crear esa capa |
line |
{ "line-color": "#00695c", "line-width": 1 } |
Paint de la línea, o false para no crear esa capa |
before |
— | Inserta las capas debajo de este id de capa |
fit |
false |
true o FitBoundsOptions para encuadrar con el bbox del índice |
Un nivel publicado solo en partes (los municipios de Brasil) se concatena
salvo que se indique part; los niveles grandes se ven mejor con
preview: true.
Estado de feature por id estable¶
Cada feature de World GeoJSON tiene un id estable como CHL:ADM1:CL-RM.
MapLibre no puede usarlo directamente: promoteId lee una propiedad, y un
id de feature no numérico se pierde al entrar en el source. Por eso el
adaptador construye los datos del source como copias superficiales con
properties.id repitiendo el id de la feature y pone promoteId: "id", de
modo que tanto feature-state como e.features[0].id ven el id de World
GeoJSON.
import { clearFeatureState, setFeatureState } from "geoworld-maplibre";
const regions = await addBoundaries(map, world, "CHL", "ADM1", {
fill: {
"fill-color": "#00695c",
"fill-opacity": ["case", ["boolean", ["feature-state", "hover"], false], 0.45, 0.15],
},
});
let hovered: string | null = null;
map.on("mousemove", regions.layers[0], (e) => {
const id = String(e.features?.[0]?.id ?? "");
if (!id || id === hovered) return;
if (hovered) clearFeatureState(map, regions.source, hovered, "hover");
hovered = id;
setFeatureState(map, regions.source, id, { hover: true });
});
map.on("mouseleave", regions.layers[0], () => {
if (hovered) clearFeatureState(map, regions.source, hovered, "hover");
hovered = null;
});
Tus propias capas¶
import { collection, fitToBounds, sourceSpec, withIdProperty } from "geoworld-maplibre";
map.addSource("provinces", await sourceSpec(world, "CHL", "ADM2")); // { type: "geojson", data, promoteId: "id" }
map.addLayer({ id: "provinces-outline", type: "line", source: "provinces" });
fitToBounds(map, await world.bbox("CHL", "ADM2"), { padding: 20 });
collection(client, iso3, level, { part?, preview? }) devuelve la
FeatureCollection que daría el cliente, concatenando partes cuando no hay
archivo combinado; withIdProperty(fc) es el paso de promoción por sí solo;
toLngLatBounds(bbox) convierte un bbox del índice en lo que toma
fitBounds; whenStyleReady(map) resuelve cuando addSource es seguro.
Antimeridiano
Los bbox del índice son valores ingenuos [oeste, sur, este, norte]. Un
dataset que cruza el antimeridiano (Rusia, Fiyi, Estados Unidos con
Alaska) da [-180, …, 180, …] y fit muestra el mundo entero.
Ejemplo¶
examples/maplibre.html
es una página completa: selector de territorio y nivel, la capa con fit y
resaltado al pasar el ratón mediante feature state. just examples la sirve.