Documentation

Pro handbook

Changelog

0.1.0#

The seven free packages are published on npm at version 0.1.0. In this repository their package.json files still carry the placeholder version 0.0.0 and "private": true; the published versions are made from a copy at release. @vectorstream/pro is not published.

This handbook and the API reference describe the code as it is in this repository. Breaking changes can happen at any time before 1.0.

Packages and license#

  • The packages build for release. Each package builds to dist/ (ES modules, type declarations, source maps; npm run build), and its exports carry the conditions source, types and import.
  • Free and Pro are separate packages. The free package @vectorstream/editor (MIT) does the core work. Everything else lives in @vectorstream/pro: the ten rule kinds beyond 'innerhalb' and 'ueberlappungsfrei', attribute conditions, rules in meters, the red preview, snapping onto target layers, the incremental check of rules, the circle as a cutting shape (CutCircleMode, DifferenceCircleMode) and the list of violations (@vectorstream/pro/ui). The editor takes extensions through EditorOptions.erweiterungen and erweiterungGlobalAnmelden; OHNE_GLOBALE builds an editor that ignores the announced ones; editor.regelarten() lists the kinds of an editor. See Free and Pro and Extensions.
  • Removed from the free package: ARTEN, REGELARTEN, EingebauteArt and bedingungErfuellt (now in @vectorstream/pro), CutCircleMode and DifferenceCircleMode, Vorschaupruefung and the two circle entries of defaultToolbarEntries() (21 entries; @vectorstream/pro brings mitProWerkzeugen). The pure check functions (pruefeRegel, regelRoh ...) know the two free kinds when no registry is handed in.
  • License key. @vectorstream/pro checks a signed license key offline and shows a watermark without a valid one. No function depends on the key. See Setting up the license key.
  • Package names. @vectorstream/core, @vectorstream/adapter, @vectorstream/editor, @vectorstream/toolbar-ui, @vectorstream/leaflet, @vectorstream/openlayers and @vectorstream/maplibre.
  • @vectorstream/toolbar-ui is new: ready-made toolbar buttons built on Toolbar (groups, separators, the tool icons, and on/off toggles for the snapping switches) for an application that would rather not draw its own (see Toolbar). It is optional and separate from @vectorstream/editor.

Rules between layers#

  • Rules of a kind the editor does not know are kept. A stored rule is read in two stages (envelope, then kind). One whose kind is not registered, or that has a condition no extension can evaluate, is listed by editor.regeln() with status: 'benoetigtErweiterung' and its stored text unchanged. It is never checked, can be removed but not changed (ruleNeedsExtension), and the import of the application no longer drops it. New exports: huelleRoh, ersetzeZiel, PRO_ARTEN, the types Fremdregel, Regeleintrag, Regelhuelle. editor.regeln() now returns Regeleintrag[]. See Compatibility.
  • More kinds of rule. 'beruehrt', 'beruehrungsfrei', 'schneidend', 'abdeckung', 'lueckenlos', 'aufLinie', 'aufRand', 'mindestabstand', 'mindestflaeche', 'mindestbreite'; a measure mass and an attribute condition bedingung per rule; Regel.ziel can be null; Regelverstoss.elementEbene; ARTEN, Bedingung, bedingungErfuellt, Laengenmass, laengenmassAus. Older builds read the new kinds as unreadable. See Rules between layers.
  • Minimum width finds long convex slivers. When the cell search of 'mindestbreite' runs out of its 20 000 cells, the convex hull of the outer ring decides: a hull narrower than the circle is reported. Rules that used to let a long thin strip or triangle pass now report it. See Minimum width.
  • Minimum distance near the poles. 'mindestabstand' no longer misses a pair at a large longitude difference close to a pole (see Meters).
  • Violations box above the layer tree in the application: always in view, the tree scrolls in itself. See The list of violations.
  • Red preview. With an active rule on the active layer, the preview of the drawing and editing tools turns red when the next action would be refused; violating legacy is drawn as invalid. See The red preview.
  • Showing an element on the map. Adapter.bereichZeigen(bereich, randPx?) (all three map adapters and NullAdapter.gezeigteBereiche), the type Bereich, and editor.zeigeElement(layer, element). A custom Adapter must implement the new method. See Rules between layers.

Data and geometry#

  • importGeoJSON checks the geometry. New option ImportOptions.geometriePruefen (default true): the result is run through checkGeometry, and findings (overlapping areas, crossing edges, a node on a foreign edge) throw an ImportError with code 'core.importInvalidGeometry' and the findings in violations. Pass geometriePruefen: false for trusted documents or to open legacy data. Data that used to import is now rejected when it is invalid. See GeoJSON.
  • Attribute keys named like Object.prototype members. A GeoJSON property called __proto__ used to be dropped on import. It and constructor, prototype, toString and the like are now ordinary attributes (import, SETATTR, undo/redo, export, saved documents). Attribute sets are objects with a null prototype, so attributeVon(p, id) has no inherited members. New helpers neuerAttributsatz, setzeSchluessel, hatSchluessel build attribute records. See Labels and attributes. Breaking for code that treats a set like a plain object: set.hasOwnProperty(...), String(set) and ${set} now throw a TypeError; use Object.hasOwn(set, key) or hatSchluessel(set, key). Object.assign({}, set) loses a __proto__ key; spread, Object.entries / Object.fromEntries, structuredClone and JSON keep it.
  • Lines are inserted exactly. insertLine accepts only tolerance 0 (or none) and throws a RangeError otherwise; inserting the same line again applies no operation.
  • Transaction labels are stable English identifiers in kebab case ('draw-polygon', 'merge-faces', ...), see Events.

