Documentation

Pro handbook

Getting started with OpenLayers

Installation#

The free packages are on npm at version 0.1.0 (all packages). Install them with the command below.

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.