@artsdatabanken/nbic-map-component 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,170 @@
1
+ # nbic-map-component
2
+
3
+ Shared, framework-agnostic map component built on OpenLayers, designed to be used by host applications (Angular, React, Lit, plain TS/JS) through a stable API.
4
+
5
+ The library separates what the host application wants to do (MapApi) from how it is rendered (MapEngine / OpenLayers), making it easier to maintain, test, and extend.
6
+
7
+ ---
8
+
9
+ ## Architecture
10
+ ```bash
11
+ The architecture is intentionally layered:
12
+
13
+ Host app (Angular/React/Lit/vanilla)
14
+ |
15
+ | calls methods + subscribes to events
16
+ v
17
+ MapApi (public facade)
18
+ |
19
+ | delegates 1:1 to an engine, keeps public types stable
20
+ v
21
+ MapEngine (interface)
22
+ |
23
+ | concrete implementation chosen at runtime (or build-time)
24
+ v
25
+ OlMapEngine (OpenLayers implementation)
26
+ |
27
+ +--> LayerRegistry (indexes layers/sources)
28
+ +--> Adapters (LayerDef -> OL layer, StyleDef -> OL style, SourceDef -> OL source)
29
+ +--> Controllers (Draw / Hover / Select / Geo / Controls / Zoom)
30
+ |
31
+ v
32
+ OpenLayers (ol/Map, ol/layer, ol/source, ol/interaction, ol/style)
33
+ ```
34
+
35
+ ### Design description
36
+ ```bash
37
+ The host application (Angular, React, Lit, etc.):
38
+ • Owns application state
39
+ • Decides when and what to draw (layers, features, interactions)
40
+ • Talks only to MapApi
41
+
42
+ It never accesses OpenLayers directly.
43
+
44
+ MapApi
45
+ • Public API exposed by nbic-map-component
46
+ • Stable contract for host applications
47
+ • Methods like:
48
+ • adding/removing layers
49
+ • starting/stopping drawing
50
+ • selecting features
51
+ • controlling interactions
52
+
53
+ MapEngine
54
+ • Internal orchestration layer
55
+ • Translates MapApi calls into engine actions
56
+ • No OpenLayers imports
57
+ • Makes it possible to swap rendering engines in the future
58
+
59
+ OlMapEngine
60
+ • Concrete implementation using OpenLayers
61
+ • Owns:
62
+ • ol/Map
63
+ • layers, sources, interactions
64
+ • OpenLayers-specific logic (cluster, hover, select, draw)
65
+
66
+ Why this design?
67
+ • Clear separation of concerns
68
+ • Host apps stay simple and future-proof
69
+ • OpenLayers complexity is fully encapsulated
70
+ • Easier testing and playground setup
71
+ ````
72
+ ---
73
+
74
+ ## Internal structure
75
+ ```bash
76
+ src/
77
+ ├─ api/ # Public types & events (no OpenLayers imports)
78
+ │ ├─ types.ts
79
+ │ ├─ events.ts
80
+ │
81
+ ├─ core/
82
+ │ ├─ MapApi.ts # Public facade
83
+ │ ├─ MapEngine.ts # Internal engine interface
84
+ │
85
+ │ └─ ol/
86
+ │ ├─ OlMapEngine.ts
87
+ │ ├─ adapters/ # Layer / source / style adapters
88
+ │ ├─ interactions/ # Draw, Hover, Select controllers
89
+ │ ├─ layers/ # LayerRegistry, base-layer logic
90
+ │ ├─ utils/ # Geometry, extent, projection helpers
91
+ │
92
+ ├─ presets/ # Predefined layers & sources (WMTS, base maps)
93
+ │
94
+ └─ index.ts # Public entry point
95
+ ```
96
+
97
+ ---
98
+
99
+ ## 🚀 Getting started
100
+
101
+ ### Install dependencies
102
+
103
+ ```bash
104
+ npm install
105
+ ```
106
+ ### Build the library
107
+ ```bash
108
+ npm run build
109
+ ```
110
+ ### Run tests
111
+ ```bash
112
+ npm run test
113
+ npm run test:watch
114
+ ```
115
+ ### Lint and format
116
+ ```bash
117
+ npm run lint
118
+ ```
119
+
120
+ ## 🧪 Playground (local testing)
121
+ This repo includes a small Vite-powered playground to test the component in the browser.
122
+
123
+ ### Start it
124
+ ```bash
125
+ npm run dev
126
+ ```
127
+
128
+ ## 📖 Usage
129
+ ### Install via npm (once published):
130
+ ```bash
131
+ npm install nbic-map-component
132
+ ```
133
+ ### Basic usage in Angular
134
+ ```bash
135
+ import { NbicMapComponent, MapEvents } from 'nbic-map-component';
136
+ import { AfterViewInit, Component, ElementRef, OnDestroy, ViewChild } from '@angular/core';
137
+
138
+ export class AppComponent implements AfterViewInit {
139
+ @ViewChild('mapEl', { static: true }) mapEl!: ElementRef<HTMLDivElement>;
140
+ private map!: InstanceType<typeof NbicMapComponent>;
141
+
142
+ ngAfterViewInit(): void {
143
+ this.map = new NbicMapComponent({
144
+ target: this.mapEl.nativeElement,
145
+ projection: 'EPSG:3857', // View must match WMTS projection
146
+ center: [1157722.7042500454, 9208962.278247332],
147
+ zoom: 4,
148
+ minZoom: 1,
149
+ maxZoom: 18,
150
+ controls: { scaleLine: true, fullscreen: true, geolocation: true, zoom: true, attribution: true },
151
+ });
152
+
153
+ this.map.on(MapEvents.Ready, () => {
154
+ this.mapReadyAction.next(true);
155
+ this.map.activateHoverInfo();
156
+ });
157
+ }
158
+ }
159
+ ```
160
+ ### html
161
+ ```bash
162
+ <div #mapEl class="map"></div>
163
+ ```
164
+ ### css
165
+ ```bash
166
+ .map {
167
+ height: 60vh;
168
+ width: 100%;
169
+ }
170
+ ```
@@ -0,0 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export {
8
+ __export
9
+ };
@@ -0,0 +1,37 @@
1
+ import "./chunk-MLKGABMK.js";
2
+
3
+ // src/core/ol/utils/geometry-analysis.ts
4
+ import Feature from "ol/Feature";
5
+ import OLGeoJSON from "ol/format/GeoJSON";
6
+ import kinks from "@turf/kinks";
7
+ var fmt = new OLGeoJSON();
8
+ function toGeoJSONFeature(map, input) {
9
+ const viewProj = String(map.getView().getProjection().getCode());
10
+ const feature = input instanceof Feature ? input : new Feature({ geometry: input });
11
+ return fmt.writeFeatureObject(feature, {
12
+ dataProjection: "EPSG:4326",
13
+ featureProjection: viewProj
14
+ });
15
+ }
16
+ function checkSelfIntersections(map, input) {
17
+ const gj = toGeoJSONFeature(map, input);
18
+ const type = gj.geometry?.type;
19
+ if (!type || !["LineString", "Polygon", "MultiLineString", "MultiPolygon"].includes(type)) {
20
+ return { valid: true };
21
+ }
22
+ const out = kinks(gj);
23
+ const count = out?.features?.length ?? 0;
24
+ return count > 0 ? { valid: false, intersections: out } : { valid: true };
25
+ }
26
+ function intersectionPointsToOlFeatures(map, points) {
27
+ const viewProj = String(map.getView().getProjection().getCode());
28
+ return fmt.readFeatures(points, {
29
+ dataProjection: "EPSG:4326",
30
+ featureProjection: viewProj
31
+ });
32
+ }
33
+ export {
34
+ checkSelfIntersections,
35
+ intersectionPointsToOlFeatures,
36
+ toGeoJSONFeature
37
+ };