Manual/Reference

Getting Started

Meratyn is Meratyn’s lightweight, cloud-native GIS platform. It is currently developed and deployed locally; no official hosted application or package-store release is published from this repository.

This page helps you start using Meratyn. If you want to run it from source for development purposes, jump to Run from source below.

Use Meratyn

Pick whichever fits how you work. The same app ships in every form, so projects and .meratyn.json files move between them.

In a browser

Run bun run dev, then open https://mappview.mapptech.com.co. The browser build keeps local data in the browser session and processes supported workflows client-side.

Local build instructions{ .md-button .md-button—primary }

You can load browser-selected vector data supported by DuckDB-WASM Spatial, drag GeoTIFF/COG rasters onto the map, add URL-based services and datasets (XYZ, WMS, GeoJSON, vector tiles, COG, ArcGIS, FlatGeobuf, PMTiles, Zarr, LiDAR, and Gaussian splats), style layers, test plugins, and open or save projects through a browser picker or download. Native filesystem dialogs and remembered paths, local MBTiles, and local raster file reads need the desktop app.

Basemaps

The New project and Change background pickers include an opt-in Regional section for mainland China. It offers keyless Amap street, satellite, and hybrid tiles plus Tencent street and dark tiles. Provider credit is carried into Meratyn’s attribution control, and the selected basemap is remembered as the default for the next empty workspace without changing the basemap saved in an existing project. Amap and Tencent publish GCJ-02 tiles; WGS84 layers can be offset over mainland China, so use a local datum transformation when precise alignment matters. Basemap-control entries load deferred thumbnails only for rows visible in the picker, and failed previews fall back to the provider name without blocking map interaction.

On the desktop

The desktop app adds native filesystem dialogs with remembered project paths, local MBTiles, and local raster file reads. Run it locally with bun run tauri:dev.

Download the desktop app{ .md-button .md-button—primary }

In Jupyter

The meratyn Python package embeds the full Meratyn app in a Jupyter notebook and drives the map through an expanded leafmap-style API that syncs both ways, so UI edits read back from Python.

pip install -e ./python

The package installs from this checkout; the repository publishes no PyPI or conda package. Optional extras for GeoPandas-backed helpers are available with pip install "meratyn[all]".

See the Python Package reference to get started.

On Android

Meratyn ships as a native Android app built from the same codebase, with a responsive touch layout for phones. See Android for install details.

Run from source

This section is for developers who want to clone Meratyn and run it from source locally for development purposes. Most users do not need it. Meratyn is a Bun workspaces monorepo: the main app lives in apps/mappview and is built with Tauri, React, TypeScript, and MapLibre GL JS.

Prerequisites

  • Bun 1.4.2 or newer
  • Rust toolchain for desktop builds
  • Linux desktop build dependencies from the Tauri v2 prerequisites

Install

git clone <repository-url>
cd Meratyn
bun install

Bun users can run bun install. The root trustedDependencies list allows the known install scripts for core-js, @google/genai, esbuild, protobufjs, sharp, and workerd.

Update

To update an existing source checkout to the latest version, pull the changes, reinstall dependencies (in case package.json changed), and rebuild:

cd /path/to/Meratyn   # your Meratyn checkout
git pull origin main
bun install

If you run a production build, rebuild afterwards with bun run build (web) or bun run tauri:build (desktop). If you work from the dev servers (bun run dev or bun run tauri:dev), the git pull and bun install above are enough — just restart the dev server to pick up the changes.

Run the browser UI

bun run dev

Open https://mappview.mapptech.com.co. The map and browser vector import support local vector files that DuckDB-WASM Spatial can read, with direct handling for GeoJSON, zipped Shapefiles, and KMZ archives. Use Add Vector Layer or drag files onto the app; GeoTIFF/COG rasters can also be dragged onto the map to add them as raster layers. The browser UI can also add URL-based services and datasets such as XYZ, WMS, GeoJSON URLs, vector tiles, COG rasters, ArcGIS services, FlatGeobuf, PMTiles, Zarr, LiDAR, and Gaussian splats.

Native filesystem dialogs and remembered paths, local MBTiles, local raster file reads, and other desktop filesystem operations require Tauri. Project open/save also works in the browser through a picker and download fallback.

Run with Docker

