🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@zwaarcontrast/ol-graticule-projected

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@zwaarcontrast/ol-graticule-projected

Generic proj4-backed grid system for ol-graticule. Works with any CRS.

latest
Source
npmnpm
Version
3.0.0
Version published
Maintainers
1
Created
Source

@zwaarcontrast/ol-graticule-projected

Generic proj4-backed GridSystem for @zwaarcontrast/ol-graticule. Use it to render a graticule in any CRS, UTM zones, state planes, national grids, on top of any OL view projection.

UTM 33N grid pinched at the poles, rendered over a Web Mercator world map

Live demo: https://zwaarcontrast.nl/ol-graticule/ol-graticule-projected/

Install

npm install @zwaarcontrast/ol-graticule @zwaarcontrast/ol-graticule-projected ol proj4

Peers: ol ^10, proj4 ^2.9, @zwaarcontrast/ol-graticule.

Usage

UTM zone 33N (metres)

import { UniversalGraticule } from '@zwaarcontrast/ol-graticule';
import { ProjectedGridSystem } from '@zwaarcontrast/ol-graticule-projected';

const gridSystem = new ProjectedGridSystem({
  crs: 'EPSG:32633',
  proj4Def: '+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs',
});

map.addLayer(new UniversalGraticule({ gridSystem, style: { edgeLabel: true } }));

MetricIntervals + MetricFormatter are auto-selected because the CRS uses metres, so labels read "500 km", "20 km", etc.

US State Plane, California Zone III (feet)

const gridSystem = new ProjectedGridSystem({
  crs: 'EPSG:2227',
  proj4Def:
    '+proj=lcc +lat_1=38.43333333333333 +lat_2=37.06666666666667 +lat_0=36.5 ' +
    '+lon_0=-120.5 +x_0=2000000.0001016 +y_0=500000.0001016001 +datum=NAD83 ' +
    '+units=us-ft +no_defs',
  // Optional: clip to the valid AoU so lines don't wander off.
  extent: [5905300, 1477700, 7540700, 2396900],
});

Register the CRS up front

If several parts of your app talk to the same CRS, register it once at app startup and omit proj4Def from the grid-system options:

import { registerCRS } from '@zwaarcontrast/ol-graticule-projected';

registerCRS('EPSG:32633', '+proj=utm +zone=33 +datum=WGS84 +units=m +no_defs');

// Later, no proj4Def needed, the CRS is already in proj4/OL's registry.
new ProjectedGridSystem({ crs: 'EPSG:32633' });

registerCRS is idempotent; passing proj4Def to the constructor is a convenience shortcut that calls it for you.

Options

OptionTypeDefaultWhat it does
crsstring, (required)EPSG code or other proj4-known name.
proj4Defstring,proj4 definition. Registered via registerCRS if provided. Omit if already registered.
extent[minX, minY, maxX, maxY]projection's built-in extentAxis-aligned validity bounds in CRS coordinates. Lines outside are clipped.
clipPolygon[x, y][],Irregular boundary polygon in CRS coordinates (for non-rectangular coverage). Overrides extent for drawing.
intervalsIntervalStrategyauto from CRS unitsSpacing strategy. Degrees → DegreeIntervals, metres → MetricIntervals.
formatterLabelFormatterauto from CRS unitsLabel formatter. Degrees → DegreeFormatter, metres → MetricFormatter.
targetScreenPxnumber100Desired minimum spacing (px) between major lines. Drives interval selection.
densificationPointsnumber100Points per grid line for curved rendering across projections. Higher = smoother, slower.

Reverse: parse a typed coordinate back

ProjectedGridSystem.parseCoordinate takes a label and returns view-projection coords:

import { ParseError } from '@zwaarcontrast/ol-graticule';

try {
  const center = gridSystem.parseCoordinate('500000 5000000', map.getView().getProjection());
  map.getView().animate({ center });
} catch (err) {
  if (err instanceof ParseError) console.warn(err.reason);
}

For per-axis CRSs (the common case) it splits on whitespace or comma and parses each half via the formatter ("500000 5000000", "500000, 5000000", "500000 m 5000000 m"). For degree-units CRSs, hemisphere markers route the two halves to lat/lon automatically; without markers, plain "x y" is treated as "lon lat". Compound formatters (e.g. MBSFormatter from ol-graticule-modified-british-system) plug in via formatter.parseCoordinate so you can type "vK 617 517" directly and the system transforms the result to your view projection.

extent vs clipPolygon

  • Use extent when the CRS has a rectangular validity region (UTM zones, state planes with square AoUs). Cheaper and sufficient most of the time.
  • Use clipPolygon when the coverage is irregularly shaped, e.g. the Netherlands outline for RD, the Nord de Guerre WWI coverage polygon. Lines are clipped to the polygon and cells outside it don't draw.

Both can coexist, the grid system intersects them.

Loading NTv2 datum-shift grids

If your CRS needs a sub-metre NTv2 datum shift (e.g. +nadgrids=@mygrid), register the grid file with proj4 once before constructing the system:

import { loadNadgrid } from '@zwaarcontrast/ol-graticule-projected';

await loadNadgrid('@mygrid', '/assets/mygrid.gsb');

new ProjectedGridSystem({
  crs: 'EPSG:1234',
  proj4Def: '+proj=… +nadgrids=@mygrid +…',
});

For Dutch RD (EPSG:28992/28991) with RDNAPTRANS 2018 pre-bundled, use @zwaarcontrast/ol-graticule-rd instead of wiring this up yourself.

Exports

  • ProjectedGridSystem, ProjectedGridSystemOptions
  • registerCRS(code, proj4Def), idempotent proj4 + OL registration.
  • loadNadgrid(name, url), fetch + register an NTv2 .gsb file.
  • MetricIntervals, MetricFormatter, re-exported from core for convenience.

License

MIT.

Keywords

openlayers

FAQs

Package last updated on 30 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts