map-boundary-editor 0.2.0 → 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 +140 -102
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
[](LICENSE)
|
|
5
5
|
[](https://www.npmjs.com/package/map-boundary-editor)
|
|
6
6
|
|
|
7
|
-
**map-boundary-editor** is a
|
|
8
|
-
|
|
7
|
+
**map-boundary-editor** is a lightweight, embeddable map-based boundary editor
|
|
8
|
+
designed for defining and validating geographic service boundaries.
|
|
9
9
|
|
|
10
|
-
It
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
It is optimized for use cases where a **user-defined area (polygon)** must be
|
|
11
|
+
evaluated against a **fixed administrative or reference boundary** — such as
|
|
12
|
+
service eligibility, coverage restriction, or zoning rules.
|
|
13
13
|
|
|
14
14
|
---
|
|
15
15
|
|
|
@@ -22,6 +22,9 @@ Many applications need users to define geographic areas:
|
|
|
22
22
|
- eligibility rules
|
|
23
23
|
- geofencing configuration
|
|
24
24
|
|
|
25
|
+
A common requirement in these use cases is a clear separation between
|
|
26
|
+
**editable user input** and **non-editable reference boundaries**.
|
|
27
|
+
|
|
25
28
|
Most teams end up rebuilding the same map drawing logic again and again,
|
|
26
29
|
tightly coupled to a specific map provider.
|
|
27
30
|
|
|
@@ -33,14 +36,31 @@ tightly coupled to a specific map provider.
|
|
|
33
36
|
|
|
34
37
|
---
|
|
35
38
|
|
|
39
|
+
## Key Concepts
|
|
40
|
+
|
|
41
|
+
### Editable Polygon
|
|
42
|
+
|
|
43
|
+
A polygon created or modified by the user to represent an area of interest
|
|
44
|
+
(e.g. delivery zone, service coverage).
|
|
45
|
+
|
|
46
|
+
### Reference Boundary
|
|
47
|
+
|
|
48
|
+
A fixed, non-editable boundary used as a reference for validation or restriction.
|
|
49
|
+
Typical examples include cities, provinces, or regulatory zones.
|
|
50
|
+
|
|
51
|
+
### Readonly Mode
|
|
52
|
+
|
|
53
|
+
A mode where editing controls are disabled, allowing the map to be used purely
|
|
54
|
+
for visualization, review, or approval workflows.
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
36
58
|
## Features
|
|
37
59
|
|
|
38
|
-
- Draw, edit, and delete polygon boundaries
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
- Framework-agnostic Web Component
|
|
43
|
-
- **Lifecycle-safe public API** (no timing hacks required)
|
|
60
|
+
- Draw, edit, and delete **editable polygon** boundaries
|
|
61
|
+
- Support for fixed, non-editable **reference boundaries**
|
|
62
|
+
- Read-only mode for review or visualization use cases
|
|
63
|
+
- Supports multiple editable boundaries (GeoJSON `FeatureCollection`)
|
|
44
64
|
|
|
45
65
|
---
|
|
46
66
|
|
|
@@ -56,166 +76,163 @@ npm install map-boundary-editor
|
|
|
56
76
|
|
|
57
77
|
## Basic Usage (Recommended)
|
|
58
78
|
|
|
59
|
-
|
|
79
|
+
The most common usage pattern is defining an editable area **within** a fixed reference boundary.
|
|
60
80
|
|
|
61
81
|
```html
|
|
62
|
-
<map-boundary-editor
|
|
63
|
-
|
|
82
|
+
<map-boundary-editor
|
|
83
|
+
id="editor"
|
|
84
|
+
style="width: 800px; height: 500px;"
|
|
85
|
+
></map-boundary-editor>
|
|
64
86
|
|
|
65
87
|
<script type="module">
|
|
66
88
|
import "map-boundary-editor";
|
|
67
89
|
|
|
68
90
|
const editor = document.getElementById("editor");
|
|
69
91
|
|
|
70
|
-
//
|
|
71
|
-
editor.
|
|
92
|
+
// Set a fixed reference boundary (e.g. administrative area)
|
|
93
|
+
editor.setBoundary({
|
|
94
|
+
type: "FeatureCollection",
|
|
95
|
+
features: [
|
|
96
|
+
{
|
|
97
|
+
type: "Feature",
|
|
98
|
+
geometry: {
|
|
99
|
+
type: "Polygon",
|
|
100
|
+
coordinates: [
|
|
101
|
+
[
|
|
102
|
+
[106.69, -6.1],
|
|
103
|
+
[107.03, -6.1],
|
|
104
|
+
[107.03, -6.38],
|
|
105
|
+
[106.69, -6.38],
|
|
106
|
+
[106.69, -6.1],
|
|
107
|
+
],
|
|
108
|
+
],
|
|
109
|
+
},
|
|
110
|
+
properties: {},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
});
|
|
72
114
|
|
|
115
|
+
// Listen for user-defined polygon changes
|
|
73
116
|
editor.addEventListener("change", (e) => {
|
|
74
|
-
console.log("GeoJSON:", e.detail.geojson);
|
|
117
|
+
console.log("Editable GeoJSON:", e.detail.geojson);
|
|
75
118
|
});
|
|
76
119
|
</script>
|
|
77
120
|
```
|
|
78
121
|
|
|
79
|
-
> All public APIs (`setView`, `setGeoJSON`, `clear
|
|
122
|
+
> All public APIs (`setView`, `setGeoJSON`, `clear`, etc.) are safe to call
|
|
123
|
+
> immediately after the element is created.
|
|
124
|
+
> No `setTimeout` or `customElements.whenDefined` is required.
|
|
80
125
|
|
|
81
126
|
---
|
|
82
127
|
|
|
83
|
-
###
|
|
128
|
+
### Loading an Existing Editable Boundary
|
|
84
129
|
|
|
85
130
|
```js
|
|
86
|
-
editor.
|
|
131
|
+
editor.setGeoJSON({
|
|
132
|
+
type: "FeatureCollection",
|
|
133
|
+
features: [
|
|
134
|
+
{
|
|
135
|
+
type: "Feature",
|
|
136
|
+
geometry: {
|
|
137
|
+
type: "Polygon",
|
|
138
|
+
coordinates: [
|
|
139
|
+
[
|
|
140
|
+
[106.8166, -6.2],
|
|
141
|
+
[106.82, -6.21],
|
|
142
|
+
[106.83, -6.205],
|
|
143
|
+
[106.8166, -6.2],
|
|
144
|
+
],
|
|
145
|
+
],
|
|
146
|
+
},
|
|
147
|
+
properties: {},
|
|
148
|
+
},
|
|
149
|
+
],
|
|
150
|
+
});
|
|
87
151
|
```
|
|
88
152
|
|
|
89
|
-
|
|
153
|
+
Even when loading a single boundary, the data must be wrapped in a `FeatureCollection` for consistency.
|
|
90
154
|
|
|
91
155
|
---
|
|
92
156
|
|
|
93
|
-
###
|
|
157
|
+
### View Control
|
|
94
158
|
|
|
95
159
|
```js
|
|
96
|
-
editor.
|
|
97
|
-
type: "Feature",
|
|
98
|
-
geometry: {
|
|
99
|
-
type: "Polygon",
|
|
100
|
-
coordinates: [
|
|
101
|
-
[
|
|
102
|
-
[106.8166, -6.2],
|
|
103
|
-
[106.82, -6.21],
|
|
104
|
-
[106.83, -6.205],
|
|
105
|
-
[106.8166, -6.2],
|
|
106
|
-
],
|
|
107
|
-
],
|
|
108
|
-
},
|
|
109
|
-
properties: {},
|
|
110
|
-
});
|
|
160
|
+
editor.setView(lat, lng, zoom);
|
|
111
161
|
```
|
|
112
162
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
### Optional: Use User Geolocation
|
|
163
|
+
If editable boundaries are later loaded using `setGeoJSON`, the map will automatically fit to the boundary.
|
|
116
164
|
|
|
117
|
-
|
|
165
|
+
---
|
|
118
166
|
|
|
119
|
-
|
|
167
|
+
### Optional: Geolocation Helper
|
|
120
168
|
|
|
121
|
-
|
|
169
|
+
An optional geolocation helper is available to center the map on the user's current location.
|
|
122
170
|
|
|
123
|
-
|
|
171
|
+
This feature only affects the initial view and does not modify boundaries or output GeoJSON.
|
|
124
172
|
|
|
125
173
|
```html
|
|
126
174
|
<map-boundary-editor use-geolocation></map-boundary-editor>
|
|
127
175
|
```
|
|
128
176
|
|
|
129
|
-
When enabled:
|
|
130
|
-
|
|
131
|
-
- The editor will attempt to center the map on the user’s current location
|
|
132
|
-
- The browser will request permission explicitly
|
|
133
|
-
- If permission is denied or unavailable, the map silently falls back to the default view
|
|
134
|
-
|
|
135
177
|
---
|
|
136
178
|
|
|
137
|
-
|
|
179
|
+
## Public API (v0.3)
|
|
138
180
|
|
|
139
|
-
|
|
181
|
+
### Editable Polygon
|
|
140
182
|
|
|
141
|
-
|
|
183
|
+
`setGeoJSON(geojson: FeatureCollection): void`
|
|
142
184
|
|
|
143
|
-
|
|
185
|
+
Loads editable polygon boundaries from GeoJSON.
|
|
144
186
|
|
|
145
|
-
|
|
187
|
+
`getGeoJSON(): FeatureCollection`
|
|
146
188
|
|
|
147
|
-
|
|
189
|
+
Returns the current editable polygon boundaries.
|
|
148
190
|
|
|
149
|
-
|
|
191
|
+
`clear(): void`
|
|
150
192
|
|
|
151
|
-
|
|
193
|
+
Removes all editable polygon boundaries.
|
|
152
194
|
|
|
153
195
|
---
|
|
154
196
|
|
|
155
|
-
###
|
|
197
|
+
### Reference Boundary
|
|
156
198
|
|
|
157
|
-
|
|
199
|
+
`setBoundary(geojson: FeatureCollection): void`
|
|
158
200
|
|
|
159
|
-
|
|
160
|
-
editor.setView(-6.2, 106.8, 11);
|
|
161
|
-
```
|
|
201
|
+
Sets a fixed, non-editable reference boundary.
|
|
162
202
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
---
|
|
203
|
+
`getBoundary(): FeatureCollection | null`
|
|
166
204
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
The `use-geolocation` attribute is reactive and can be toggled at runtime.
|
|
170
|
-
|
|
171
|
-
```js
|
|
172
|
-
editor.setAttribute("use-geolocation", "");
|
|
173
|
-
editor.removeAttribute("use-geolocation");
|
|
174
|
-
```
|
|
205
|
+
Returns the current reference boundary.
|
|
175
206
|
|
|
176
|
-
|
|
177
|
-
- Removing the attribute does not reset the map view automatically
|
|
178
|
-
- Only one geolocation request can be active at a time
|
|
179
|
-
- Browser permission handling is respected (no repeated prompts)
|
|
207
|
+
`clearBoundary(): void`
|
|
180
208
|
|
|
181
|
-
|
|
209
|
+
Removes the reference boundary from the map.
|
|
182
210
|
|
|
183
211
|
---
|
|
184
212
|
|
|
185
|
-
###
|
|
186
|
-
|
|
187
|
-
- Geolocation is never requested automatically
|
|
188
|
-
- Location data is not stored
|
|
189
|
-
- Location data is not transmitted
|
|
190
|
-
- The feature only affects the initial map view
|
|
213
|
+
### Mode Control
|
|
191
214
|
|
|
192
|
-
|
|
215
|
+
`setReadonly(value: boolean): void`
|
|
193
216
|
|
|
194
|
-
|
|
217
|
+
Enables or disables editing controls.
|
|
195
218
|
|
|
196
|
-
`
|
|
219
|
+
`isReadonly(): boolean`
|
|
197
220
|
|
|
198
|
-
Returns the current
|
|
221
|
+
Returns the current readonly state.
|
|
199
222
|
|
|
200
|
-
|
|
223
|
+
---
|
|
201
224
|
|
|
202
|
-
|
|
225
|
+
### View Control
|
|
203
226
|
|
|
204
227
|
`setView(lat: number, lng: number, zoom?: number): void`
|
|
205
228
|
|
|
206
229
|
Moves the map to the specified location.
|
|
207
230
|
|
|
208
|
-
`clear(): void`
|
|
209
|
-
|
|
210
|
-
Removes all boundaries.
|
|
211
|
-
|
|
212
|
-
---
|
|
213
|
-
|
|
214
231
|
## Events
|
|
215
232
|
|
|
216
|
-
|
|
233
|
+
### change
|
|
217
234
|
|
|
218
|
-
Fired whenever the
|
|
235
|
+
Fired whenever the editable polygon is created, edited, or deleted.
|
|
219
236
|
|
|
220
237
|
```js
|
|
221
238
|
editor.addEventListener("change", (e) => {
|
|
@@ -229,8 +246,7 @@ editor.addEventListener("change", (e) => {
|
|
|
229
246
|
|
|
230
247
|
The editor uses GeoJSON as its data contract.
|
|
231
248
|
|
|
232
|
-
GeoJSON is treated as the single source of truth and is intentionally decoupled
|
|
233
|
-
from any specific map engine.
|
|
249
|
+
GeoJSON is treated as the single source of truth and is intentionally decoupled from any specific map engine.
|
|
234
250
|
|
|
235
251
|
The output is compatible with:
|
|
236
252
|
|
|
@@ -240,10 +256,32 @@ The output is compatible with:
|
|
|
240
256
|
|
|
241
257
|
---
|
|
242
258
|
|
|
259
|
+
## Demo
|
|
260
|
+
|
|
261
|
+
A demo is included in the repository to showcase:
|
|
262
|
+
|
|
263
|
+
- Editable polygons vs administrative reference boundaries
|
|
264
|
+
- Visual hierarchy between reference and user-defined areas
|
|
265
|
+
- Readonly vs editable interaction modes
|
|
266
|
+
|
|
267
|
+
The demo also serves as a reference implementation for integrating the component
|
|
268
|
+
into real-world applications.
|
|
269
|
+
|
|
270
|
+
---
|
|
271
|
+
|
|
243
272
|
## Roadmap
|
|
244
273
|
|
|
245
|
-
- v0.3: read-only mode
|
|
274
|
+
- v0.3: reference boundary support, read-only mode, improved demo UX
|
|
246
275
|
- v0.4: additional map engine adapters (MapLibre, Google Maps)
|
|
247
276
|
- v1.0: stable API
|
|
248
277
|
|
|
249
278
|
---
|
|
279
|
+
|
|
280
|
+
## Non-Goals
|
|
281
|
+
|
|
282
|
+
This project is intentionally not:
|
|
283
|
+
|
|
284
|
+
- A full GIS editor
|
|
285
|
+
- A GeoJSON validation library
|
|
286
|
+
- A replacement for tools like geojson.io
|
|
287
|
+
- A general-purpose map rendering framework
|