Skip to content

Concepts

Kohei Otsuka edited this page Jul 24, 2026 · 1 revision

Concepts

Background and theory behind MaplatTin: TIN transform, homeomorphic mapping, strict/loose modes, and the relationship to the Maplat ecosystem.

Table of Contents


What MaplatTin provides

MaplatTin is a standalone JavaScript library that implements the coordinate transform at the heart of the Maplat viewer. It takes a set of control points (GCPs) and a boundary, builds a Triangulated Irregular Network (TIN), and produces a bidirectional transform between two plane coordinate systems.

MaplatTin has no OpenLayers dependency, so it can run in pure Node.js for offline preprocessing (e.g. as part of a MaplatTransform pipeline) as well as in the browser.

TIN-based homeomorphic transform

The defining property of MaplatTin is that the transform is:

  • Nonlinear — each triangle has its own affine map, so the overall transform can bend smoothly across the image.
  • Homeomorphic — the transform is continuous and has a continuous inverse, so the topology of the original image is preserved. No folding, no tearing.
  • Bidirectional / bijective (in strict mode) — each point in the source plane maps to exactly one point in the target plane and vice versa.

This is what lets Maplat overlay historical maps on accurate modern maps without distorting the original image.

How the TIN is built

  1. The control points (GCPs) are triangulated using a Delaunay algorithm (see delaunator).
  2. For each triangle, a local affine map is computed from the three GCP pairs.
  3. When transforming a point, the triangle containing that point is located (via a search index), and its affine map is applied.
  4. The inverse transform uses the same triangulation, with the affine maps inverted.

Strict and loose modes

When the triangulation cannot preserve bidirectional bijection (topology is broken — typically because control points create folding triangles), MaplatTin has three behaviors controlled by strictMode:

strictMode strict_status after updateTin() Behavior
"strict" STATUS_STRICT or throws Strict topology required; if impossible, updateTin() throws
"auto" (default) STATUS_STRICT or STATUS_LOOSE Try strict first; fall back to loose if strict fails
"loose" STATUS_LOOSE Always allow, even if bijection is not guaranteed

In STATUS_LOOSE, the forward transform still works, but the inverse transform may produce non-unique results. Use STATUS_STRICT when roundtrip guarantees matter (e.g. user-facing map overlay). Use STATUS_LOOSE for one-way preprocessing pipelines where the forward transform is enough.

Edge constraints

In addition to control points, MaplatTin accepts constrained edges via setEdges(edges). These edges are forced into the triangulation, which is useful when you know that two control points should remain connected (e.g. along a road, river, or boundary) and the default Delaunay triangulation would have skipped that edge.

The internal EdgeBound constraint engine handles the geometric re-triangulation. See the tests/edgebound/ suite for behavior details.

Vertex modes (plain / birdeye)

vertexMode controls how the boundary vertices are handled:

  • "plain" — the source-plane boundary is used as-is.
  • "birdeye" — a bird's-eye view adjustment is applied, useful when the source image has perspective distortion that should be partially corrected before triangulation.

Most maps use "plain". "birdeye" is a specialized mode for illustrated maps with perspective.

Y-axis modes

Image coordinates typically have Y increasing downward, while cartographic coordinates have Y increasing upward. MaplatTin handles this with yaxisMode:

  • Tin.YAXIS_FOLLOW — the source Y-axis has the same direction as the target.
  • Tin.YAXIS_INVERT (default) — the source Y-axis is inverted relative to the target.

Choose based on the coordinate systems you are bridging. For pixel → Web-Mercator transforms (the Maplat use case), the default YAXIS_INVERT is usually correct.

Relationship to MaplatCore and MaplatTransform

  • MaplatCore (@maplat/core) uses MaplatTin internally for the live viewer transform. It wraps the OpenLayers rendering and the Maplat app-data protocol around MaplatTin.
  • MaplatTransform (@maplat/transform) is the preprocessing toolchain that uses MaplatTin to pre-compute compiled transform data for offline batch pipelines.

MaplatTin itself is the lowest-level building block: pure coordinate math, no rendering, no I/O.


日本語版はこちら / Read this page in Japanese

See Also

MaplatTin

Language / 言語

Pages / ページ

English

日本語

External / 外部

Clone this wiki locally