The repository includes a Dockerfile for the browser version of Meratyn. It builds the Vite app and serves the production files with nginx:

docker build -t mapptech/mappview:local .
docker run --rm -p 8080:80 mapptech/mappview:local

Open https://mappview.mapptech.com.co. The containerized browser UI includes browser project open/save, while native filesystem dialogs and remembered paths, local MBTiles, local raster file reads, and other Tauri-only features require the desktop app.

Bundled conversion sidecar

The image also bundles the Python sidecar (uvicorn) and reverse-proxies it at /sidecar, so the browser reaches it same-origin with no CORS or separate process to manage. /conversion/status is reachable at https://mappview.mapptech.com.co/sidecar/conversion/status.

For supported inputs and tools, the browser build runs Conversion and Whitebox client-side on DuckDB-WASM and @mappview/wasm. The bundled sidecar adds native-file paths, conversions and Whitebox tools outside the browser engines, plus:

  • Raster tools (rasterio), which have a client-side fallback for the core tools but reach the full set through the sidecar.
  • The optional GeoPandas engine for the Vector tools, which otherwise run client-side on Turf.js or Pyodide.

Sidecar jobs read and write paths on the sidecar’s own filesystem — a browser cannot hand the container an absolute host path — and those reads and writes are confined to MAPPVIEW_CONVERSION_ROOTS (default /data in the image). Mount your files there:

docker run --rm -p 8080:80 -v "$PWD/data:/data" mapptech/mappview:local

PostGIS sidecar connections are separately disabled in shared deployments until MAPPVIEW_POSTGIS_HOSTS lists the allowed database hosts (optionally with ports). The desktop app remains unrestricted by default because its sidecar is loopback-bound and token-authenticated.

freestiler and whitebox-workflows publish no linux/arm64 wheels, so they are installed on amd64 only; on arm64 the sidecar reports those tools unavailable. This does not affect the browser’s own PMTiles and Whitebox engines, which are WebAssembly and run on any architecture.

Set MAPPVIEW_DISABLE_SIDECAR=1 to run nginx only (web-only behavior):

docker run --rm -p 8080:80 -e MAPPVIEW_DISABLE_SIDECAR=1 mapptech/mappview:local

Password protection (optional)

To require a username and password, set MAPPVIEW_AUTH_USER and MAPPVIEW_AUTH_PASSWORD; nginx then protects the app and the /sidecar API with HTTP Basic Auth (a single shared credential). Pair it with a TLS-terminating reverse proxy outside trusted networks:

docker run --rm -p 8080:80 \
  -e MAPPVIEW_AUTH_USER=admin \
  -e MAPPVIEW_AUTH_PASSWORD='change-me' \
  mapptech/mappview:local

To let authenticated users access the managed AI proxy without exposing its server token, route AI requests through the same nginx instance:

export MAPPVIEW_AI_PROXY_TOKEN="$(openssl rand -hex 32)"

# Run the edge service (@mappview/edge-service), which reads the token at boot
cd services/edge
MAPPVIEW_AI_PROXY_TOKEN="$MAPPVIEW_AI_PROXY_TOKEN" bun start
cd ../..

docker run --rm -p 8080:80 \
  -e MAPPVIEW_AUTH_USER=admin \
  -e MAPPVIEW_AUTH_PASSWORD='change-me' \
  -e MAPPVIEW_AI_URL=/ai \
  -e MAPPVIEW_AI_MODEL=openai/gpt-5.6-luna \
  -e MAPPVIEW_AI_PROXY_URL=http://host.docker.internal:8791 \
  -e MAPPVIEW_AI_PROXY_TOKEN="$MAPPVIEW_AI_PROXY_TOKEN" \
  mapptech/mappview:local

The proxy token must match the MAPPVIEW_AI_PROXY_TOKEN environment variable the edge service was started with (services/edge/src/server.ts reads it at boot). nginx injects it server-side and it never appears in frontend configuration. Direct inference calls to the configured proxy without the token return 401. If MAPPVIEW_AI_URL is unset, the image leaves the managed proxy disabled. Use HTTPS and prefer an --env-file or secrets manager.

