@loaders.gl/services 5.0.0-alpha.7 → 5.0.0-alpha.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/README.md +7 -46
  2. package/dist/authentication.d.ts +22 -9
  3. package/dist/authentication.d.ts.map +1 -1
  4. package/dist/authentication.js +28 -11
  5. package/dist/authentication.js.map +1 -1
  6. package/dist/index.cjs +301 -23886
  7. package/dist/index.cjs.map +3 -3
  8. package/dist/index.d.ts +2 -31
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -20
  11. package/dist/index.js.map +1 -1
  12. package/package.json +6 -16
  13. package/src/authentication.ts +31 -19
  14. package/src/index.ts +3 -84
  15. package/dist/arcgis/arcgis-capability-graph.d.ts +0 -48
  16. package/dist/arcgis/arcgis-capability-graph.d.ts.map +0 -1
  17. package/dist/arcgis/arcgis-capability-graph.js +0 -220
  18. package/dist/arcgis/arcgis-capability-graph.js.map +0 -1
  19. package/dist/arcgis/arcgis-feature-server-source-loader.d.ts +0 -94
  20. package/dist/arcgis/arcgis-feature-server-source-loader.d.ts.map +0 -1
  21. package/dist/arcgis/arcgis-feature-server-source-loader.js +0 -231
  22. package/dist/arcgis/arcgis-feature-server-source-loader.js.map +0 -1
  23. package/dist/arcgis/arcgis-image-server-source-loader.d.ts +0 -96
  24. package/dist/arcgis/arcgis-image-server-source-loader.d.ts.map +0 -1
  25. package/dist/arcgis/arcgis-image-server-source-loader.js +0 -143
  26. package/dist/arcgis/arcgis-image-server-source-loader.js.map +0 -1
  27. package/dist/arcgis/arcgis-image-tile-source-loader.d.ts +0 -71
  28. package/dist/arcgis/arcgis-image-tile-source-loader.d.ts.map +0 -1
  29. package/dist/arcgis/arcgis-image-tile-source-loader.js +0 -153
  30. package/dist/arcgis/arcgis-image-tile-source-loader.js.map +0 -1
  31. package/dist/arcgis/arcgis-map-tile-source-loader.d.ts +0 -106
  32. package/dist/arcgis/arcgis-map-tile-source-loader.d.ts.map +0 -1
  33. package/dist/arcgis/arcgis-map-tile-source-loader.js +0 -202
  34. package/dist/arcgis/arcgis-map-tile-source-loader.js.map +0 -1
  35. package/dist/arcgis/arcgis-scene-aggregation.d.ts +0 -34
  36. package/dist/arcgis/arcgis-scene-aggregation.d.ts.map +0 -1
  37. package/dist/arcgis/arcgis-scene-aggregation.js +0 -57
  38. package/dist/arcgis/arcgis-scene-aggregation.js.map +0 -1
  39. package/dist/arcgis/arcgis-scene-server-source-loader.d.ts +0 -112
  40. package/dist/arcgis/arcgis-scene-server-source-loader.d.ts.map +0 -1
  41. package/dist/arcgis/arcgis-scene-server-source-loader.js +0 -157
  42. package/dist/arcgis/arcgis-scene-server-source-loader.js.map +0 -1
  43. package/dist/arcgis/arcgis-server.d.ts +0 -15
  44. package/dist/arcgis/arcgis-server.d.ts.map +0 -1
  45. package/dist/arcgis/arcgis-server.js +0 -41
  46. package/dist/arcgis/arcgis-server.js.map +0 -1
  47. package/dist/arcgis/arcgis-url-utils.d.ts +0 -3
  48. package/dist/arcgis/arcgis-url-utils.d.ts.map +0 -1
  49. package/dist/arcgis/arcgis-url-utils.js +0 -23
  50. package/dist/arcgis/arcgis-url-utils.js.map +0 -1
  51. package/dist/arcgis/arcgis-vector-tile-server-source-loader.d.ts +0 -115
  52. package/dist/arcgis/arcgis-vector-tile-server-source-loader.d.ts.map +0 -1
  53. package/dist/arcgis/arcgis-vector-tile-server-source-loader.js +0 -156
  54. package/dist/arcgis/arcgis-vector-tile-server-source-loader.js.map +0 -1
  55. package/dist/service-registry.d.ts +0 -18
  56. package/dist/service-registry.d.ts.map +0 -1
  57. package/dist/service-registry.js +0 -29
  58. package/dist/service-registry.js.map +0 -1
  59. package/src/arcgis/arcgis-capability-graph.ts +0 -295
  60. package/src/arcgis/arcgis-feature-server-source-loader.ts +0 -346
  61. package/src/arcgis/arcgis-image-server-source-loader.ts +0 -242
  62. package/src/arcgis/arcgis-image-tile-source-loader.ts +0 -206
  63. package/src/arcgis/arcgis-map-tile-source-loader.ts +0 -286
  64. package/src/arcgis/arcgis-scene-aggregation.ts +0 -90
  65. package/src/arcgis/arcgis-scene-server-source-loader.ts +0 -258
  66. package/src/arcgis/arcgis-server.ts +0 -61
  67. package/src/arcgis/arcgis-url-utils.ts +0 -26
  68. package/src/arcgis/arcgis-vector-tile-server-source-loader.ts +0 -233
  69. package/src/service-registry.ts +0 -43
