Skip to content

Concepts

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

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_nameappName app_name appName camelCase
fake_gpsfakeGps fake_gps fakeGps camelCase
fake_centerfakeCenter fake_center fakeCenter Now often a plain string, not locales
home_positionhomePosition home_position homePosition camelCase
default_zoomdefaultZoom default_zoom defaultZoom camelCase
pois Inline POI objects Array of POI source filenames (e.g. ["tatebayashi.json", "stones_poi.geojson"]) POI are now external GeoJSON sources
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
startFrom startFrom (string) Initial map selection
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.

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.


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

See Also

Maplat

Language / 言語

Pages / ページ

English

日本語

External / 外部

Clone this wiki locally