Incrustación y compartición
La build de navegador de MappView puede incrustarse en cualquier página web y configurarse mediante parámetros de consulta en la URL. Así convierte un proyecto compartido en un mapa en vivo y centrado para un sitio web, un informe o un panel.
El visor en vivo
La build de navegador se ejecuta localmente en http://localhost:5173/ tras bun run dev;
un despliegue de la build de navegador se sirve en su propio origen HTTPS. Los ejemplos
de abajo usan https://viewer.example.com en lugar del origen que sirva su despliegue.
Funciona íntegramente en su navegador: no tiene analíticas ni cuentas de servidor,
y los datos que carga se procesan en el cliente. Los datos solo salen de su navegador
cuando añade una URL remota o comparte explícitamente un proyecto.
Abra un proyecto público pasando su URL .mappview.json con el parámetro url:
https://viewer.example.com/?url=https://example.com/project.mappview.json
Una URL de proyecto como esta proviene de Proyecto → Compartir. Consulte Proyectos.
Un embed maponly sin adornos muestra solo el mapa, como en este proyecto 3D Tiles compartido:
Parámetros de URL
| Parámetro | Ejemplo | Descripción |
|---|---|---|
url | url=https://example.com/project.mappview.json | Carga un proyecto .mappview.json desde una URL pública. |
layout | layout=compact | Diseño de incrustación compacto: botones de barra solo con iconos y metadatos del proyecto ocultos. embed e iframe son alias. |
toolbar | toolbar=icons | Botones de la barra de herramientas solo con iconos, sin el diseño compacto completo. icon e icon-only son alias. |
panels | panels=none | Oculta los paneles Capas, Estilo y Tabla de atributos. hidden, hide y off son alias. |
hidePanels | hidePanels=true | Forma alternativa de ocultar esos paneles. |
maponly | maponly | Oculta todo el entorno (barra de herramientas, paneles y barra de estado), dejando solo el mapa. La marca sola o true, 1, yes, on lo activan. |
welcome | welcome=0 | Oculta el asistente de bienvenida del primer arranque. Acepta 0, false, off o no. Un enlace profundo con url= ya lo suprime automáticamente. |
theme | theme=dark | Fija el tema de color inicial, anulando la preferencia del sistema operativo. Acepta dark o light; el interruptor dentro de la aplicación sigue funcionando después. |
tool | tool=adaptive_filter | Abre el cuadro de diálogo Procesamiento (caja de herramientas Whitebox) sobre una herramienta concreta por su id. Los ids desconocidos abren el cuadro sin preseleccionar una herramienta. |
Los parámetros se combinan. Para una incrustación estrecha, sin adornos y oscura de un proyecto compartido:
https://viewer.example.com/?url=https://example.com/project.mappview.json&maponly&theme=dark
Enlace profundo a una herramienta de procesamiento
tool=<id> abre el cuadro de diálogo Procesamiento (caja de herramientas Whitebox) con una herramienta preseleccionada.
Cualquier parámetro de consulta adicional rellena previamente el formulario de esa herramienta, usando los
nombres de parámetro propios de la herramienta, de modo que un enlace puede llegar listo para ejecutarse:
https://viewer.example.com/?tool=extract_cog_subset&url=https%3A%2F%2Fexample.com%2Fdem.tif&bbox_crs=4326
Cuando está presente tool=, la aplicación está en modo herramienta: url nombra una entrada de la herramienta
(aquí, el COG a subconjuntar) en lugar de un proyecto a cargar, así que el cargador de proyectos
se retira. Los parámetros de aplicación/embed anteriores (theme, layout, panels, maponly,
locale, …) conservan su propio significado y nunca se pasan a la herramienta.
La preselección y el prerrellenado de parámetros se aplican solo a un id que coincida con el
menú Procesamiento: un id fuera del menú aún abre el cuadro de diálogo, pero sin
preseleccionar ninguna herramienta ni aplicar parámetros. Un id conocido que el motor actual
no expone (WASM en el navegador, el sidecar Python en escritorio) tampoco se preselecciona. Los ids de herramientas coinciden con el menú Procesamiento — los mismos ids usados en
la caja de herramientas Whitebox.
Incrustar en una página
Coloque el visor en un <iframe>:
<iframe
src="https://viewer.example.com/?url=https://example.com/project.mappview.json&maponly"
title="MappView map"
width="100%"
height="600"
style="border: 0;"
loading="lazy"
allow="fullscreen; geolocation"
></iframe>
Use layout=compact cuando quiera que permanezca una barra delgada (por ejemplo, para que quien lo vea pueda cambiar el mapa base), o maponly para un mapa puro.
Dialogar con el mapa en tiempo de ejecución
Los parámetros de URL configuran la aplicación una vez, al cargar. Para seguir dialogando con un embed
en vivo (volar hasta el registro que el usuario acaba de pulsar en su aplicación, resaltarlo, abrir una
herramienta de procesamiento) y escuchar lo que hace el usuario dentro del mapa, use la API
postMessage del embed.
Activarla
La API está desactivada por defecto: un despliegue público nunca puede ser controlado por la página que lo enmarca. Actívela nombrando los orígenes en los que confía. Para la imagen Docker, es una variable de entorno:
docker run --rm -p 8080:80 \
-e MAPPVIEW_EMBED_ORIGINS="https://portal.example.com,https://erp.example.com" \
mapptech/mappview:local
Para una build estática, hornéela en su lugar:
VITE_MAPPVIEW_EMBED_ORIGINS="https://portal.example.com" bun run build.
Las entradas son orígenes (scheme://host[:port]); una ruta final se ignora. *
permite cualquier origen y solo es apropiado en una red privada. La lista blanca se
aplica en ambas direcciones: un mensaje de un origen no listado se ignora, y
cada mensaje que envía la aplicación va dirigido a un origen listado. (Con *
configurado, los mensajes salientes van dirigidos a * hasta que el primer mensaje del host
lo identifique, razón más para nombrar sus orígenes.)
Establecer la lista blanca también acota los puentes ?embed=1 de proyectos/scripts (usados
por el paquete Python) a los mismos orígenes. Como endurecimiento adicional,
puede impedir que otros sitios enmarquen la aplicación añadiendo
Content-Security-Policy: frame-ancestors <your origins> en su proxy inverso.
Forma de los mensajes
Cada mensaje, en ambas direcciones, está versionado:
{ "v": 1, "type": "setView", "payload": { "center": [-95.7, 37.1], "zoom": 5 } }
Los mensajes que envía la aplicación llevan además "source": "mappview", de modo que pueda filtrarlos del resto del tráfico postMessage de su página.
Del host a MappView
| Tipo | Payload | Efecto |
|---|---|---|
loadProject | { url } | Carga un proyecto .mappview.json sin recargar el iframe. |
setView | { bbox } o { center, zoom, bearing, pitch, duration } | Ajusta a un rectángulo delimitador, o vuela la cámara a las propiedades enviadas. |
highlightFeature | { layerId, featureId | featureIds | filter, fit } | Selecciona y resalta geometrías; filter coincide con propiedades. fit hace zoom hacia ellas. |
openTool | { id, params } | Abre el cuadro de diálogo Procesamiento sobre una herramienta, prerrellenando params. Gemelo en runtime de ?tool=. |
Envíe { layerId } solo a highlightFeature para limpiar el resaltado. Una petición
que nombre geometrías (o un filtro) pero no coincida con ninguna se rechaza en lugar de
tratarse como limpieza, de modo que un id mal escrito no borre silenciosamente la selección del usuario.
El resaltado lee las geometrías de la capa desde el proyecto, así que se aplica a capas vectoriales
que MappView mantiene como GeoJSON, no a aquellas cuyas geometrías viven solo en una fuente de teselas.
Añada un requestId a cualquier mensaje y la aplicación responderá con un ack (abajo)
informando de si funcionó.
De MappView al host
| Tipo | Payload | Se dispara cuando |
|---|---|---|
ready | { version } | La aplicación se ha montado y está escuchando. |
ack | { requestId, ok, error } | Un mensaje enviado con requestId fue aplicado (o rechazado). |
projectLoaded | { url, name, layerIds } | Un proyecto terminó de cargarse, sea quien sea que lo inició. |
selectionChanged | { layerId, featureIds } | El usuario (o su highlightFeature) cambió la selección. |
viewChanged | { bbox, center, zoom, bearing, pitch } | La cámara se movió (limitado a unos cuatro eventos por segundo). |
toolCompleted | { id, name, status, engine, durationMs, outputLayerNames } | Una ejecución de procesamiento terminó, con éxito o no. |
serverFileWritten | { path, toolId } | Una herramienta basada en archivos escribió una salida (herramientas de conversión y ráster). |
Una página anfitriona
<iframe
id="map"
src="https://gis.example.com/?url=https://erp.example.com/fields.mappview.json&maponly"
title="MappView map"
width="100%"
height="600"
style="border: 0"
></iframe>
<script>
const frame = document.getElementById("map");
const APP_ORIGIN = "https://gis.example.com";
const send = (type, payload) =>
frame.contentWindow.postMessage({ v: 1, type, payload }, APP_ORIGIN);
window.addEventListener("message", (event) => {
if (event.origin !== APP_ORIGIN) return;
const message = event.data;
if (message?.source !== "mappview" || message.v !== 1) return;
if (message.type === "ready") {
// Safe to start sending commands.
} else if (message.type === "selectionChanged") {
showRecordFor(message.payload.featureIds[0]);
}
});
// Click a record in your own UI: fly to it and highlight it, no reload.
function focusField(field) {
send("setView", { bbox: field.bbox });
send("highlightFeature", {
layerId: "fields",
filter: { parcel_id: field.id },
fit: true,
});
}
</script>
Espere a ready antes de enviar: los mensajes que llegan antes de que la aplicación se haya montado no se ponen en cola. Trate ready como idempotente, pues se reenvía siempre que la aplicación vuelva a montarse (una navegación dentro del frame, una recarga en caliente en desarrollo).
Qué funciona en una incrustación
La build de navegador soporta navegación del mapa, datos seleccionados en el navegador y basados en URL, estilizado, el espacio de trabajo SQL y la mayoría de los plugins. Las funciones exclusivas del escritorio (diálogos de archivos locales, MBTiles locales y lecturas ráster, guardar/abrir proyectos y las herramientas del sidecar Python) no están disponibles en una incrustación. Consulte Primeros pasos.
Vea el tutorial de compartición e incrustación para un recorrido completo.