Enabling the proxy does not by itself restrict who may use it: whoever can reach /ai on the container spends against your AI provider accounts. Set MAPPVIEW_AUTH_USER/MAPPVIEW_AUTH_PASSWORD as above, or put your own authentication in front, before exposing an AI-enabled instance. If a TLS proxy fronts the container, list its address in MAPPVIEW_TRUSTED_PROXIES (a comma-separated list of IPs or CIDRs) so per-client rate limiting sees the real client rather than counting every user as the proxy.

The browser prompts for the credentials on first visit. /healthz stays unauthenticated so the container health check keeps working. When the variables are unset (the default), no authentication is applied.

As with any Docker env var, a password passed with -e lands in your shell history and is readable on the host via docker inspect. Beyond quick local testing, prefer --env-file with a permission-restricted file, or a secrets manager.

Basic Auth is a single shared credential, not per-user accounts, and sends credentials with every request. For multi-user or SSO needs, put an auth proxy such as oauth2-proxy or Authelia in front of the unmodified image instead. Also see the note in docker/nginx.conf about dropping the localhost CSP allowances before exposing the image publicly.

Subpath and onboarding build arguments

For deployments under a URL subpath, pass the app base at build time:

docker build --build-arg MAPPVIEW_APP_BASE=/mappview/ -t mappview .

