Skip to content

Concepts

Kohei Otsuka edited this page Aug 10, 2026 · 3 revisions

Concepts

Background and theory behind Maplat: data formats, coordinate transform, and the TIN library.

Table of Contents


Data Formats

Application Data Format

An application data file defines a map-switchable application by collecting multiple map data sources and POI definitions. It is placed under the apps folder in the Maplat root, named {appID}.json.

The sample application is at apps/sample.json.

Schema (0.2.6 era — draft-04)

The schema below is from the 0.2.6 era (August 2018). It uses snake_case field names. The current version uses camelCase (e.g. appName, fakeGps, homePosition, defaultZoom, fakeCenter, fakeRadius, startFrom). See the note below for details.

$schema: "http://json-schema.org/draft-04/schema#"
title: "Maplat Application"
type: "object"
required:
  - "app_name"
  - "home_position"
  - "default_zoom"
  - "sources"
properties:
  app_name:
    oneOf:
      - type: "string"
      - type: "locales"
  fake_gps:
    type: "boolean"
  fake_center:
    oneOf:
      - type: "string"
      - type: "locales"
  fake_radius:
    type: "number"
  home_position:
    type: "array"
    items:
      type: "number"
      minItems: 2
      maxItems: 2
  default_zoom:
    type: "number"
  sources:
    type: "array"
    items:
      anyOf:
        - type: "string"
          enum: ["osm", "gsi"]
        - type: "object"
          required: ["mapID"]
          properties:
            mapID: { type: "string" }
            label: { oneOf: [{ type: "string" }, { type: "locales" }] }
            maptype:
              type: "string"
              enum: ["base", "overlay", "maplat"]
            url: { type: "string" }
  pois:
    type: "array"
    items:
      type: "object"
      required: ["name", "lat", "lng", "desc"]
      properties:
        name: { oneOf: [{ type: "string" }, { type: "locales" }] }
        address: { oneOf: [{ type: "string" }, { type: "locales" }] }
        lat: { type: "number" }
        lng: { type: "number" }
        desc: { oneOf: [{ type: "string" }, { type: "locales" }] }
        image: { type: "string" }

Current-version differences (2026-07 verification)

The current apps/sample.json (on the foss4g-stories branch) differs from the 0.2.6 schema in the following ways:

Field 0.2.6 (snake_case) Current (camelCase) Notes
app_name → appName app_name appName camelCase
fake_gps → fakeGps fake_gps fakeGps camelCase
fake_center → fakeCenter fake_center fakeCenter Now often a plain string, not locales
home_position → homePosition home_position homePosition camelCase
default_zoom → defaultZoom default_zoom defaultZoom camelCase
pois Inline POI objects Layer refs, external URL references, and map-embedded POI No longer a plain array of source filenames. See POI in the current version
sources shortcuts "osm", "gsi" "osm", "gsi", "gsi_ortho" gsi_ortho (orthophoto) added
sources item fields mapID, label, maptype, url + maxZoom, envelopeLngLats, mercatorXShift, mercatorYShift, title, attr, contributor, author, createdAt Richer source metadata. envelopeLngLats is the usage extent — the area the app actually uses — given as longitude/latitude pairs
startFrom — startFrom (string) Initial map
splash — splash (string) Splash screen image
description — description (string) App description

The JSON Schema structure (locales type, required fields) is conceptually still valid, but the field naming convention and POI handling have changed. The authoritative reference is the current apps/sample.json and the TypeScript types in the source code.

POI in the current version

pois is no longer an array of POI source filenames. It is an array whose elements may take any of the following forms, freely mixed:

Form Shape What it means
Layer ref (wrapper) { "layer": <URL or FeatureCollection>, "hide"?, "title"?, "icon"?, "selectedIcon"? } References a POI layer and overrides only how it is presented in this app. The referenced content itself is not modified
External URL reference "pois/tatebayashi.geojson" A URL string that is fetched and normalised into a layer at load time
Map-embedded POI An inline FeatureCollection written directly in the app/map JSON POI defined in the app/map file itself, with no external file

Older shapes (a bare array of POI objects, an array of FeatureCollections, and the legacy layer dictionary) are still accepted unchanged.

This gives POI presentation two levels: the attributes carried by the POI source itself (FeatureCollection.properties), and the per-reference override supplied by a layer ref. The override wins over the source attribute of the same name. The rules are documented in the MaplatCore Wiki § POI and layer model and in docs/api/maplat-core.md of the MaplatCore repository.