@@ -1,346 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT
3
- // Copyright (c) vis.gl contributors
4
-
5
- import type {DataType, Schema, GeoJSONTable} from '@loaders.gl/schema';
6
- import {
7
- convertFeaturesToWKBArrowTable,
8
- convertGeojsonToBinaryFeatureCollection
9
- } from '@loaders.gl/gis';
10
- import type {
11
- CoreAPI,
12
- DataSourceOptions,
13
- VectorSourceMetadata,
14
- GetFeaturesParameters,
15
- VectorSource,
16
- VectorSourceData
17
- } from '@loaders.gl/loader-utils';
18
- import type {SourceLoader} from '@loaders.gl/loader-utils';
19
- import {DataSource} from '@loaders.gl/loader-utils';
20
- import {buildArcGISResourceURL} from './arcgis-url-utils';
21
-
22
- /** Parameters for ArcGIS FeatureServer query requests. */
23
- export type ArcGISFeatureServiceQueryOptions = {
24
- /** Include feature geometries in the response. */
25
- returnGeometry?: boolean;
26
- /** SQL where clause. */
27
- where?: string;
28
- /** Output spatial reference. */
29
- outSR?: string | number;
30
- /** Output fields. */
31
- outFields?: string | string[];
32
- /** Input spatial reference for supplied geometry. */
33
- inSR?: string | number;
34
- /** Filter geometry as an ArcGIS REST geometry string. */
35
- geometry?: string;
36
- /** Filter geometry type. */
37
- geometryType?:
38
- | 'esriGeometryEnvelope'
39
- | 'esriGeometryPoint'
40
- | 'esriGeometryPolyline'
41
- | 'esriGeometryPolygon';
42
- /** Spatial relationship for geometry filters. */
43
- spatialRel?:
44
- | 'esriSpatialRelIntersects'
45
- | 'esriSpatialRelContains'
46
- | 'esriSpatialRelCrosses'
47
- | 'esriSpatialRelEnvelopeIntersects'
48
- | 'esriSpatialRelIndexIntersects'
49
- | 'esriSpatialRelOverlaps'
50
- | 'esriSpatialRelTouches'
51
- | 'esriSpatialRelWithin';
52
- /** Geometry precision. */
53
- geometryPrecision?: number;
54
- /** Query result type. */
55
- resultType?: 'none' | 'standard' | 'tile';
56
- /** ArcGIS response format. */
57
- f?: 'geojson' | 'json' | 'pjson';
58
- };
59
-
60
- /** Options for the ArcGIS FeatureServer source. */
61
- export type ArcGISFeatureServerSourceLoaderOptions = DataSourceOptions & {
62
- 'arcgis-feature-server'?: {
63
- /** Default ArcGIS query request parameters. */
64
- queryParameters?: Partial<ArcGISFeatureServiceQueryOptions>;
65
- };
66
- };
67
-
68
- /**
69
- * @see https://developers.arcgis.com/rest/services-reference/enterprise/feature-service.htm
70
- */
71
- export const ArcGISFeatureServerSourceLoader = {
72
- dataType: null as unknown as ArcGISVectorSource,
73
- batchType: null as never,
74
- name: 'ArcGISFeatureServer',
75
- id: 'arcgis-feature-server',
76
- module: 'services',
77
- version: '0.0.0',
78
- extensions: [],
79
- mimeTypes: [],
80
- type: 'arcgis-feature-server',
81
- fromUrl: true,
82
- fromBlob: false,
83
-
84
- options: {
85
- url: undefined!,
86
- 'arcgis-feature-server': {}
87
- },
88
-
89
- defaultOptions: {
90
- url: undefined!,
91
- 'arcgis-feature-server': {}
92
- },
93
-
94
- testURL: (url: string): boolean => url.toLowerCase().includes('featureserver'),
95
- createDataSource: (
96
- url: string,
97
- options: ArcGISFeatureServerSourceLoaderOptions,
98
- coreApi?: CoreAPI
99
- ): ArcGISVectorSource => new ArcGISVectorSource(url, options, coreApi)
100
- } as const satisfies SourceLoader<ArcGISVectorSource>;
101
-
102
- /**
103
- * ArcGIS FeatureServer
104
- * Note - exports a big API, that could be exposed here if there is a use case
105
- * @see https://developers.arcgis.com/rest/services-reference/enterprise/feature-service.htm
106
- */
107
- export class ArcGISVectorSource
108
- extends DataSource<string, ArcGISFeatureServerSourceLoaderOptions>
109
- implements VectorSource
110
- {
111
- /** Cached ArcGIS FeatureServer metadata request. */
112
- protected formatSpecificMetadata: Promise<any> | null = null;
113
-
114
- constructor(url: string, options: ArcGISFeatureServerSourceLoaderOptions, coreApi?: CoreAPI) {
115
- super(url, options, ArcGISFeatureServerSourceLoader.defaultOptions, coreApi);
116
- }
117
-
118
- /** Returns a schema inferred from ArcGIS FeatureServer metadata fields. */
119
- async getSchema(): Promise<Schema> {
120
- const metadata = await this.getFormatSpecificMetadata();
121
- return parseArcGISFeatureServerSchema(metadata);
122
- }
123
-
124
- /** Returns normalized VectorSource metadata. */
125
- async getMetadata(
126
- options: {formatSpecificMetadata?: boolean} = {}
127
- ): Promise<VectorSourceMetadata> {
128
- // Wait for raw metadata to load
129
- const formatSpecificMetadata = await this.getFormatSpecificMetadata();
130
-
131
- const metadata = parseArcGISFeatureServerMetadata(formatSpecificMetadata);
132
-
133
- // Only add the big blob of source metadata if explicitly requested
134
- if (options.formatSpecificMetadata) {
135
- metadata.formatSpecificMetadata = formatSpecificMetadata;
136
- }
137
- return metadata;
138
- }
139
-
140
- /** Requests features from the ArcGIS FeatureServer query endpoint. */
141
- async getFeatures(parameters: GetFeaturesParameters): Promise<VectorSourceData> {
142
- const url = this.getFeaturesURL(parameters);
143
- const response = await this.fetch(
144
- url,
145
- parameters.signal ? {signal: parameters.signal} : undefined
146
- );
147
- await this.checkResponse(response);
148
- const geoJsonTable = parseGeoJSONTable(await response.json());
149
- const format = parameters.format || 'arrow';
150
-
151
- switch (format) {
152
- case 'binary':
153
- return convertGeojsonToBinaryFeatureCollection(geoJsonTable.features);
154
- case 'geojson':
155
- return geoJsonTable;
156
- case 'arrow':
157
- default:
158
- return convertFeaturesToWKBArrowTable(geoJsonTable.features, {
159
- encodingPreference: parameters.geoarrow?.encodingPreference
160
- });
161
- }
162
- }
163
-
164
- /** Requests the raw ArcGIS FeatureServer metadata document. */
165
- protected async _getFormatSpecificMetadata() {
166
- // PJSON is formatted by a bit slower than JSON
167
- const url = this.metadataURL();
168
- const response = await this.fetch(url);
169
- await this.checkResponse(response);
170
- return await response.json();
171
- }
172
-
173
- /** Loads and caches the raw ArcGIS FeatureServer metadata. */
174
- protected async getFormatSpecificMetadata(): Promise<any> {
175
- this.formatSpecificMetadata ||= this._getFormatSpecificMetadata();
176
- return await this.formatSpecificMetadata;
177
- }
178
-
179
- /** Builds a metadata URL for the ArcGIS FeatureServer endpoint. */
180
- metadataURL(options?: {parameters?: Record<string, unknown>}): string {
181
- return this.getUrl('', {f: 'pjson', ...options?.parameters});
182
- }
183
-
184
- /** Builds a query URL from generic vector source parameters. */
185
- getFeaturesURL(parameters: GetFeaturesParameters): string {
186
- const defaultParameters = this.options['arcgis-feature-server']?.queryParameters || {};
187
- const outputSpatialReference = normalizeArcGISSpatialReference(parameters.crs) || 4326;
188
- const requestSpatialReference =
189
- normalizeArcGISSpatialReference(parameters.requestCrs) || outputSpatialReference;
190
- const queryParameters: ArcGISFeatureServiceQueryOptions = {
191
- returnGeometry: true,
192
- where: '1=1',
193
- outFields: '*',
194
- outSR: outputSpatialReference,
195
- inSR: requestSpatialReference,
196
- f: 'geojson',
197
- ...defaultParameters
198
- };
199
-
200
- if (parameters.boundingBox) {
201
- queryParameters.geometry = [
202
- parameters.boundingBox[0][0],
203
- parameters.boundingBox[0][1],
204
- parameters.boundingBox[1][0],
205
- parameters.boundingBox[1][1]
206
- ].join(',');
207
- queryParameters.geometryType = 'esriGeometryEnvelope';
208
- queryParameters.spatialRel ||= 'esriSpatialRelIntersects';
209
- }
210
-
211
- const layer = Array.isArray(parameters.layers) ? parameters.layers[0] : parameters.layers;
212
- const isLayerEndpoint = /\/FeatureServer\/\d+\/?(?:\?|$)/i.test(this.url);
213
- const resourcePath = isLayerEndpoint || !layer ? 'query' : `${layer}/query`;
214
- return this.getUrl(resourcePath, queryParameters);
215
- }
216
-
217
- /** Builds an ArcGIS FeatureServer URL. */
218
- protected getUrl(
219
- path: string,
220
- options: Record<string, unknown>,
221
- extra?: Record<string, unknown>
222
- ): string {
223
- return buildArcGISResourceURL(this.url, path, {...options, ...extra});
224
- }
225
-
226
- /** Checks an ArcGIS FeatureServer response. */
227
- protected async checkResponse(response: Response): Promise<void> {
228
- if (!response.ok) {
229
- throw new Error(
230
- response.statusText || `ArcGIS FeatureServer request failed: ${response.status}`
231
- );
232
- }
233
- }
234
- }
235
-
236
- function parseArcGISFeatureServerMetadata(json: any): VectorSourceMetadata {
237
- const layers: VectorSourceMetadata['layers'] = [];
238
- for (const layer of json.layers || []) {
239
- const extent = layer.extent;
240
- const spatialReference = layer.spatialReference || extent?.spatialReference;
241
- layers.push({
242
- name: layer.id === undefined ? layer.name : String(layer.id),
243
- title: layer.name,
244
- crs: getArcGISCoordinateReferenceSystems(spatialReference),
245
- boundingBox: normalizeArcGISExtent(extent)
246
- });
247
- }
248
-
249
- if (!layers.length && (json.id !== undefined || json.name)) {
250
- const extent = json.extent;
251
- layers.push({
252
- name: json.id === undefined ? json.name : String(json.id),
253
- title: json.name,
254
- crs: getArcGISCoordinateReferenceSystems(json.spatialReference || extent?.spatialReference),
255
- boundingBox: normalizeArcGISExtent(extent)
256
- });
257
- }
258
-
259
- return {
260
- // version: json.currentVersion || '',
261
- title: json.serviceDescription || '',
262
- name: json.serviceDescription || '',
263
- abstract: json.description || '',
264
- keywords: [],
265
- // attrribution: json.copyrightText || ''.
266
- // crs: 'EPSG:4326',
267
- layers
268
- };
269
- }
270
-
271
- /** Normalizes an ArcGIS spatial reference to a one-element CRS list. */
272
- function getArcGISCoordinateReferenceSystems(
273
- spatialReference: {wkid?: number; latestWkid?: number} | undefined
274
- ): string[] | undefined {
275
- const wellKnownIdentifier = spatialReference?.latestWkid || spatialReference?.wkid;
276
- return wellKnownIdentifier ? [`EPSG:${wellKnownIdentifier}`] : undefined;
277
- }
278
-
279
- /** Normalizes an ArcGIS extent to the loaders.gl two-corner shape. */
280
- function normalizeArcGISExtent(
281
- extent: {xmin?: number; ymin?: number; xmax?: number; ymax?: number} | undefined
282
- ): [[number, number], [number, number]] | undefined {
283
- return extent && [extent.xmin, extent.ymin, extent.xmax, extent.ymax].every(Number.isFinite)
284
- ? [
285
- [extent.xmin!, extent.ymin!],
286
- [extent.xmax!, extent.ymax!]
287
- ]
288
- : undefined;
289
- }
290
-
291
- /** Normalizes EPSG-prefixed CRS strings to ArcGIS WKID values. */
292
- function normalizeArcGISSpatialReference(
293
- spatialReference: string | number | undefined
294
- ): string | number | undefined {
295
- if (typeof spatialReference === 'string') {
296
- const match = /^EPSG:(\d+)$/i.exec(spatialReference);
297
- if (match) {
298
- return match[1];
299
- }
300
- }
301
- return spatialReference;
302
- }
303
-
304
- /** Builds a schema from ArcGIS FeatureServer metadata fields. */
305
- function parseArcGISFeatureServerSchema(json: any): Schema {
306
- const fields = Array.isArray(json.fields)
307
- ? json.fields.map((field: any) => ({
308
- name: field.name,
309
- type: getSchemaTypeFromArcGISFieldType(field.type),
310
- nullable: field.nullable
311
- }))
312
- : [];
313
-
314
- return {metadata: {}, fields};
315
- }
316
-
317
- /** Maps common ArcGIS field types to loaders.gl schema type strings. */
318
- function getSchemaTypeFromArcGISFieldType(type: string): DataType {
319
- switch (type) {
320
- case 'esriFieldTypeDouble':
321
- return 'float64';
322
- case 'esriFieldTypeSingle':
323
- return 'float32';
324
- case 'esriFieldTypeInteger':
325
- case 'esriFieldTypeSmallInteger':
326
- case 'esriFieldTypeOID':
327
- return 'int32';
328
- case 'esriFieldTypeDate':
329
- return 'timestamp-millisecond';
330
- default:
331
- return 'utf8';
332
- }
333
- }
334
-
335
- /** Parses a GeoJSON FeatureCollection into the loaders.gl GeoJSON table shape. */
336
- function parseGeoJSONTable(json: any): GeoJSONTable {
337
- if (json?.type === 'FeatureCollection' && Array.isArray(json.features)) {
338
- return {
339
- shape: 'geojson-table',
340
- type: 'FeatureCollection',
341
- features: json.features
342
- };
343
- }
344
-
345
- throw new Error('ArcGIS FeatureServer query did not return a GeoJSON FeatureCollection');
346
- }
@@ -1,242 +0,0 @@
1
- // loaders.gl
2
- // SPDX-License-Identifier: MIT
3
- // Copyright (c) vis.gl contributors
4
-
5
- import type {ImageType} from '@loaders.gl/images';
6
- import {ImageLoader} from '@loaders.gl/images';
7
- import type {
8
- CoreAPI,
9
- SourceLoader,
10
- DataSourceOptions,
11
- ImageSource,
12
- ImageSourceMetadata,
13
- GetImageParameters
14
- } from '@loaders.gl/loader-utils';
15
- import {DataSource} from '@loaders.gl/loader-utils';
16
- import type {LERCData} from '@loaders.gl/lerc';
17
- import {LERCLoader} from '@loaders.gl/lerc';
18
- import {buildArcGISResourceURL} from './arcgis-url-utils';
19
-
20
- /** Options for the ArcGIS ImageServer source. */
21
- export type ArcGISImageSourceLoaderProps = DataSourceOptions & {
22
- 'arcgis-image-server'?: {
23
- /** Default ArcGIS exportImage request parameters. */
24
- exportImageParameters?: Partial<ArcGISExportImageParameters>;
25
- };
26
- };
27
-
28
- /** Parameters for ArcGIS ImageServer exportImage requests. */
29
- export type ArcGISExportImageParameters = {
30
- /** Bounding box of the requested image. */
31
- bbox: [number, number, number, number];
32
- /** Spatial reference of the supplied bbox. */
33
- bboxSR?: string | number;
34
- /** Pixel width of returned image. */
35
- width: number;
36
- /** Pixel height of returned image. */
37
- height: number;
38
- /** Spatial reference of the returned image. */
39
- imageSR?: string | number;
40
- /** Requested image format. */
41
- format?: 'jpgpng' | 'png' | 'png8' | 'png24' | 'jpg' | 'bmp' | 'gif' | 'tiff' | 'png32' | 'lerc';
42
- /** Requested pixel type. */
43
- pixelType?: 'U1' | 'U2' | 'U4' | 'U8' | 'S8' | 'U16' | 'S16' | 'U32' | 'S32' | 'F32' | 'F64';
44
- /** NoData pixel value. */
45
- noData?: string | number;
46
- /** NoData interpretation mode. */
47
- noDataInterpretation?: 'esriNoDataMatchAny' | 'esriNoDataMatchAll';
48
- /** Resampling interpolation. */
49
- interpolation?: string;
50
- /** Compression type. */
51
- compression?: string;
52
- /** Compression quality. */
53
- compressionQuality?: number;
54
- /** Band ids to export. */
55
- bandIds?: string | number[];
56
- /** Mosaic rule JSON string or object. */
57
- mosaicRule?: string | Record<string, unknown>;
58
- /** Rendering rule JSON string or object. */
59
- renderingRule?: string | Record<string, unknown>;
60
- /** ArcGIS response format. */
61
- f?: 'image' | 'json' | 'pjson';
62
- };
63
-
64
- export const ArcGISImageServerSourceLoader = {
65
- dataType: null as unknown as ArcGISImageSource,
66
- batchType: null as never,
67
- name: 'ArcGISImageServer',
68
- id: 'arcgis-image-server',
69
- module: 'services',
70
- version: '0.0.0',
71
- extensions: [],
72
- mimeTypes: [],
73
- type: 'arcgis-image-server',
74
- fromUrl: true,
75
- fromBlob: false,
76
-
77
- options: {
78
- 'arcgis-image-server': {
79
- // TODO - add options here
80
- }
81
- },
82
-
83
- defaultOptions: {
84
- 'arcgis-image-server': {
85
- // TODO - add options here
86
- }
87
- },
88
-
89
- testURL: (url: string): boolean => url.toLowerCase().includes('imageserver'),
90
- createDataSource: (
91
- url: string,
92
- props: ArcGISImageSourceLoaderProps,
93
- coreApi?: CoreAPI
94
- ): ArcGISImageSource => new ArcGISImageSource(url, props, coreApi)
95
- } as const satisfies SourceLoader<ArcGISImageSource>;
96
-
97
- /**
98
- * ArcGIS ImageServer
99
- * Note - exports a big API, that could be exposed here if there is a use case
100
- * @see https://developers.arcgis.com/rest/services-reference/enterprise/image-service.htm
101
- */
102
- export class ArcGISImageSource
103
- extends DataSource<string, ArcGISImageSourceLoaderProps>
104
- implements ImageSource
105
- {
106
- constructor(url: string, props: ArcGISImageSourceLoaderProps, coreApi?: CoreAPI) {
107
- super(url, props, ArcGISImageServerSourceLoader.defaultOptions, coreApi);
108
- }
109
-
110
- /** Returns normalized ImageSource metadata. */
111
- async getMetadata(): Promise<ImageSourceMetadata> {
112
- return normalizeArcGISImageServerMetadata(await this.metadata());
113
- }
114
-
115
- /** Requests an image from generic ImageSource parameters. */
116
- async getImage(parameters: GetImageParameters): Promise<ImageType> {
117
- const {boundingBox, width, height, crs, format, signal} = parameters;
118
- const spatialReference = normalizeArcGISSpatialReference(crs) || '4326';
119
- const imageParameters: ArcGISExportImageParameters = {
120
- bbox: [...boundingBox[0], ...boundingBox[1]],
121
- bboxSR: spatialReference,
122
- imageSR: spatialReference,
123
- width,
124
- height,
125
- format: format === 'image/png' ? 'png' : undefined
126
- };
127
- return await this.exportImage(imageParameters, signal);
128
- }
129
-
130
- /** Requests the ArcGIS ImageServer metadata document. */
131
- async metadata(): Promise<unknown> {
132
- const response = await this.fetch(this.metadataURL());
133
- await this.checkResponse(response);
134
- return await response.json();
135
- }
136
-
137
- /** Requests an exported image from the ArcGIS ImageServer endpoint. */
138
- async exportImage(
139
- options: ArcGISExportImageParameters,
140
- signal?: AbortSignal
141
- ): Promise<ImageType> {
142
- const response = await this.fetch(this.exportImageURL(options), signal ? {signal} : undefined);
143
- await this.checkResponse(response);
144
- const arrayBuffer = await response.arrayBuffer();
145
- return (await this.coreApi.parse(arrayBuffer, ImageLoader, this.loadOptions)) as ImageType;
146
- }
147
-
148
- /** Requests an analytical LERC raster from the ArcGIS ImageServer endpoint. */
149
- async exportRaster(
150
- options: ArcGISExportImageParameters,
151
- signal?: AbortSignal
152
- ): Promise<LERCData> {
153
- const response = await this.fetch(
154
- this.exportImageURL({...options, format: 'lerc'}),
155
- signal ? {signal} : undefined
156
- );
157
- await this.checkResponse(response);
158
- return (await this.coreApi.parse(
159
- await response.arrayBuffer(),
160
- LERCLoader,
161
- this.loadOptions
162
- )) as LERCData;
163
- }
164
-
165
- /** Builds a metadata URL for the ArcGIS ImageServer endpoint. */
166
- metadataURL(options?: {parameters?: Record<string, unknown>}): string {
167
- return this.getUrl('', {f: 'pjson', ...options?.parameters});
168
- }
169
-
170
- /** Builds an exportImage URL for the ArcGIS ImageServer endpoint. */
171
- exportImageURL(options: ArcGISExportImageParameters): string {
172
- const defaultParameters = this.options['arcgis-image-server']?.exportImageParameters || {};
173
- const {width, height, ...parameters} = {...defaultParameters, ...options};
174
- return this.getUrl('exportImage', {
175
- ...parameters,
176
- bbox: parameters.bbox,
177
- size: [width, height],
178
- f: parameters.f || 'image'
179
- });
180
- }
181
-
182
- /** Builds an ArcGIS ImageServer URL. */
183
- protected getUrl(
184
- path: string,
185
- options: Record<string, unknown>,
186
- extra?: Record<string, unknown>
187
- ): string {
188
- return buildArcGISResourceURL(this.url, path, {...options, ...extra});
189
- }
190
-
191
- /** Checks an ArcGIS ImageServer response. */
192
- protected async checkResponse(response: Response): Promise<void> {
193
- if (!response.ok) {
194
- throw new Error(
195
- response.statusText || `ArcGIS ImageServer request failed: ${response.status}`
196
- );
197
- }
198
- }
199
- }
200
-
201
- /** Normalizes EPSG-prefixed CRS strings to ArcGIS WKID values. */
202
- function normalizeArcGISSpatialReference(
203
- spatialReference: string | number | undefined
204
- ): string | number | undefined {
205
- if (typeof spatialReference === 'string') {
206
- const match = /^EPSG:(\d+)$/i.exec(spatialReference);
207
- if (match) {
208
- return match[1];
209
- }
210
- }
211
- return spatialReference;
212
- }
213
-
214
- /** Normalizes ArcGIS ImageServer metadata to the generic ImageSource metadata shape. */
215
- function normalizeArcGISImageServerMetadata(metadata: unknown): ImageSourceMetadata {
216
- const arcgisMetadata = metadata as any;
217
- const extent = arcgisMetadata.fullExtent || arcgisMetadata.extent;
218
- const spatialReference = arcgisMetadata.spatialReference || extent?.spatialReference;
219
- const wellKnownIdentifier = spatialReference?.latestWkid || spatialReference?.wkid;
220
- const boundingBox =
221
- extent && [extent.xmin, extent.ymin, extent.xmax, extent.ymax].every(Number.isFinite)
222
- ? ([
223
- [extent.xmin, extent.ymin],
224
- [extent.xmax, extent.ymax]
225
- ] as [[number, number], [number, number]])
226
- : undefined;
227
- const name = arcgisMetadata.name || arcgisMetadata.serviceDescription || '';
228
- return {
229
- name,
230
- title: name,
231
- abstract: arcgisMetadata.description || arcgisMetadata.serviceDescription || '',
232
- keywords: Array.isArray(arcgisMetadata.keywords) ? arcgisMetadata.keywords : [],
233
- layers: [
234
- {
235
- name,
236
- title: name,
237
- crs: wellKnownIdentifier ? [`EPSG:${wellKnownIdentifier}`] : undefined,
238
- boundingBox
239
- }
240
- ]
241
- };
242
- }