esri-gl 0.9.0-alpha.9 → 0.9.1
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 +366 -35
- package/dist/IdentifyImage-B1oeOjpm.js +4174 -0
- package/dist/IdentifyImage-B1oeOjpm.js.map +1 -0
- package/dist/index-DuO9oU8x.d.ts +1500 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +4215 -0
- package/dist/index.umd.js.map +1 -0
- package/dist/package.json +69 -0
- package/dist/react-map-gl.d.ts +101 -0
- package/dist/react-map-gl.js +479 -0
- package/dist/react-map-gl.js.map +1 -0
- package/dist/react.d.ts +114 -0
- package/dist/react.js +406 -0
- package/dist/react.js.map +1 -0
- package/dist/useFeatureService-BSZr2zvH.d.ts +140 -0
- package/dist/useFeatureService-D2kPkS3Y.js +205 -0
- package/dist/useFeatureService-D2kPkS3Y.js.map +1 -0
- package/package.json +93 -47
- package/dist/esri-gl.esm.js +0 -2694
- package/dist/esri-gl.esm.js.map +0 -1
- package/dist/esri-gl.js +0 -2719
- package/dist/esri-gl.js.map +0 -1
- package/dist/esri-gl.min.js +0 -2
- package/dist/esri-gl.min.js.map +0 -1
- package/dist/types/Services/DynamicMapService.d.ts +0 -35
- package/dist/types/Services/FeatureService.d.ts +0 -48
- package/dist/types/Services/ImageService.d.ts +0 -32
- package/dist/types/Services/MapService.d.ts +0 -30
- package/dist/types/Services/MapServiceTypes.d.ts +0 -87
- package/dist/types/Services/Service.d.ts +0 -118
- package/dist/types/Services/SimpleMapService.d.ts +0 -30
- package/dist/types/Services/TiledMapService.d.ts +0 -28
- package/dist/types/Services/VectorBasemapStyle.d.ts +0 -9
- package/dist/types/Services/VectorTileService.d.ts +0 -41
- package/dist/types/Tasks/Find.d.ts +0 -85
- package/dist/types/Tasks/IdentifyFeatures.d.ts +0 -91
- package/dist/types/Tasks/IdentifyImage.d.ts +0 -107
- package/dist/types/Tasks/Query.d.ts +0 -180
- package/dist/types/Tasks/Task.d.ts +0 -50
- package/dist/types/examples/EsriLeafletStyleAPI.d.ts +0 -8
- package/dist/types/main.d.ts +0 -14
- package/dist/types/types.d.ts +0 -88
- package/dist/types/utils.d.ts +0 -4
package/README.md
CHANGED
|
@@ -37,7 +37,13 @@ A TypeScript library that bridges Esri ArcGIS REST services with MapLibre GL JS
|
|
|
37
37
|
- **Layer Definitions** - Filter data server-side using SQL-like expressions
|
|
38
38
|
- **Time-aware Services** - Support for temporal data visualization
|
|
39
39
|
- **Attribution Management** - Automatic service attribution handling
|
|
40
|
+
- **React Integration** - Hooks and components for React applications
|
|
41
|
+
- **React Map GL Support** - Direct integration with react-map-gl
|
|
40
42
|
- **TypeScript Support** - Full type safety with comprehensive interfaces
|
|
43
|
+
- **ArcGIS Online (AGOL) Support** - Proper JSON error handling, token auth, and API key support
|
|
44
|
+
- **Feature Editing** - Add, update, delete features and apply batch edits
|
|
45
|
+
- **Attachments** - Query, add, and delete feature attachments
|
|
46
|
+
- **Query Pagination** - Automatic pagination through large result sets
|
|
41
47
|
|
|
42
48
|
## Installation
|
|
43
49
|
|
|
@@ -46,30 +52,7 @@ A TypeScript library that bridges Esri ArcGIS REST services with MapLibre GL JS
|
|
|
46
52
|
npm install esri-gl
|
|
47
53
|
```
|
|
48
54
|
|
|
49
|
-
### Alpha/Beta Releases
|
|
50
|
-
```bash
|
|
51
|
-
# Latest alpha release (current: v0.1.0-alpha.2)
|
|
52
|
-
npm install esri-gl@alpha
|
|
53
|
-
|
|
54
|
-
# Specific alpha version
|
|
55
|
-
npm install esri-gl@0.1.0-alpha.2
|
|
56
55
|
|
|
57
|
-
# Latest beta release
|
|
58
|
-
npm install esri-gl@beta
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
### GitHub Packages (Alternative Registry)
|
|
62
|
-
```bash
|
|
63
|
-
# Configure npm to use GitHub Packages for @muimsd scope
|
|
64
|
-
npm config set @muimsd:registry https://npm.pkg.github.com/
|
|
65
|
-
|
|
66
|
-
# Install from GitHub Packages
|
|
67
|
-
npm install @muimsd/esri-gl
|
|
68
|
-
|
|
69
|
-
# Or use the setup script
|
|
70
|
-
./scripts/github-packages.sh configure
|
|
71
|
-
./scripts/github-packages.sh install
|
|
72
|
-
```
|
|
73
56
|
|
|
74
57
|
## Quick Start
|
|
75
58
|
|
|
@@ -183,16 +166,60 @@ const service = new TiledMapService('source-id', map, {
|
|
|
183
166
|
```
|
|
184
167
|
|
|
185
168
|
### FeatureService
|
|
186
|
-
|
|
169
|
+
Efficient tile-based feature loading from ArcGIS FeatureServers with PBF (Protocol Buffer) support for minimal payload size.
|
|
187
170
|
|
|
188
171
|
```typescript
|
|
189
172
|
const service = new FeatureService('source-id', map, {
|
|
190
173
|
url: 'https://example.com/arcgis/rest/services/MyService/FeatureServer/0',
|
|
191
|
-
useVectorTiles: true, // Smart detection with fallback
|
|
192
|
-
useBoundingBox: true, // Viewport-based loading
|
|
193
174
|
where: '1=1',
|
|
194
175
|
outFields: '*',
|
|
195
|
-
|
|
176
|
+
// PBF options (requires ArcGIS Server 10.7+)
|
|
177
|
+
minZoom: 2, // Minimum zoom level for data requests
|
|
178
|
+
simplifyFactor: 0.3, // Geometry simplification (0-1)
|
|
179
|
+
precision: 8, // Coordinate decimal precision
|
|
180
|
+
useServiceBounds: true, // Limit requests to service extent
|
|
181
|
+
setAttributionFromService: true // Auto-set attribution
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Update filters dynamically
|
|
185
|
+
service.setWhere("STATUS = 'Active'");
|
|
186
|
+
service.setDate(new Date(), new Date('2024-01-01'));
|
|
187
|
+
service.setToken('your-token');
|
|
188
|
+
|
|
189
|
+
// Query features by location
|
|
190
|
+
const features = await service.getFeaturesByLonLat({ lng: -118, lat: 34 }, 100);
|
|
191
|
+
|
|
192
|
+
// Query by object IDs
|
|
193
|
+
const specific = await service.getFeaturesByObjectIds([1, 2, 3], true);
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
#### Feature Editing (AGOL)
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
// Edit features on an AGOL Feature Service
|
|
200
|
+
const service = new FeatureService('editable-source', map, {
|
|
201
|
+
url: 'https://services.arcgis.com/.../FeatureServer/0',
|
|
202
|
+
token: 'your-agol-token'
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
// Add features
|
|
206
|
+
const addResults = await service.addFeatures([
|
|
207
|
+
{ type: 'Feature', geometry: { type: 'Point', coordinates: [-95, 37] }, properties: { name: 'New Point' } }
|
|
208
|
+
]);
|
|
209
|
+
|
|
210
|
+
// Update features
|
|
211
|
+
const updateResults = await service.updateFeatures([
|
|
212
|
+
{ type: 'Feature', geometry: { type: 'Point', coordinates: [-95, 37] }, properties: { OBJECTID: 1, name: 'Updated' } }
|
|
213
|
+
]);
|
|
214
|
+
|
|
215
|
+
// Delete features
|
|
216
|
+
const deleteResults = await service.deleteFeatures({ objectIds: [1, 2, 3] });
|
|
217
|
+
|
|
218
|
+
// Batch edits
|
|
219
|
+
const batchResults = await service.applyEdits({
|
|
220
|
+
adds: [newFeature],
|
|
221
|
+
updates: [updatedFeature],
|
|
222
|
+
deletes: [4, 5]
|
|
196
223
|
});
|
|
197
224
|
```
|
|
198
225
|
|
|
@@ -236,6 +263,15 @@ const service = new VectorBasemapStyle('source-id', map, {
|
|
|
236
263
|
});
|
|
237
264
|
```
|
|
238
265
|
|
|
266
|
+
```typescript
|
|
267
|
+
// Custom portal item style
|
|
268
|
+
const customBasemap = new VectorBasemapStyle('source-id', map, {
|
|
269
|
+
style: 'arcgis/streets',
|
|
270
|
+
itemId: 'your-portal-item-id',
|
|
271
|
+
token: 'your-token'
|
|
272
|
+
});
|
|
273
|
+
```
|
|
274
|
+
|
|
239
275
|
## Task-Based Operations
|
|
240
276
|
|
|
241
277
|
Modeled after Esri Leaflet's chainable task pattern for querying and identifying features.
|
|
@@ -291,6 +327,252 @@ const results = await query({
|
|
|
291
327
|
.run();
|
|
292
328
|
```
|
|
293
329
|
|
|
330
|
+
```typescript
|
|
331
|
+
// Automatic pagination through all results
|
|
332
|
+
import { query } from 'esri-gl';
|
|
333
|
+
|
|
334
|
+
const allResults = await query({
|
|
335
|
+
url: 'https://example.com/arcgis/rest/services/MyService/FeatureServer/0'
|
|
336
|
+
})
|
|
337
|
+
.where("STATE_NAME = 'California'")
|
|
338
|
+
.runAll(); // Automatically paginates through all pages
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## React Integration
|
|
342
|
+
|
|
343
|
+
esri-gl provides first-class React.js support with comprehensive hooks, components, and seamless integration with **react-map-gl**. Whether you're building with vanilla React + MapLibre/Mapbox or using the react-map-gl wrapper, esri-gl has you covered.
|
|
344
|
+
|
|
345
|
+
### Installation for React Projects
|
|
346
|
+
|
|
347
|
+
```bash
|
|
348
|
+
# Core library
|
|
349
|
+
npm install esri-gl
|
|
350
|
+
|
|
351
|
+
# For React hooks and components
|
|
352
|
+
npm install react react-dom @types/react @types/react-dom
|
|
353
|
+
|
|
354
|
+
# For react-map-gl integration (recommended)
|
|
355
|
+
npm install react-map-gl mapbox-gl
|
|
356
|
+
# OR for MapLibre
|
|
357
|
+
npm install react-map-gl maplibre-gl
|
|
358
|
+
```
|
|
359
|
+
|
|
360
|
+
### React Hooks Pattern
|
|
361
|
+
|
|
362
|
+
Perfect for custom React components with full control over map lifecycle:
|
|
363
|
+
|
|
364
|
+
```typescript
|
|
365
|
+
import React, { useState, useRef, useEffect } from 'react';
|
|
366
|
+
import { Map } from 'maplibre-gl';
|
|
367
|
+
import { useDynamicMapService, useIdentifyFeatures, useFeatureService } from 'esri-gl/react';
|
|
368
|
+
|
|
369
|
+
function CustomMapComponent() {
|
|
370
|
+
const mapRef = useRef<HTMLDivElement>(null);
|
|
371
|
+
const [map, setMap] = useState<Map | null>(null);
|
|
372
|
+
|
|
373
|
+
// Initialize MapLibre map
|
|
374
|
+
useEffect(() => {
|
|
375
|
+
if (!mapRef.current) return;
|
|
376
|
+
const mapInstance = new Map({
|
|
377
|
+
container: mapRef.current,
|
|
378
|
+
style: 'https://demotiles.maplibre.org/style.json',
|
|
379
|
+
center: [-95, 37],
|
|
380
|
+
zoom: 4
|
|
381
|
+
});
|
|
382
|
+
setMap(mapInstance);
|
|
383
|
+
return () => mapInstance.remove();
|
|
384
|
+
}, []);
|
|
385
|
+
|
|
386
|
+
// Use esri-gl React hooks
|
|
387
|
+
const { service: dynamicService, loading, error } = useDynamicMapService({
|
|
388
|
+
sourceId: 'usa-service',
|
|
389
|
+
map,
|
|
390
|
+
options: {
|
|
391
|
+
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
|
|
392
|
+
layers: [0, 1, 2],
|
|
393
|
+
transparent: true
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
|
|
397
|
+
const { service: featureService } = useFeatureService({
|
|
398
|
+
sourceId: 'states-service',
|
|
399
|
+
map,
|
|
400
|
+
options: {
|
|
401
|
+
url: 'https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Census_States/FeatureServer/0',
|
|
402
|
+
useVectorTiles: true,
|
|
403
|
+
useBoundingBox: true
|
|
404
|
+
}
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
const { identify } = useIdentifyFeatures({
|
|
408
|
+
url: 'https://sampleserver6.arcgisonline.com/arcgis/rest/services/USA/MapServer',
|
|
409
|
+
tolerance: 3
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// Handle map clicks for identify
|
|
413
|
+
useEffect(() => {
|
|
414
|
+
if (!map) return;
|
|
415
|
+
const handleClick = async (e: any) => {
|
|
416
|
+
const results = await identify({ lng: e.lngLat.lng, lat: e.lngLat.lat }, map);
|
|
417
|
+
console.log('Identify results:', results);
|
|
418
|
+
};
|
|
419
|
+
map.on('click', handleClick);
|
|
420
|
+
return () => map.off('click', handleClick);
|
|
421
|
+
}, [map, identify]);
|
|
422
|
+
|
|
423
|
+
return (
|
|
424
|
+
<div>
|
|
425
|
+
<div ref={mapRef} style={{ width: '100%', height: '500px' }} />
|
|
426
|
+
{loading && <div>Loading Esri services...</div>}
|
|
427
|
+
{error && <div>Error: {error.message}</div>}
|
|
428
|
+
</div>
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### React Map GL Components (Recommended)
|
|
434
|
+
|
|
435
|
+
For the smoothest React experience with declarative layer management:
|
|
436
|
+
|
|
437
|
+
```typescript
|
|
438
|
+
import React, { useState } from 'react';
|
|
439
|
+
import { Map } from 'react-map-gl/mapbox';
|
|
440
|
+
import {
|
|
441
|
+
EsriDynamicLayer,
|
|
442
|
+
EsriFeatureLayer,
|
|
443
|
+
EsriVectorTileLayer,
|
|
444
|
+
EsriImageLayer
|
|
445
|
+
} from 'esri-gl/react-map-gl';
|
|
446
|
+
|
|
447
|
+
function MapWithEsriLayers() {
|
|
448
|
+
const [viewState, setViewState] = useState({
|
|
449
|
+
longitude: -95,
|
|
450
|
+
latitude: 37,
|
|
451
|
+
zoom: 4
|
|
452
|
+
});
|
|
453
|
+
|
|
454
|
+
const [selectedStates, setSelectedStates] = useState<string[]>([]);
|
|
455
|
+
|
|
456
|
+
return (
|
|
457
|
+
<Map
|
|
458
|
+
{...viewState}
|
|
459
|
+
onMove={evt => setViewState(evt.viewState)}
|
|
460
|
+
mapStyle="mapbox://styles/mapbox/streets-v11"
|
|
461
|
+
style={{ width: '100%', height: '600px' }}
|
|
462
|
+
>
|
|
463
|
+
{/* Dynamic Map Service Layer */}
|
|
464
|
+
<EsriDynamicLayer
|
|
465
|
+
id="usa-demographics"
|
|
466
|
+
url="https://sampleserver6.arcgisonline.com/arcgis/rest/services/Census/MapServer"
|
|
467
|
+
layers={[0, 1, 2]}
|
|
468
|
+
layerDefs={{
|
|
469
|
+
0: "POP2000 > 100000",
|
|
470
|
+
1: "STATE_NAME IN ('California', 'Texas', 'New York')"
|
|
471
|
+
}}
|
|
472
|
+
opacity={0.8}
|
|
473
|
+
beforeId="waterway-label"
|
|
474
|
+
/>
|
|
475
|
+
|
|
476
|
+
{/* Feature Service with Vector Tiles */}
|
|
477
|
+
<EsriFeatureLayer
|
|
478
|
+
id="us-states"
|
|
479
|
+
url="https://services.arcgis.com/P3ePLMYs2RVChkJx/arcgis/rest/services/USA_Census_States/FeatureServer/0"
|
|
480
|
+
useVectorTiles={true}
|
|
481
|
+
useBoundingBox={true}
|
|
482
|
+
where={selectedStates.length > 0 ? `STATE_NAME IN ('${selectedStates.join("','")}')` : undefined}
|
|
483
|
+
paint={{
|
|
484
|
+
'fill-color': [
|
|
485
|
+
'case',
|
|
486
|
+
['in', ['get', 'STATE_NAME'], ['literal', selectedStates]],
|
|
487
|
+
'#ff6b6b',
|
|
488
|
+
'#627BC1'
|
|
489
|
+
],
|
|
490
|
+
'fill-opacity': 0.6,
|
|
491
|
+
'fill-outline-color': '#ffffff'
|
|
492
|
+
}}
|
|
493
|
+
onClick={(feature) => {
|
|
494
|
+
const stateName = feature.properties?.STATE_NAME;
|
|
495
|
+
if (stateName) {
|
|
496
|
+
setSelectedStates(prev =>
|
|
497
|
+
prev.includes(stateName)
|
|
498
|
+
? prev.filter(s => s !== stateName)
|
|
499
|
+
: [...prev, stateName]
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
}}
|
|
503
|
+
/>
|
|
504
|
+
|
|
505
|
+
{/* Vector Tile Service */}
|
|
506
|
+
<EsriVectorTileLayer
|
|
507
|
+
id="world-imagery-labels"
|
|
508
|
+
url="https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/VectorTileServer"
|
|
509
|
+
beforeId="usa-demographics"
|
|
510
|
+
/>
|
|
511
|
+
|
|
512
|
+
{/* Image Service for Analytical Data */}
|
|
513
|
+
<EsriImageLayer
|
|
514
|
+
id="elevation-hillshade"
|
|
515
|
+
url="https://sampleserver6.arcgisonline.com/arcgis/rest/services/Elevation/ImageServer"
|
|
516
|
+
renderingRule={{
|
|
517
|
+
rasterFunction: "Hillshade",
|
|
518
|
+
rasterFunctionArguments: {
|
|
519
|
+
Azimuth: 315,
|
|
520
|
+
Altitude: 45
|
|
521
|
+
}
|
|
522
|
+
}}
|
|
523
|
+
opacity={0.5}
|
|
524
|
+
/>
|
|
525
|
+
</Map>
|
|
526
|
+
);
|
|
527
|
+
}
|
|
528
|
+
```
|
|
529
|
+
|
|
530
|
+
### Why Choose React Integration?
|
|
531
|
+
|
|
532
|
+
#### React Hooks Benefits
|
|
533
|
+
- **🎛️ Full Control** - Direct access to map instance and service lifecycle
|
|
534
|
+
- **🔄 State Management** - Seamless integration with React state and effects
|
|
535
|
+
- **🎯 Custom Logic** - Perfect for complex interactions and custom components
|
|
536
|
+
- **📦 Lightweight** - Use only what you need
|
|
537
|
+
|
|
538
|
+
#### React Map GL Benefits
|
|
539
|
+
- **📋 Declarative** - Define layers as JSX components
|
|
540
|
+
- **🔄 Automatic Updates** - Props changes automatically update layers
|
|
541
|
+
- **🎨 Built-in Styling** - Direct paint and layout prop support
|
|
542
|
+
- **👆 Event Handling** - onClick, onHover events built-in
|
|
543
|
+
- **🏗️ Component Ecosystem** - Works with all react-map-gl features
|
|
544
|
+
|
|
545
|
+
### TypeScript Support
|
|
546
|
+
|
|
547
|
+
Full TypeScript support with comprehensive type definitions:
|
|
548
|
+
|
|
549
|
+
```typescript
|
|
550
|
+
import type {
|
|
551
|
+
DynamicMapServiceOptions,
|
|
552
|
+
FeatureServiceOptions,
|
|
553
|
+
IdentifyResult,
|
|
554
|
+
EsriLayerProps
|
|
555
|
+
} from 'esri-gl';
|
|
556
|
+
import type { MapRef } from 'react-map-gl/mapbox';
|
|
557
|
+
|
|
558
|
+
// Fully typed component props
|
|
559
|
+
interface MapComponentProps {
|
|
560
|
+
serviceUrl: string;
|
|
561
|
+
initialLayers?: number[];
|
|
562
|
+
onFeatureClick?: (feature: IdentifyResult) => void;
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
const TypedMapComponent: React.FC<MapComponentProps> = ({
|
|
566
|
+
serviceUrl,
|
|
567
|
+
initialLayers = [0],
|
|
568
|
+
onFeatureClick
|
|
569
|
+
}) => {
|
|
570
|
+
// Component implementation with full type safety
|
|
571
|
+
};
|
|
572
|
+
```
|
|
573
|
+
|
|
574
|
+
See [REACT.md](REACT.md) for complete React integration documentation and advanced patterns.
|
|
575
|
+
|
|
294
576
|
## Advanced Features
|
|
295
577
|
|
|
296
578
|
### Dynamic Layer Management
|
|
@@ -341,14 +623,33 @@ const service = new FeatureService('optimized-source', map, {
|
|
|
341
623
|
});
|
|
342
624
|
```
|
|
343
625
|
|
|
626
|
+
### Authentication
|
|
627
|
+
|
|
628
|
+
```typescript
|
|
629
|
+
// Token-based authentication (URL parameter)
|
|
630
|
+
const service = new DynamicMapService('secure-source', map, {
|
|
631
|
+
url: 'https://example.com/arcgis/rest/services/SecureService/MapServer',
|
|
632
|
+
token: 'your-auth-token'
|
|
633
|
+
});
|
|
634
|
+
|
|
635
|
+
// Update token dynamically
|
|
636
|
+
service.setToken('new-token');
|
|
637
|
+
|
|
638
|
+
// API Key authentication (X-Esri-Authorization header)
|
|
639
|
+
const featureService = new FeatureService('api-key-source', map, {
|
|
640
|
+
url: 'https://services.arcgis.com/.../FeatureServer/0',
|
|
641
|
+
apiKey: 'your-api-key' // Sent as X-Esri-Authorization: Bearer header
|
|
642
|
+
});
|
|
643
|
+
```
|
|
644
|
+
|
|
344
645
|
## Development
|
|
345
646
|
|
|
346
647
|
### Build System
|
|
347
|
-
- **Library Build**: Rollup with
|
|
348
|
-
- **Type Declarations**:
|
|
349
|
-
- **Demo Development**: Vite dev server
|
|
648
|
+
- **Library Build**: Rollup with TypeScript, Babel, and Terser (UMD + ESM outputs)
|
|
649
|
+
- **Type Declarations**: Generated with rollup-plugin-dts in `dist/` directory
|
|
650
|
+
- **Demo Development**: Vite dev server with React and TypeScript
|
|
350
651
|
- **Documentation**: Docusaurus build system
|
|
351
|
-
- **Test Coverage**:
|
|
652
|
+
- **Test Coverage**: 717 comprehensive test cases across 31 test suites
|
|
352
653
|
|
|
353
654
|
### Development Commands
|
|
354
655
|
|
|
@@ -400,9 +701,13 @@ src/
|
|
|
400
701
|
└── types.ts # TypeScript interfaces
|
|
401
702
|
|
|
402
703
|
dist/
|
|
403
|
-
├──
|
|
404
|
-
├──
|
|
405
|
-
├──
|
|
704
|
+
├── index.d.ts # Main TypeScript declarations
|
|
705
|
+
├── react.d.ts # React integration declarations
|
|
706
|
+
├── react-map-gl.d.ts # React Map GL declarations
|
|
707
|
+
├── index.js # ESM build
|
|
708
|
+
├── index.umd.js # UMD build
|
|
709
|
+
├── esri-gl.esm.js # ESM build (legacy)
|
|
710
|
+
├── esri-gl.js # UMD build (legacy)
|
|
406
711
|
└── esri-gl.min.js # Minified UMD build
|
|
407
712
|
```
|
|
408
713
|
|
|
@@ -431,10 +736,12 @@ const options: FeatureServiceOptions = {
|
|
|
431
736
|
};
|
|
432
737
|
```
|
|
433
738
|
|
|
434
|
-
All type declarations are available in the `dist
|
|
739
|
+
All type declarations are available in the `dist/` directory after building.
|
|
435
740
|
|
|
436
741
|
## Contributing
|
|
437
742
|
|
|
743
|
+
We welcome contributions! Please follow these steps:
|
|
744
|
+
|
|
438
745
|
1. Fork the repository
|
|
439
746
|
2. Create a feature branch: `git checkout -b feature/my-feature`
|
|
440
747
|
3. Make changes and add tests
|
|
@@ -443,6 +750,17 @@ All type declarations are available in the `dist/types/` directory after buildin
|
|
|
443
750
|
6. Push to branch: `git push origin feature/my-feature`
|
|
444
751
|
7. Submit a pull request
|
|
445
752
|
|
|
753
|
+
### Pre-commit Hooks
|
|
754
|
+
|
|
755
|
+
This project uses [Husky](https://typicode.github.io/husky/) to automatically run quality checks before each commit:
|
|
756
|
+
|
|
757
|
+
- **Formatting & Linting**: Automatically formats and lints staged files using Prettier and ESLint
|
|
758
|
+
- **Testing**: Runs the full test suite to ensure no regressions
|
|
759
|
+
|
|
760
|
+
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`.
|
|
761
|
+
|
|
762
|
+
For more details, see [.husky/README.md](.husky/README.md).
|
|
763
|
+
|
|
446
764
|
## License
|
|
447
765
|
|
|
448
766
|
MIT License - see [LICENSE](LICENSE) file for details.
|
|
@@ -453,3 +771,16 @@ MIT License - see [LICENSE](LICENSE) file for details.
|
|
|
453
771
|
- **MapLibre GL JS** & **Mapbox GL JS** - Incredible WebGL mapping libraries
|
|
454
772
|
- **Esri ArcGIS Platform** - Comprehensive GIS services and APIs
|
|
455
773
|
- **[mapbox-gl-esri-sources](https://github.com/frontiersi/mapbox-gl-esri-sources/)** - Reference implementation for Esri service integration patterns
|
|
774
|
+
- **[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.
|
|
775
|
+
|
|
776
|
+
## Fork Notice
|
|
777
|
+
|
|
778
|
+
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:
|
|
779
|
+
|
|
780
|
+
- Migrated to a service + task architecture similar to Esri Leaflet
|
|
781
|
+
- Added unified TypeScript typing and consolidated build outputs (ESM + UMD)
|
|
782
|
+
- Introduced additional services (Dynamic, Image, Vector Basemap Styles, Identify / Query tasks, smart FeatureService vector tile detection, etc.)
|
|
783
|
+
- Implemented a React/Vite demo suite and extended test coverage
|
|
784
|
+
|
|
785
|
+
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.
|
|
786
|
+
|