Documentation

Pro handbook

Getting started with OpenLayers

Installation#

Not yet published on npm. The command below is what installation will look like once the packages are released. Until then, work inside this repository (a pnpm workspace) or link the packages from it. Their entry points are TypeScript sources, so your bundler must compile TypeScript (Vite does).

npm install @vectorstream/core @vectorstream/editor @vectorstream/openlayers ol

ol is a peer dependency (^10.10.0); @vectorstream/adapter comes along with @vectorstream/openlayers.

The complete example#

A real file of this repository (docs/handbuch/beispiele/openlayers-quickstart.ts); a test draws a triangle through it, exports, undoes and switches tools by key.

openlayers
import OlMap from 'ol/Map.js';
import View from 'ol/View.js';
import TileLayer from 'ol/layer/Tile.js';
import OSM from 'ol/source/OSM.js';
import { fromLonLat } from 'ol/proj.js';
import 'ol/ol.css';
import { exportGeoJSON, importGeoJSON, type FeatureCollection } from '@vectorstream/core';
import { Editor, Toolbar, defaultToolbarEntries } from '@vectorstream/editor';
import { OpenLayersAdapter } from '@vectorstream/openlayers';

export function startEditor(container: HTMLElement, data: FeatureCollection) {
  // 1. The map. The view stays in Web Mercator; the adapter converts to longitude/latitude.
  const map = new OlMap({
    target: container,
    layers: [new TileLayer({ source: new OSM() })],
    view: new View({ center: fromLonLat([7.4555, 51.5112]), zoom: 17 }),
  });

  // 2. The adapter draws the editor's scene on the map and reports pointer and key events.
  const adapter = new OpenLayersAdapter(map);

  // 3. The editor works on a partition — here one built from GeoJSON.
  const editor = new Editor(importGeoJSON(data), adapter);

  // 4. The toolbar is state, not UI: it knows the tools and their shortcut keys.
  const toolbar = new Toolbar(editor, defaultToolbarEntries());
  toolbar.select('draw');

  // 5. Every transaction ends in exactly one of three events.
  editor.on('change', ({ label }) => console.log('changed:', label));
  editor.on('unchanged', ({ label }) => console.log('nothing to do:', label));
  editor.on('rejected', ({ label, violations }) => {
    console.warn('rejected:', label, violations.map((v) => v.detail));
  });

  return {
    map,
    editor,
    toolbar,
    // 6. Export the active layer as GeoJSON (longitude/latitude, not Web Mercator).
    save: (): FeatureCollection => exportGeoJSON(editor.partition),
    // 7. Undo and redo; `false` means there was nothing to do, or the step was rejected.
    undo: (): boolean => editor.undo(),
    redo: (): boolean => editor.redo(),
    destroy(): void {
      toolbar.destroy();
      editor.destroy();
      adapter.destroy();
      map.setTarget(undefined);
    },
  };
}

The steps are the same as on Getting started with Leaflet: map, adapter, editor, toolbar, events, export, undo. Only the map and the adapter differ.

OpenLayers specifics#

  • Coordinates. The view keeps its own projection (Web Mercator by default). The editor, the scene, GeoJSON import and export all work in longitude/latitude; the adapter converts with the view's projection when it draws and when it reports pointer positions.
  • Layers. The adapter adds five vector layers (faces, edges, guide lines, handles, labels) with a zIndex from 1000 upward, so that tile layers added later do not cover the drawing.
  • No rotation. While the adapter exists it switches off the map's rotate interactions (DragRotate, PinchRotate, DragRotateAndZoom): Alt and Shift have editing meanings, and the editor assumes north is up. adapter.destroy() restores their previous state.
  • Pointer events are taken from the map's own pointer events, so the editor can switch off panning before OpenLayers starts a drag. Keys come from keydown on the document, except while typing in an input field, text area, select box or contenteditable element.
  • Options. new OpenLayersAdapter(map, { ebenenFarbe }) — the color of a layer, as with Leaflet.
  • Teardown. Destroy toolbar, editor and adapter, then detach the map with map.setTarget(undefined).

Next: Faces and edges, Modes, API reference: OpenLayersAdapter.

See it on a map.