Map Data Format

Maplat has two interoperable map data formats, placed under the maps folder as {mapID}.json.

Standard Data Format

The standard format is human-editable because it defines coordinate correspondence pairs (GCPs) between the standard map coordinate system (Web Mercator, SRID:3857) and the historical map image coordinates.

$schema: "http://json-schema.org/draft-04/schema#"
title: "Maplat Standard"
type: "object"
required: ["title", "attr", "width", "height", "gcps"]
properties:
  title: { type: "string" }
  attr: { type: "string" }
  width: { type: "number" }
  height: { type: "number" }
  year: { type: ["string", "number"] }
  url: { type: "string" }
  gcps:
    type: "array"
    items:
      type: "array"
      minItems: 2
      maxItems: 2
      items:
        type: "number"
        minItems: 2
        maxItems: 2
  • gcps — array of coordinate pairs: [[imageX, imageY], [mercatorX, mercatorY]]
  • width, height — original map image pixel dimensions
  • Other attributes (title, attr, year) are metadata

Compiled Data Format

The compiled format pre-computes the transform data from the standard format. It replaces gcps with a compiled property containing the pre-computed TIN structure. This format is not intended for human editing (consistency would be lost). MaplatEditor can convert between the two formats losslessly.

Choosing between formats: The compiled format is larger (sometimes 100x) but loads faster because no runtime computation is needed. For maps with many GCPs, compiled is recommended for better perceived load speed.

Coordinate Transform

The Tin Transform Class

Maplat's coordinate transform is based on a TIN (Triangulated Irregular Network) approach that guarantees a nonlinear but homeomorphic (topology- preserving) bidirectional mapping between two coordinate systems.

The transform class lives in the MaplatTin repository (published as @maplat/tin). Historically it was part of the Maplat repository at js/tin.js, but it has been split into a separate package.

Dependencies:

Object creation

var tin = new Tin({
    wh: [width, height],
    points: points
});
  • wh — pixel width/height of the historical map image
  • points — array of GCP pairs (same format as the gcps property in the standard map data format)

Both wh and points are optional and can be set later via setWh / setPoints. Changing either resets the pre-computed transform, so the object can be reused. Partial addition/removal of points is not supported — always full replacement.

Pre-computation: updateTinAsync

tin.setPoints(points);
tin.updateTinAsync(true).then(function() {
    var illstXy = tin.transform(mapXy, true);
});

updateTinAsync(strict) returns a Promise. The strict argument controls behavior when topology-preserving TIN cannot be constructed.

Transform: transform(xy, inverse)

  • First argument: the XY coordinate to transform
  • Second argument: if true, reverse direction (standard → image); if omitted or false, forward direction (image → standard)

Compiled data: getCompiled / setCompiled

  • getCompiled() — extract pre-computed data for serialization
  • setCompiled(data) — load pre-computed data, skipping updateTinAsync
  • wh must still be set before setCompiled

Strict and Loose Modes

Maplat guarantees bidirectional bijective (one-to-one and onto) transform when the generated TIN network maintains topology in both directions.

State strict_status Behavior
Topology preserved STATUS_STRICT Bidirectional bijection guaranteed
Topology broken, strict mode STATUS_STRICT_ERROR Forward transform only; kinks property contains edge intersection list
Topology broken, loose mode STATUS_LOOSE Bidirectional transform possible, but bijection is not guaranteed

This is the core theoretical guarantee that lets Maplat overlay historical maps on accurate modern maps without distorting the original image.

TIN Transform Library

The detailed API reference for the TIN transform library (@maplat/tin) is maintained in the MaplatTin repository. It is published as a separate npm package and has its own Wiki / documentation.

For the Maplat-level API (MaplatUi), see API-Reference.

Internationalization

The viewer UI text (labels, controls, and similar chrome) supports multiple languages out of the box, independent of the data being displayed (map titles, POI names, etc., which come from the historical-map data itself and follow their own language settings). For the current, up-to-date list of supported UI languages, see the README § Key Features — the list is release-dependent and grows over time, so it is intentionally not duplicated here.


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

See Also

Maplat

Language / 言語

Pages / ページ

English

日本語

External / 外部

Clone this wiki locally