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.
Files changed (2) hide show
  1. package/README.md +140 -102
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -4,12 +4,12 @@
4
4
  [![license](https://img.shields.io/npm/l/map-boundary-editor)](LICENSE)
5
5
  [![downloads](https://img.shields.io/npm/dm/map-boundary-editor)](https://www.npmjs.com/package/map-boundary-editor)
6
6
 
7
- **map-boundary-editor** is a generic, embeddable, map-based boundary editor
8
- implemented as a Web Component.
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 allows users to visually draw and edit a geographic boundary
11
- and outputs a standard **GeoJSON** representation that can be reused
12
- across different map engines and backend systems.
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
- - Supports **multiple boundaries** (GeoJSON `FeatureCollection`)
40
- - Leaflet-based (no API key required)
41
- - Outputs standard GeoJSON (RFC 7946)
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
- Use module scripts only to ensure correct loading order.
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 id="editor" style="width: 800px; height: 500px;">
63
- </map-boundary-editor>
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
- // Public APIs are lifecycle-safe
71
- editor.setView(-6.2, 106.8, 11);
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`) are safe to call immediately after the element is created. No `setTimeout` or `customElements.whenDefined` is required.
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
- ### Setting Initial View
128
+ ### Loading an Existing Editable Boundary
84
129
 
85
130
  ```js
86
- editor.setView(lat, lng, zoom);
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
- If a boundary is later loaded using setGeoJSON, the map will automatically fit to the boundary.
153
+ Even when loading a single boundary, the data must be wrapped in a `FeatureCollection` for consistency.
90
154
 
91
155
  ---
92
156
 
93
- ### Loading an Existing Boundary
157
+ ### View Control
94
158
 
95
159
  ```js
96
- editor.setGeoJSON({
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
- `map-boundary-editor` supports an optional geolocation-based initial view to help users quickly focus on their current area.
165
+ ---
118
166
 
119
- This feature is **opt-in** and **disabled by default**.
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
- ### Enable Geolocation (Opt-in)
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
- ### Behavior & Priority Rules
179
+ ## Public API (v0.3)
138
180
 
139
- The initial map view follows this priority order:
181
+ ### Editable Polygon
140
182
 
141
- 1. `setGeoJSON()`
183
+ `setGeoJSON(geojson: FeatureCollection): void`
142
184
 
143
- If boundaries are loaded, the map will automatically fit to them.
185
+ Loads editable polygon boundaries from GeoJSON.
144
186
 
145
- 2. `use-geolocation` **attribute**
187
+ `getGeoJSON(): FeatureCollection`
146
188
 
147
- If enabled and permission is granted, the map centers on the user’s location.
189
+ Returns the current editable polygon boundaries.
148
190
 
149
- 3. **Default view**
191
+ `clear(): void`
150
192
 
151
- Falls back to a neutral world view (`[0, 0]`, zoom `2`).
193
+ Removes all editable polygon boundaries.
152
194
 
153
195
  ---
154
196
 
155
- ### Interaction with setView()
197
+ ### Reference Boundary
156
198
 
157
- If `setView()` is called by the host application, it will override the geolocation-based view.
199
+ `setBoundary(geojson: FeatureCollection): void`
158
200
 
159
- ```js
160
- editor.setView(-6.2, 106.8, 11);
161
- ```
201
+ Sets a fixed, non-editable reference boundary.
162
202
 
163
- This allows full programmatic control when needed.
164
-
165
- ---
203
+ `getBoundary(): FeatureCollection | null`
166
204
 
167
- ### Geolocation Toggle Behavior
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
- - Adding the attribute triggers a geolocation request
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
- Geolocation is treated as a UX helper, not persistent state.
209
+ Removes the reference boundary from the map.
182
210
 
183
211
  ---
184
212
 
185
- ### Privacy Notes
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
- ## Public API (v0.1)
217
+ Enables or disables editing controls.
195
218
 
196
- `getGeoJSON(): FeatureCollection`
219
+ `isReadonly(): boolean`
197
220
 
198
- Returns the current boundaries as GeoJSON.
221
+ Returns the current readonly state.
199
222
 
200
- `setGeoJSON(geojson: FeatureCollection): void`
223
+ ---
201
224
 
202
- Loads boundaries from GeoJSON and renders them on the map.
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
- `change`
233
+ ### change
217
234
 
218
- Fired whenever the boundary is created, edited, or deleted.
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "map-boundary-editor",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Generic embeddable map boundary editor as a Web Component",
5
5
  "license": "MIT",
6
6
  "type": "module",