esri-gl 1.0.2 โ 1.0.4
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 +112 -700
- package/dist/package.json +2 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,805 +1,217 @@
|
|
|
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)
|
|
9
|
+
[](https://www.buymeacoffee.com/muimsd)
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
**[Documentation](https://esri-gl.pages.dev/)** ยท **[Live Demos](https://esri-gl-demo.pages.dev/)** ยท **[npm](https://www.npmjs.com/package/esri-gl)**
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
- **๐ฎ [Live Demos](https://esri-gl-demo.netlify.app/)** - Interactive examples and code samples
|
|
13
|
+
## Features
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
### Services
|
|
16
|
+
- **DynamicMapService** โ Server-rendered raster tiles with dynamic styling, filtering, labeling, and identify
|
|
17
|
+
- **TiledMapService** โ Pre-cached tiles for fast basemaps
|
|
18
|
+
- **ImageService** โ Analytical raster data with rendering rules and temporal support
|
|
19
|
+
- **FeatureService** โ Vector data with smart vector tile detection, GeoJSON fallback, editing, and attachments
|
|
20
|
+
- **VectorTileService** โ Client-rendered vector tiles
|
|
21
|
+
- **VectorBasemapStyle** โ Esri's professional basemap styles
|
|
15
22
|
|
|
16
|
-
|
|
23
|
+
### Tasks
|
|
24
|
+
- **IdentifyFeatures / IdentifyImage** โ Query features and pixel values at map locations
|
|
25
|
+
- **Query** โ Spatial and attribute queries with automatic pagination
|
|
26
|
+
- **Find** โ Text-based feature search across layers
|
|
17
27
|
|
|
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
|
|
28
|
+
### Integrations
|
|
29
|
+
- **React Hooks** โ `useDynamicMapService`, `useFeatureService`, `useQuery`, etc.
|
|
30
|
+
- **react-map-gl** โ Declarative `<EsriDynamicLayer>`, `<EsriFeatureLayer>`, etc.
|
|
31
|
+
- **TypeScript** โ Full type safety with comprehensive interfaces
|
|
43
32
|
|
|
44
33
|
## Installation
|
|
45
34
|
|
|
46
|
-
### Stable Release
|
|
47
35
|
```bash
|
|
48
36
|
npm install esri-gl
|
|
49
37
|
```
|
|
50
38
|
|
|
51
39
|
### Entry Points
|
|
52
40
|
|
|
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 |
|
|
41
|
+
| Import | Use Case |
|
|
42
|
+
|--------|----------|
|
|
43
|
+
| `esri-gl` | Core services and tasks |
|
|
44
|
+
| `esri-gl/react` | React hooks |
|
|
45
|
+
| `esri-gl/react-map-gl` | react-map-gl components |
|
|
60
46
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
### Basic Usage with MapLibre GL JS
|
|
47
|
+
### CDN (UMD)
|
|
64
48
|
|
|
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
|
-
});
|
|
49
|
+
```html
|
|
50
|
+
<script src="https://unpkg.com/esri-gl@latest/dist/index.umd.js"></script>
|
|
51
|
+
<script>
|
|
52
|
+
const service = new esrigl.DynamicMapService('source', map, { url: '...' });
|
|
53
|
+
</script>
|
|
107
54
|
```
|
|
108
55
|
|
|
109
|
-
|
|
56
|
+
## Quick Start
|
|
110
57
|
|
|
111
58
|
```typescript
|
|
112
|
-
import
|
|
113
|
-
import { VectorBasemapStyle, ImageService } from 'esri-gl';
|
|
114
|
-
|
|
115
|
-
mapboxgl.accessToken = 'your-mapbox-token';
|
|
59
|
+
import { DynamicMapService } from 'esri-gl';
|
|
116
60
|
|
|
117
|
-
const map = new
|
|
61
|
+
const map = new maplibregl.Map({
|
|
118
62
|
container: 'map',
|
|
63
|
+
style: 'https://demotiles.maplibre.org/style.json',
|
|
119
64
|
center: [-95, 37],
|
|
120
65
|
zoom: 4
|
|
121
66
|
});
|
|
122
67
|
|
|
123
68
|
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'
|
|
69
|
+
const service = new DynamicMapService('usa-source', map, {
|
|
70
|
+
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
|
|
71
|
+
layers: [0, 1, 2],
|
|
72
|
+
transparent: true
|
|
141
73
|
});
|
|
142
|
-
});
|
|
143
|
-
```
|
|
144
|
-
|
|
145
|
-
## Service Classes
|
|
146
|
-
|
|
147
|
-
### DynamicMapService
|
|
148
|
-
Server-rendered raster tiles from ArcGIS Map Services.
|
|
149
74
|
|
|
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'
|
|
75
|
+
map.addLayer({ id: 'usa-layer', type: 'raster', source: 'usa-source' });
|
|
160
76
|
});
|
|
161
77
|
```
|
|
162
78
|
|
|
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
|
-
```
|
|
79
|
+
## Service Examples
|
|
171
80
|
|
|
172
81
|
### 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
82
|
|
|
202
83
|
```typescript
|
|
203
|
-
|
|
204
|
-
const service = new FeatureService('editable-source', map, {
|
|
84
|
+
const service = new FeatureService('features-source', map, {
|
|
205
85
|
url: 'https://services.arcgis.com/.../FeatureServer/0',
|
|
206
|
-
|
|
86
|
+
where: "STATUS = 'Active'",
|
|
87
|
+
outFields: 'NAME,STATUS',
|
|
88
|
+
token: 'your-token' // optional
|
|
207
89
|
});
|
|
208
90
|
|
|
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]
|
|
91
|
+
map.addLayer({
|
|
92
|
+
id: 'features-layer',
|
|
93
|
+
type: 'circle',
|
|
94
|
+
source: 'features-source',
|
|
95
|
+
paint: { 'circle-radius': 5, 'circle-color': '#007cbf' }
|
|
227
96
|
});
|
|
228
|
-
```
|
|
229
|
-
|
|
230
|
-
### VectorTileService
|
|
231
|
-
Client-rendered vector tiles for fast styling and interaction.
|
|
232
97
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
});
|
|
98
|
+
// Edit features
|
|
99
|
+
await service.addFeatures([feature]);
|
|
100
|
+
await service.applyEdits({ adds: [], updates: [], deletes: [1, 2] });
|
|
237
101
|
```
|
|
238
102
|
|
|
239
103
|
### ImageService
|
|
240
|
-
Analytical raster data with server-side processing capabilities.
|
|
241
104
|
|
|
242
105
|
```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
|
-
}
|
|
106
|
+
const service = new ImageService('landsat-source', map, {
|
|
107
|
+
url: 'https://landsat2.arcgis.com/arcgis/rest/services/Landsat/MS/ImageServer',
|
|
108
|
+
renderingRule: { rasterFunction: 'Natural Color' }
|
|
256
109
|
});
|
|
257
110
|
```
|
|
258
111
|
|
|
259
112
|
### 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
113
|
|
|
270
114
|
```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
|
-
});
|
|
115
|
+
VectorBasemapStyle.applyStyle(map, 'arcgis/streets', { apiKey: 'YOUR_KEY' });
|
|
277
116
|
```
|
|
278
117
|
|
|
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.
|
|
118
|
+
## Tasks
|
|
285
119
|
|
|
286
120
|
```typescript
|
|
287
|
-
import { IdentifyFeatures } from 'esri-gl';
|
|
121
|
+
import { IdentifyFeatures, query } from 'esri-gl';
|
|
288
122
|
|
|
289
|
-
// Identify features at a point
|
|
290
|
-
const results = await new IdentifyFeatures('https
|
|
123
|
+
// Identify features at a point
|
|
124
|
+
const results = await new IdentifyFeatures('https://.../MapServer')
|
|
291
125
|
.at({ lng: -95, lat: 37 })
|
|
292
126
|
.on(map)
|
|
293
127
|
.layers('all')
|
|
294
128
|
.tolerance(5)
|
|
295
|
-
.returnGeometry(true)
|
|
296
129
|
.run();
|
|
297
130
|
|
|
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
|
|
131
|
+
// Query with pagination
|
|
132
|
+
const all = await query({ url: 'https://.../FeatureServer/0' })
|
|
133
|
+
.where("STATE_NAME = 'California'")
|
|
134
|
+
.runAll();
|
|
340
135
|
```
|
|
341
136
|
|
|
342
137
|
## React Integration
|
|
343
138
|
|
|
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:
|
|
139
|
+
### Hooks
|
|
364
140
|
|
|
365
141
|
```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
|
-
});
|
|
142
|
+
import { useDynamicMapService, useIdentifyFeatures } from 'esri-gl/react';
|
|
407
143
|
|
|
408
|
-
|
|
144
|
+
const { service, loading, error } = useDynamicMapService({
|
|
145
|
+
sourceId: 'usa-service',
|
|
146
|
+
map,
|
|
147
|
+
options: {
|
|
409
148
|
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
|
|
149
|
+
layers: [0, 1, 2]
|
|
150
|
+
}
|
|
624
151
|
});
|
|
625
152
|
```
|
|
626
153
|
|
|
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
|
-
});
|
|
154
|
+
### react-map-gl Components
|
|
635
155
|
|
|
636
|
-
|
|
637
|
-
|
|
156
|
+
```tsx
|
|
157
|
+
import { EsriDynamicLayer, EsriFeatureLayer } from 'esri-gl/react-map-gl';
|
|
638
158
|
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
}
|
|
159
|
+
<Map mapStyle="mapbox://styles/mapbox/streets-v11">
|
|
160
|
+
<EsriDynamicLayer
|
|
161
|
+
id="census"
|
|
162
|
+
url="https://.../Census/MapServer"
|
|
163
|
+
layers={[0, 1]}
|
|
164
|
+
opacity={0.8}
|
|
165
|
+
/>
|
|
166
|
+
<EsriFeatureLayer
|
|
167
|
+
id="states"
|
|
168
|
+
url="https://.../FeatureServer/0"
|
|
169
|
+
paint={{ 'fill-color': '#627BC1', 'fill-opacity': 0.6 }}
|
|
170
|
+
/>
|
|
171
|
+
</Map>
|
|
644
172
|
```
|
|
645
173
|
|
|
646
174
|
## Examples
|
|
647
175
|
|
|
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 |
|
|
176
|
+
Working examples in [`examples/`](examples/):
|
|
655
177
|
|
|
656
|
-
|
|
178
|
+
| Example | Description |
|
|
179
|
+
|---------|-------------|
|
|
180
|
+
| [maplibre-esm](examples/maplibre-esm/) | All services and tasks with vanilla MapLibre |
|
|
181
|
+
| [maplibre-react-hooks](examples/maplibre-react-hooks/) | React hooks with MapLibre |
|
|
182
|
+
| [maplibre-react-map-gl](examples/maplibre-react-map-gl/) | react-map-gl components |
|
|
657
183
|
|
|
658
184
|
```bash
|
|
659
|
-
cd examples/maplibre-esm
|
|
660
|
-
npm install
|
|
661
|
-
npm run dev
|
|
185
|
+
cd examples/maplibre-esm && npm install && npm run dev
|
|
662
186
|
```
|
|
663
187
|
|
|
664
188
|
## Development
|
|
665
189
|
|
|
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
190
|
```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
|
-
};
|
|
191
|
+
npm run dev # Start demo dev server
|
|
192
|
+
npm run build # Build library (ESM + UMD)
|
|
193
|
+
npm run test # Run tests (727 tests, 31 suites)
|
|
194
|
+
npm run type-check # TypeScript check
|
|
195
|
+
npm run lint # ESLint
|
|
196
|
+
npm run build:docs # Build documentation site
|
|
197
|
+
npm run build:demo # Build demo site
|
|
756
198
|
```
|
|
757
199
|
|
|
758
|
-
All type declarations are available in the `dist/` directory after building.
|
|
759
|
-
|
|
760
200
|
## Contributing
|
|
761
201
|
|
|
762
|
-
|
|
202
|
+
1. Fork and create a feature branch
|
|
203
|
+
2. Make changes and add tests
|
|
204
|
+
3. Run `npm run test && npm run type-check && npm run lint`
|
|
205
|
+
4. Submit a pull request
|
|
763
206
|
|
|
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).
|
|
207
|
+
Pre-commit hooks automatically run formatting, linting, and tests via [Husky](https://typicode.github.io/husky/).
|
|
782
208
|
|
|
783
209
|
## License
|
|
784
210
|
|
|
785
|
-
MIT
|
|
211
|
+
MIT โ see [LICENSE](LICENSE)
|
|
786
212
|
|
|
787
213
|
## Acknowledgements
|
|
788
214
|
|
|
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
|
-
|
|
215
|
+
- **[Esri Leaflet](https://esri.github.io/esri-leaflet/)** โ API design inspiration
|
|
216
|
+
- **[mapbox-gl-esri-sources](https://github.com/frontiersi/mapbox-gl-esri-sources/)** โ Foundational integration patterns (this project originated as a fork)
|
|
217
|
+
- **[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.4",
|
|
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.4",
|
|
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": [
|