The container always serves the app from its root path. The build argument only sets the URL prefix that the app expects, so subpath deployments also require a reverse proxy in front of the container that strips the prefix before forwarding requests (for example, nginx proxy_pass http://mappview/; with a trailing slash).

To skip the first-launch welcome wizard for every visitor (kiosk or embedded deployments), bake VITE_WELCOME_DISABLED=1 into the build:

docker build --build-arg VITE_WELCOME_DISABLED=1 -t mappview .

Individual links can also opt out at runtime with ?welcome=0. See Embedding & Sharing.

Driving an embedded map from a host page

To let a page that frames the app talk to the live map over postMessage (fly to a record, highlight a feature, open a processing tool, and receive selection, view, and tool events), list the origins you trust:

docker run --rm -p 8080:80 \
  -e MAPPVIEW_EMBED_ORIGINS="https://portal.example.com" \
  mapptech/mappview:local

Unset (the default) the API stays off, so a public deployment can never be driven by whoever frames it. See Talking to the map at runtime for the message reference and a host-page example.

Run the desktop app

bun run tauri:dev

Build

bun run build
bun run tauri:build

The default desktop build keeps the Linux binary small and uses DuckDB-WASM for DuckDB-backed browser features. To build a larger desktop binary with the native duckdb-rs vector loader enabled, run:

bun run tauri:build:native-duckdb

Where to find the output:

  • Web build — static files in apps/mappview/dist/. Serve this directory with any static web server (or the Docker image above).
  • Desktop installers — apps/mappview/src-tauri/target/release/bundle/, with per-platform subfolders: deb/, rpm/, and appimage/ on Linux; msi/ and nsis/ on Windows; dmg/ and macos/ on macOS. The unbundled executable is in apps/mappview/src-tauri/target/release/. On Linux, bun run tauri:build builds deb and rpm by default; passing --bundles replaces that default selection rather than adding to it, so list every format you want, for example bun run tauri:build -- --bundles deb,rpm,appimage for all three.

Optional imagery credentials

The Street View plugin can use Google Street View and Mapillary imagery. The 3D Tiles panel can also load Google Photorealistic 3D Tiles with the same Google Maps key. Create apps/mappview/.env.local and set one or both provider credentials:

VITE_GOOGLE_MAPS_API_KEY=your_google_maps_api_key
VITE_MAPILLARY_ACCESS_TOKEN=your_mapillary_access_token

For Google Street View, enable the Maps Embed API for the key in Google Cloud. For Google Photorealistic 3D Tiles, enable the Map Tiles API. For local shell testing, GOOGLE_MAPS_API_KEY is also accepted by the desktop Vite build. For Mapillary, create an app in the Mapillary developer dashboard and use its client access token.

Restart bun run dev or bun run tauri:dev after changing environment variables.

Optional basemap credentials

The New map dialog offers Protomaps basemaps (Light, Dark, White, Grayscale, Black) when a Protomaps API key is configured. Without a key these options are hidden, and you can still use the OpenFreeMap basemaps or a custom style URL.

Use your own key — create one in the Protomaps dashboard. Set it one of two ways:

  • For your own deployment — bake it into the build with the VITE_PROTOMAPS_API_KEY environment variable, for example in apps/mappview/.env.local:

    VITE_PROTOMAPS_API_KEY=your_protomaps_api_key

    For a managed build, pass it as a build-time environment variable. The resulting style URL is https://api.protomaps.com/styles/v5/<flavor>/en.json?key=<your_key>.

  • At runtime, no rebuild — add an environment variable named VITE_PROTOMAPS_API_KEY in Settings → Environment Variables. The Protomaps basemaps appear as soon as the key is enabled. See Settings.

Optional traffic overlays

The Basemaps control includes a Traffic category with real-time traffic overlays that stack on top of any basemap (enable the panel’s add/multiple toggle). Each provider authenticates with your own API key, set in Settings → Environment Variables (or baked into apps/mappview/.env.local):

VITE_GOOGLE_MAPS_API_KEY=your_google_maps_api_key   # Google Traffic (Map Tiles API)
VITE_TOMTOM_API_KEY=your_tomtom_api_key             # TomTom Traffic Flow
VITE_HERE_API_KEY=your_here_api_key                 # HERE Traffic Flow

Google Traffic and Google Photorealistic 3D Tiles reuse the same VITE_GOOGLE_MAPS_API_KEY as Street View; enable the Map Tiles API for that key in Google Cloud. A newly entered key takes effect immediately, without reopening the project. Until a provider’s key is set, its overlay reports a missing-key error instead of loading tiles.

Optional Amazon Location styles

The Amazon Location entries in the Basemaps control are style basemaps (they replace the whole map style, unlike the traffic overlays above). They authenticate with your own Amazon Location API key, set in Settings → Environment Variables (or baked into apps/mappview/.env.local):

VITE_AMAZON_LOCATION_API_KEY=your_amazon_location_api_key   # Amazon Location styles
VITE_AMAZON_LOCATION_AWS_REGION=us-east-1                   # optional; omit to use the control's built-in default region

Optional Protomaps and Stadia Maps basemaps

The Basemaps control also carries Protomaps and Stadia Maps (including Stadia x Stamen) style basemaps. Both authenticate with your own key:

VITE_PROTOMAPS_API_KEY=your_protomaps_api_key   # same key as the New map dialog's Protomaps basemaps
VITE_STADIA_API_KEY=your_stadia_api_key         # https://client.stadiamaps.com

Protomaps reuses the key described in Optional basemap credentials above — set it once and both places pick it up. Until each key is set, the panel shows a “Get a … API key” prompt in place of the basemap rather than loading tiles.

Keys set via Settings → Environment Variables, or typed directly into the panel’s API keys view (the key button in the panel header), apply at runtime without reopening the project. A key baked into apps/mappview/.env.local is read at build time and needs a dev server restart. When VITE_AMAZON_LOCATION_API_KEY is set in the environment it takes precedence over a key typed in the panel; removing it from the environment clears it on the next page reload.

Optional 3D globe credentials (Cesium Ion)

The optional Cesium 3D-globe view — a split-pane globe rendered with CesiumJS alongside the 2D MapLibre map — needs a Cesium Ion access token for its world imagery and terrain. Create a free Ion account, copy your default access token, and set it at build time:

CESIUM_TOKEN=your_cesium_ion_access_token

CESIUM_TOKEN (or the VITE_-prefixed VITE_CESIUM_TOKEN) is read by vite.config.ts and baked into the build. You can also set it at runtime — with no rebuild — in the Settings dialog’s Environment Variables section, which has a dedicated masked Cesium Ion token field. That token is stored locally on the device (in browser storage on the web build), not in the shared project file, and overrides the build-time value; it is how a web user brings their own Ion token. (A free-form VITE_CESIUM_TOKEN variable in the same section still works and takes precedence, as an override.) Without a token from any source, the 3D-globe toggle is hidden entirely (the 2D map is unaffected). Ion access tokens are designed to ship in client bundles. See Architecture for how the globe integrates.

Optional runtime mirrors (offline and air-gapped)

The Python (Pyodide) vector engine loads its runtime from the public jsDelivr CDN by default. To self-host it for offline or production use, point it at a mirrored copy of the Pyodide distribution:

VITE_PYODIDE_INDEX_URL=https://your-host/pyodide/v0.27.7/full/

Similarly, the DuckDB Spatial extension is installed from DuckDB’s remote extension repository by default. To load it from a mirror instead (so INSTALL spatial is skipped and the extension is loaded directly), set the full path or URL to the extension file:

VITE_DUCKDB_SPATIAL_EXTENSION_PATH=https://your-host/duckdb/spatial.duckdb_extension.wasm

Both variables can also be set at runtime through the Settings dialog’s environment variables (no rebuild required), so air-gapped or corporate deployments can point Pyodide and the DuckDB Spatial extension at internal mirrors without rebuilding.

For a deployment that must not contact a third-party CDN, set the build-time Meratyn policy before building the viewer:

MAPPVIEW_NO_EXTERNAL_CDN=1 VITE_PYODIDE_INDEX_URL=https://geo.example.test/pyodide/v0.27.7/full/ bun run build

This policy bundles the PGlite/PostGIS, CereusDB, and DuckDB-WASM assets that Meratyn controls, disables GDAL export (which has no bundled runtime), removes built-in models that are hosted on external model CDNs, and disables story-map HTML export and browser vision/depth models until operator-hosted assets are configured. The build fails if a known Meratyn-controlled CDN URL survives in the emitted JavaScript or service worker, so a dependency change cannot silently reintroduce an outbound fetch. The guard covers Meratyn-owned executable and model targets; third-party packages may retain inert fallback URL strings, while operator-owned service and dataset endpoints remain deployment policy. The Pyodide mirror is required because its runtime and wheels are loaded by a worker at runtime; the Effect configuration boundary rejects an air-gapped build with no valid mirror instead of falling back to a public URL. User-owned basemap, tile, service, plugin-registry, and dataset URLs remain runtime data and must be mirrored or allowlisted separately when the network boundary requires a fully private deployment.

Optional Python sidecar

The optional FastAPI sidecar is reserved for heavier processing workflows and is not required for the desktop UI.

cd services/server
python -m venv .venv
source .venv/bin/activate
pip install -e "."
uvicorn sidecar.app.main:app --host 127.0.0.1 --port 8765

The sidecar self-bootstraps a managed runtime on first use; set MAPPVIEW_CONVERSION_PYTHON=$(which python) to reuse the current environment instead. See the sidecar README (services/server/README.md) for details.

Optional extras

The base install is deliberately small. Each group of tools has its own extra; install only the ones you need, then run mappview-server (or the uvicorn command above). These continue from services/server, the directory the snippet above changes into:

# Conversion tools (DuckDB, rio-cogeo, freestiler)
pip install -e ".[conversion]"

# Vector tools — GeoPandas engine (GeoPandas, Shapely)
pip install -e ".[vector]"

# Raster tools (rasterio, numpy, contourpy)
pip install -e ".[raster]"

# AI Segmentation proxy (lightweight HTTP client; models use the separate runtime)
pip install -e ".[ml]"

# Operator-managed SamGeo/SAM3 runtime (Python 3.12+, separate environment)
pip install -e ".[samgeo-runtime]"

The [ml] extra keeps the sidecar lightweight and does not install PyTorch or model files. Run samgeo-api from the Python 3.12+ environment with a compatible PyTorch build. The [samgeo-runtime] extra pins segment-geospatial[api,samgeo3]==1.4.2; then set MAPPVIEW_ML_SAMGEO_URL in the sidecar environment. After supplying weights and accepting their terms, set MAPPVIEW_ML_SAMGEO_WEIGHTS_CONFIGURED=1 and MAPPVIEW_ML_SAMGEO_LICENSE_ACCEPTED=1. Meratyn never stores those weights, credentials, or acknowledgements in a project file. See AI Segmentation for the full boundary.

From the repository root instead, use the full path — for example pip install -e "services/server[conversion]".

To use the sidecar from the web build, start it and serve the app from localhost:5173 — CORS is restricted to that origin and the Tauri origins. Where a tool has a browser engine (all Vector tools, and the GeoParquet/CSV conversions), the dialog falls back to it automatically when the sidecar or its extra is unavailable. See Processing Tools for what each engine does, and AI Segmentation for the separate samgeo-api model server.