Editing#

  • Switchable snap-target kinds. New editor.rastArten: readonly Rastart[] (default all four, in rank order: corner, edge midpoint, quarter point, edge) is the global setting every tool falls back to when it leaves the choice open on its own ctx.rasten(...) call (see Snapping). An empty array switches snapping off kind by kind, the same effect as rastenAktiv = false has all at once.
  • Rotation pivot. TransformMode.setzeDrehpunkt(point | null) fixes the center the next rotation drag turns around, in place of the selection's bounding-box center. It is programmatic only. The next rotation grab consumes the pivot; the one after that falls back to the center again (see Modes, section transform).
  • Circle as a cutting shape. Two new modes, CutCircleMode (key H) and DifferenceCircleMode (key J), the circle variants of cut and difference (see Modes). Drag a circle instead of placing a ring. New transaction labels 'cut-circle' and 'difference-circle'.
  • Utilities page. The Utilities page collects the pure helper functions each package exports. New export: kreisPolygon (@vectorstream/core), the circle or ellipse n-gon DrawCircleMode draws with.

Map and rendering#

  • Image export. New Adapter.exportImage(): Promise<Blob>, the same call on every renderer: a PNG of the current view at screen resolution, background tiles included, with the same CSS tile darkening the screen shows and the map's attribution line in the bottom-right corner (see Exporting the map view as an image). Breaking for a custom implementation of Adapter: exportImage is a required method. Handles, snap markers and guide lines never appear in the image. A tainted background (no CORS permission on the tile server) rejects with the new ExportError (adapter.exportCorsBlocked); adapter.exportFailed covers every other encode failure. The application's Leaflet map sets crossOrigin: true on its tile layer. New exports of @vectorstream/adapter: zeichneFlaechenAufCanvas, zeichneKantenAufCanvas, ladePunktBilder, zeichnePunkteAufCanvas, zeichneBeschriftungenAufCanvas, zeichneAttributionAufCanvas, pngBlobVonCanvas, alsPngExport.
  • Customizing the look. New darstellung option on LeafletAdapterOptions, OpenLayersAdapterOptions and MapLibreAdapterOptions (see Customizing the look): a partial, per-field override of the editor's colors and line styles, merged with the built-in defaults once, at construction. An explicit override of flaechen.normal or kanten.normal wins over a per-layer color for the fields it names. A dash pattern (strich) is overridable on every state; strich: [] forces a solid line. An unknown state or field throws DarstellungFehler (code adapter.darstellungUnbekannterSchluessel) at construction. Override values reach cssText unchecked (familie, hintergrund), so never pass untrusted input there. New exports of @vectorstream/adapter: baueDarstellung, mitUeberschreibung, Darstellung, DarstellungUeberschreibung, TeilUeberschreibung, STANDARD_DARSTELLUNG, DarstellungFehler, BESCHRIFTUNG_FARBE, BESCHRIFTUNG_GROESSE, Weiten. The style helpers (griffDarstellung, punktDarstellung, hilfslinienStil, beschriftungsStil, schildRahmenAus and the canvas draw functions) take the resolved table set as a new, optional trailing parameter.
  • Large data sets (see Large data sets). The editor builds the scene only from what lies in the visible map area (plus half a view of margin, selected elements always included), and below zoom 15 it leaves node and midpoint handles out (selected ones excepted). Free-standing points are not affected. On a Web Mercator map below zoom 15 only selected nodes can be grabbed. New, all additive: optional Adapter.viewport?() and the Viewport type, implemented by all three adapters and settable on NullAdapter (viewport option, setViewport()); sichtfeldAusEcken (@vectorstream/adapter); SpatialIndex.facesInBox() and SpatialIndex.extent() (@vectorstream/core); SceneOptions.viewport and index, EbenenSzeneOptions.viewport and indexFuer, and the constant GRIFFE_AB_ZOOM (@vectorstream/editor). MapLibreAdapter.viewport() reports map.getBounds(), and OpenLayersAdapter.viewport() derives its zoom from the view's resolution, so custom resolution ladders work.

Language#

  • User-visible texts come from message tables. English is built in, German is opt-in through registerLocale (see Language). Rejections carry a namespaced code and params; the former MELDUNG_* text exports were removed.
  • French, Spanish and Dutch. Complete tables for @vectorstream/core, @vectorstream/editor and @vectorstream/adapter: coreFr/editorFr/adapterFr, coreEs/editorEs/adapterEs, coreNl/editorNl/adapterNl. Register them the same way as German (registerLocale(tag, messages, table)). They are machine-translated and not reviewed by a native speaker, so the wording may read oddly. Keys, placeholders and plural forms are checked the same way as for German.

See it on a map.