esri-gl 1.0.2 โ 1.0.3
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 +111 -700
- package/dist/package.json +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,805 +1,216 @@
|
|
|
1
1
|
# esri-gl
|
|
2
2
|
|
|
3
|
-
A TypeScript library that bridges Esri ArcGIS REST services with MapLibre GL JS and Mapbox GL JS.
|
|
3
|
+
A TypeScript library that bridges Esri ArcGIS REST services with MapLibre GL JS and Mapbox GL JS.
|
|
4
4
|
|
|
5
5
|
[](https://badge.fury.io/js/esri-gl)
|
|
6
|
+
[](https://github.com/muimsd/esri-gl/actions/workflows/ci.yml)
|
|
6
7
|
[](http://www.typescriptlang.org/)
|
|
7
8
|
[](https://opensource.org/licenses/MIT)
|
|
8
9
|
|
|
9
|
-
|
|
10
|
+
**[Documentation](https://esri-gl.pages.dev/)** ยท **[Live Demos](https://esri-gl-demo.pages.dev/)** ยท **[npm](https://www.npmjs.com/package/esri-gl)**
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
- **๐ฎ [Live Demos](https://esri-gl-demo.netlify.app/)** - Interactive examples and code samples
|
|
12
|
+
## Features
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
### Services
|
|
15
|
+
- **DynamicMapService** โ Server-rendered raster tiles with dynamic styling, filtering, labeling, and identify
|
|
16
|
+
- **TiledMapService** โ Pre-cached tiles for fast basemaps
|
|
17
|
+
- **ImageService** โ Analytical raster data with rendering rules and temporal support
|
|
18
|
+
- **FeatureService** โ Vector data with smart vector tile detection, GeoJSON fallback, editing, and attachments
|
|
19
|
+
- **VectorTileService** โ Client-rendered vector tiles
|
|
20
|
+
- **VectorBasemapStyle** โ Esri's professional basemap styles
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
### Tasks
|
|
23
|
+
- **IdentifyFeatures / IdentifyImage** โ Query features and pixel values at map locations
|
|
24
|
+
- **Query** โ Spatial and attribute queries with automatic pagination
|
|
25
|
+
- **Find** โ Text-based feature search across layers
|
|
17
26
|
|
|
18
|
-
###
|
|
19
|
-
|
|
20
|
-
- **
|
|
21
|
-
- **
|
|
22
|
-
- **Image Services** - Analytical raster data with server-side processing
|
|
23
|
-
- **Vector Tile Services** - Client-rendered vector tiles for fast styling
|
|
24
|
-
- **Vector Basemap Styles** - Esri's vector basemap styles with custom styling
|
|
25
|
-
- **Feature Services** - Vector data with smart vector tile detection and GeoJSON fallback
|
|
26
|
-
|
|
27
|
-
### Advanced Features
|
|
28
|
-
|
|
29
|
-
- **Smart Vector Tile Detection** - Automatically detects vector tile endpoints with GeoJSON fallback
|
|
30
|
-
- **Dynamic Layer Management** - Add/remove layers dynamically with proper cleanup
|
|
31
|
-
- **Identify Tasks** - Query features and raster data at specific locations
|
|
32
|
-
- **Bounding Box Filtering** - Optimize performance with viewport-based data loading
|
|
33
|
-
- **Layer Definitions** - Filter data server-side using SQL-like expressions
|
|
34
|
-
- **Time-aware Services** - Support for temporal data visualization
|
|
35
|
-
- **Attribution Management** - Automatic service attribution handling
|
|
36
|
-
- **React Integration** - Hooks and components for React applications
|
|
37
|
-
- **React Map GL Support** - Direct integration with react-map-gl
|
|
38
|
-
- **TypeScript Support** - Full type safety with comprehensive interfaces
|
|
39
|
-
- **ArcGIS Online (AGOL) Support** - Proper JSON error handling, token auth, and API key support
|
|
40
|
-
- **Feature Editing** - Add, update, delete features and apply batch edits
|
|
41
|
-
- **Attachments** - Query, add, and delete feature attachments
|
|
42
|
-
- **Query Pagination** - Automatic pagination through large result sets
|
|
27
|
+
### Integrations
|
|
28
|
+
- **React Hooks** โ `useDynamicMapService`, `useFeatureService`, `useQuery`, etc.
|
|
29
|
+
- **react-map-gl** โ Declarative `<EsriDynamicLayer>`, `<EsriFeatureLayer>`, etc.
|
|
30
|
+
- **TypeScript** โ Full type safety with comprehensive interfaces
|
|
43
31
|
|
|
44
32
|
## Installation
|
|
45
33
|
|
|
46
|
-
### Stable Release
|
|
47
34
|
```bash
|
|
48
35
|
npm install esri-gl
|
|
49
36
|
```
|
|
50
37
|
|
|
51
38
|
### Entry Points
|
|
52
39
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
|
56
|
-
|
|
57
|
-
| `esri-gl` |
|
|
58
|
-
| `esri-gl/react` | `import { useDynamicMapService, useQuery, ... } from 'esri-gl/react'` | React hooks for service lifecycle management |
|
|
59
|
-
| `esri-gl/react-map-gl` | `import { EsriDynamicLayer, ... } from 'esri-gl/react-map-gl'` | Declarative react-map-gl components |
|
|
40
|
+
| Import | Use Case |
|
|
41
|
+
|--------|----------|
|
|
42
|
+
| `esri-gl` | Core services and tasks |
|
|
43
|
+
| `esri-gl/react` | React hooks |
|
|
44
|
+
| `esri-gl/react-map-gl` | react-map-gl components |
|
|
60
45
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### Basic Usage with MapLibre GL JS
|
|
46
|
+
### CDN (UMD)
|
|
64
47
|
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
container: 'map',
|
|
71
|
-
style: 'https://demotiles.maplibre.org/style.json',
|
|
72
|
-
center: [-95, 37],
|
|
73
|
-
zoom: 4
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
map.on('load', () => {
|
|
77
|
-
// Add a dynamic map service
|
|
78
|
-
const dynamicService = new DynamicMapService('census-source', map, {
|
|
79
|
-
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer'
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
map.addLayer({
|
|
83
|
-
id: 'census-layer',
|
|
84
|
-
type: 'raster',
|
|
85
|
-
source: 'census-source'
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// Add a feature service with smart vector tile detection
|
|
89
|
-
const featureService = new FeatureService('parcels-source', map, {
|
|
90
|
-
url: 'https://services.arcgis.com/.../FeatureServer/0',
|
|
91
|
-
useVectorTiles: true, // Automatically detects and falls back to GeoJSON if needed
|
|
92
|
-
useBoundingBox: true, // Optimize with viewport filtering
|
|
93
|
-
where: "STATUS = 'Active'", // Server-side filtering
|
|
94
|
-
outFields: '*'
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
map.addLayer({
|
|
98
|
-
id: 'parcels-layer',
|
|
99
|
-
type: 'fill',
|
|
100
|
-
source: 'parcels-source',
|
|
101
|
-
paint: {
|
|
102
|
-
'fill-color': '#007cbf',
|
|
103
|
-
'fill-opacity': 0.5
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
|
48
|
+
```html
|
|
49
|
+
<script src="https://unpkg.com/esri-gl@latest/dist/index.umd.js"></script>
|
|
50
|
+
<script>
|
|
51
|
+
const service = new esrigl.DynamicMapService('source', map, { url: '...' });
|
|
52
|
+
</script>
|
|
107
53
|
```
|
|
108
54
|
|
|
109
|
-
|
|
55
|
+
## Quick Start
|
|
110
56
|
|
|
111
57
|
```typescript
|
|
112
|
-
import
|
|
113
|
-
import { VectorBasemapStyle, ImageService } from 'esri-gl';
|
|
114
|
-
|
|
115
|
-
mapboxgl.accessToken = 'your-mapbox-token';
|
|
58
|
+
import { DynamicMapService } from 'esri-gl';
|
|
116
59
|
|
|
117
|
-
const map = new
|
|
60
|
+
const map = new maplibregl.Map({
|
|
118
61
|
container: 'map',
|
|
62
|
+
style: 'https://demotiles.maplibre.org/style.json',
|
|
119
63
|
center: [-95, 37],
|
|
120
64
|
zoom: 4
|
|
121
65
|
});
|
|
122
66
|
|
|
123
67
|
map.on('load', () => {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
// Add image service for analytical raster data
|
|
130
|
-
const imageService = new ImageService('elevation-source', map, {
|
|
131
|
-
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/ImageServer',
|
|
132
|
-
renderingRule: {
|
|
133
|
-
rasterFunction: 'Hillshade'
|
|
134
|
-
}
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
map.addLayer({
|
|
138
|
-
id: 'elevation-layer',
|
|
139
|
-
type: 'raster',
|
|
140
|
-
source: 'elevation-source'
|
|
68
|
+
const service = new DynamicMapService('usa-source', map, {
|
|
69
|
+
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
|
|
70
|
+
layers: [0, 1, 2],
|
|
71
|
+
transparent: true
|
|
141
72
|
});
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Service Classes
|
|
146
|
-
|
|
147
|
-
### DynamicMapService
|
|
148
|
-
Server-rendered raster tiles from ArcGIS Map Services.
|
|
149
73
|
|
|
150
|
-
|
|
151
|
-
const service = new DynamicMapService('source-id', map, {
|
|
152
|
-
url: 'https://example.com/arcgis/rest/services/MyService/MapServer',
|
|
153
|
-
layers: [0, 1, 2], // Specific layers to display
|
|
154
|
-
layerDefs: {
|
|
155
|
-
0: "POP2000 > 100000", // Filter layer 0
|
|
156
|
-
1: "STATE_NAME = 'California'" // Filter layer 1
|
|
157
|
-
},
|
|
158
|
-
transparent: true,
|
|
159
|
-
format: 'png32'
|
|
74
|
+
map.addLayer({ id: 'usa-layer', type: 'raster', source: 'usa-source' });
|
|
160
75
|
});
|
|
161
76
|
```
|
|
162
77
|
|
|
163
|
-
|
|
164
|
-
Pre-cached tile services for optimal performance.
|
|
165
|
-
|
|
166
|
-
```typescript
|
|
167
|
-
const service = new TiledMapService('source-id', map, {
|
|
168
|
-
url: 'https://example.com/arcgis/rest/services/MyTiledService/MapServer'
|
|
169
|
-
});
|
|
170
|
-
```
|
|
78
|
+
## Service Examples
|
|
171
79
|
|
|
172
80
|
### FeatureService
|
|
173
|
-
Efficient tile-based feature loading from ArcGIS FeatureServers with PBF (Protocol Buffer) support for minimal payload size.
|
|
174
|
-
|
|
175
|
-
```typescript
|
|
176
|
-
const service = new FeatureService('source-id', map, {
|
|
177
|
-
url: 'https://example.com/arcgis/rest/services/MyService/FeatureServer/0',
|
|
178
|
-
where: '1=1',
|
|
179
|
-
outFields: '*',
|
|
180
|
-
// PBF options (requires ArcGIS Server 10.7+)
|
|
181
|
-
minZoom: 2, // Minimum zoom level for data requests
|
|
182
|
-
simplifyFactor: 0.3, // Geometry simplification (0-1)
|
|
183
|
-
precision: 8, // Coordinate decimal precision
|
|
184
|
-
useServiceBounds: true, // Limit requests to service extent
|
|
185
|
-
setAttributionFromService: true // Auto-set attribution
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Update filters dynamically
|
|
189
|
-
service.setWhere("STATUS = 'Active'");
|
|
190
|
-
service.setDate(new Date(), new Date('2024-01-01'));
|
|
191
|
-
service.setToken('your-token');
|
|
192
|
-
|
|
193
|
-
// Query features by location
|
|
194
|
-
const features = await service.getFeaturesByLonLat({ lng: -118, lat: 34 }, 100);
|
|
195
|
-
|
|
196
|
-
// Query by object IDs
|
|
197
|
-
const specific = await service.getFeaturesByObjectIds([1, 2, 3], true);
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
#### Feature Editing (AGOL)
|
|
201
81
|
|
|
202
82
|
```typescript
|
|
203
|
-
|
|
204
|
-
const service = new FeatureService('editable-source', map, {
|
|
83
|
+
const service = new FeatureService('features-source', map, {
|
|
205
84
|
url: 'https://services.arcgis.com/.../FeatureServer/0',
|
|
206
|
-
|
|
85
|
+
where: "STATUS = 'Active'",
|
|
86
|
+
outFields: 'NAME,STATUS',
|
|
87
|
+
token: 'your-token' // optional
|
|
207
88
|
});
|
|
208
89
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
// Update features
|
|
215
|
-
const updateResults = await service.updateFeatures([
|
|
216
|
-
{ type: 'Feature', geometry: { type: 'Point', coordinates: [-95, 37] }, properties: { OBJECTID: 1, name: 'Updated' } }
|
|
217
|
-
]);
|
|
218
|
-
|
|
219
|
-
// Delete features
|
|
220
|
-
const deleteResults = await service.deleteFeatures({ objectIds: [1, 2, 3] });
|
|
221
|
-
|
|
222
|
-
// Batch edits
|
|
223
|
-
const batchResults = await service.applyEdits({
|
|
224
|
-
adds: [newFeature],
|
|
225
|
-
updates: [updatedFeature],
|
|
226
|
-
deletes: [4, 5]
|
|
90
|
+
map.addLayer({
|
|
91
|
+
id: 'features-layer',
|
|
92
|
+
type: 'circle',
|
|
93
|
+
source: 'features-source',
|
|
94
|
+
paint: { 'circle-radius': 5, 'circle-color': '#007cbf' }
|
|
227
95
|
});
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### VectorTileService
|
|
231
|
-
Client-rendered vector tiles for fast styling and interaction.
|
|
232
96
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
});
|
|
97
|
+
// Edit features
|
|
98
|
+
await service.addFeatures([feature]);
|
|
99
|
+
await service.applyEdits({ adds: [], updates: [], deletes: [1, 2] });
|
|
237
100
|
```
|
|
238
101
|
|
|
239
102
|
### ImageService
|
|
240
|
-
Analytical raster data with server-side processing capabilities.
|
|
241
103
|
|
|
242
104
|
```typescript
|
|
243
|
-
const service = new ImageService('source
|
|
244
|
-
url: 'https://
|
|
245
|
-
renderingRule: {
|
|
246
|
-
rasterFunction: 'Stretch',
|
|
247
|
-
rasterFunctionArguments: {
|
|
248
|
-
StretchType: 6,
|
|
249
|
-
NumberOfStandardDeviations: 2
|
|
250
|
-
}
|
|
251
|
-
},
|
|
252
|
-
mosaicRule: {
|
|
253
|
-
mosaicMethod: 'esriMosaicLockRaster',
|
|
254
|
-
lockRasterIds: [1, 2, 3]
|
|
255
|
-
}
|
|
105
|
+
const service = new ImageService('landsat-source', map, {
|
|
106
|
+
url: 'https://landsat2.arcgis.com/arcgis/rest/services/Landsat/MS/ImageServer',
|
|
107
|
+
renderingRule: { rasterFunction: 'Natural Color' }
|
|
256
108
|
});
|
|
257
109
|
```
|
|
258
110
|
|
|
259
111
|
### VectorBasemapStyle
|
|
260
|
-
Esri's vector basemap styles with customization options.
|
|
261
|
-
|
|
262
|
-
```typescript
|
|
263
|
-
const service = new VectorBasemapStyle('source-id', map, {
|
|
264
|
-
style: 'arcgis/streets', // or 'arcgis/navigation', 'arcgis/topographic', etc.
|
|
265
|
-
language: 'en',
|
|
266
|
-
worldview: 'USA'
|
|
267
|
-
});
|
|
268
|
-
```
|
|
269
112
|
|
|
270
113
|
```typescript
|
|
271
|
-
|
|
272
|
-
const customBasemap = new VectorBasemapStyle('source-id', map, {
|
|
273
|
-
style: 'arcgis/streets',
|
|
274
|
-
itemId: 'your-portal-item-id',
|
|
275
|
-
token: 'your-token'
|
|
276
|
-
});
|
|
114
|
+
VectorBasemapStyle.applyStyle(map, 'arcgis/streets', { apiKey: 'YOUR_KEY' });
|
|
277
115
|
```
|
|
278
116
|
|
|
279
|
-
##
|
|
280
|
-
|
|
281
|
-
Modeled after Esri Leaflet's chainable task pattern for querying and identifying features.
|
|
282
|
-
|
|
283
|
-
### IdentifyFeatures
|
|
284
|
-
Query vector features at specific locations.
|
|
117
|
+
## Tasks
|
|
285
118
|
|
|
286
119
|
```typescript
|
|
287
|
-
import { IdentifyFeatures } from 'esri-gl';
|
|
120
|
+
import { IdentifyFeatures, query } from 'esri-gl';
|
|
288
121
|
|
|
289
|
-
// Identify features at a point
|
|
290
|
-
const results = await new IdentifyFeatures('https
|
|
122
|
+
// Identify features at a point
|
|
123
|
+
const results = await new IdentifyFeatures('https://.../MapServer')
|
|
291
124
|
.at({ lng: -95, lat: 37 })
|
|
292
125
|
.on(map)
|
|
293
126
|
.layers('all')
|
|
294
127
|
.tolerance(5)
|
|
295
|
-
.returnGeometry(true)
|
|
296
128
|
.run();
|
|
297
129
|
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
Query raster values from image services.
|
|
303
|
-
|
|
304
|
-
```typescript
|
|
305
|
-
import { IdentifyImage } from 'esri-gl';
|
|
306
|
-
|
|
307
|
-
const results = await new IdentifyImage('https://example.com/arcgis/rest/services/Elevation/ImageServer')
|
|
308
|
-
.at({ lng: -120, lat: 40 })
|
|
309
|
-
.run();
|
|
310
|
-
|
|
311
|
-
console.log('Pixel value:', results.results[0]?.value);
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### Query
|
|
315
|
-
Advanced feature querying with spatial and attribute filters.
|
|
316
|
-
|
|
317
|
-
```typescript
|
|
318
|
-
import { query } from 'esri-gl';
|
|
319
|
-
|
|
320
|
-
const results = await query({
|
|
321
|
-
url: 'https://example.com/arcgis/rest/services/MyService/FeatureServer/0'
|
|
322
|
-
})
|
|
323
|
-
.where("STATE_NAME = 'California'")
|
|
324
|
-
.intersects({
|
|
325
|
-
type: 'Point',
|
|
326
|
-
coordinates: [-118, 34]
|
|
327
|
-
})
|
|
328
|
-
.run();
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
```typescript
|
|
332
|
-
// Automatic pagination through all results
|
|
333
|
-
import { query } from 'esri-gl';
|
|
334
|
-
|
|
335
|
-
const allResults = await query({
|
|
336
|
-
url: 'https://example.com/arcgis/rest/services/MyService/FeatureServer/0'
|
|
337
|
-
})
|
|
338
|
-
.where("STATE_NAME = 'California'")
|
|
339
|
-
.runAll(); // Automatically paginates through all pages
|
|
130
|
+
// Query with pagination
|
|
131
|
+
const all = await query({ url: 'https://.../FeatureServer/0' })
|
|
132
|
+
.where("STATE_NAME = 'California'")
|
|
133
|
+
.runAll();
|
|
340
134
|
```
|
|
341
135
|
|
|
342
136
|
## React Integration
|
|
343
137
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
### Installation for React Projects
|
|
347
|
-
|
|
348
|
-
```bash
|
|
349
|
-
# Core library
|
|
350
|
-
npm install esri-gl
|
|
351
|
-
|
|
352
|
-
# For React hooks and components
|
|
353
|
-
npm install react react-dom @types/react @types/react-dom
|
|
354
|
-
|
|
355
|
-
# For react-map-gl integration (recommended)
|
|
356
|
-
npm install react-map-gl mapbox-gl
|
|
357
|
-
# OR for MapLibre
|
|
358
|
-
npm install react-map-gl maplibre-gl
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
### React Hooks Pattern
|
|
362
|
-
|
|
363
|
-
Perfect for custom React components with full control over map lifecycle:
|
|
138
|
+
### Hooks
|
|
364
139
|
|
|
365
140
|
```typescript
|
|
366
|
-
import
|
|
367
|
-
import { Map } from 'maplibre-gl';
|
|
368
|
-
import { useDynamicMapService, useIdentifyFeatures, useFeatureService } from 'esri-gl/react';
|
|
369
|
-
|
|
370
|
-
function CustomMapComponent() {
|
|
371
|
-
const mapRef = useRef<HTMLDivElement>(null);
|
|
372
|
-
const [map, setMap] = useState<Map | null>(null);
|
|
373
|
-
|
|
374
|
-
// Initialize MapLibre map
|
|
375
|
-
useEffect(() => {
|
|
376
|
-
if (!mapRef.current) return;
|
|
377
|
-
const mapInstance = new Map({
|
|
378
|
-
container: mapRef.current,
|
|
379
|
-
style: 'https://demotiles.maplibre.org/style.json',
|
|
380
|
-
center: [-95, 37],
|
|
381
|
-
zoom: 4
|
|
382
|
-
});
|
|
383
|
-
setMap(mapInstance);
|
|
384
|
-
return () => mapInstance.remove();
|
|
385
|
-
}, []);
|
|
386
|
-
|
|
387
|
-
// Use esri-gl React hooks
|
|
388
|
-
const { service: dynamicService, loading, error } = useDynamicMapService({
|
|
389
|
-
sourceId: 'usa-service',
|
|
390
|
-
map,
|
|
391
|
-
options: {
|
|
392
|
-
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
|
|
393
|
-
layers: [0, 1, 2],
|
|
394
|
-
transparent: true
|
|
395
|
-
}
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
const { service: featureService } = useFeatureService({
|
|
399
|
-
sourceId: 'states-service',
|
|
400
|
-
map,
|
|
401
|
-
options: {
|
|
402
|
-
url: 'https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Census_States/FeatureServer/0',
|
|
403
|
-
useVectorTiles: true,
|
|
404
|
-
useBoundingBox: true
|
|
405
|
-
}
|
|
406
|
-
});
|
|
141
|
+
import { useDynamicMapService, useIdentifyFeatures } from 'esri-gl/react';
|
|
407
142
|
|
|
408
|
-
|
|
143
|
+
const { service, loading, error } = useDynamicMapService({
|
|
144
|
+
sourceId: 'usa-service',
|
|
145
|
+
map,
|
|
146
|
+
options: {
|
|
409
147
|
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
|
|
410
|
-
|
|
411
|
-
}
|
|
412
|
-
|
|
413
|
-
// Handle map clicks for identify
|
|
414
|
-
useEffect(() => {
|
|
415
|
-
if (!map) return;
|
|
416
|
-
const handleClick = async (e: any) => {
|
|
417
|
-
const results = await identify({ lng: e.lngLat.lng, lat: e.lngLat.lat }, map);
|
|
418
|
-
console.log('Identify results:', results);
|
|
419
|
-
};
|
|
420
|
-
map.on('click', handleClick);
|
|
421
|
-
return () => map.off('click', handleClick);
|
|
422
|
-
}, [map, identify]);
|
|
423
|
-
|
|
424
|
-
return (
|
|
425
|
-
<div>
|
|
426
|
-
<div ref={mapRef} style={{ width: '100%', height: '500px' }} />
|
|
427
|
-
{loading && <div>Loading Esri services...</div>}
|
|
428
|
-
{error && <div>Error: {error.message}</div>}
|
|
429
|
-
</div>
|
|
430
|
-
);
|
|
431
|
-
}
|
|
432
|
-
```
|
|
433
|
-
|
|
434
|
-
### React Map GL Components (Recommended)
|
|
435
|
-
|
|
436
|
-
For the smoothest React experience with declarative layer management:
|
|
437
|
-
|
|
438
|
-
```typescript
|
|
439
|
-
import React, { useState } from 'react';
|
|
440
|
-
import { Map } from 'react-map-gl/mapbox';
|
|
441
|
-
import {
|
|
442
|
-
EsriDynamicLayer,
|
|
443
|
-
EsriFeatureLayer,
|
|
444
|
-
EsriVectorTileLayer,
|
|
445
|
-
EsriImageLayer
|
|
446
|
-
} from 'esri-gl/react-map-gl';
|
|
447
|
-
|
|
448
|
-
function MapWithEsriLayers() {
|
|
449
|
-
const [viewState, setViewState] = useState({
|
|
450
|
-
longitude: -95,
|
|
451
|
-
latitude: 37,
|
|
452
|
-
zoom: 4
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
const [selectedStates, setSelectedStates] = useState<string[]>([]);
|
|
456
|
-
|
|
457
|
-
return (
|
|
458
|
-
<Map
|
|
459
|
-
{...viewState}
|
|
460
|
-
onMove={evt => setViewState(evt.viewState)}
|
|
461
|
-
mapStyle="mapbox://styles/mapbox/streets-v11"
|
|
462
|
-
style={{ width: '100%', height: '600px' }}
|
|
463
|
-
>
|
|
464
|
-
{/* Dynamic Map Service Layer */}
|
|
465
|
-
<EsriDynamicLayer
|
|
466
|
-
id="usa-demographics"
|
|
467
|
-
url="https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer"
|
|
468
|
-
layers={[0, 1, 2]}
|
|
469
|
-
layerDefs={{
|
|
470
|
-
0: "POP2000 > 100000",
|
|
471
|
-
1: "STATE_NAME IN ('California', 'Texas', 'New York')"
|
|
472
|
-
}}
|
|
473
|
-
opacity={0.8}
|
|
474
|
-
beforeId="waterway-label"
|
|
475
|
-
/>
|
|
476
|
-
|
|
477
|
-
{/* Feature Service with Vector Tiles */}
|
|
478
|
-
<EsriFeatureLayer
|
|
479
|
-
id="us-states"
|
|
480
|
-
url="https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Census_States/FeatureServer/0"
|
|
481
|
-
useVectorTiles={true}
|
|
482
|
-
useBoundingBox={true}
|
|
483
|
-
where={selectedStates.length > 0 ? `STATE_NAME IN ('${selectedStates.join("','")}')` : undefined}
|
|
484
|
-
paint={{
|
|
485
|
-
'fill-color': [
|
|
486
|
-
'case',
|
|
487
|
-
['in', ['get', 'STATE_NAME'], ['literal', selectedStates]],
|
|
488
|
-
'#ff6b6b',
|
|
489
|
-
'#627BC1'
|
|
490
|
-
],
|
|
491
|
-
'fill-opacity': 0.6,
|
|
492
|
-
'fill-outline-color': '#ffffff'
|
|
493
|
-
}}
|
|
494
|
-
onClick={(feature) => {
|
|
495
|
-
const stateName = feature.properties?.STATE_NAME;
|
|
496
|
-
if (stateName) {
|
|
497
|
-
setSelectedStates(prev =>
|
|
498
|
-
prev.includes(stateName)
|
|
499
|
-
? prev.filter(s => s !== stateName)
|
|
500
|
-
: [...prev, stateName]
|
|
501
|
-
);
|
|
502
|
-
}
|
|
503
|
-
}}
|
|
504
|
-
/>
|
|
505
|
-
|
|
506
|
-
{/* Vector Tile Service */}
|
|
507
|
-
<EsriVectorTileLayer
|
|
508
|
-
id="world-imagery-labels"
|
|
509
|
-
url="https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/VectorTileServer"
|
|
510
|
-
beforeId="usa-demographics"
|
|
511
|
-
/>
|
|
512
|
-
|
|
513
|
-
{/* Image Service for Analytical Data */}
|
|
514
|
-
<EsriImageLayer
|
|
515
|
-
id="elevation-hillshade"
|
|
516
|
-
url="https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/ImageServer"
|
|
517
|
-
renderingRule={{
|
|
518
|
-
rasterFunction: "Hillshade",
|
|
519
|
-
rasterFunctionArguments: {
|
|
520
|
-
Azimuth: 315,
|
|
521
|
-
Altitude: 45
|
|
522
|
-
}
|
|
523
|
-
}}
|
|
524
|
-
opacity={0.5}
|
|
525
|
-
/>
|
|
526
|
-
</Map>
|
|
527
|
-
);
|
|
528
|
-
}
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
### Why Choose React Integration?
|
|
532
|
-
|
|
533
|
-
#### React Hooks Benefits
|
|
534
|
-
- **๐๏ธ Full Control** - Direct access to map instance and service lifecycle
|
|
535
|
-
- **๐ State Management** - Seamless integration with React state and effects
|
|
536
|
-
- **๐ฏ Custom Logic** - Perfect for complex interactions and custom components
|
|
537
|
-
- **๐ฆ Lightweight** - Use only what you need
|
|
538
|
-
|
|
539
|
-
#### React Map GL Benefits
|
|
540
|
-
- **๐ Declarative** - Define layers as JSX components
|
|
541
|
-
- **๐ Automatic Updates** - Props changes automatically update layers
|
|
542
|
-
- **๐จ Built-in Styling** - Direct paint and layout prop support
|
|
543
|
-
- **๐ Event Handling** - onClick, onHover events built-in
|
|
544
|
-
- **๐๏ธ Component Ecosystem** - Works with all react-map-gl features
|
|
545
|
-
|
|
546
|
-
### TypeScript Support
|
|
547
|
-
|
|
548
|
-
Full TypeScript support with comprehensive type definitions:
|
|
549
|
-
|
|
550
|
-
```typescript
|
|
551
|
-
import type {
|
|
552
|
-
DynamicMapServiceOptions,
|
|
553
|
-
FeatureServiceOptions,
|
|
554
|
-
IdentifyResult,
|
|
555
|
-
EsriLayerProps
|
|
556
|
-
} from 'esri-gl';
|
|
557
|
-
import type { MapRef } from 'react-map-gl/mapbox';
|
|
558
|
-
|
|
559
|
-
// Fully typed component props
|
|
560
|
-
interface MapComponentProps {
|
|
561
|
-
serviceUrl: string;
|
|
562
|
-
initialLayers?: number[];
|
|
563
|
-
onFeatureClick?: (feature: IdentifyResult) => void;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
const TypedMapComponent: React.FC<MapComponentProps> = ({
|
|
567
|
-
serviceUrl,
|
|
568
|
-
initialLayers = [0],
|
|
569
|
-
onFeatureClick
|
|
570
|
-
}) => {
|
|
571
|
-
// Component implementation with full type safety
|
|
572
|
-
};
|
|
573
|
-
```
|
|
574
|
-
|
|
575
|
-
See [REACT.md](REACT.md) for complete React integration documentation and advanced patterns.
|
|
576
|
-
|
|
577
|
-
## Advanced Features
|
|
578
|
-
|
|
579
|
-
### Dynamic Layer Management
|
|
580
|
-
|
|
581
|
-
```typescript
|
|
582
|
-
// Add layers dynamically
|
|
583
|
-
const service = new DynamicMapService('census-source', map, {
|
|
584
|
-
url: 'https://example.com/MapServer'
|
|
585
|
-
});
|
|
586
|
-
|
|
587
|
-
// Update visible layers
|
|
588
|
-
service.setLayers([0, 2, 5]);
|
|
589
|
-
|
|
590
|
-
// Update layer definitions
|
|
591
|
-
service.setLayerDefs({
|
|
592
|
-
0: "POP2000 > 50000",
|
|
593
|
-
2: "STATE_NAME IN ('California', 'Nevada')"
|
|
594
|
-
});
|
|
595
|
-
|
|
596
|
-
// Clean up
|
|
597
|
-
service.remove();
|
|
598
|
-
```
|
|
599
|
-
|
|
600
|
-
### Smart Vector Tile Detection
|
|
601
|
-
|
|
602
|
-
The `FeatureService` automatically detects vector tile availability:
|
|
603
|
-
|
|
604
|
-
```typescript
|
|
605
|
-
const service = new FeatureService('smart-source', map, {
|
|
606
|
-
url: 'https://example.com/FeatureServer/0',
|
|
607
|
-
useVectorTiles: true // Will automatically:
|
|
608
|
-
// 1. Check for VectorTileServer endpoint
|
|
609
|
-
// 2. Test various URL patterns
|
|
610
|
-
// 3. Fall back to GeoJSON if vector tiles unavailable
|
|
611
|
-
// 4. Log the decision process to console
|
|
612
|
-
});
|
|
613
|
-
```
|
|
614
|
-
|
|
615
|
-
### Performance Optimization
|
|
616
|
-
|
|
617
|
-
```typescript
|
|
618
|
-
const service = new FeatureService('optimized-source', map, {
|
|
619
|
-
url: 'https://example.com/FeatureServer/0',
|
|
620
|
-
useBoundingBox: true, // Only load features in current viewport
|
|
621
|
-
maxRecordCount: 1000, // Limit records per request
|
|
622
|
-
where: 'STATUS = "Active"', // Server-side filtering
|
|
623
|
-
outFields: ['OBJECTID', 'NAME', 'STATUS'] // Limit fields
|
|
148
|
+
layers: [0, 1, 2]
|
|
149
|
+
}
|
|
624
150
|
});
|
|
625
151
|
```
|
|
626
152
|
|
|
627
|
-
###
|
|
628
|
-
|
|
629
|
-
```typescript
|
|
630
|
-
// Token-based authentication (URL parameter)
|
|
631
|
-
const service = new DynamicMapService('secure-source', map, {
|
|
632
|
-
url: 'https://example.com/arcgis/rest/services/SecureService/MapServer',
|
|
633
|
-
token: 'your-auth-token'
|
|
634
|
-
});
|
|
153
|
+
### react-map-gl Components
|
|
635
154
|
|
|
636
|
-
|
|
637
|
-
|
|
155
|
+
```tsx
|
|
156
|
+
import { EsriDynamicLayer, EsriFeatureLayer } from 'esri-gl/react-map-gl';
|
|
638
157
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
}
|
|
158
|
+
<Map mapStyle="mapbox://styles/mapbox/streets-v11">
|
|
159
|
+
<EsriDynamicLayer
|
|
160
|
+
id="census"
|
|
161
|
+
url="https://.../Census/MapServer"
|
|
162
|
+
layers={[0, 1]}
|
|
163
|
+
opacity={0.8}
|
|
164
|
+
/>
|
|
165
|
+
<EsriFeatureLayer
|
|
166
|
+
id="states"
|
|
167
|
+
url="https://.../FeatureServer/0"
|
|
168
|
+
paint={{ 'fill-color': '#627BC1', 'fill-opacity': 0.6 }}
|
|
169
|
+
/>
|
|
170
|
+
</Map>
|
|
644
171
|
```
|
|
645
172
|
|
|
646
173
|
## Examples
|
|
647
174
|
|
|
648
|
-
Working examples
|
|
649
|
-
|
|
650
|
-
| Example | Entry Point | Description |
|
|
651
|
-
|---------|-------------|-------------|
|
|
652
|
-
| [maplibre-esm](examples/maplibre-esm/) | `esri-gl` | All services and tasks with vanilla MapLibre GL JS |
|
|
653
|
-
| [maplibre-react-hooks](examples/maplibre-react-hooks/) | `esri-gl/react` | All React hooks with MapLibre GL JS |
|
|
654
|
-
| [maplibre-react-map-gl](examples/maplibre-react-map-gl/) | `esri-gl/react-map-gl` | All react-map-gl components and tasks |
|
|
175
|
+
Working examples in [`examples/`](examples/):
|
|
655
176
|
|
|
656
|
-
|
|
177
|
+
| Example | Description |
|
|
178
|
+
|---------|-------------|
|
|
179
|
+
| [maplibre-esm](examples/maplibre-esm/) | All services and tasks with vanilla MapLibre |
|
|
180
|
+
| [maplibre-react-hooks](examples/maplibre-react-hooks/) | React hooks with MapLibre |
|
|
181
|
+
| [maplibre-react-map-gl](examples/maplibre-react-map-gl/) | react-map-gl components |
|
|
657
182
|
|
|
658
183
|
```bash
|
|
659
|
-
cd examples/maplibre-esm
|
|
660
|
-
npm install
|
|
661
|
-
npm run dev
|
|
184
|
+
cd examples/maplibre-esm && npm install && npm run dev
|
|
662
185
|
```
|
|
663
186
|
|
|
664
187
|
## Development
|
|
665
188
|
|
|
666
|
-
### Build System
|
|
667
|
-
- **Library Build**: Rollup with TypeScript, Babel, and Terser (UMD + ESM outputs)
|
|
668
|
-
- **Type Declarations**: Generated with rollup-plugin-dts in `dist/` directory
|
|
669
|
-
- **Demo Development**: Vite dev server with React and TypeScript
|
|
670
|
-
- **Documentation**: Docusaurus build system
|
|
671
|
-
- **Test Coverage**: 727 tests across 31 test suites
|
|
672
|
-
|
|
673
|
-
### Development Commands
|
|
674
|
-
|
|
675
189
|
```bash
|
|
676
|
-
# Start demo
|
|
677
|
-
npm run
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
npm run
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
npm run build:watch
|
|
684
|
-
|
|
685
|
-
# Type checking
|
|
686
|
-
npm run type-check
|
|
687
|
-
|
|
688
|
-
# Linting and formatting
|
|
689
|
-
npm run lint
|
|
690
|
-
npm run format
|
|
691
|
-
|
|
692
|
-
# Run tests
|
|
693
|
-
npm run test
|
|
694
|
-
npm run test:watch
|
|
695
|
-
npm run test:coverage
|
|
696
|
-
|
|
697
|
-
# Build documentation
|
|
698
|
-
npm run build-docs
|
|
699
|
-
npm run dev:docs
|
|
700
|
-
```
|
|
701
|
-
|
|
702
|
-
### Project Structure
|
|
703
|
-
|
|
704
|
-
```
|
|
705
|
-
src/
|
|
706
|
-
โโโ Services/ # Core service classes
|
|
707
|
-
โ โโโ DynamicMapService.ts
|
|
708
|
-
โ โโโ FeatureService.ts
|
|
709
|
-
โ โโโ ImageService.ts
|
|
710
|
-
โ โโโ TiledMapService.ts
|
|
711
|
-
โ โโโ VectorTileService.ts
|
|
712
|
-
โ โโโ VectorBasemapStyle.ts
|
|
713
|
-
โโโ Tasks/ # Task-based operations
|
|
714
|
-
โ โโโ Find.ts
|
|
715
|
-
โ โโโ IdentifyFeatures.ts
|
|
716
|
-
โ โโโ IdentifyImage.ts
|
|
717
|
-
โ โโโ Query.ts
|
|
718
|
-
โโโ demo/ # Demo React components
|
|
719
|
-
โโโ tests/ # Comprehensive test suite (92.94% coverage)
|
|
720
|
-
โโโ types.ts # TypeScript interfaces
|
|
721
|
-
|
|
722
|
-
dist/
|
|
723
|
-
โโโ index.d.ts # Main TypeScript declarations
|
|
724
|
-
โโโ react.d.ts # React hooks declarations
|
|
725
|
-
โโโ react-map-gl.d.ts # React Map GL declarations
|
|
726
|
-
โโโ index.js # ESM build
|
|
727
|
-
โโโ index.umd.js # UMD build
|
|
728
|
-
โโโ react.js # React hooks ESM build
|
|
729
|
-
โโโ react-map-gl.js # React Map GL ESM build
|
|
730
|
-
โโโ package.json # Package metadata with exports map
|
|
731
|
-
```
|
|
732
|
-
|
|
733
|
-
## Browser Support
|
|
734
|
-
|
|
735
|
-
- **Modern Browsers**: Chrome, Firefox, Safari, Edge (ES2018+)
|
|
736
|
-
- **MapLibre GL JS**: v2.0+ (recommended), v1.15+
|
|
737
|
-
- **Mapbox GL JS**: v2.0+ (recommended), v1.13+
|
|
738
|
-
|
|
739
|
-
## TypeScript Support
|
|
740
|
-
|
|
741
|
-
esri-gl is written in TypeScript and provides full type definitions consolidated in a single directory:
|
|
742
|
-
|
|
743
|
-
```typescript
|
|
744
|
-
import type {
|
|
745
|
-
DynamicMapServiceOptions,
|
|
746
|
-
FeatureServiceOptions,
|
|
747
|
-
IdentifyResult,
|
|
748
|
-
EsriGeoJSONFeatureCollection
|
|
749
|
-
} from 'esri-gl';
|
|
750
|
-
|
|
751
|
-
const options: FeatureServiceOptions = {
|
|
752
|
-
url: 'https://example.com/FeatureServer/0',
|
|
753
|
-
useVectorTiles: true,
|
|
754
|
-
where: '1=1'
|
|
755
|
-
};
|
|
190
|
+
npm run dev # Start demo dev server
|
|
191
|
+
npm run build # Build library (ESM + UMD)
|
|
192
|
+
npm run test # Run tests (727 tests, 31 suites)
|
|
193
|
+
npm run type-check # TypeScript check
|
|
194
|
+
npm run lint # ESLint
|
|
195
|
+
npm run build:docs # Build documentation site
|
|
196
|
+
npm run build:demo # Build demo site
|
|
756
197
|
```
|
|
757
198
|
|
|
758
|
-
All type declarations are available in the `dist/` directory after building.
|
|
759
|
-
|
|
760
199
|
## Contributing
|
|
761
200
|
|
|
762
|
-
|
|
201
|
+
1. Fork and create a feature branch
|
|
202
|
+
2. Make changes and add tests
|
|
203
|
+
3. Run `npm run test && npm run type-check && npm run lint`
|
|
204
|
+
4. Submit a pull request
|
|
763
205
|
|
|
764
|
-
|
|
765
|
-
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
766
|
-
3. Make changes and add tests
|
|
767
|
-
4. Run validation: `npm run validate`
|
|
768
|
-
5. Commit changes: `git commit -m 'Add new feature'`
|
|
769
|
-
6. Push to branch: `git push origin feature/my-feature`
|
|
770
|
-
7. Submit a pull request
|
|
771
|
-
|
|
772
|
-
### Pre-commit Hooks
|
|
773
|
-
|
|
774
|
-
This project uses [Husky](https://typicode.github.io/husky/) to automatically run quality checks before each commit:
|
|
775
|
-
|
|
776
|
-
- **Formatting & Linting**: Automatically formats and lints staged files using Prettier and ESLint
|
|
777
|
-
- **Testing**: Runs the full test suite to ensure no regressions
|
|
778
|
-
|
|
779
|
-
The hooks are automatically installed when you run `npm install`. If you need to skip them (not recommended), you can use `git commit --no-verify`.
|
|
780
|
-
|
|
781
|
-
For more details, see [.husky/README.md](.husky/README.md).
|
|
206
|
+
Pre-commit hooks automatically run formatting, linting, and tests via [Husky](https://typicode.github.io/husky/).
|
|
782
207
|
|
|
783
208
|
## License
|
|
784
209
|
|
|
785
|
-
MIT
|
|
210
|
+
MIT โ see [LICENSE](LICENSE)
|
|
786
211
|
|
|
787
212
|
## Acknowledgements
|
|
788
213
|
|
|
789
|
-
- **Esri Leaflet**
|
|
790
|
-
- **
|
|
791
|
-
- **
|
|
792
|
-
- **[mapbox-gl-esri-sources](https://github.com/frontiersi/mapbox-gl-esri-sources/)** - Reference implementation for Esri service integration patterns
|
|
793
|
-
- **[mapbox-gl-arcgis-featureserver](https://github.com/rowanwins/mapbox-gl-arcgis-featureserver)** by **Rowan Winsemius** - The FeatureService implementation with PBF support is based on this excellent library. It provides efficient tile-based feature loading with Protocol Buffer Format (PBF) support for minimal payload size.
|
|
794
|
-
|
|
795
|
-
## Fork Notice
|
|
796
|
-
|
|
797
|
-
This project originated as a fork of **[frontiersi/mapbox-gl-esri-sources](https://github.com/frontiersi/mapbox-gl-esri-sources/)**. It has been substantially refactored and expanded:
|
|
798
|
-
|
|
799
|
-
- Migrated to a service + task architecture similar to Esri Leaflet
|
|
800
|
-
- Added unified TypeScript typing and consolidated build outputs (ESM + UMD)
|
|
801
|
-
- Introduced additional services (Dynamic, Image, Vector Basemap Styles, Identify / Query tasks, smart FeatureService vector tile detection, etc.)
|
|
802
|
-
- Implemented a React/Vite demo suite and extended test coverage
|
|
803
|
-
|
|
804
|
-
All original credit for the foundational concept and early integration patterns goes to the maintainers of the upstream repository. If you need the simpler original implementation, or want to compare behavior, please visit the upstream project.
|
|
805
|
-
|
|
214
|
+
- **[Esri Leaflet](https://esri.github.io/esri-leaflet/)** โ API design inspiration
|
|
215
|
+
- **[mapbox-gl-esri-sources](https://github.com/frontiersi/mapbox-gl-esri-sources/)** โ Foundational integration patterns (this project originated as a fork)
|
|
216
|
+
- **[mapbox-gl-arcgis-featureserver](https://github.com/rowanwins/mapbox-gl-arcgis-featureserver)** by Rowan Winsemius โ FeatureService PBF implementation
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "esri-gl",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "A module for making it easier to use Esri services in mapbox-gl or maplibre-gl.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"bugs": {
|
|
34
34
|
"url": "https://github.com/muimsd/esri-gl/issues"
|
|
35
35
|
},
|
|
36
|
-
"homepage": "https://esri-gl.
|
|
36
|
+
"homepage": "https://esri-gl.pages.dev",
|
|
37
37
|
"keywords": [
|
|
38
38
|
"mapbox",
|
|
39
39
|
"maplibre",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "esri-gl",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A module for making it easier to use Esri services in mapbox-gl or maplibre-gl.",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -124,8 +124,8 @@
|
|
|
124
124
|
"bugs": {
|
|
125
125
|
"url": "https://github.com/muimsd/esri-gl/issues"
|
|
126
126
|
},
|
|
127
|
-
"homepage": "https://esri-gl.
|
|
128
|
-
"demo": "https://esri-gl-demo.
|
|
127
|
+
"homepage": "https://esri-gl.pages.dev",
|
|
128
|
+
"demo": "https://esri-gl-demo.pages.dev",
|
|
129
129
|
"author": "Muhammad Imran Siddique 2025, Rowan Winsemius 2020-2025",
|
|
130
130
|
"license": "MIT",
|
|
131
131
|
"keywords": [
|