npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@metsa/isom-maplibre

v0.1.1

Published

ISOM 2017-2 orienteering map style for MapLibre GL, generated from the ISOM symbol dimensions

Readme

isom-maplibre

A MapLibre GL style that renders orienteering maps per ISOM 2017-2, the IOF International Specification for Orienteering Maps, at 1:10,000.

Every line width, dash, pattern and symbol is computed from the ISOM dimensions (mm at 1:15,000, enlarged ×1.5 and converted at 96 dpi), uses the ISOM colours, and is stacked in the ISOM colour order. The dimensions come from ISOM 2017-2 itself: the symbol definitions of section 3, the precise definitions of section 3.8, and the colours of Appendix 1 (CMYK printing and colour definitions). The colour order is the IOF's table for ISOM 2017-2 in "IOF Map Specifications - Printing and Colour Definitions" (2022, the successor of Appendix 1): olive above the greens, streams above the contours, contours above lakes.

Install

npm install @metsa/isom-maplibre maplibre-gl

Releases are published to npm with provenance.

Usage

In-memory GeoJSON

isomGeojsonStyle() returns the GeoJSON style (one GeoJSON source per table, no sprite) with your data attached, and registerIsomIcons() supplies the pattern and symbol images at runtime:

import maplibregl from "maplibre-gl";
import { isomGeojsonStyle, registerIsomIcons } from "@metsa/isom-maplibre";

const map = new maplibregl.Map({
  container: "map",
  style: isomGeojsonStyle({ contours, water, paths }), // FeatureCollections, lng/lat
});
registerIsomIcons(map);

Tables you leave out start empty; fill them later with map.getSource(table).setData(featureCollection). DETAIL_TABLES lists them. The style without data is also exported as @metsa/isom-maplibre/style.geojson.json.

Vector tiles

import style from "@metsa/isom-maplibre/style.json";

The style reads one vector source per table from /tiles/<table> (TileJSON) and its images from the sprite /sprite/isom. Point those URLs at your server and build the sprite from ICONS (SVGs keyed by image id), or pass -sprites to the generator (see Development). Two optional sources serve large tile sets:

  • overview: one source whose layers carry vegetation_areas, water, paths and manmade, drawn below zoom 13 in place of the per-table sources.
  • coverage: polygons outlining where data exists. From zoom 10 they are white paper under the map, so a basemap merged underneath never shows through; below zoom 10 they are a translucent brown patch marking where maps are.

Every layer except the background carries metadata for selecting layers without parsing ids: isom:pass (detail, overview or coverage), and on symbol layers isom:code and isom:group (the ISOM colour group). The style's own metadata["isom:tables"] lists the tables in definition order.

Data

Each feature carries a string isom_code property. Codes without a symbol stay invisible.

| Table | Geometry | isom_code | |--------------------|-----------------|----------------------------------------------------------------------| | contours | lines | 101.000, 101.001 (slope line), 102.000, 103.000, 104.000, 105.000 | | cliffs | lines, polygons | 201.000, 202.000, 206.000 | | knolls_points | points | 109.000, 111.000 | | vegetation_areas | polygons, lines | 401.000 to 410.000, 412.000, 413.000, 415.000 | | water | lines, polygons | 301.000, 302.000, 304.000, 305.000, 306.000, 308.000 | | paths | lines | 502.000 to 507.000 | | manmade | lines, polygons | 501.000, 509.000, 510.000, 511.000, 515.000, 516.000, 520.000, 521.000, 521.001 (large building: outline and 50% infill), 529.000 |

A 101.001 slope line is a two-point line from the contour downhill; the symbol takes its bearing from it. Coordinates are lng/lat, as for any MapLibre source.

Scale

Up to zoom 15 every dimension is constant; above it the whole map magnifies ×2 per zoom level, which keeps ISOM proportions intact. Zoom 15 is true 1:10,000 at about 56° latitude. At latitude φ the true-scale zoom is log2(156543.03 · cos φ / 2.6458).

Limitations

MapLibre cannot draw some ISOM ornaments, so these symbols are simplified:

  • Plain line without its ornament: 104 tags, 105 dots, 201 tags, 510 pylon bars, 515 dots, 516 tags, 529 tick pairs.
  • Flat fill without its pattern: 402 and 404 holes, 412 dots, 413 dot rows.
  • Dashes are not balanced per feature as ISOM asks.
  • The white core of 509 and 511 masks what lies beneath it.
  • Fill patterns (308, 407, 409) keep their density above zoom 15.
  • The map must be displayed north-up for the north-oriented patterns to be correct.

Development

isom.yaml defines the whole style: scale, palette (referenced through YAML anchors), images, and the symbol stack. It is validated by isom.schema.json, which editors with the YAML language server pick up automatically; the generator enforces the schema too, plus the cross-references it cannot express (palette colours, table and image names). src/style.json, src/style.geojson.json and src/icons.json are generated from it:

go generate ./...   # regenerate src/
go test ./...       # schema, ISOM dimension and colour-order checks
npm run build && npm test

The generator is also usable directly, for example to write a sprite directory for a tile server. It reads the definition embedded in the module unless -spec names another file:

go run github.com/MetsaApp/isom-maplibre/cmd/genstyle@latest \
  -style style.json -geojson-style style.geojson.json -icons icons.json -sprites sprites/

Go programs get the parsed definition from isomstyle.Default() in github.com/MetsaApp/isom-maplibre/pkg/isomstyle (Load and Parse take another one), and render it with Style, GeojsonStyle and Icons.

Commits follow Conventional Commits; release-please opens the release PR, and merging it tags the release and publishes the package.

License

MIT. ISOM is a specification of the International Orienteering Federation; this project is not affiliated with the IOF.