@loaders.gl/services 5.0.0-alpha.5 → 5.0.0-alpha.6

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/dist/index.cjs CHANGED
@@ -919,6 +919,78 @@ var init_convert_geometry_to_wkb = __esm({
919
919
  }
920
920
  });
921
921
 
922
+ // ../gis/src/lib/geometry-converters/wkb/convert-geometry-to-wkt.ts
923
+ function convertGeometryToWKT(geometry, options) {
924
+ const dimension = getWKTDimension(geometry, options);
925
+ if (geometry.type === "GeometryCollection" && !(options == null ? void 0 : options.dimension) && !(options == null ? void 0 : options.hasZ) && !(options == null ? void 0 : options.hasM) && hasMixedChildDimensions(geometry)) {
926
+ if (geometry.geometries.length === 0) return "GEOMETRYCOLLECTION EMPTY";
927
+ return `GEOMETRYCOLLECTION (${geometry.geometries.map((child) => convertGeometryToWKT(child)).join(", ")})`;
928
+ }
929
+ return (0, import_wkb.formatWKT)(normalizeGeometryDimension(geometry, dimension), dimension);
930
+ }
931
+ function normalizeGeometryDimension(geometry, dimension) {
932
+ if (geometry.type === "GeometryCollection") {
933
+ return {
934
+ type: "GeometryCollection",
935
+ geometries: geometry.geometries.map((child) => normalizeGeometryDimension(child, dimension))
936
+ };
937
+ }
938
+ return {
939
+ ...geometry,
940
+ coordinates: normalizeCoordinateNesting(geometry.coordinates, getDimensionSize(dimension))
941
+ };
942
+ }
943
+ function normalizeCoordinateNesting(value, dimensionSize) {
944
+ if (value.length === 0) return value;
945
+ if (typeof value[0] === "number") {
946
+ const coordinate = value.slice(0, dimensionSize);
947
+ while (coordinate.length < dimensionSize) coordinate.push(0);
948
+ return coordinate;
949
+ }
950
+ return value.map((child) => normalizeCoordinateNesting(child, dimensionSize));
951
+ }
952
+ function hasMixedChildDimensions(geometry) {
953
+ const dimensions = geometry.geometries.map((child) => getCoordinateDimension(child));
954
+ return dimensions.some((dimension) => dimension !== dimensions[0]);
955
+ }
956
+ function getWKTDimension(geometry, options) {
957
+ if (options == null ? void 0 : options.dimension) return options.dimension;
958
+ if ((options == null ? void 0 : options.hasZ) && (options == null ? void 0 : options.hasM)) return "xyzm";
959
+ if (options == null ? void 0 : options.hasZ) return "xyz";
960
+ if (options == null ? void 0 : options.hasM) return "xym";
961
+ const declaredDimension = geometry.__geoarrowDimension;
962
+ if (declaredDimension) return declaredDimension;
963
+ return getCoordinateDimension(geometry);
964
+ }
965
+ function getCoordinateDimension(geometry) {
966
+ const declaredDimension = geometry.__geoarrowDimension;
967
+ if (declaredDimension) return declaredDimension;
968
+ if (geometry.type === "GeometryCollection") {
969
+ const childDimensions = geometry.geometries.map(getCoordinateDimension);
970
+ return childDimensions.length > 0 && childDimensions.every((dimension) => dimension === childDimensions[0]) ? childDimensions[0] : "xy";
971
+ }
972
+ const coordinate = getFirstCoordinate(geometry);
973
+ return coordinate && coordinate.length >= 4 ? "xyzm" : coordinate && coordinate.length >= 3 ? "xyz" : "xy";
974
+ }
975
+ function getDimensionSize(dimension) {
976
+ return dimension === "xy" ? 2 : dimension === "xyzm" ? 4 : 3;
977
+ }
978
+ function getFirstCoordinate(geometry) {
979
+ if (geometry.type === "Point") return geometry.coordinates;
980
+ if (geometry.type === "GeometryCollection") return null;
981
+ const coordinates = geometry.coordinates;
982
+ let value = coordinates;
983
+ while (Array.isArray(value) && Array.isArray(value[0])) value = value[0];
984
+ return Array.isArray(value) ? value : null;
985
+ }
986
+ var import_wkb;
987
+ var init_convert_geometry_to_wkt = __esm({
988
+ "../gis/src/lib/geometry-converters/wkb/convert-geometry-to-wkt.ts"() {
989
+ "use strict";
990
+ import_wkb = require("@math.gl/wkb");
991
+ }
992
+ });
993
+
922
994
  // ../schema/src/metadata.ts
923
995
  function getMetadataValue(metadata, key) {
924
996
  return metadata instanceof Map ? metadata.get(key) || null : metadata[key] || null;
@@ -2073,32 +2145,956 @@ var init_src2 = __esm({
2073
2145
  }
2074
2146
  });
2075
2147
 
2076
- // ../gis/src/lib/geoarrow/feature-collection-to-arrow.ts
2077
- function convertFeaturesToWKBArrowTable(features) {
2078
- const propertyRows = features.map((feature) => normalizeProperties(feature.properties));
2079
- const propertySchema = getPropertySchema(propertyRows);
2080
- const schema = buildFeatureArrowSchema(propertySchema, features);
2081
- const arrowTableBuilder = new ArrowTableBuilder(schema);
2082
- for (let featureIndex = 0; featureIndex < features.length; featureIndex++) {
2083
- arrowTableBuilder.addObjectRow({
2084
- ...propertyRows[featureIndex],
2085
- [GEOMETRY_COLUMN_NAME]: encodeWKBGeometryValue(features[featureIndex].geometry)
2148
+ // ../gis/src/lib/geoarrow/geoarrow-builder.ts
2149
+ function makePrimitiveData(values) {
2150
+ return arrow6.makeData({ type: new arrow6.Float64(), data: values });
2151
+ }
2152
+ function getBoxFieldNames(dimension) {
2153
+ const minimumNames = dimension === "xy" ? ["xmin", "ymin"] : dimension === "xyz" ? ["xmin", "ymin", "zmin"] : dimension === "xym" ? ["xmin", "ymin", "mmin"] : ["xmin", "ymin", "zmin", "mmin"];
2154
+ const maximumNames = dimension === "xy" ? ["xmax", "ymax"] : dimension === "xyz" ? ["xmax", "ymax", "zmax"] : dimension === "xym" ? ["xmax", "ymax", "mmax"] : ["xmax", "ymax", "zmax", "mmax"];
2155
+ return [...minimumNames, ...maximumNames];
2156
+ }
2157
+ function getCoordinateSize2(dimension) {
2158
+ return dimension === "xy" ? 2 : dimension === "xyzm" ? 4 : 3;
2159
+ }
2160
+ function makeCoordinateData(values, dimension, coordinateLayout) {
2161
+ if (coordinateLayout === "separated") {
2162
+ const coordinateBuffers = values;
2163
+ const coordinateNames = getCoordinateNames(dimension);
2164
+ return arrow6.makeData({
2165
+ type: new arrow6.Struct(
2166
+ coordinateNames.map((name) => new arrow6.Field(name, new arrow6.Float64(), false))
2167
+ ),
2168
+ children: coordinateNames.map((name) => makePrimitiveData(coordinateBuffers[name]))
2086
2169
  });
2087
2170
  }
2171
+ return arrow6.makeData({
2172
+ type: new arrow6.FixedSizeList(
2173
+ getCoordinateSize2(dimension),
2174
+ new arrow6.Field("xy", new arrow6.Float64(), false)
2175
+ ),
2176
+ child: makePrimitiveData(values)
2177
+ });
2178
+ }
2179
+ function makeBoxData(values, dimension) {
2180
+ const names = getBoxFieldNames(dimension);
2181
+ const children = names.map((name, index) => {
2182
+ if (values instanceof Float64Array) {
2183
+ const boxSize = names.length;
2184
+ return makePrimitiveData(
2185
+ Float64Array.from(
2186
+ { length: values.length / boxSize },
2187
+ (_, rowIndex) => values[rowIndex * boxSize + index]
2188
+ )
2189
+ );
2190
+ }
2191
+ return makePrimitiveData(values[name]);
2192
+ });
2193
+ return arrow6.makeData({
2194
+ type: new arrow6.Struct(names.map((name) => new arrow6.Field(name, new arrow6.Float64(), false))),
2195
+ children
2196
+ });
2197
+ }
2198
+ function makeListData(child, offsets, fieldName, offsetType) {
2199
+ return arrow6.makeData({
2200
+ type: offsetType === "int64" ? new arrow6.LargeList(new arrow6.Field(fieldName, child.type, false)) : new arrow6.List(new arrow6.Field(fieldName, child.type, false)),
2201
+ valueOffsets: offsets,
2202
+ child
2203
+ });
2204
+ }
2205
+ function makeCoordinateBuffers(coordinateCount, dimension, coordinateLayout) {
2206
+ if (coordinateLayout === "interleaved") {
2207
+ return new Float64Array(coordinateCount * getCoordinateSize2(dimension));
2208
+ }
2209
+ const coordinateNames = getCoordinateNames(dimension);
2210
+ const buffers = {
2211
+ x: new Float64Array(coordinateCount),
2212
+ y: new Float64Array(coordinateCount)
2213
+ };
2214
+ for (const name of coordinateNames.slice(2)) buffers[name] = new Float64Array(coordinateCount);
2215
+ return buffers;
2216
+ }
2217
+ function makeBoxBuffers(boxCount, dimension, coordinateLayout) {
2218
+ const names = getBoxFieldNames(dimension);
2219
+ if (coordinateLayout === "interleaved") {
2220
+ return new Float64Array(boxCount * names.length);
2221
+ }
2222
+ const buffers = {};
2223
+ for (const name of names) {
2224
+ buffers[name] = new Float64Array(boxCount);
2225
+ }
2226
+ return buffers;
2227
+ }
2228
+ function getBoxValues(dimension, xmin, ymin, xmax, ymax, zmin, zmax, mmin, mmax) {
2229
+ switch (dimension) {
2230
+ case "xy":
2231
+ return [xmin, ymin, xmax, ymax];
2232
+ case "xyz":
2233
+ return [xmin, ymin, zmin ?? Number.NaN, xmax, ymax, zmax ?? Number.NaN];
2234
+ case "xym":
2235
+ return [xmin, ymin, mmin ?? Number.NaN, xmax, ymax, mmax ?? Number.NaN];
2236
+ case "xyzm":
2237
+ return [
2238
+ xmin,
2239
+ ymin,
2240
+ zmin ?? Number.NaN,
2241
+ mmin ?? Number.NaN,
2242
+ xmax,
2243
+ ymax,
2244
+ zmax ?? Number.NaN,
2245
+ mmax ?? Number.NaN
2246
+ ];
2247
+ }
2248
+ }
2249
+ function getCoordinateNames(dimension) {
2250
+ switch (dimension) {
2251
+ case "xy":
2252
+ return ["x", "y"];
2253
+ case "xyz":
2254
+ return ["x", "y", "z"];
2255
+ case "xym":
2256
+ return ["x", "y", "m"];
2257
+ case "xyzm":
2258
+ return ["x", "y", "z", "m"];
2259
+ }
2260
+ }
2261
+ function withNulls(data, geometryArray) {
2262
+ return new arrow6.Data(
2263
+ data.type,
2264
+ 0,
2265
+ geometryArray.length,
2266
+ geometryArray.nullCount,
2267
+ [
2268
+ data.valueOffsets,
2269
+ data.values,
2270
+ geometryArray.nullCount > 0 ? geometryArray.nullBitmap : void 0
2271
+ ],
2272
+ data.children
2273
+ );
2274
+ }
2275
+ var arrow6, GeoArrowBuilder;
2276
+ var init_geoarrow_builder = __esm({
2277
+ "../gis/src/lib/geoarrow/geoarrow-builder.ts"() {
2278
+ "use strict";
2279
+ arrow6 = __toESM(require("apache-arrow"), 1);
2280
+ GeoArrowBuilder = class _GeoArrowBuilder {
2281
+ /** GeoArrow extension encoding emitted by this builder. */
2282
+ encoding;
2283
+ /** Whether coordinate tuples include Z. */
2284
+ hasZ;
2285
+ /** Whether coordinate tuples include M. */
2286
+ hasM;
2287
+ /** Exact coordinate dimension emitted by this builder. */
2288
+ dimension;
2289
+ state;
2290
+ /** Creates a GeoArrow builder in measure or write mode. */
2291
+ constructor(options) {
2292
+ this.encoding = options.encoding;
2293
+ this.dimension = options.dimension || (options.hasZ && options.hasM ? "xyzm" : options.hasZ ? "xyz" : options.hasM ? "xym" : "xy");
2294
+ this.hasZ = this.dimension === "xyz" || this.dimension === "xyzm";
2295
+ this.hasM = this.dimension === "xym" || this.dimension === "xyzm";
2296
+ const coordinateLayout = options.coordinateLayout || "interleaved";
2297
+ const offsetType = options.offsetType || "int32";
2298
+ this.state = {
2299
+ mode: options.mode,
2300
+ encoding: options.encoding,
2301
+ coordinateSize: getCoordinateSize2(this.dimension),
2302
+ coordinateLayout,
2303
+ offsetType,
2304
+ transform: options.transform,
2305
+ length: 0,
2306
+ nullCount: 0,
2307
+ coordinateCount: 0,
2308
+ geometryChildCount: 0,
2309
+ partChildCount: 0,
2310
+ geometryOffsetCount: 1,
2311
+ partOffsetCount: 1,
2312
+ ringOffsetCount: 1,
2313
+ target: options.mode === "write" ? options.target : void 0
2314
+ };
2315
+ this.initializeOffsets();
2316
+ }
2317
+ /** Emits one null geometry row. */
2318
+ writeNullGeometry() {
2319
+ this.state.length++;
2320
+ this.state.nullCount++;
2321
+ if (this.encoding !== "geoarrow.point" && this.encoding !== "geoarrow.box") {
2322
+ this.writeGeometryOffset();
2323
+ }
2324
+ if (this.encoding === "geoarrow.point") this.state.coordinateCount++;
2325
+ }
2326
+ /** Begins one top-level geometry. */
2327
+ beginGeometry(_type, _count) {
2328
+ this.setValid(this.state.length);
2329
+ this.state.length++;
2330
+ }
2331
+ /** Begins one point geometry or nested point. */
2332
+ beginPoint() {
2333
+ if (this.encoding === "geoarrow.point") this.beginGeometry();
2334
+ }
2335
+ /** Begins one axis-aligned GeoArrow box row. */
2336
+ beginBox() {
2337
+ if (this.encoding !== "geoarrow.box") {
2338
+ throw new Error(`Cannot write Box into ${this.encoding}`);
2339
+ }
2340
+ this.beginGeometry();
2341
+ }
2342
+ /** Writes one axis-aligned box in canonical minimum-then-maximum ordinate order. */
2343
+ writeBox(xmin, ymin, xmax, ymax, zmin, zmax, mmin, mmax) {
2344
+ if (this.encoding !== "geoarrow.box") {
2345
+ throw new Error(`Cannot write Box into ${this.encoding}`);
2346
+ }
2347
+ const coordinateIndex = this.state.coordinateCount;
2348
+ const values = getBoxValues(this.dimension, xmin, ymin, xmax, ymax, zmin, zmax, mmin, mmax);
2349
+ if (this.state.mode === "write") {
2350
+ this.writeBoxValues(this.getTarget().coordinates, coordinateIndex, values);
2351
+ }
2352
+ this.state.coordinateCount++;
2353
+ }
2354
+ /** Begins one line string geometry or nested line string. */
2355
+ beginLineString(pointCount) {
2356
+ if (this.encoding === "geoarrow.linestring") {
2357
+ this.beginGeometry();
2358
+ this.writeGeometryOffset(pointCount);
2359
+ return;
2360
+ }
2361
+ if (this.encoding === "geoarrow.multilinestring") {
2362
+ this.writePartOffset(pointCount);
2363
+ return;
2364
+ }
2365
+ throw new Error(`Cannot write LineString into ${this.encoding}`);
2366
+ }
2367
+ /** Begins one polygon geometry or nested polygon. */
2368
+ beginPolygon(ringCount) {
2369
+ if (this.encoding === "geoarrow.polygon") {
2370
+ this.beginGeometry();
2371
+ this.writeGeometryOffset(ringCount);
2372
+ return;
2373
+ }
2374
+ if (this.encoding === "geoarrow.multipolygon") {
2375
+ this.writePartOffset(ringCount);
2376
+ return;
2377
+ }
2378
+ throw new Error(`Cannot write Polygon into ${this.encoding}`);
2379
+ }
2380
+ /** Begins one polygon linear ring. */
2381
+ beginLinearRing(pointCount) {
2382
+ if (this.encoding === "geoarrow.polygon") {
2383
+ this.writePartOffset(pointCount);
2384
+ return;
2385
+ }
2386
+ if (this.encoding === "geoarrow.multipolygon") {
2387
+ this.writeRingOffset(pointCount);
2388
+ return;
2389
+ }
2390
+ throw new Error(`Cannot write LinearRing into ${this.encoding}`);
2391
+ }
2392
+ /** Begins one multipoint geometry. */
2393
+ beginMultiPoint(pointCount) {
2394
+ if (this.encoding !== "geoarrow.multipoint") {
2395
+ throw new Error(`Cannot write MultiPoint into ${this.encoding}`);
2396
+ }
2397
+ this.beginGeometry();
2398
+ this.writeGeometryOffset(pointCount);
2399
+ }
2400
+ /** Begins one multilinestring geometry. */
2401
+ beginMultiLineString(lineCount) {
2402
+ if (this.encoding !== "geoarrow.multilinestring") {
2403
+ throw new Error(`Cannot write MultiLineString into ${this.encoding}`);
2404
+ }
2405
+ this.beginGeometry();
2406
+ this.writeGeometryOffset(lineCount);
2407
+ }
2408
+ /** Begins one multipolygon geometry. */
2409
+ beginMultiPolygon(polygonCount) {
2410
+ if (this.encoding !== "geoarrow.multipolygon") {
2411
+ throw new Error(`Cannot write MultiPolygon into ${this.encoding}`);
2412
+ }
2413
+ this.beginGeometry();
2414
+ this.writeGeometryOffset(polygonCount);
2415
+ }
2416
+ /** Writes one coordinate tuple. The third ordinate is M for an XYM builder. */
2417
+ writeCoordinate(x, y, z2, m) {
2418
+ const coordinateIndex = this.state.coordinateCount;
2419
+ if (this.state.mode === "write") {
2420
+ const target = this.getTarget();
2421
+ const coordinate = this.getCoordinateValuesForWrite(x, y, z2, m);
2422
+ const transformedCoordinate = this.state.transform ? this.state.transform(coordinate) : coordinate;
2423
+ this.writeCoordinateValues(
2424
+ target.coordinates,
2425
+ coordinateIndex,
2426
+ transformedCoordinate,
2427
+ coordinate
2428
+ );
2429
+ }
2430
+ this.state.coordinateCount++;
2431
+ }
2432
+ /** Completes the current geometry array and returns its row count. */
2433
+ finishGeometry() {
2434
+ return this.state.length;
2435
+ }
2436
+ /** Returns current measured or written array metadata. */
2437
+ getGeometryArray() {
2438
+ return {
2439
+ encoding: this.encoding,
2440
+ coordinateSize: this.state.coordinateSize,
2441
+ dimension: this.dimension,
2442
+ coordinateLayout: this.state.coordinateLayout,
2443
+ offsetType: this.state.offsetType,
2444
+ length: this.state.length,
2445
+ nullCount: this.state.nullCount,
2446
+ nullBitmap: this.getNullBitmap(),
2447
+ coordinates: this.getCoordinateValues(),
2448
+ geometryOffsets: this.getGeometryOffsets(),
2449
+ partOffsets: this.getPartOffsets(),
2450
+ ringOffsets: this.getRingOffsets()
2451
+ };
2452
+ }
2453
+ /** Measures geometry callbacks and returns allocated offsets. */
2454
+ static measureGeometryArray(writers, options) {
2455
+ const builder = new _GeoArrowBuilder({ mode: "measure", ...options });
2456
+ for (const writer of writers) writer ? writer(builder) : builder.writeNullGeometry();
2457
+ builder.finishGeometry();
2458
+ return builder.getGeometryArray();
2459
+ }
2460
+ /** Writes geometry callbacks into a measured target. */
2461
+ static writeGeometryArray(writers, measured, options) {
2462
+ const builder = new _GeoArrowBuilder({ mode: "write", target: measured, ...options });
2463
+ for (const writer of writers) writer ? writer(builder) : builder.writeNullGeometry();
2464
+ builder.finishGeometry();
2465
+ return builder.getGeometryArray();
2466
+ }
2467
+ /** Builds GeoArrow buffers from callbacks in two passes. */
2468
+ static buildGeometryArray(writers, options) {
2469
+ const measured = _GeoArrowBuilder.measureGeometryArray(writers, options);
2470
+ return _GeoArrowBuilder.writeGeometryArray(writers, measured, options);
2471
+ }
2472
+ /** Wraps GeoArrow buffers in an Apache Arrow Data instance. */
2473
+ static makeGeometryData(geometryArray) {
2474
+ if (geometryArray.encoding === "geoarrow.box") {
2475
+ return withNulls(
2476
+ makeBoxData(geometryArray.coordinates, geometryArray.dimension),
2477
+ geometryArray
2478
+ );
2479
+ }
2480
+ const coordinateData = makeCoordinateData(
2481
+ geometryArray.coordinates,
2482
+ geometryArray.dimension,
2483
+ geometryArray.coordinateLayout
2484
+ );
2485
+ let data = coordinateData;
2486
+ switch (geometryArray.encoding) {
2487
+ case "geoarrow.point":
2488
+ return withNulls(data, geometryArray);
2489
+ case "geoarrow.linestring":
2490
+ case "geoarrow.multipoint":
2491
+ data = makeListData(
2492
+ coordinateData,
2493
+ geometryArray.geometryOffsets,
2494
+ "vertices",
2495
+ geometryArray.offsetType
2496
+ );
2497
+ return withNulls(data, geometryArray);
2498
+ case "geoarrow.polygon":
2499
+ case "geoarrow.multilinestring":
2500
+ data = makeListData(
2501
+ coordinateData,
2502
+ geometryArray.partOffsets,
2503
+ "vertices",
2504
+ geometryArray.offsetType
2505
+ );
2506
+ data = makeListData(
2507
+ data,
2508
+ geometryArray.geometryOffsets,
2509
+ "rings",
2510
+ geometryArray.offsetType
2511
+ );
2512
+ return withNulls(data, geometryArray);
2513
+ case "geoarrow.multipolygon":
2514
+ data = makeListData(
2515
+ coordinateData,
2516
+ geometryArray.ringOffsets,
2517
+ "vertices",
2518
+ geometryArray.offsetType
2519
+ );
2520
+ data = makeListData(data, geometryArray.partOffsets, "rings", geometryArray.offsetType);
2521
+ data = makeListData(
2522
+ data,
2523
+ geometryArray.geometryOffsets,
2524
+ "polygons",
2525
+ geometryArray.offsetType
2526
+ );
2527
+ return withNulls(data, geometryArray);
2528
+ default:
2529
+ throw new Error(`Unsupported GeoArrow encoding ${geometryArray.encoding}`);
2530
+ }
2531
+ }
2532
+ initializeOffsets() {
2533
+ if (this.state.mode !== "measure") return;
2534
+ const target = {
2535
+ nullBitmap: new Uint8Array(0),
2536
+ coordinates: makeCoordinateBuffers(0, this.dimension, this.state.coordinateLayout)
2537
+ };
2538
+ if (this.encoding !== "geoarrow.point" && this.encoding !== "geoarrow.box") {
2539
+ target.geometryOffsets = this.makeOffsets(1);
2540
+ }
2541
+ if (this.encoding === "geoarrow.polygon" || this.encoding === "geoarrow.multilinestring" || this.encoding === "geoarrow.multipolygon") {
2542
+ target.partOffsets = this.makeOffsets(1);
2543
+ }
2544
+ if (this.encoding === "geoarrow.multipolygon") target.ringOffsets = this.makeOffsets(1);
2545
+ this.state.target = target;
2546
+ }
2547
+ getCoordinateValuesForWrite(x, y, z2, m) {
2548
+ if (this.dimension === "xy") return [x, y];
2549
+ if (this.dimension === "xyz") return [x, y, z2 ?? Number.NaN];
2550
+ if (this.dimension === "xym") return [x, y, m ?? z2 ?? Number.NaN];
2551
+ return [x, y, z2 ?? Number.NaN, m ?? Number.NaN];
2552
+ }
2553
+ writeGeometryOffset(childCount = 0) {
2554
+ if (this.encoding === "geoarrow.point") return;
2555
+ this.state.geometryChildCount += childCount;
2556
+ this.appendOffset("geometryOffsets", this.state.geometryChildCount);
2557
+ }
2558
+ writePartOffset(childCount = 0) {
2559
+ this.state.partChildCount += childCount;
2560
+ this.appendOffset("partOffsets", this.state.partChildCount);
2561
+ }
2562
+ writeRingOffset(childCount = 0) {
2563
+ this.appendOffset("ringOffsets", this.state.coordinateCount + childCount);
2564
+ }
2565
+ appendOffset(name, value) {
2566
+ const target = this.getTarget();
2567
+ const offsets = target[name];
2568
+ if (!offsets) return;
2569
+ if (this.state.mode === "measure") {
2570
+ this.incrementOffsetCount(name);
2571
+ return;
2572
+ }
2573
+ const index = this.getOffsetCount(name);
2574
+ if (index >= offsets.length) throw new Error(`GeoArrowBuilder target ${name} overflow`);
2575
+ offsets[index] = offsets instanceof BigInt64Array ? BigInt(value) : value;
2576
+ this.incrementOffsetCount(name);
2577
+ }
2578
+ getOffsetCount(name) {
2579
+ switch (name) {
2580
+ case "geometryOffsets":
2581
+ return this.state.geometryOffsetCount;
2582
+ case "partOffsets":
2583
+ return this.state.partOffsetCount;
2584
+ case "ringOffsets":
2585
+ return this.state.ringOffsetCount;
2586
+ default:
2587
+ throw new Error(`Unexpected offset buffer ${name}`);
2588
+ }
2589
+ }
2590
+ incrementOffsetCount(name) {
2591
+ switch (name) {
2592
+ case "geometryOffsets":
2593
+ this.state.geometryOffsetCount++;
2594
+ return;
2595
+ case "partOffsets":
2596
+ this.state.partOffsetCount++;
2597
+ return;
2598
+ case "ringOffsets":
2599
+ this.state.ringOffsetCount++;
2600
+ return;
2601
+ default:
2602
+ throw new Error(`Unexpected offset buffer ${name}`);
2603
+ }
2604
+ }
2605
+ setValid(rowIndex) {
2606
+ if (this.state.mode !== "write") return;
2607
+ const bitmap = this.getTarget().nullBitmap;
2608
+ bitmap[rowIndex >> 3] |= 1 << (rowIndex & 7);
2609
+ }
2610
+ getTarget() {
2611
+ if (!this.state.target) throw new Error("GeoArrowBuilder target is not initialized");
2612
+ return this.state.target;
2613
+ }
2614
+ getNullBitmap() {
2615
+ return this.state.mode === "measure" ? new Uint8Array(Math.ceil(this.state.length / 8)) : this.getTarget().nullBitmap;
2616
+ }
2617
+ getCoordinateValues() {
2618
+ return this.state.mode === "measure" ? this.encoding === "geoarrow.box" ? makeBoxBuffers(this.state.coordinateCount, this.dimension, this.state.coordinateLayout) : makeCoordinateBuffers(
2619
+ this.state.coordinateCount,
2620
+ this.dimension,
2621
+ this.state.coordinateLayout
2622
+ ) : this.getTarget().coordinates;
2623
+ }
2624
+ getGeometryOffsets() {
2625
+ return this.state.mode === "measure" && this.encoding !== "geoarrow.point" && this.encoding !== "geoarrow.box" ? this.makeOffsets(this.state.geometryOffsetCount) : this.getTarget().geometryOffsets;
2626
+ }
2627
+ getPartOffsets() {
2628
+ return this.state.mode === "measure" && (this.encoding === "geoarrow.polygon" || this.encoding === "geoarrow.multilinestring" || this.encoding === "geoarrow.multipolygon") ? this.makeOffsets(this.state.partOffsetCount) : this.getTarget().partOffsets;
2629
+ }
2630
+ getRingOffsets() {
2631
+ return this.state.mode === "measure" && this.encoding === "geoarrow.multipolygon" ? this.makeOffsets(this.state.ringOffsetCount) : this.getTarget().ringOffsets;
2632
+ }
2633
+ makeOffsets(length) {
2634
+ return this.state.offsetType === "int64" ? new BigInt64Array(length) : new Int32Array(length);
2635
+ }
2636
+ writeCoordinateValues(coordinates, coordinateIndex, transformedCoordinate, originalCoordinate) {
2637
+ if (coordinates instanceof Float64Array) {
2638
+ if (coordinateIndex >= coordinates.length / this.state.coordinateSize) {
2639
+ throw new Error("GeoArrowBuilder target coordinate buffer overflow");
2640
+ }
2641
+ const valueOffset = coordinateIndex * this.state.coordinateSize;
2642
+ for (let dimensionIndex = 0; dimensionIndex < this.state.coordinateSize; dimensionIndex++) {
2643
+ coordinates[valueOffset + dimensionIndex] = transformedCoordinate[dimensionIndex] ?? originalCoordinate[dimensionIndex] ?? Number.NaN;
2644
+ }
2645
+ return;
2646
+ }
2647
+ const coordinateNames = getCoordinateNames(this.dimension);
2648
+ for (let dimensionIndex = 0; dimensionIndex < coordinateNames.length; dimensionIndex++) {
2649
+ const coordinateValues = coordinates[coordinateNames[dimensionIndex]];
2650
+ if (!coordinateValues || coordinateIndex >= coordinateValues.length) {
2651
+ throw new Error("GeoArrowBuilder target coordinate buffer overflow");
2652
+ }
2653
+ coordinateValues[coordinateIndex] = transformedCoordinate[dimensionIndex] ?? originalCoordinate[dimensionIndex] ?? Number.NaN;
2654
+ }
2655
+ }
2656
+ writeBoxValues(coordinates, coordinateIndex, values) {
2657
+ if (coordinates instanceof Float64Array) {
2658
+ const valueOffset = coordinateIndex * values.length;
2659
+ if (valueOffset + values.length > coordinates.length) {
2660
+ throw new Error("GeoArrowBuilder target box buffer overflow");
2661
+ }
2662
+ coordinates.set(values, valueOffset);
2663
+ return;
2664
+ }
2665
+ const boxCoordinates = coordinates;
2666
+ const names = getBoxFieldNames(this.dimension);
2667
+ for (let index = 0; index < names.length; index++) {
2668
+ const valuesBuffer = boxCoordinates[names[index]];
2669
+ if (!(valuesBuffer instanceof Float64Array) || coordinateIndex >= valuesBuffer.length) {
2670
+ throw new Error("GeoArrowBuilder target box buffer overflow");
2671
+ }
2672
+ valuesBuffer[coordinateIndex] = values[index];
2673
+ }
2674
+ }
2675
+ };
2676
+ }
2677
+ });
2678
+
2679
+ // ../gis/src/lib/table-converters/convert-geojson-to-geoarrow.ts
2680
+ function convertFeaturesToGeoArrowTable(features, options) {
2681
+ const preference = resolveGeoArrowEncodingPreference(options);
2682
+ if (preference === "geoarrow.geometry" || preference === "optimized") {
2683
+ return convertFeaturesToNativeGeoArrowTable(features, options, preference);
2684
+ }
2685
+ const rows = makeGeoArrowFeatureRows(features, options);
2686
+ const schema = makeGeoArrowFeatureSchema(features, options);
2687
+ const arrowTableBuilder = new ArrowTableBuilder(schema);
2688
+ for (const row of rows) {
2689
+ arrowTableBuilder.addObjectRow(row);
2690
+ }
2088
2691
  return arrowTableBuilder.finishTable();
2089
2692
  }
2090
- function buildFeatureArrowSchema(propertySchema, features) {
2091
- const geometryField = makeWKBGeometryField(GEOMETRY_COLUMN_NAME);
2693
+ function convertFeaturesToNativeGeoArrowTable(features, options, preference) {
2694
+ const geometries = features.map((feature) => feature.geometry || null);
2695
+ const dimension = getFeatureDimension(geometries);
2696
+ const encoding = preference === "geoarrow.geometry" ? preference : selectOptimizedEncoding(geometries);
2697
+ const geometryVector = encoding === "geoarrow.geometry" ? makeGeometryUnionVector(geometries, dimension) : makeNativeGeometryVector(geometries, encoding, dimension);
2698
+ const geometryColumnName = (options == null ? void 0 : options.geometryColumnName) || DEFAULT_GEOMETRY_COLUMN_NAME;
2699
+ const propertyRows = features.map((feature) => {
2700
+ const properties = normalizeProperties(feature.properties);
2701
+ assertNoGeometryPropertyCollision(properties, geometryColumnName);
2702
+ return properties;
2703
+ });
2704
+ const propertySchema = (options == null ? void 0 : options.propertySchema) || getPropertySchema(propertyRows);
2705
+ const schema = convertSchemaToArrow(propertySchema);
2706
+ const inferredGeometryColumnMetadata = {
2707
+ encoding,
2708
+ geometry_types: inferGeoParquetGeometryTypes(geometries)
2709
+ };
2710
+ const existingGeoMetadata = getGeoMetadata2(schema.metadata);
2711
+ const existingGeometryColumnMetadata = existingGeoMetadata == null ? void 0 : existingGeoMetadata.columns[geometryColumnName];
2712
+ const geometryColumnMetadata = existingGeometryColumnMetadata ? { ...existingGeometryColumnMetadata } : inferredGeometryColumnMetadata;
2713
+ const extensionMetadata = existingGeometryColumnMetadata ? { ...existingGeometryColumnMetadata } : inferredGeometryColumnMetadata;
2714
+ if (isLegacyGeoJSONCRS(options == null ? void 0 : options.crs)) {
2715
+ const normalizedCRS = normalizeLegacyGeoJSONCRS(options.crs);
2716
+ geometryColumnMetadata.geojson_crs = options.crs;
2717
+ extensionMetadata.geojson_crs = options.crs;
2718
+ if (normalizedCRS) {
2719
+ geometryColumnMetadata.crs = normalizedCRS.projjson;
2720
+ extensionMetadata.crs = normalizedCRS.projjson;
2721
+ extensionMetadata.crs_type = "projjson";
2722
+ }
2723
+ }
2724
+ const geometryField = new arrow7.Field(
2725
+ geometryColumnName,
2726
+ geometryVector.type,
2727
+ true,
2728
+ /* @__PURE__ */ new Map([
2729
+ ["ARROW:extension:name", encoding],
2730
+ ["ARROW:extension:metadata", JSON.stringify(extensionMetadata)]
2731
+ ])
2732
+ );
2733
+ const nextFields = [...schema.fields, geometryField];
2734
+ const nextMetadata = new Map(schema.metadata || []);
2735
+ nextMetadata.set(
2736
+ "geo",
2737
+ JSON.stringify({
2738
+ version: DEFAULT_GEO_METADATA_VERSION2,
2739
+ primary_column: geometryColumnName,
2740
+ columns: {
2741
+ [geometryColumnName]: geometryColumnMetadata
2742
+ }
2743
+ })
2744
+ );
2745
+ const nextSchema = new arrow7.Schema(nextFields, nextMetadata);
2746
+ const propertyTableBuilder = new ArrowTableBuilder(propertySchema);
2747
+ for (const row of propertyRows) {
2748
+ propertyTableBuilder.addObjectRow(row);
2749
+ }
2750
+ const propertyTable = propertyTableBuilder.finishTable().data;
2751
+ const propertyBatch = propertyTable.batches[0];
2752
+ const children = nextFields.map(
2753
+ (field, fieldIndex) => {
2754
+ var _a2;
2755
+ return fieldIndex < schema.fields.length ? (_a2 = propertyBatch == null ? void 0 : propertyBatch.getChildAt(fieldIndex)) == null ? void 0 : _a2.data[0] : geometryVector.data[0];
2756
+ }
2757
+ );
2758
+ const data = arrow7.makeData({
2759
+ type: new arrow7.Struct(nextFields),
2760
+ length: features.length,
2761
+ nullCount: 0,
2762
+ children
2763
+ });
2764
+ return {
2765
+ shape: "arrow-table",
2766
+ schema: convertArrowToSchema(nextSchema),
2767
+ data: new arrow7.Table(nextSchema, [new arrow7.RecordBatch(nextSchema, data)])
2768
+ };
2769
+ }
2770
+ function resolveGeoArrowEncodingPreference(options) {
2771
+ var _a2;
2772
+ return ((_a2 = options == null ? void 0 : options.geoarrow) == null ? void 0 : _a2.encodingPreference) ?? (options == null ? void 0 : options.encodingPreference);
2773
+ }
2774
+ function selectOptimizedEncoding(geometries) {
2775
+ const geometryKinds = new Set(
2776
+ geometries.filter(Boolean).map((geometry) => geometry.type)
2777
+ );
2778
+ if (geometryKinds.size === 0 || geometryKinds.has("GeometryCollection")) {
2779
+ return "geoarrow.geometry";
2780
+ }
2781
+ if (geometryKinds.size === 1) {
2782
+ return getNativeEncoding([...geometryKinds][0]);
2783
+ }
2784
+ if (geometryKinds.size === 2) {
2785
+ if (geometryKinds.has("Point") && geometryKinds.has("MultiPoint")) {
2786
+ return "geoarrow.multipoint";
2787
+ }
2788
+ if (geometryKinds.has("LineString") && geometryKinds.has("MultiLineString")) {
2789
+ return "geoarrow.multilinestring";
2790
+ }
2791
+ if (geometryKinds.has("Polygon") && geometryKinds.has("MultiPolygon")) {
2792
+ return "geoarrow.multipolygon";
2793
+ }
2794
+ }
2795
+ return "geoarrow.geometry";
2796
+ }
2797
+ function getFeatureDimension(geometries) {
2798
+ let coordinateSize = 2;
2799
+ for (const geometry of geometries) {
2800
+ coordinateSize = Math.max(coordinateSize, getGeometryCoordinateSize(geometry));
2801
+ }
2802
+ return coordinateSize >= 4 ? "xyzm" : coordinateSize === 3 ? "xyz" : "xy";
2803
+ }
2804
+ function getGeometryCoordinateSize(geometry) {
2805
+ if (!geometry) return 2;
2806
+ if (geometry.type === "GeometryCollection") {
2807
+ return Math.max(2, ...geometry.geometries.map(getGeometryCoordinateSize));
2808
+ }
2809
+ let value = geometry.coordinates;
2810
+ while (Array.isArray(value) && value.length > 0 && Array.isArray(value[0])) {
2811
+ value = value[0];
2812
+ }
2813
+ return Array.isArray(value) && value.every((item) => typeof item === "number") ? value.length : 2;
2814
+ }
2815
+ function makeNativeGeometryVector(geometries, encoding, dimension) {
2816
+ const writers = geometries.map(
2817
+ (geometry) => geometry ? (builder) => writeGeometryToBuilder(builder, geometry, encoding) : null
2818
+ );
2819
+ const geometryArray = GeoArrowBuilder.buildGeometryArray(writers, { encoding, dimension });
2820
+ return arrow7.makeVector(GeoArrowBuilder.makeGeometryData(geometryArray));
2821
+ }
2822
+ function makeGeometryUnionVector(geometries, dimension, includeGeometryCollections = true) {
2823
+ const childRows = /* @__PURE__ */ new Map();
2824
+ const typeIds = [];
2825
+ const valueOffsets = [];
2826
+ const nullCarrierKind = "Point";
2827
+ const allGeometryKinds = [
2828
+ "Point",
2829
+ "LineString",
2830
+ "Polygon",
2831
+ "MultiPoint",
2832
+ "MultiLineString",
2833
+ "MultiPolygon",
2834
+ ...includeGeometryCollections ? ["GeometryCollection"] : []
2835
+ ];
2836
+ for (const geometryKind of allGeometryKinds) {
2837
+ childRows.set(geometryKind, []);
2838
+ }
2839
+ for (const geometry of geometries) {
2840
+ const kind = (geometry == null ? void 0 : geometry.type) || nullCarrierKind;
2841
+ const rows = childRows.get(kind) || [];
2842
+ valueOffsets.push(rows.length);
2843
+ typeIds.push(getUnionTypeId(kind, dimension));
2844
+ rows.push(geometry);
2845
+ childRows.set(kind, rows);
2846
+ }
2847
+ const orderedKinds = [...childRows.keys()].sort(
2848
+ (left, right) => getUnionTypeId(left, dimension) - getUnionTypeId(right, dimension)
2849
+ );
2850
+ const fields = orderedKinds.map(
2851
+ (kind) => new arrow7.Field(
2852
+ getUnionFieldName(kind, dimension),
2853
+ kind === "GeometryCollection" ? makeGeometryCollectionVector(childRows.get(kind), dimension).type : makeNativeGeometryVector(childRows.get(kind), getNativeEncoding(kind), dimension).type,
2854
+ true
2855
+ )
2856
+ );
2857
+ const children = orderedKinds.map((kind) => {
2858
+ if (kind === "GeometryCollection") {
2859
+ return makeGeometryCollectionVector(childRows.get(kind), dimension).data[0];
2860
+ }
2861
+ return makeNativeGeometryVector(childRows.get(kind), getNativeEncoding(kind), dimension).data[0];
2862
+ });
2863
+ const unionType = new arrow7.DenseUnion(
2864
+ orderedKinds.map((kind) => getUnionTypeId(kind, dimension)),
2865
+ fields
2866
+ );
2867
+ return arrow7.makeVector(
2868
+ arrow7.makeData({
2869
+ type: unionType,
2870
+ length: geometries.length,
2871
+ nullCount: 0,
2872
+ typeIds: Int8Array.from(typeIds),
2873
+ valueOffsets: Int32Array.from(valueOffsets),
2874
+ children
2875
+ })
2876
+ );
2877
+ }
2878
+ function makeGeometryCollectionVector(geometries, dimension) {
2879
+ const flattenedGeometries = [];
2880
+ const offsets = [0];
2881
+ for (const geometry of geometries) {
2882
+ if ((geometry == null ? void 0 : geometry.type) === "GeometryCollection") {
2883
+ appendGeometryCollectionMembers(flattenedGeometries, geometry.geometries);
2884
+ }
2885
+ offsets.push(flattenedGeometries.length);
2886
+ }
2887
+ const memberUnion = makeGeometryUnionVector(flattenedGeometries, dimension, false);
2888
+ const listType = new arrow7.List(new arrow7.Field("geometries", memberUnion.type, true));
2889
+ return arrow7.makeVector(
2890
+ arrow7.makeData({
2891
+ type: listType,
2892
+ length: geometries.length,
2893
+ nullCount: 0,
2894
+ valueOffsets: Int32Array.from(offsets),
2895
+ child: memberUnion.data[0]
2896
+ })
2897
+ );
2898
+ }
2899
+ function appendGeometryCollectionMembers(target, geometries) {
2900
+ for (const geometry of geometries) {
2901
+ if ((geometry == null ? void 0 : geometry.type) === "GeometryCollection") {
2902
+ appendGeometryCollectionMembers(target, geometry.geometries);
2903
+ } else {
2904
+ target.push(geometry);
2905
+ }
2906
+ }
2907
+ }
2908
+ function writeGeometryToBuilder(builder, geometry, encoding) {
2909
+ switch (geometry.type) {
2910
+ case "Point":
2911
+ if (encoding === "geoarrow.multipoint") builder.beginMultiPoint(1);
2912
+ builder.beginPoint();
2913
+ writeCoordinateToBuilder(builder, geometry.coordinates);
2914
+ return;
2915
+ case "MultiPoint":
2916
+ builder.beginMultiPoint(geometry.coordinates.length);
2917
+ for (const coordinate of geometry.coordinates) {
2918
+ builder.beginPoint();
2919
+ writeCoordinateToBuilder(builder, coordinate);
2920
+ }
2921
+ return;
2922
+ case "LineString":
2923
+ if (encoding === "geoarrow.multilinestring") builder.beginMultiLineString(1);
2924
+ writeLineStringToBuilder(builder, geometry.coordinates);
2925
+ return;
2926
+ case "MultiLineString":
2927
+ builder.beginMultiLineString(geometry.coordinates.length);
2928
+ for (const line of geometry.coordinates) writeLineStringToBuilder(builder, line);
2929
+ return;
2930
+ case "Polygon":
2931
+ if (encoding === "geoarrow.multipolygon") builder.beginMultiPolygon(1);
2932
+ writePolygonToBuilder(builder, geometry.coordinates);
2933
+ return;
2934
+ case "MultiPolygon":
2935
+ builder.beginMultiPolygon(geometry.coordinates.length);
2936
+ for (const polygon of geometry.coordinates) writePolygonToBuilder(builder, polygon);
2937
+ return;
2938
+ case "GeometryCollection":
2939
+ throw new Error("GeometryCollection must be written through the dense union builder.");
2940
+ }
2941
+ }
2942
+ function writeLineStringToBuilder(builder, coordinates) {
2943
+ builder.beginLineString(coordinates.length);
2944
+ for (const coordinate of coordinates) writeCoordinateToBuilder(builder, coordinate);
2945
+ }
2946
+ function writePolygonToBuilder(builder, coordinates) {
2947
+ builder.beginPolygon(coordinates.length);
2948
+ for (const ring of coordinates) {
2949
+ builder.beginLinearRing(ring.length);
2950
+ for (const coordinate of ring) writeCoordinateToBuilder(builder, coordinate);
2951
+ }
2952
+ }
2953
+ function writeCoordinateToBuilder(builder, coordinate) {
2954
+ builder.writeCoordinate(
2955
+ coordinate[0] ?? Number.NaN,
2956
+ coordinate[1] ?? Number.NaN,
2957
+ coordinate[2],
2958
+ coordinate[3]
2959
+ );
2960
+ }
2961
+ function getNativeEncoding(kind) {
2962
+ switch (kind) {
2963
+ case "Point":
2964
+ return "geoarrow.point";
2965
+ case "LineString":
2966
+ return "geoarrow.linestring";
2967
+ case "Polygon":
2968
+ return "geoarrow.polygon";
2969
+ case "MultiPoint":
2970
+ return "geoarrow.multipoint";
2971
+ case "MultiLineString":
2972
+ return "geoarrow.multilinestring";
2973
+ case "MultiPolygon":
2974
+ return "geoarrow.multipolygon";
2975
+ default:
2976
+ throw new Error(`No native GeoArrow encoding exists for ${kind}.`);
2977
+ }
2978
+ }
2979
+ function getUnionTypeId(kind, dimension) {
2980
+ const baseTypeId = {
2981
+ Point: 1,
2982
+ LineString: 2,
2983
+ Polygon: 3,
2984
+ MultiPoint: 4,
2985
+ MultiLineString: 5,
2986
+ MultiPolygon: 6,
2987
+ GeometryCollection: 7
2988
+ };
2989
+ const dimensionOffset = dimension === "xyz" ? 10 : dimension === "xym" ? 20 : dimension === "xyzm" ? 30 : 0;
2990
+ return baseTypeId[kind] + dimensionOffset;
2991
+ }
2992
+ function getUnionFieldName(kind, dimension) {
2993
+ return dimension === "xy" ? kind : `${kind} ${dimension.slice(1).toUpperCase()}`;
2994
+ }
2995
+ function makeGeoArrowFeatureRows(features, options) {
2996
+ const geometryColumnName = (options == null ? void 0 : options.geometryColumnName) || DEFAULT_GEOMETRY_COLUMN_NAME;
2997
+ const encoding = (options == null ? void 0 : options.encoding) || "wkb";
2998
+ return features.map((feature) => {
2999
+ const properties = normalizeProperties(feature.properties);
3000
+ assertNoGeometryPropertyCollision(properties, geometryColumnName);
3001
+ return {
3002
+ ...properties,
3003
+ [geometryColumnName]: encodeGeoArrowGeometry(feature.geometry, encoding)
3004
+ };
3005
+ });
3006
+ }
3007
+ function makeGeoArrowFeatureSchema(features, options) {
3008
+ const geometryColumnName = (options == null ? void 0 : options.geometryColumnName) || DEFAULT_GEOMETRY_COLUMN_NAME;
3009
+ const encoding = (options == null ? void 0 : options.encoding) || "wkb";
3010
+ const propertyRows = features.map((feature) => {
3011
+ const properties = normalizeProperties(feature.properties);
3012
+ assertNoGeometryPropertyCollision(properties, geometryColumnName);
3013
+ return properties;
3014
+ });
3015
+ const propertySchema = getPropertySchema(propertyRows);
3016
+ const geometryField = encoding === "wkb" ? makeWKBGeometryField(geometryColumnName, true) : {
3017
+ name: geometryColumnName,
3018
+ type: "utf8",
3019
+ nullable: true,
3020
+ metadata: {}
3021
+ };
2092
3022
  const schema = {
2093
3023
  fields: [...propertySchema.fields, geometryField],
2094
3024
  metadata: { ...propertySchema.metadata || {} }
2095
3025
  };
2096
- setWKBGeometrySchemaMetadata(schema, {
2097
- geometryColumnName: GEOMETRY_COLUMN_NAME,
2098
- geometryTypes: inferGeoParquetGeometryTypes(features.map((feature) => feature.geometry))
2099
- });
3026
+ if (encoding === "wkb") {
3027
+ setWKBGeometrySchemaMetadata(schema, {
3028
+ geometryColumnName,
3029
+ primaryColumnName: geometryColumnName,
3030
+ geometryTypes: inferGeoParquetGeometryTypes(features.map((feature) => feature.geometry))
3031
+ });
3032
+ } else {
3033
+ schema.metadata.geo = JSON.stringify({
3034
+ version: DEFAULT_GEO_METADATA_VERSION2,
3035
+ primary_column: geometryColumnName,
3036
+ columns: {
3037
+ [geometryColumnName]: {
3038
+ encoding,
3039
+ geometry_types: inferGeoParquetGeometryTypes(features.map((feature) => feature.geometry))
3040
+ }
3041
+ }
3042
+ });
3043
+ }
3044
+ applyLegacyGeoJSONCRSToSchema(schema, geometryColumnName, options == null ? void 0 : options.crs);
3045
+ return schema;
3046
+ }
3047
+ function applyLegacyGeoJSONCRSToSchema(schema, geometryColumnName, crs) {
3048
+ if (!isLegacyGeoJSONCRS(crs)) {
3049
+ return schema;
3050
+ }
3051
+ const geometryField = schema.fields.find((field) => field.name === geometryColumnName);
3052
+ if (!geometryField) {
3053
+ return schema;
3054
+ }
3055
+ const normalizedCRS = normalizeLegacyGeoJSONCRS(crs);
3056
+ const columnMetadata = {
3057
+ [GEOJSON_CRS_METADATA_KEY]: crs
3058
+ };
3059
+ if (normalizedCRS) {
3060
+ columnMetadata.crs = normalizedCRS.projjson;
3061
+ }
3062
+ schema.metadata ||= {};
3063
+ const geoMetadata = getGeoMetadata2(schema.metadata) || {
3064
+ version: DEFAULT_GEO_METADATA_VERSION2,
3065
+ primary_column: geometryColumnName,
3066
+ columns: {}
3067
+ };
3068
+ geoMetadata.version ||= DEFAULT_GEO_METADATA_VERSION2;
3069
+ geoMetadata.primary_column ||= geometryColumnName;
3070
+ geoMetadata.columns ||= {};
3071
+ const existingColumnMetadata = geoMetadata.columns[geometryColumnName] || {
3072
+ encoding: geometryField.type === "utf8" ? "wkt" : "wkb",
3073
+ geometry_types: []
3074
+ };
3075
+ geoMetadata.columns[geometryColumnName] = {
3076
+ ...existingColumnMetadata,
3077
+ ...columnMetadata
3078
+ };
3079
+ setGeoMetadata2(schema.metadata, geoMetadata);
3080
+ geometryField.metadata ||= {};
3081
+ const extensionMetadata = parseExtensionMetadata(
3082
+ geometryField.metadata[GEOARROW_EXTENSION_METADATA_KEY]
3083
+ );
3084
+ extensionMetadata[GEOJSON_CRS_METADATA_KEY] = crs;
3085
+ if (normalizedCRS) {
3086
+ extensionMetadata.crs = normalizedCRS.projjson;
3087
+ extensionMetadata.crs_type = "projjson";
3088
+ }
3089
+ geometryField.metadata[GEOARROW_EXTENSION_METADATA_KEY] = JSON.stringify(extensionMetadata);
2100
3090
  return schema;
2101
3091
  }
3092
+ function encodeGeoArrowGeometry(geometry, encoding) {
3093
+ if (!geometry) {
3094
+ return null;
3095
+ }
3096
+ return encoding === "wkt" ? convertGeometryToWKT(geometry) : encodeWKBGeometryValue(geometry);
3097
+ }
2102
3098
  function normalizeProperties(properties) {
2103
3099
  if (!properties || typeof properties !== "object") {
2104
3100
  return {};
@@ -2126,7 +3122,7 @@ function getPropertySchema(propertyRows) {
2126
3122
  return {
2127
3123
  metadata: {},
2128
3124
  fields: fieldNames.map((fieldName) => {
2129
- const inferredType = getDataTypeFromArray(
3125
+ const inferredType = getPropertyFieldType(
2130
3126
  propertyRows.map((propertyRow) => propertyRow[fieldName])
2131
3127
  );
2132
3128
  return {
@@ -2137,8 +3133,254 @@ function getPropertySchema(propertyRows) {
2137
3133
  })
2138
3134
  };
2139
3135
  }
2140
- function getFieldNames(propertyRows) {
2141
- const fieldNames = /* @__PURE__ */ new Set();
3136
+ function getPropertyFieldType(values) {
3137
+ let type = "null";
3138
+ let nullable = false;
3139
+ for (const value of values) {
3140
+ if (value === null || value === void 0) {
3141
+ nullable = true;
3142
+ continue;
3143
+ }
3144
+ const valueType = getPropertyValueType(value);
3145
+ if (type === "null") {
3146
+ type = valueType;
3147
+ continue;
3148
+ }
3149
+ if (type !== valueType) {
3150
+ throw new Error(`GeoJSONLoader: incompatible property types ${type} and ${valueType}`);
3151
+ }
3152
+ }
3153
+ return { type, nullable };
3154
+ }
3155
+ function getPropertyValueType(value) {
3156
+ switch (typeof value) {
3157
+ case "boolean":
3158
+ return "bool";
3159
+ case "number":
3160
+ return "float64";
3161
+ case "string":
3162
+ return "utf8";
3163
+ default:
3164
+ return "null";
3165
+ }
3166
+ }
3167
+ function isLegacyGeoJSONCRS(value) {
3168
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3169
+ }
3170
+ function normalizeLegacyGeoJSONCRS(crs) {
3171
+ const name = getLegacyGeoJSONCRSName(crs);
3172
+ if (!name) {
3173
+ return null;
3174
+ }
3175
+ const normalizedName = name.toLowerCase();
3176
+ if (normalizedName === "crs84" || normalizedName === "ogc:crs84" || normalizedName === "urn:ogc:def:crs:ogc:1.3:crs84" || normalizedName === "urn:ogc:def:crs:ogc::crs84" || normalizedName === "http://www.opengis.net/def/crs/ogc/1.3/crs84") {
3177
+ return { name, projjson: cloneJSON(CRS84_PROJJSON) };
3178
+ }
3179
+ if (normalizedName === "epsg:4326" || normalizedName === "urn:ogc:def:crs:epsg::4326" || normalizedName === "urn:ogc:def:crs:epsg:6.6:4326" || normalizedName === "http://www.opengis.net/def/crs/epsg/0/4326") {
3180
+ return { name, projjson: cloneJSON(EPSG_4326_PROJJSON) };
3181
+ }
3182
+ return null;
3183
+ }
3184
+ function getLegacyGeoJSONCRSName(crs) {
3185
+ var _a2;
3186
+ if (typeof ((_a2 = crs.properties) == null ? void 0 : _a2.name) === "string") {
3187
+ return crs.properties.name;
3188
+ }
3189
+ if (typeof crs.name === "string") {
3190
+ return crs.name;
3191
+ }
3192
+ return null;
3193
+ }
3194
+ function parseExtensionMetadata(metadata) {
3195
+ if (!metadata) {
3196
+ return {};
3197
+ }
3198
+ try {
3199
+ const parsedMetadata = JSON.parse(metadata);
3200
+ return parsedMetadata && typeof parsedMetadata === "object" && !Array.isArray(parsedMetadata) ? parsedMetadata : {};
3201
+ } catch {
3202
+ return {};
3203
+ }
3204
+ }
3205
+ function cloneJSON(value) {
3206
+ return JSON.parse(JSON.stringify(value));
3207
+ }
3208
+ function getFieldNames(propertyRows) {
3209
+ const fieldNames = /* @__PURE__ */ new Set();
3210
+ for (const propertyRow of propertyRows) {
3211
+ for (const fieldName of Object.keys(propertyRow)) {
3212
+ fieldNames.add(fieldName);
3213
+ }
3214
+ }
3215
+ return [...fieldNames];
3216
+ }
3217
+ function assertNoGeometryPropertyCollision(properties, geometryColumnName) {
3218
+ if (Object.prototype.hasOwnProperty.call(properties, geometryColumnName)) {
3219
+ throw new Error(
3220
+ `GeoArrow conversion: GeoJSON property "${geometryColumnName}" conflicts with the geometry column name`
3221
+ );
3222
+ }
3223
+ }
3224
+ var arrow7, DEFAULT_GEOMETRY_COLUMN_NAME, DEFAULT_GEO_METADATA_VERSION2, GEOJSON_CRS_METADATA_KEY, GEOARROW_EXTENSION_METADATA_KEY, CRS84_PROJJSON, EPSG_4326_PROJJSON;
3225
+ var init_convert_geojson_to_geoarrow = __esm({
3226
+ "../gis/src/lib/table-converters/convert-geojson-to-geoarrow.ts"() {
3227
+ "use strict";
3228
+ arrow7 = __toESM(require("apache-arrow"), 1);
3229
+ init_src2();
3230
+ init_convert_geometry_to_wkt();
3231
+ init_wkb_geoarrow_utils();
3232
+ init_geoparquet_metadata();
3233
+ init_geoarrow_builder();
3234
+ DEFAULT_GEOMETRY_COLUMN_NAME = "geometry";
3235
+ DEFAULT_GEO_METADATA_VERSION2 = "1.1.0";
3236
+ GEOJSON_CRS_METADATA_KEY = "geojson_crs";
3237
+ GEOARROW_EXTENSION_METADATA_KEY = "ARROW:extension:metadata";
3238
+ CRS84_PROJJSON = {
3239
+ $schema: "https://proj.org/schemas/v0.7/projjson.schema.json",
3240
+ type: "GeographicCRS",
3241
+ name: "WGS 84 longitude-latitude",
3242
+ datum_ensemble: {
3243
+ name: "World Geodetic System 1984 ensemble",
3244
+ members: [
3245
+ { name: "World Geodetic System 1984 (Transit)" },
3246
+ { name: "World Geodetic System 1984 (G730)" },
3247
+ { name: "World Geodetic System 1984 (G873)" },
3248
+ { name: "World Geodetic System 1984 (G1150)" },
3249
+ { name: "World Geodetic System 1984 (G1674)" },
3250
+ { name: "World Geodetic System 1984 (G1762)" },
3251
+ { name: "World Geodetic System 1984 (G2139)" }
3252
+ ],
3253
+ ellipsoid: {
3254
+ name: "WGS 84",
3255
+ semi_major_axis: 6378137,
3256
+ inverse_flattening: 298.257223563
3257
+ },
3258
+ accuracy: "2.0",
3259
+ id: {
3260
+ authority: "EPSG",
3261
+ code: 6326
3262
+ }
3263
+ },
3264
+ coordinate_system: {
3265
+ subtype: "ellipsoidal",
3266
+ axis: [
3267
+ {
3268
+ name: "Geodetic longitude",
3269
+ abbreviation: "Lon",
3270
+ direction: "east",
3271
+ unit: "degree"
3272
+ },
3273
+ {
3274
+ name: "Geodetic latitude",
3275
+ abbreviation: "Lat",
3276
+ direction: "north",
3277
+ unit: "degree"
3278
+ }
3279
+ ]
3280
+ },
3281
+ id: {
3282
+ authority: "OGC",
3283
+ code: "CRS84"
3284
+ }
3285
+ };
3286
+ EPSG_4326_PROJJSON = {
3287
+ ...CRS84_PROJJSON,
3288
+ name: "WGS 84",
3289
+ coordinate_system: {
3290
+ subtype: "ellipsoidal",
3291
+ axis: [
3292
+ {
3293
+ name: "Geodetic latitude",
3294
+ abbreviation: "Lat",
3295
+ direction: "north",
3296
+ unit: "degree"
3297
+ },
3298
+ {
3299
+ name: "Geodetic longitude",
3300
+ abbreviation: "Lon",
3301
+ direction: "east",
3302
+ unit: "degree"
3303
+ }
3304
+ ]
3305
+ },
3306
+ id: {
3307
+ authority: "EPSG",
3308
+ code: 4326
3309
+ }
3310
+ };
3311
+ }
3312
+ });
3313
+
3314
+ // ../gis/src/lib/geoarrow/feature-collection-to-arrow.ts
3315
+ function convertFeaturesToWKBArrowTable(features, options = {}) {
3316
+ const encodingPreference = resolveGeoArrowEncodingPreference(options);
3317
+ if (encodingPreference && encodingPreference !== "geoarrow.wkb") {
3318
+ return convertFeaturesToGeoArrowTable(features, options);
3319
+ }
3320
+ const propertyRows = features.map((feature) => normalizeProperties2(feature.properties));
3321
+ const propertySchema = getPropertySchema2(propertyRows);
3322
+ const schema = buildFeatureArrowSchema(propertySchema, features);
3323
+ const arrowTableBuilder = new ArrowTableBuilder(schema);
3324
+ for (let featureIndex = 0; featureIndex < features.length; featureIndex++) {
3325
+ arrowTableBuilder.addObjectRow({
3326
+ ...propertyRows[featureIndex],
3327
+ [GEOMETRY_COLUMN_NAME]: encodeWKBGeometryValue(features[featureIndex].geometry)
3328
+ });
3329
+ }
3330
+ return arrowTableBuilder.finishTable();
3331
+ }
3332
+ function buildFeatureArrowSchema(propertySchema, features) {
3333
+ const geometryField = makeWKBGeometryField(GEOMETRY_COLUMN_NAME);
3334
+ const schema = {
3335
+ fields: [...propertySchema.fields, geometryField],
3336
+ metadata: { ...propertySchema.metadata || {} }
3337
+ };
3338
+ setWKBGeometrySchemaMetadata(schema, {
3339
+ geometryColumnName: GEOMETRY_COLUMN_NAME,
3340
+ geometryTypes: inferGeoParquetGeometryTypes(features.map((feature) => feature.geometry))
3341
+ });
3342
+ return schema;
3343
+ }
3344
+ function normalizeProperties2(properties) {
3345
+ if (!properties || typeof properties !== "object") {
3346
+ return {};
3347
+ }
3348
+ const normalizedProperties = {};
3349
+ for (const [propertyName, propertyValue] of Object.entries(properties)) {
3350
+ normalizedProperties[propertyName] = normalizePropertyValue2(propertyValue);
3351
+ }
3352
+ return normalizedProperties;
3353
+ }
3354
+ function normalizePropertyValue2(propertyValue) {
3355
+ if (propertyValue === null || propertyValue === void 0 || typeof propertyValue === "string" || typeof propertyValue === "number" || typeof propertyValue === "boolean") {
3356
+ return propertyValue ?? null;
3357
+ }
3358
+ if (propertyValue instanceof Date) {
3359
+ return propertyValue.toISOString();
3360
+ }
3361
+ return JSON.stringify(propertyValue);
3362
+ }
3363
+ function getPropertySchema2(propertyRows) {
3364
+ if (propertyRows.length === 0) {
3365
+ return { fields: [], metadata: {} };
3366
+ }
3367
+ const fieldNames = getFieldNames2(propertyRows);
3368
+ return {
3369
+ metadata: {},
3370
+ fields: fieldNames.map((fieldName) => {
3371
+ const inferredType = getDataTypeFromArray(
3372
+ propertyRows.map((propertyRow) => propertyRow[fieldName])
3373
+ );
3374
+ return {
3375
+ name: fieldName,
3376
+ type: inferredType.type === "float32" ? "float64" : inferredType.type,
3377
+ nullable: inferredType.nullable
3378
+ };
3379
+ })
3380
+ };
3381
+ }
3382
+ function getFieldNames2(propertyRows) {
3383
+ const fieldNames = /* @__PURE__ */ new Set();
2142
3384
  for (const propertyRow of propertyRows) {
2143
3385
  for (const fieldName of Object.keys(propertyRow)) {
2144
3386
  fieldNames.add(fieldName);
@@ -2152,6 +3394,7 @@ var init_feature_collection_to_arrow = __esm({
2152
3394
  "use strict";
2153
3395
  init_src2();
2154
3396
  init_wkb_geoarrow_utils();
3397
+ init_convert_geojson_to_geoarrow();
2155
3398
  GEOMETRY_COLUMN_NAME = "geometry";
2156
3399
  }
2157
3400
  });
@@ -2598,6 +3841,10 @@ var init_worker_thread = __esm({
2598
3841
  name;
2599
3842
  source;
2600
3843
  url;
3844
+ /** Lazily resolves the classic worker URL used as a fallback. */
3845
+ getUrl;
3846
+ /** Creates a browser Worker directly. */
3847
+ loadWorker;
2601
3848
  terminated = false;
2602
3849
  worker;
2603
3850
  onMessage;
@@ -2608,11 +3855,13 @@ var init_worker_thread = __esm({
2608
3855
  return typeof Worker !== "undefined" && isBrowser2 || typeof NodeWorker !== "undefined" && !isBrowser2;
2609
3856
  }
2610
3857
  constructor(props) {
2611
- const { name, source, url } = props;
2612
- assert2(source || url);
3858
+ const { name, source, url, getUrl, loadWorker } = props;
3859
+ assert2(source || url || getUrl || loadWorker);
2613
3860
  this.name = name;
2614
3861
  this.source = source;
2615
3862
  this.url = url;
3863
+ this.getUrl = getUrl;
3864
+ this.loadWorker = loadWorker;
2616
3865
  this.onMessage = NOOP;
2617
3866
  this.onError = (error) => console.log(error);
2618
3867
  this.worker = isBrowser2 ? this._createBrowserWorker() : this._createNodeWorker();
@@ -2658,7 +3907,7 @@ var init_worker_thread = __esm({
2658
3907
  */
2659
3908
  _getErrorFromErrorEvent(event) {
2660
3909
  let message = "Failed to load ";
2661
- message += `worker ${this.name} from ${this.url}. `;
3910
+ message += `worker ${this.name} from ${this.url || "built-in worker factory"}. `;
2662
3911
  if (event.message) {
2663
3912
  message += `${event.message} in `;
2664
3913
  }
@@ -2671,8 +3920,26 @@ var init_worker_thread = __esm({
2671
3920
  * Creates a worker thread on the browser
2672
3921
  */
2673
3922
  _createBrowserWorker() {
2674
- this._loadableURL = getLoadableWorkerURL({ source: this.source, url: this.url });
3923
+ var _a2;
3924
+ if (this.loadWorker) {
3925
+ try {
3926
+ const worker2 = this.loadWorker();
3927
+ if (worker2) {
3928
+ return this._initializeBrowserWorker(worker2);
3929
+ }
3930
+ } catch (error) {
3931
+ if (!this.source && !this.url && !this.getUrl) {
3932
+ throw error;
3933
+ }
3934
+ }
3935
+ }
3936
+ const url = this.url || ((_a2 = this.getUrl) == null ? void 0 : _a2.call(this));
3937
+ this._loadableURL = getLoadableWorkerURL({ source: this.source, url });
2675
3938
  const worker = new Worker(this._loadableURL, { name: this.name });
3939
+ return this._initializeBrowserWorker(worker);
3940
+ }
3941
+ /** Attaches protocol handlers to a browser worker. */
3942
+ _initializeBrowserWorker(worker) {
2676
3943
  worker.onmessage = (event) => {
2677
3944
  if (!event.data) {
2678
3945
  this.onError(new Error("No data received"));
@@ -2731,6 +3998,10 @@ var init_worker_pool = __esm({
2731
3998
  source;
2732
3999
  // | Function;
2733
4000
  url;
4001
+ /** Lazily resolves a classic worker fallback URL. */
4002
+ getUrl;
4003
+ /** Creates a browser Worker directly. */
4004
+ loadWorker;
2734
4005
  maxConcurrency = 1;
2735
4006
  maxMobileConcurrency = 1;
2736
4007
  onDebug = () => {
@@ -2752,6 +4023,8 @@ var init_worker_pool = __esm({
2752
4023
  constructor(props) {
2753
4024
  this.source = props.source;
2754
4025
  this.url = props.url;
4026
+ this.getUrl = props.getUrl;
4027
+ this.loadWorker = props.loadWorker;
2755
4028
  this.setProps(props);
2756
4029
  }
2757
4030
  /**
@@ -2861,7 +4134,13 @@ var init_worker_pool = __esm({
2861
4134
  if (this.count < this._getMaxConcurrency()) {
2862
4135
  this.count++;
2863
4136
  const name = `${this.name.toLowerCase()} (#${this.count} of ${this.maxConcurrency})`;
2864
- return new WorkerThread({ name, source: this.source, url: this.url });
4137
+ return new WorkerThread({
4138
+ name,
4139
+ source: this.source,
4140
+ url: this.url,
4141
+ getUrl: this.getUrl,
4142
+ loadWorker: this.loadWorker
4143
+ });
2865
4144
  }
2866
4145
  return null;
2867
4146
  }
@@ -2873,7 +4152,22 @@ var init_worker_pool = __esm({
2873
4152
  });
2874
4153
 
2875
4154
  // ../worker-utils/src/lib/worker-farm/worker-farm.ts
2876
- var DEFAULT_PROPS, WorkerFarm;
4155
+ function getWorkerPoolKey(options) {
4156
+ const { name, source, url, urlKey, loadWorker } = options;
4157
+ const sourceKey = source ? `source:${source}` : "";
4158
+ const urlKeyPart = url || urlKey ? `url:${url || urlKey}` : "";
4159
+ const loadWorkerKey = loadWorker ? `loadWorker:${getLoadWorkerId(loadWorker)}` : "";
4160
+ return [name, sourceKey, urlKeyPart, loadWorkerKey].filter(Boolean).join("|");
4161
+ }
4162
+ function getLoadWorkerId(loadWorker) {
4163
+ let loadWorkerId = loadWorkerIds.get(loadWorker);
4164
+ if (!loadWorkerId) {
4165
+ loadWorkerId = nextLoadWorkerId++;
4166
+ loadWorkerIds.set(loadWorker, loadWorkerId);
4167
+ }
4168
+ return loadWorkerId;
4169
+ }
4170
+ var DEFAULT_PROPS, loadWorkerIds, nextLoadWorkerId, WorkerFarm;
2877
4171
  var init_worker_farm = __esm({
2878
4172
  "../worker-utils/src/lib/worker-farm/worker-farm.ts"() {
2879
4173
  "use strict";
@@ -2886,6 +4180,8 @@ var init_worker_farm = __esm({
2886
4180
  onDebug: () => {
2887
4181
  }
2888
4182
  };
4183
+ loadWorkerIds = /* @__PURE__ */ new WeakMap();
4184
+ nextLoadWorkerId = 1;
2889
4185
  WorkerFarm = class _WorkerFarm {
2890
4186
  props;
2891
4187
  workerPools = /* @__PURE__ */ new Map();
@@ -2929,24 +4225,28 @@ var init_worker_farm = __esm({
2929
4225
  }
2930
4226
  /**
2931
4227
  * Returns a worker pool for the specified worker
2932
- * @param options - only used first time for a specific worker name
2933
- * @param options.name - the name of the worker - used to identify worker pool
2934
- * @param options.url -
2935
- * @param options.source -
4228
+ * @param options Worker target used to identify and initialize the pool.
4229
+ * @param options.name Worker name used as the base pool identity.
4230
+ * @param options.url Worker script URL.
4231
+ * @param options.source Inline worker source.
4232
+ * @param options.loadWorker Built-in browser worker factory.
2936
4233
  * @example
2937
4234
  * const job = WorkerFarm.getWorkerFarm().getWorkerPool({name, url}).startJob(...);
2938
4235
  */
2939
4236
  getWorkerPool(options) {
2940
- const { name, source, url } = options;
2941
- let workerPool = this.workerPools.get(name);
4237
+ const { name, source, url, getUrl, loadWorker } = options;
4238
+ const workerPoolKey = getWorkerPoolKey(options);
4239
+ let workerPool = this.workerPools.get(workerPoolKey);
2942
4240
  if (!workerPool) {
2943
4241
  workerPool = new WorkerPool({
2944
4242
  name,
2945
4243
  source,
2946
- url
4244
+ url,
4245
+ getUrl,
4246
+ loadWorker
2947
4247
  });
2948
4248
  workerPool.setProps(this._getWorkerPoolProps());
2949
- this.workerPools.set(name, workerPool);
4249
+ this.workerPools.set(workerPoolKey, workerPool);
2950
4250
  }
2951
4251
  return workerPool;
2952
4252
  }
@@ -2962,40 +4262,123 @@ var init_worker_farm = __esm({
2962
4262
  }
2963
4263
  });
2964
4264
 
4265
+ // ../worker-utils/src/lib/async-queue/async-queue.ts
4266
+ var AsyncQueue;
4267
+ var init_async_queue = __esm({
4268
+ "../worker-utils/src/lib/async-queue/async-queue.ts"() {
4269
+ "use strict";
4270
+ AsyncQueue = class {
4271
+ _values;
4272
+ _settlers;
4273
+ _closed;
4274
+ constructor() {
4275
+ this._values = [];
4276
+ this._settlers = [];
4277
+ this._closed = false;
4278
+ }
4279
+ /** Return an async iterator for this queue */
4280
+ [Symbol.asyncIterator]() {
4281
+ return this;
4282
+ }
4283
+ /** Push a new value - the async iterator will yield a promise resolved to this value */
4284
+ push(value) {
4285
+ return this.enqueue(value);
4286
+ }
4287
+ /**
4288
+ * Push a new value - the async iterator will yield a promise resolved to this value
4289
+ * Add an error - the async iterator will yield a promise rejected with this value
4290
+ */
4291
+ enqueue(value) {
4292
+ if (this._closed) {
4293
+ throw new Error("Closed");
4294
+ }
4295
+ if (this._settlers.length > 0) {
4296
+ if (this._values.length > 0) {
4297
+ throw new Error("Illegal internal state");
4298
+ }
4299
+ const settler = this._settlers.shift();
4300
+ if (value instanceof Error) {
4301
+ settler.reject(value);
4302
+ } else {
4303
+ settler.resolve({ value });
4304
+ }
4305
+ } else {
4306
+ this._values.push(value);
4307
+ }
4308
+ }
4309
+ /** Indicate that we not waiting for more values - The async iterator will be done */
4310
+ close() {
4311
+ while (this._settlers.length > 0) {
4312
+ const settler = this._settlers.shift();
4313
+ settler.resolve({ done: true });
4314
+ }
4315
+ this._closed = true;
4316
+ }
4317
+ // ITERATOR IMPLEMENTATION
4318
+ /** @returns a Promise for an IteratorResult */
4319
+ next() {
4320
+ if (this._values.length > 0) {
4321
+ const value = this._values.shift();
4322
+ if (value instanceof Error) {
4323
+ return Promise.reject(value);
4324
+ }
4325
+ return Promise.resolve({ done: false, value });
4326
+ }
4327
+ if (this._closed) {
4328
+ if (this._settlers.length > 0) {
4329
+ throw new Error("Illegal internal state");
4330
+ }
4331
+ return Promise.resolve({ done: true, value: void 0 });
4332
+ }
4333
+ return new Promise((resolve2, reject) => {
4334
+ this._settlers.push({ resolve: resolve2, reject });
4335
+ });
4336
+ }
4337
+ };
4338
+ }
4339
+ });
4340
+
2965
4341
  // ../worker-utils/src/lib/worker-api/get-worker-url.ts
2966
4342
  function getWorkerName(worker) {
2967
4343
  const warning = worker.version !== VERSION2 ? ` (worker-utils@${VERSION2})` : "";
2968
4344
  return `${worker.name}@${worker.version}${warning}`;
2969
4345
  }
2970
- function getWorkerURL(worker, options = {}) {
4346
+ function getCustomWorkerURL(worker, options = {}) {
2971
4347
  var _a2;
2972
4348
  const workerOptions = options[worker.id] || {};
2973
- const workerFile = isBrowser2 ? `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
4349
+ const workerFile = isBrowser2 ? worker.workerFile || `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
2974
4350
  let url = workerOptions.workerUrl;
2975
- if (!url && typeof worker.worker === "string") {
2976
- url = worker.worker;
2977
- }
2978
4351
  if (!url && worker.id === "compression") {
2979
4352
  url = options.workerUrl;
2980
4353
  }
2981
4354
  const workerType = options._workerType || ((_a2 = options == null ? void 0 : options.core) == null ? void 0 : _a2._workerType);
2982
- if (workerType === "test") {
4355
+ if (!url && workerType === "test") {
2983
4356
  if (isBrowser2) {
2984
4357
  url = `modules/${worker.module}/dist/${workerFile}`;
2985
4358
  } else {
2986
4359
  url = `modules/${worker.module}/src/workers/${worker.id}-worker-node.ts`;
2987
4360
  }
2988
4361
  }
2989
- if (!url) {
2990
- let version2 = worker.version;
2991
- if (version2 === "latest") {
2992
- version2 = NPM_TAG;
2993
- }
2994
- const versionTag = version2 ? `@${version2}` : "";
2995
- url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
4362
+ return url || null;
4363
+ }
4364
+ function getWorkerURL(worker, options = {}) {
4365
+ const customWorkerUrl = getCustomWorkerURL(worker, options);
4366
+ const descriptorWorkerUrl = typeof worker.worker === "string" ? worker.worker : null;
4367
+ const url = customWorkerUrl || descriptorWorkerUrl || getDefaultWorkerURL(worker, true);
4368
+ assert2(url);
4369
+ return url;
4370
+ }
4371
+ function getDefaultWorkerURL(worker, warn = false) {
4372
+ const workerFile = isBrowser2 ? worker.workerFile || `${worker.id}-worker.js` : worker.workerNode || `${worker.id}-worker-node.js`;
4373
+ let version2 = worker.version;
4374
+ if (version2 === "latest") {
4375
+ version2 = NPM_TAG;
4376
+ }
4377
+ const versionTag = version2 ? `@${version2}` : "";
4378
+ const url = `https://unpkg.com/@loaders.gl/${worker.module}${versionTag}/dist/${workerFile}`;
4379
+ if (warn) {
2996
4380
  warnIfUsingNpmTagFallback(worker, url);
2997
4381
  }
2998
- assert2(url);
2999
4382
  return url;
3000
4383
  }
3001
4384
  function warnIfUsingNpmTagFallback(worker, url) {
@@ -3029,19 +4412,16 @@ function canProcessOnWorker(worker, options) {
3029
4412
  return false;
3030
4413
  }
3031
4414
  const workerOptions = options == null ? void 0 : options[worker.id];
3032
- return Boolean((worker.worker || (workerOptions == null ? void 0 : workerOptions.workerUrl)) && (options == null ? void 0 : options.worker));
4415
+ return Boolean(
4416
+ (worker.worker || worker.loadWorker || (workerOptions == null ? void 0 : workerOptions.workerUrl)) && (options == null ? void 0 : options.worker)
4417
+ );
3033
4418
  }
3034
4419
  async function processOnWorker(worker, data, options = {}, context = {}, jobContext = {}) {
3035
4420
  var _a2, _b, _c;
3036
4421
  throwIfAborted(options.signal);
3037
4422
  const name = getWorkerName(worker);
3038
4423
  const workerFarm = WorkerFarm.getWorkerFarm(options);
3039
- const { source } = options;
3040
- const workerPoolProps = { name, source };
3041
- if (!source) {
3042
- workerPoolProps.url = getWorkerURL(worker, options);
3043
- }
3044
- const workerPool = workerFarm.getWorkerPool(workerPoolProps);
4424
+ const workerPool = workerFarm.getWorkerPool(getWorkerPoolTarget(worker, options, name));
3045
4425
  const jobName = options.jobName || worker.name;
3046
4426
  const job = await workerPool.startJob(
3047
4427
  jobName,
@@ -3070,6 +4450,115 @@ async function processOnWorker(worker, data, options = {}, context = {}, jobCont
3070
4450
  (_c = options.signal) == null ? void 0 : _c.removeEventListener("abort", abortJob);
3071
4451
  }
3072
4452
  }
4453
+ function processOnWorkerInBatches(worker, input, options = {}, context = {}, jobContext = {}) {
4454
+ return processOnWorkerInBatchesIterator(worker, input, options, context, jobContext);
4455
+ }
4456
+ async function* processOnWorkerInBatchesIterator(worker, input, options, context, jobContext) {
4457
+ var _a2, _b, _c;
4458
+ throwIfAborted(options.signal);
4459
+ const name = getWorkerName(worker);
4460
+ const workerFarm = WorkerFarm.getWorkerFarm(options);
4461
+ const workerPool = workerFarm.getWorkerPool(getWorkerPoolTarget(worker, options, name));
4462
+ const outputBatches = new AsyncQueue();
4463
+ const inputIterator = getAsyncIterator(input);
4464
+ let outputFinished = false;
4465
+ let inputFinished = false;
4466
+ let inputRequest = Promise.resolve();
4467
+ const batchJobFailed = new Error("Worker batch job failed");
4468
+ const finishOutput = () => {
4469
+ if (!outputFinished) {
4470
+ outputFinished = true;
4471
+ outputBatches.close();
4472
+ }
4473
+ };
4474
+ const failOutput = (_error) => {
4475
+ if (!outputFinished) {
4476
+ outputFinished = true;
4477
+ outputBatches.enqueue(batchJobFailed);
4478
+ outputBatches.close();
4479
+ }
4480
+ };
4481
+ const job = await workerPool.startJob(
4482
+ options.jobName || worker.name,
4483
+ (activeJob, type, payload) => {
4484
+ switch (type) {
4485
+ case "input-request":
4486
+ inputRequest = inputRequest.then(async () => {
4487
+ const nextBatch = await inputIterator.next();
4488
+ if (!activeJob.isRunning) {
4489
+ return;
4490
+ }
4491
+ if (nextBatch.done) {
4492
+ inputFinished = true;
4493
+ activeJob.postMessage("input-done", {});
4494
+ } else {
4495
+ activeJob.postMessage("input-batch", { input: nextBatch.value });
4496
+ }
4497
+ }).catch((error) => activeJob.abort(error));
4498
+ break;
4499
+ case "output-batch":
4500
+ outputBatches.push(payload.result);
4501
+ break;
4502
+ case "done":
4503
+ activeJob.done(payload);
4504
+ finishOutput();
4505
+ break;
4506
+ case "error": {
4507
+ const error = new Error(payload.error || "Worker batch processing failed");
4508
+ activeJob.error(error);
4509
+ failOutput(error);
4510
+ break;
4511
+ }
4512
+ case "process":
4513
+ void onMessage(context, activeJob, type, payload);
4514
+ break;
4515
+ default: {
4516
+ const error = new Error(`Unexpected worker batch message: ${type}`);
4517
+ activeJob.error(error);
4518
+ failOutput(error);
4519
+ break;
4520
+ }
4521
+ }
4522
+ }
4523
+ );
4524
+ const abortJob = () => job.abort(getAbortReason(options.signal));
4525
+ (_a2 = options.signal) == null ? void 0 : _a2.addEventListener("abort", abortJob, { once: true });
4526
+ if ((_b = options.signal) == null ? void 0 : _b.aborted) {
4527
+ abortJob();
4528
+ }
4529
+ void job.result.catch(failOutput);
4530
+ try {
4531
+ const { signal: _signal, ...workerOptions } = options;
4532
+ if (job.isRunning) {
4533
+ job.postMessage("process-in-batches", {
4534
+ options: getTransferListForWriter(workerOptions),
4535
+ context: getTransferListForWriter(jobContext)
4536
+ });
4537
+ }
4538
+ try {
4539
+ for await (const outputBatch of outputBatches) {
4540
+ yield outputBatch;
4541
+ if (job.isRunning) {
4542
+ job.postMessage("output-ack", {});
4543
+ }
4544
+ }
4545
+ } catch (error) {
4546
+ if (error === batchJobFailed) {
4547
+ await job.result;
4548
+ }
4549
+ throw error;
4550
+ }
4551
+ await job.result;
4552
+ } finally {
4553
+ (_c = options.signal) == null ? void 0 : _c.removeEventListener("abort", abortJob);
4554
+ if (job.isRunning) {
4555
+ job.abort(createAbortError2("Worker batch iterator was closed"));
4556
+ }
4557
+ if (!inputFinished) {
4558
+ closeInputIterator(inputIterator);
4559
+ }
4560
+ }
4561
+ }
3073
4562
  function throwIfAborted(signal) {
3074
4563
  if (!(signal == null ? void 0 : signal.aborted)) {
3075
4564
  return;
@@ -3084,6 +4573,39 @@ function createAbortError2(message) {
3084
4573
  error.name = "AbortError";
3085
4574
  return error;
3086
4575
  }
4576
+ function getAsyncIterator(input) {
4577
+ if (Symbol.asyncIterator in input) {
4578
+ return input[Symbol.asyncIterator]();
4579
+ }
4580
+ return (async function* iterateSynchronously() {
4581
+ yield* input;
4582
+ })();
4583
+ }
4584
+ function closeInputIterator(inputIterator) {
4585
+ var _a2;
4586
+ try {
4587
+ void Promise.resolve((_a2 = inputIterator.return) == null ? void 0 : _a2.call(inputIterator)).catch(() => void 0);
4588
+ } catch {
4589
+ }
4590
+ }
4591
+ function getWorkerPoolTarget(worker, options, name) {
4592
+ if (options.source) {
4593
+ return { name, source: options.source };
4594
+ }
4595
+ const customWorkerUrl = getCustomWorkerURL(worker, options);
4596
+ if (customWorkerUrl) {
4597
+ return { name, url: customWorkerUrl };
4598
+ }
4599
+ if (isBrowser2 && worker.loadWorker) {
4600
+ return {
4601
+ name,
4602
+ loadWorker: worker.loadWorker,
4603
+ getUrl: () => getWorkerURL(worker, options),
4604
+ urlKey: getDefaultWorkerURL(worker)
4605
+ };
4606
+ }
4607
+ return { name, url: getWorkerURL(worker, options) };
4608
+ }
3087
4609
  async function onMessage(context, job, type, payload) {
3088
4610
  switch (type) {
3089
4611
  case "done":
@@ -3113,9 +4635,11 @@ async function onMessage(context, job, type, payload) {
3113
4635
  var init_process_on_worker = __esm({
3114
4636
  "../worker-utils/src/lib/worker-api/process-on-worker.ts"() {
3115
4637
  "use strict";
4638
+ init_async_queue();
3116
4639
  init_worker_farm();
3117
4640
  init_get_worker_url();
3118
4641
  init_get_transfer_list();
4642
+ init_globals2();
3119
4643
  }
3120
4644
  });
3121
4645
 
@@ -3308,12 +4832,30 @@ function canParseWithWorker(loader, options) {
3308
4832
  }
3309
4833
  return Boolean(canProcessOnWorker(loader, workerOptions));
3310
4834
  }
4835
+ function shouldParseWithWorker(loader, data, options, context, estimateLoader = loader) {
4836
+ var _a2, _b;
4837
+ if (!canParseWithWorker(loader, options)) {
4838
+ return false;
4839
+ }
4840
+ if (((_a2 = options == null ? void 0 : options.core) == null ? void 0 : _a2.worker) !== "auto" || !estimateLoader.getWorkerEstimate) {
4841
+ return true;
4842
+ }
4843
+ try {
4844
+ const estimate = estimateLoader.getWorkerEstimate(data, options, context);
4845
+ if (estimate === void 0 || !Number.isFinite(estimate) || estimate < 0 || estimate > 1) {
4846
+ return true;
4847
+ }
4848
+ return estimate >= (((_b = options.core) == null ? void 0 : _b.workerThreshold) ?? 0.1);
4849
+ } catch {
4850
+ return true;
4851
+ }
4852
+ }
3311
4853
  async function parseWithWorker(loader, data, options, context, parseOnMainThread, signal) {
3312
4854
  const workerSignal = signal || getWorkerAbortSignal(options);
3313
4855
  const result = await processOnWorker(
3314
4856
  loader,
3315
4857
  data,
3316
- { ...getWorkerOptions(options), signal: workerSignal },
4858
+ { ...getWorkerOptions(options, loader), signal: workerSignal },
3317
4859
  {
3318
4860
  process: async (input, processOptions, _workerContext, parseContext) => {
3319
4861
  if (!parseOnMainThread) {
@@ -3332,8 +4874,34 @@ async function parseWithWorker(loader, data, options, context, parseOnMainThread
3332
4874
  );
3333
4875
  return isLoaderWithWorkerResultDeserializer(loader) ? loader.deserializeWorkerResult(result, options, context) : result;
3334
4876
  }
3335
- function getWorkerAbortSignal(options) {
3336
- var _a2;
4877
+ async function* parseWithWorkerInBatches(loader, inputIterator, options, context, parseOnMainThread, signal) {
4878
+ const workerSignal = signal || getWorkerAbortSignal(options);
4879
+ const outputIterator = processOnWorkerInBatches(
4880
+ loader,
4881
+ inputIterator,
4882
+ { ...getWorkerOptions(options), signal: workerSignal },
4883
+ {
4884
+ process: async (input, processOptions, _workerContext, parseContext) => {
4885
+ if (!parseOnMainThread) {
4886
+ throw new Error("Worker not set up to parse on main thread");
4887
+ }
4888
+ const mainThreadContext = context ? { ...context, ...parseContext || {} } : void 0;
4889
+ return await callParseOnMainThread(
4890
+ parseOnMainThread,
4891
+ input,
4892
+ processOptions,
4893
+ mainThreadContext
4894
+ );
4895
+ }
4896
+ },
4897
+ getSerializableLoaderContext(context)
4898
+ );
4899
+ for await (const batch of outputIterator) {
4900
+ yield loader.deserializeWorkerBatch ? loader.deserializeWorkerBatch(batch, options, context) : batch;
4901
+ }
4902
+ }
4903
+ function getWorkerAbortSignal(options) {
4904
+ var _a2;
3337
4905
  const parquetSignal = (_a2 = options == null ? void 0 : options.parquet) == null ? void 0 : _a2.signal;
3338
4906
  if (typeof AbortSignal !== "undefined" && parquetSignal instanceof AbortSignal) {
3339
4907
  return parquetSignal;
@@ -3346,12 +4914,19 @@ function callParseOnMainThread(parseOnMainThread, input, options, context) {
3346
4914
  }
3347
4915
  return parseOnMainThread(input, void 0, options, context);
3348
4916
  }
3349
- function getWorkerOptions(options = {}) {
4917
+ function getWorkerOptions(options = {}, loader) {
3350
4918
  const serializedOptions = JSON.parse(JSON.stringify(options));
3351
- return {
4919
+ const workerOptions = {
3352
4920
  ...serializedOptions.core,
3353
4921
  ...serializedOptions
3354
4922
  };
4923
+ if (workerOptions.worker === "auto") {
4924
+ workerOptions.worker = true;
4925
+ }
4926
+ if (loader) {
4927
+ workerOptions._workerLoaderId = loader.id;
4928
+ }
4929
+ return workerOptions;
3355
4930
  }
3356
4931
  function getSerializableLoaderContext(context) {
3357
4932
  if (!context) {
@@ -3506,6 +5081,31 @@ function createAuthenticatedFetch(options) {
3506
5081
  });
3507
5082
  return authenticatedFetch;
3508
5083
  }
5084
+ function getAuthenticatedFetch(options = {}) {
5085
+ var _a2, _b;
5086
+ const fetchOption = options.fetch ?? ((_a2 = options.core) == null ? void 0 : _a2.fetch);
5087
+ let fetchFunction;
5088
+ if (typeof fetchOption === "function") {
5089
+ fetchFunction = fetchOption;
5090
+ } else if (fetchOption) {
5091
+ fetchFunction = (url, requestOptions) => fetch(url, mergeFetchOptions(fetchOption, requestOptions));
5092
+ } else {
5093
+ fetchFunction = (url, requestOptions) => fetch(url, requestOptions);
5094
+ }
5095
+ return createAuthenticatedFetch({
5096
+ fetch: fetchFunction,
5097
+ credentials: ((_b = options.core) == null ? void 0 : _b.credentials) || []
5098
+ });
5099
+ }
5100
+ function mergeFetchOptions(defaultOptions, requestOptions) {
5101
+ const mergedOptions = { ...defaultOptions, ...requestOptions };
5102
+ if (defaultOptions.headers || (requestOptions == null ? void 0 : requestOptions.headers)) {
5103
+ const headers = new Headers(defaultOptions.headers);
5104
+ new Headers(requestOptions == null ? void 0 : requestOptions.headers).forEach((value, key) => headers.set(key, value));
5105
+ mergedOptions.headers = headers;
5106
+ }
5107
+ return mergedOptions;
5108
+ }
3509
5109
  async function authorizeRequest(sourceURL, requestOptions, credentials, tokenOverrides = /* @__PURE__ */ new Map(), previousCredentials = []) {
3510
5110
  const url = new URL(sourceURL);
3511
5111
  const headers = new Headers(requestOptions.headers);
@@ -4977,7 +6577,7 @@ function getFetchFunction(options) {
4977
6577
  if (typeof fetchOption === "function") {
4978
6578
  fetchFunction = (url, fetchOptions) => fetchOption(url, fetchOptions);
4979
6579
  } else if (fetchOption) {
4980
- fetchFunction = (url, requestOptions) => fetch(url, mergeFetchOptions(fetchOption, requestOptions));
6580
+ fetchFunction = (url, requestOptions) => fetch(url, mergeFetchOptions2(fetchOption, requestOptions));
4981
6581
  } else {
4982
6582
  fetchFunction = (url, requestOptions) => fetch(url, requestOptions);
4983
6583
  }
@@ -4986,7 +6586,7 @@ function getFetchFunction(options) {
4986
6586
  credentials: ((_b = options == null ? void 0 : options.core) == null ? void 0 : _b.credentials) || []
4987
6587
  });
4988
6588
  }
4989
- function mergeFetchOptions(fetchOptions, requestOptions) {
6589
+ function mergeFetchOptions2(fetchOptions, requestOptions) {
4990
6590
  const mergedOptions = { ...fetchOptions, ...requestOptions };
4991
6591
  if (fetchOptions.headers || (requestOptions == null ? void 0 : requestOptions.headers)) {
4992
6592
  mergedOptions.headers = mergeHeaders(fetchOptions.headers, requestOptions == null ? void 0 : requestOptions.headers);
@@ -5962,10 +7562,10 @@ function splitArrowTableBuffersInternal(table, options) {
5962
7562
  const recordBatches = table.batches.map(
5963
7563
  (recordBatch) => splitArrowRecordBatchBuffers(recordBatch, options)
5964
7564
  );
5965
- return new arrow6.Table(table.schema, recordBatches);
7565
+ return new arrow8.Table(table.schema, recordBatches);
5966
7566
  }
5967
7567
  function splitArrowRecordBatchBuffers(recordBatch, options) {
5968
- return new arrow6.RecordBatch(
7568
+ return new arrow8.RecordBatch(
5969
7569
  recordBatch.schema,
5970
7570
  splitArrowDataBuffers(recordBatch.data, options)
5971
7571
  );
@@ -5974,12 +7574,12 @@ function splitArrowDataBuffers(data, options) {
5974
7574
  const children = data.children.map((childData) => splitArrowDataBuffers(childData, options));
5975
7575
  const dictionary = data.dictionary ? splitArrowVectorBuffers(data.dictionary, options) : void 0;
5976
7576
  const buffers = {
5977
- [arrow6.BufferType.OFFSET]: splitArrowBuffer(data.buffers[arrow6.BufferType.OFFSET], options),
5978
- [arrow6.BufferType.DATA]: splitArrowBuffer(data.buffers[arrow6.BufferType.DATA], options),
5979
- [arrow6.BufferType.VALIDITY]: splitArrowBuffer(data.buffers[arrow6.BufferType.VALIDITY], options),
5980
- [arrow6.BufferType.TYPE]: splitArrowBuffer(data.buffers[arrow6.BufferType.TYPE], options)
7577
+ [arrow8.BufferType.OFFSET]: splitArrowBuffer(data.buffers[arrow8.BufferType.OFFSET], options),
7578
+ [arrow8.BufferType.DATA]: splitArrowBuffer(data.buffers[arrow8.BufferType.DATA], options),
7579
+ [arrow8.BufferType.VALIDITY]: splitArrowBuffer(data.buffers[arrow8.BufferType.VALIDITY], options),
7580
+ [arrow8.BufferType.TYPE]: splitArrowBuffer(data.buffers[arrow8.BufferType.TYPE], options)
5981
7581
  };
5982
- return new arrow6.Data(
7582
+ return new arrow8.Data(
5983
7583
  data.type,
5984
7584
  data.offset,
5985
7585
  data.length,
@@ -5991,7 +7591,7 @@ function splitArrowDataBuffers(data, options) {
5991
7591
  );
5992
7592
  }
5993
7593
  function splitArrowVectorBuffers(vector, options) {
5994
- return new arrow6.Vector(vector.data.map((data) => splitArrowDataBuffers(data, options)));
7594
+ return new arrow8.Vector(vector.data.map((data) => splitArrowDataBuffers(data, options)));
5995
7595
  }
5996
7596
  function splitArrowBuffer(array, options) {
5997
7597
  if (!isArrowTypedArray(array)) {
@@ -6008,11 +7608,11 @@ function splitArrowBuffer(array, options) {
6008
7608
  function isArrowTypedArray(value) {
6009
7609
  return ArrayBuffer.isView(value) && !(value instanceof DataView);
6010
7610
  }
6011
- var arrow6;
7611
+ var arrow8;
6012
7612
  var init_split_arrow_buffers = __esm({
6013
7613
  "../arrow/src/lib/utils/split-arrow-buffers.ts"() {
6014
7614
  "use strict";
6015
- arrow6 = __toESM(require("apache-arrow"), 1);
7615
+ arrow8 = __toESM(require("apache-arrow"), 1);
6016
7616
  }
6017
7617
  });
6018
7618
 
@@ -6029,9 +7629,9 @@ function dehydrateArrowTable(table, options) {
6029
7629
  function hydrateArrowTable(table) {
6030
7630
  const schema = deserializeArrowSchema(table.schema);
6031
7631
  const recordBatches = table.batches.map(
6032
- (recordBatch) => new arrow7.RecordBatch(schema, hydrateArrowData(recordBatch.data))
7632
+ (recordBatch) => new arrow9.RecordBatch(schema, hydrateArrowData(recordBatch.data))
6033
7633
  );
6034
- return new arrow7.Table(schema, recordBatches);
7634
+ return new arrow9.Table(schema, recordBatches);
6035
7635
  }
6036
7636
  function dehydrateArrowRecordBatch(recordBatch) {
6037
7637
  return { data: dehydrateArrowData(recordBatch.data) };
@@ -6044,10 +7644,10 @@ function dehydrateArrowData(data) {
6044
7644
  // @ts-expect-error _nullCount is protected. Preserve the Arrow lazy null-count state.
6045
7645
  nullCount: data._nullCount,
6046
7646
  buffers: {
6047
- [arrow7.BufferType.OFFSET]: data.buffers[arrow7.BufferType.OFFSET],
6048
- [arrow7.BufferType.DATA]: data.buffers[arrow7.BufferType.DATA],
6049
- [arrow7.BufferType.VALIDITY]: data.buffers[arrow7.BufferType.VALIDITY],
6050
- [arrow7.BufferType.TYPE]: data.buffers[arrow7.BufferType.TYPE]
7647
+ [arrow9.BufferType.OFFSET]: data.buffers[arrow9.BufferType.OFFSET],
7648
+ [arrow9.BufferType.DATA]: data.buffers[arrow9.BufferType.DATA],
7649
+ [arrow9.BufferType.VALIDITY]: data.buffers[arrow9.BufferType.VALIDITY],
7650
+ [arrow9.BufferType.TYPE]: data.buffers[arrow9.BufferType.TYPE]
6051
7651
  },
6052
7652
  children: data.children.map((childData) => dehydrateArrowData(childData)),
6053
7653
  dictionary: data.dictionary ? dehydrateArrowVector(data.dictionary) : void 0
@@ -6059,7 +7659,7 @@ function dehydrateArrowVector(vector) {
6059
7659
  function hydrateArrowData(data) {
6060
7660
  const children = data.children.map((childData) => hydrateArrowData(childData));
6061
7661
  const dictionary = data.dictionary ? hydrateArrowVector(data.dictionary) : void 0;
6062
- return new arrow7.Data(
7662
+ return new arrow9.Data(
6063
7663
  deserializeArrowType(data.type),
6064
7664
  data.offset,
6065
7665
  data.length,
@@ -6070,13 +7670,13 @@ function hydrateArrowData(data) {
6070
7670
  );
6071
7671
  }
6072
7672
  function hydrateArrowVector(vector) {
6073
- return new arrow7.Vector(vector.data.map((data) => hydrateArrowData(data)));
7673
+ return new arrow9.Vector(vector.data.map((data) => hydrateArrowData(data)));
6074
7674
  }
6075
- var arrow7;
7675
+ var arrow9;
6076
7676
  var init_arrow_table_transport = __esm({
6077
7677
  "../arrow/src/lib/utils/arrow-table-transport.ts"() {
6078
7678
  "use strict";
6079
- arrow7 = __toESM(require("apache-arrow"), 1);
7679
+ arrow9 = __toESM(require("apache-arrow"), 1);
6080
7680
  init_src2();
6081
7681
  init_split_arrow_buffers();
6082
7682
  }
@@ -6682,7 +8282,7 @@ var init_vector_tile = __esm({
6682
8282
 
6683
8283
  // ../mvt/src/lib/parse-mvt.ts
6684
8284
  function parseMVT(arrayBuffer, options) {
6685
- var _a2, _b;
8285
+ var _a2, _b, _c, _d;
6686
8286
  const mvtOptions = checkOptions(options);
6687
8287
  const shape = ((_a2 = options == null ? void 0 : options.gis) == null ? void 0 : _a2.format) || ((_b = options == null ? void 0 : options.mvt) == null ? void 0 : _b.shape) || (options == null ? void 0 : options.shape);
6688
8288
  switch (shape) {
@@ -6698,7 +8298,10 @@ function parseMVT(arrayBuffer, options) {
6698
8298
  }
6699
8299
  case "arrow-table": {
6700
8300
  const table = convertFeaturesToWKBArrowTable(
6701
- parseToGeojsonFeatures(arrayBuffer, mvtOptions)
8301
+ parseToGeojsonFeatures(arrayBuffer, mvtOptions),
8302
+ {
8303
+ encodingPreference: ((_c = options == null ? void 0 : options.geoarrow) == null ? void 0 : _c.encodingPreference) || ((_d = mvtOptions.geoarrow) == null ? void 0 : _d.encodingPreference)
8304
+ }
6702
8305
  );
6703
8306
  return table;
6704
8307
  }
@@ -7117,7 +8720,7 @@ var init_constants = __esm({
7117
8720
  });
7118
8721
 
7119
8722
  // ../i3s/src/i3s-format.ts
7120
- var binary, json, I3SFormat, I3SContentFormat, I3SAttributeFormat, I3SNodePageFormat, ArcGISWebSceneFormat, I3SBuildingSceneLayerFormat;
8723
+ var binary, json, I3SFormat, I3SContentFormat, I3SAttributeFormat, I3SLEPCCFormat, I3SNodePageFormat, ArcGISWebSceneFormat, I3SBuildingSceneLayerFormat;
7121
8724
  var init_i3s_format = __esm({
7122
8725
  "../i3s/src/i3s-format.ts"() {
7123
8726
  "use strict";
@@ -7146,6 +8749,7 @@ var init_i3s_format = __esm({
7146
8749
  I3SAttributeFormat = binary("I3S Attribute", "i3s-attribute", "i3s-attribute", [
7147
8750
  "bin"
7148
8751
  ]);
8752
+ I3SLEPCCFormat = binary("I3S LEPCC", "i3s-lepcc", "i3s-lepcc", ["bin"]);
7149
8753
  I3SNodePageFormat = json("I3S Node Page", "i3s-node-page", "i3s-node-page");
7150
8754
  ArcGISWebSceneFormat = json(
7151
8755
  "ArcGIS Web Scene",
@@ -7160,6 +8764,28 @@ var init_i3s_format = __esm({
7160
8764
  }
7161
8765
  });
7162
8766
 
8767
+ // ../i3s/src/i3s-loader-options.ts
8768
+ var I3S_LOADER_OPTIONS;
8769
+ var init_i3s_loader_options = __esm({
8770
+ "../i3s/src/i3s-loader-options.ts"() {
8771
+ "use strict";
8772
+ init_constants();
8773
+ I3S_LOADER_OPTIONS = {
8774
+ token: void 0,
8775
+ isTileset: "auto",
8776
+ isTileHeader: "auto",
8777
+ tile: void 0,
8778
+ tileset: void 0,
8779
+ _tileOptions: void 0,
8780
+ _tilesetOptions: void 0,
8781
+ useDracoGeometry: true,
8782
+ useCompressedTextures: true,
8783
+ decodeTextures: true,
8784
+ coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
8785
+ };
8786
+ }
8787
+ });
8788
+
7163
8789
  // ../draco/src/lib/draco-module-loader.ts
7164
8790
  async function loadDracoDecoderModule(options = {}, type, profile = "full") {
7165
8791
  const draco3DModule = getInjectedDraco3DModule(options);
@@ -10696,6 +12322,10 @@ var init_tileset_traverser = __esm({
10696
12322
  DEFAULT_PROPS3 = {
10697
12323
  loadSiblings: false,
10698
12324
  skipLevelOfDetail: false,
12325
+ baseScreenSpaceError: 1024,
12326
+ skipScreenSpaceErrorFactor: 16,
12327
+ skipLevels: 1,
12328
+ immediatelyLoadDesiredLevelOfDetail: false,
10699
12329
  updateTransforms: true,
10700
12330
  onTraversalEnd: () => {
10701
12331
  },
@@ -10704,6 +12334,8 @@ var init_tileset_traverser = __esm({
10704
12334
  };
10705
12335
  TilesetTraverser = class {
10706
12336
  options;
12337
+ /** Whether loaded content has disabled skip-LOD traversal for this tileset. */
12338
+ disableSkipLevelOfDetail = false;
10707
12339
  // fulfill in traverse call
10708
12340
  root = null;
10709
12341
  // tiles should be rendered
@@ -10729,6 +12361,10 @@ var init_tileset_traverser = __esm({
10729
12361
  constructor(options) {
10730
12362
  this.options = { ...DEFAULT_PROPS3, ...options };
10731
12363
  }
12364
+ /** Returns whether skip-LOD traversal is enabled and supported by the loaded content. */
12365
+ isSkipLevelOfDetailEnabled() {
12366
+ return this.options.skipLevelOfDetail && !this.disableSkipLevelOfDetail;
12367
+ }
10732
12368
  // tiles should be visible
10733
12369
  traverse(root, frameState, options) {
10734
12370
  this.root = root;
@@ -10786,13 +12422,17 @@ var init_tileset_traverser = __esm({
10786
12422
  this.selectTile(tile, frameState);
10787
12423
  } else if (tile.refine === 2 /* REPLACE */) {
10788
12424
  this.loadTile(tile, frameState);
10789
- if (stoppedRefining || this.options.skipLevelOfDetail) {
12425
+ if (stoppedRefining || this.isSkipLevelOfDetailEnabled()) {
10790
12426
  this.selectTile(tile, frameState);
10791
12427
  }
10792
12428
  }
10793
12429
  this.touchTile(tile, frameState);
10794
12430
  tile._shouldRefine = shouldRefine && parentRefines;
10795
12431
  }
12432
+ this.completeTraversal(frameState);
12433
+ }
12434
+ /** Notifies the owning tileset when traversal is complete or its debounce interval expires. */
12435
+ completeTraversal(frameState) {
10796
12436
  const newTime = (/* @__PURE__ */ new Date()).getTime();
10797
12437
  if (this.traversalFinished(frameState) || newTime - this.lastUpdate > this.updateDebounceTime) {
10798
12438
  this.lastUpdate = newTime;
@@ -10807,7 +12447,8 @@ var init_tileset_traverser = __esm({
10807
12447
  }
10808
12448
  /* eslint-disable complexity, max-statements */
10809
12449
  updateAndPushChildren(tile, frameState, stack, depth) {
10810
- const { loadSiblings, skipLevelOfDetail } = this.options;
12450
+ const { loadSiblings } = this.options;
12451
+ const skipLevelOfDetail = this.isSkipLevelOfDetailEnabled();
10811
12452
  const children = tile.children;
10812
12453
  children.sort(this.compareDistanceToCamera.bind(this));
10813
12454
  const checkRefines = tile.refine === 2 /* REPLACE */ && tile.hasRenderContent && !skipLevelOfDetail;
@@ -11343,7 +12984,7 @@ var init_tile_3d = __esm({
11343
12984
  // eslint-disable-next-line complexity
11344
12985
  _calculateRequestPriority(allowUnloadedContent) {
11345
12986
  const traverser = this.tileset._traverser;
11346
- const { skipLevelOfDetail } = traverser.options;
12987
+ const skipLevelOfDetail = traverser.options.skipLevelOfDetail && !traverser.disableSkipLevelOfDetail;
11347
12988
  const maySkipTile = this.refine === 1 /* ADD */ || skipLevelOfDetail;
11348
12989
  if (maySkipTile && !this.isVisible && this._visible !== void 0) {
11349
12990
  return -1;
@@ -11574,9 +13215,11 @@ var init_tile_3d = __esm({
11574
13215
  return;
11575
13216
  }
11576
13217
  this._foveatedFactor = calculateFoveatedFactor(this.boundingVolume, frameState.camera);
13218
+ const traverser = this.tileset._traverser;
13219
+ const skipLevelOfDetail = traverser.options.skipLevelOfDetail && !traverser.disableSkipLevelOfDetail;
11577
13220
  const deferralEligible = isFoveatedRequestDeferred({
11578
13221
  refinement: this.refine,
11579
- skipLevelOfDetail: this.tileset._traverser.options.skipLevelOfDetail,
13222
+ skipLevelOfDetail,
11580
13223
  foveatedScreenSpaceError: options.foveatedScreenSpaceError,
11581
13224
  foveatedConeSize: options.foveatedConeSize,
11582
13225
  minimumScreenSpaceErrorRelaxation: options.foveatedMinimumScreenSpaceErrorRelaxation,
@@ -13217,6 +14860,9 @@ var init_i3s_spatial_transformer = __esm({
13217
14860
  });
13218
14861
 
13219
14862
  // ../tiles/src/tileset-3d/format-i3s/i3s-source.ts
14863
+ function getI3SContentLoader(loader) {
14864
+ return loader.contentLoader || loader;
14865
+ }
13220
14866
  function isTilesetRequest(input) {
13221
14867
  return Boolean(
13222
14868
  input && typeof input === "object" && "url" in input && "loader" in input && !("type" in input)
@@ -13258,8 +14904,10 @@ var init_i3s_source = __esm({
13258
14904
  I3SSource = class {
13259
14905
  /** I3S format discriminator. */
13260
14906
  type = "I3S" /* I3S */;
13261
- /** Loader used for tile metadata and content requests. */
14907
+ /** Primary I3S loader used for root and child metadata requests. */
13262
14908
  loader;
14909
+ /** Worker-capable loader used for binary tile content when supplied by the format loader. */
14910
+ contentLoader;
13263
14911
  /** Root I3S layer URL. */
13264
14912
  url;
13265
14913
  /** Base path used for relative tile resource resolution. */
@@ -13294,6 +14942,7 @@ var init_i3s_source = __esm({
13294
14942
  this.rootTileset = isTilesetRequest(input) ? null : input;
13295
14943
  this.tileset = this.rootTileset;
13296
14944
  this.loader = request.loader;
14945
+ this.contentLoader = getI3SContentLoader(request.loader);
13297
14946
  this.url = request.url;
13298
14947
  this.basePath = request.basePath || path_exports.dirname(request.url);
13299
14948
  this.resolver = request.resolver;
@@ -13415,7 +15064,7 @@ var init_i3s_source = __esm({
13415
15064
  isTileHeader: false
13416
15065
  }
13417
15066
  };
13418
- tile.content = await this.loadResourceData(contentUrl, options);
15067
+ tile.content = await this.loadResourceData(contentUrl, options, this.contentLoader);
13419
15068
  return { loaded: true };
13420
15069
  }
13421
15070
  /**
@@ -13552,11 +15201,11 @@ var init_i3s_source = __esm({
13552
15201
  /**
13553
15202
  * Loads data through injected core APIs so this module stays independent from `@loaders.gl/core`.
13554
15203
  */
13555
- async loadWithCoreApi(url, options) {
15204
+ async loadWithCoreApi(url, options, loader = this.loader) {
13556
15205
  if (!this.coreApi) {
13557
15206
  throw new Error("I3SSource requires an injected coreApi to load tileset data");
13558
15207
  }
13559
- return await this.coreApi.load(url, this.loader, options);
15208
+ return await this.coreApi.load(url, loader, options);
13560
15209
  }
13561
15210
  /**
13562
15211
  * Loads data through an injected resolver when present, otherwise through the injected core API.
@@ -13583,11 +15232,11 @@ var init_i3s_source = __esm({
13583
15232
  /**
13584
15233
  * Loads tile metadata or content through an injected resolver when present, otherwise through the injected core API.
13585
15234
  */
13586
- async loadResourceData(url, options) {
15235
+ async loadResourceData(url, options, loader = this.loader) {
13587
15236
  if (this.resolver) {
13588
- return await this.resolver.loadResource(url, this.loader, options);
15237
+ return await this.resolver.loadResource(url, loader, options);
13589
15238
  }
13590
- return await this.loadWithCoreApi(url, options);
15239
+ return await this.loadWithCoreApi(url, options, loader);
13591
15240
  }
13592
15241
  /** Transform one I3S header bound after target options and elevation providers are available. */
13593
15242
  async transformTileHeader(header) {
@@ -14330,33 +15979,6 @@ var init_parse_i3s_tile_content = __esm({
14330
15979
  }
14331
15980
  });
14332
15981
 
14333
- // ../i3s/src/i3s-content-loader.ts
14334
- var VERSION8, I3SContentLoader;
14335
- var init_i3s_content_loader = __esm({
14336
- "../i3s/src/i3s-content-loader.ts"() {
14337
- "use strict";
14338
- init_i3s_format();
14339
- VERSION8 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
14340
- I3SContentLoader = {
14341
- ...I3SContentFormat,
14342
- dataType: null,
14343
- batchType: null,
14344
- name: "I3S Content (Indexed Scene Layers)",
14345
- id: "i3s-content",
14346
- module: "i3s",
14347
- worker: true,
14348
- version: VERSION8,
14349
- mimeTypes: ["application/octet-stream"],
14350
- /** Loads the parser-bearing I3S content loader implementation. */
14351
- preload: async () => (await Promise.resolve().then(() => (init_i3s_content_loader_with_parser(), i3s_content_loader_with_parser_exports))).I3SContentLoaderWithParser,
14352
- extensions: ["bin"],
14353
- options: {
14354
- "i3s-content": {}
14355
- }
14356
- };
14357
- }
14358
- });
14359
-
14360
15982
  // ../i3s/src/i3s-content-loader-with-parser.ts
14361
15983
  var i3s_content_loader_with_parser_exports = {};
14362
15984
  __export(i3s_content_loader_with_parser_exports, {
@@ -14391,6 +16013,35 @@ var init_i3s_content_loader_with_parser = __esm({
14391
16013
  }
14392
16014
  });
14393
16015
 
16016
+ // ../i3s/src/i3s-content-loader.ts
16017
+ var VERSION8, I3SContentLoader;
16018
+ var init_i3s_content_loader = __esm({
16019
+ "../i3s/src/i3s-content-loader.ts"() {
16020
+ "use strict";
16021
+ init_i3s_format();
16022
+ init_i3s_loader_options();
16023
+ VERSION8 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
16024
+ I3SContentLoader = {
16025
+ ...I3SContentFormat,
16026
+ dataType: null,
16027
+ batchType: null,
16028
+ name: "I3S Content (Indexed Scene Layers)",
16029
+ id: "i3s-content",
16030
+ module: "i3s",
16031
+ worker: true,
16032
+ version: VERSION8,
16033
+ mimeTypes: ["application/octet-stream"],
16034
+ /** Loads the parser-bearing I3S content loader implementation. */
16035
+ preload: async () => (await Promise.resolve().then(() => (init_i3s_content_loader_with_parser(), i3s_content_loader_with_parser_exports))).I3SContentLoaderWithParser,
16036
+ extensions: ["bin"],
16037
+ options: {
16038
+ i3s: I3S_LOADER_OPTIONS,
16039
+ "i3s-content": {}
16040
+ }
16041
+ };
16042
+ }
16043
+ });
16044
+
14394
16045
  // ../core/src/lib/fetch/fetch-error.ts
14395
16046
  var FetchError;
14396
16047
  var init_fetch_error = __esm({
@@ -14740,6 +16391,7 @@ var init_option_defaults = __esm({
14740
16391
  CDN: "https://unpkg.com/@loaders.gl",
14741
16392
  worker: true,
14742
16393
  // By default, use worker if provided by loader.
16394
+ workerThreshold: 0.1,
14743
16395
  maxConcurrency: 3,
14744
16396
  // How many worker instances should be created for each loader.
14745
16397
  maxMobileConcurrency: 1,
@@ -14826,7 +16478,10 @@ function normalizeOptions(options, loader, loaders, url) {
14826
16478
  loaders = loaders || [];
14827
16479
  loaders = Array.isArray(loaders) ? loaders : [loaders];
14828
16480
  validateOptions(options, loaders);
14829
- return normalizeLoaderOptions(normalizeOptionsInternal(loader, options, url));
16481
+ validateWorkerThreshold(options);
16482
+ const normalizedOptions = normalizeLoaderOptions(normalizeOptionsInternal(loader, options, url));
16483
+ validateWorkerThreshold(normalizedOptions);
16484
+ return normalizedOptions;
14830
16485
  }
14831
16486
  function normalizeLoaderOptions(options) {
14832
16487
  const normalized = cloneLoaderOptions(options);
@@ -14850,6 +16505,13 @@ function validateOptions(options, loaders) {
14850
16505
  validateOptionsObject(idOptions, loader.id, loaderOptions, deprecatedOptions, loaders);
14851
16506
  }
14852
16507
  }
16508
+ function validateWorkerThreshold(options) {
16509
+ var _a2;
16510
+ const threshold = (_a2 = options.core) == null ? void 0 : _a2.workerThreshold;
16511
+ if (threshold !== void 0 && (!Number.isFinite(threshold) || threshold < 0 || threshold > 1)) {
16512
+ throw new Error("core.workerThreshold must be a finite number between 0 and 1");
16513
+ }
16514
+ }
14853
16515
  function validateOptionsObject(options, id, defaultOptions, deprecatedOptions, loaders) {
14854
16516
  const loaderName = id || "Top level";
14855
16517
  const prefix = id ? `${id}.` : "";
@@ -15023,6 +16685,7 @@ var init_option_utils = __esm({
15023
16685
  "useLocalLibraries",
15024
16686
  "CDN",
15025
16687
  "worker",
16688
+ "workerThreshold",
15026
16689
  "maxConcurrency",
15027
16690
  "maxMobileConcurrency",
15028
16691
  "reuseWorkers",
@@ -15661,7 +17324,8 @@ function getFetchFunction2(options, context) {
15661
17324
  if (typeof fetchOption === "function") {
15662
17325
  fetchFunction = fetchOption;
15663
17326
  } else if (isObject(fetchOption)) {
15664
- fetchFunction = (url, requestOptions) => fetchFile(url, mergeFetchOptions2(fetchOption, requestOptions));
17327
+ const baseFetch = (context == null ? void 0 : context.fetch) || fetchFile;
17328
+ fetchFunction = (url, requestOptions) => baseFetch(url, mergeFetchOptions3(fetchOption, requestOptions));
15665
17329
  } else if (context == null ? void 0 : context.fetch) {
15666
17330
  fetchFunction = context.fetch;
15667
17331
  } else {
@@ -15672,7 +17336,7 @@ function getFetchFunction2(options, context) {
15672
17336
  credentials: ((_b = loaderOptions.core) == null ? void 0 : _b.credentials) || []
15673
17337
  });
15674
17338
  }
15675
- function mergeFetchOptions2(defaultOptions, requestOptions) {
17339
+ function mergeFetchOptions3(defaultOptions, requestOptions) {
15676
17340
  const options = { ...defaultOptions, ...requestOptions };
15677
17341
  if (defaultOptions.headers || (requestOptions == null ? void 0 : requestOptions.headers)) {
15678
17342
  const headers = new Headers(defaultOptions.headers);
@@ -15983,6 +17647,9 @@ async function parseToOutputIterator(loader, data, options, context) {
15983
17647
  ((_a2 = options == null ? void 0 : options.core) == null ? void 0 : _a2.transforms) || []
15984
17648
  );
15985
17649
  if (loader.parseInBatches) {
17650
+ if (loader.id === "csv" && isBrowser && canParseWithWorker(loader, options)) {
17651
+ return parseWithWorkerInBatches(loader, transformedIterator, options, context, parse2);
17652
+ }
15986
17653
  return loader.parseInBatches(transformedIterator, options, context);
15987
17654
  }
15988
17655
  return parseChunkInBatches(transformedIterator, loader, options, context);
@@ -16223,7 +17890,10 @@ var init_core_api = __esm({
16223
17890
  // ../core/src/lib/loader-utils/loader-context.ts
16224
17891
  function getLoaderContext(context, options, parentContext) {
16225
17892
  if (parentContext) {
16226
- return parentContext;
17893
+ return {
17894
+ ...parentContext,
17895
+ fetch: getFetchFunction2(options, parentContext)
17896
+ };
16227
17897
  }
16228
17898
  const newContext = {
16229
17899
  ...context,
@@ -16305,7 +17975,7 @@ async function parseWithLoader(loader, data, options, context) {
16305
17975
  context.response = { headers, ok, redirected, status, statusText, type, url };
16306
17976
  }
16307
17977
  const loaderWithParser = await getLoaderImplementation(loader, options, context.url);
16308
- if (canParseWithWorker(loaderWithParser, options)) {
17978
+ if (shouldParseWithWorker(loaderWithParser, data, options, context, loader)) {
16309
17979
  data = await getArrayBufferFromData(data, options);
16310
17980
  return await parseWithWorker(loaderWithParser, data, options, context, parse2);
16311
17981
  }
@@ -16407,15 +18077,13 @@ var init_i3s_node_page_loader_with_parser = __esm({
16407
18077
  });
16408
18078
 
16409
18079
  // ../i3s/src/lib/helpers/i3s-nodepages-tiles.ts
16410
- async function loadNodePage(url, options) {
16411
- var _a2;
16412
- const fetchFunction = typeof options.fetch === "function" ? options.fetch : typeof ((_a2 = options.core) == null ? void 0 : _a2.fetch) === "function" ? options.core.fetch : fetch;
18080
+ async function loadNodePage(url, fetchFunction) {
16413
18081
  const response = await fetchFunction(url);
16414
18082
  if (!response.ok) {
16415
18083
  throw new Error(`Failed to load I3S node page: ${response.status} ${response.statusText}`);
16416
18084
  }
16417
18085
  const arrayBuffer = await response.arrayBuffer();
16418
- return await I3SNodePageLoaderWithParser.parse(arrayBuffer, options);
18086
+ return await I3SNodePageLoaderWithParser.parse(arrayBuffer);
16419
18087
  }
16420
18088
  function getSupportedGPUTextureFormats(gl) {
16421
18089
  const formats = /* @__PURE__ */ new Set();
@@ -16456,6 +18124,7 @@ var init_i3s_nodepages_tiles = __esm({
16456
18124
  init_i3s_node_page_loader_with_parser();
16457
18125
  init_parse_i3s();
16458
18126
  init_url_utils();
18127
+ init_src5();
16459
18128
  BROWSER_PREFIXES2 = ["", "WEBKIT_", "MOZ_"];
16460
18129
  WEBGL_EXTENSIONS = {
16461
18130
  /* eslint-disable camelcase */
@@ -16479,6 +18148,7 @@ var init_i3s_nodepages_tiles = __esm({
16479
18148
  textureDefinitionsSelectedFormats = [];
16480
18149
  nodesInNodePages;
16481
18150
  url;
18151
+ fetchFunction;
16482
18152
  textureLoaderOptions = {};
16483
18153
  /**
16484
18154
  * @constructs
@@ -16486,14 +18156,16 @@ var init_i3s_nodepages_tiles = __esm({
16486
18156
  * @param tileset - i3s tileset header ('layers/0')
16487
18157
  * @param url - tileset url
16488
18158
  * @param options - i3s loader options
18159
+ * @param context - loader context carrying the authenticated fetch function
16489
18160
  */
16490
- constructor(tileset, url = "", options) {
18161
+ constructor(tileset, url = "", options, context) {
16491
18162
  this.tileset = { ...tileset };
16492
18163
  this.url = url;
16493
18164
  const nodePageDefinition = tileset.nodePages || tileset.pointNodePages;
16494
18165
  this.nodesPerPage = (nodePageDefinition == null ? void 0 : nodePageDefinition.nodesPerPage) || 64;
16495
18166
  this.lodSelectionMetricType = nodePageDefinition == null ? void 0 : nodePageDefinition.lodSelectionMetricType;
16496
18167
  this.options = options;
18168
+ this.fetchFunction = (context == null ? void 0 : context.fetch) || getAuthenticatedFetch(options);
16497
18169
  this.nodesInNodePages = 0;
16498
18170
  this.initSelectedFormatsForTextureDefinitions(tileset);
16499
18171
  }
@@ -16512,7 +18184,7 @@ var init_i3s_nodepages_tiles = __esm({
16512
18184
  );
16513
18185
  this.pendingNodePages[pageIndex] = {
16514
18186
  status: "Pending",
16515
- promise: loadNodePage(nodePageUrl, this.options)
18187
+ promise: loadNodePage(nodePageUrl, this.fetchFunction)
16516
18188
  };
16517
18189
  this.nodePages[pageIndex] = await this.pendingNodePages[pageIndex].promise;
16518
18190
  this.nodesInNodePages += this.nodePages[pageIndex].nodes.length;
@@ -16943,7 +18615,7 @@ async function normalizeTilesetData(tileset, options, context) {
16943
18615
  let root;
16944
18616
  const nodePageDefinition = tileset.nodePages || tileset.pointNodePages;
16945
18617
  if (nodePageDefinition) {
16946
- nodePagesTile = new I3SNodePagesTiles(tileset, url, options);
18618
+ nodePagesTile = new I3SNodePagesTiles(tileset, url, options, context);
16947
18619
  root = await nodePagesTile.formTileFromNodePages(nodePageDefinition.rootIndex || 0);
16948
18620
  } else {
16949
18621
  const parseOptions = options.i3s && typeof options.i3s === "object" ? options.i3s : {};
@@ -17074,8 +18746,9 @@ var VERSION10, I3SLoader;
17074
18746
  var init_i3s_loader = __esm({
17075
18747
  "../i3s/src/i3s-loader.ts"() {
17076
18748
  "use strict";
17077
- init_constants();
17078
18749
  init_i3s_format();
18750
+ init_i3s_content_loader();
18751
+ init_i3s_loader_options();
17079
18752
  VERSION10 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
17080
18753
  I3SLoader = {
17081
18754
  ...I3SFormat,
@@ -17084,25 +18757,15 @@ var init_i3s_loader = __esm({
17084
18757
  name: "I3S (Indexed Scene Layers)",
17085
18758
  id: "i3s",
17086
18759
  module: "i3s",
18760
+ /** Worker-capable loader used by I3S sources for binary tile content. */
18761
+ contentLoader: I3SContentLoader,
17087
18762
  version: VERSION10,
17088
18763
  mimeTypes: ["application/octet-stream"],
17089
18764
  /** Loads the parser-bearing I3S loader implementation. */
17090
18765
  preload: async () => (await Promise.resolve().then(() => (init_i3s_loader_with_parser(), i3s_loader_with_parser_exports))).I3SLoaderWithParser,
17091
18766
  extensions: ["bin"],
17092
18767
  options: {
17093
- i3s: {
17094
- token: void 0,
17095
- isTileset: "auto",
17096
- isTileHeader: "auto",
17097
- tile: void 0,
17098
- tileset: void 0,
17099
- _tileOptions: void 0,
17100
- _tilesetOptions: void 0,
17101
- useDracoGeometry: true,
17102
- useCompressedTextures: true,
17103
- decodeTextures: true,
17104
- coordinateSystem: COORDINATE_SYSTEM.METER_OFFSETS
17105
- }
18768
+ i3s: I3S_LOADER_OPTIONS
17106
18769
  }
17107
18770
  };
17108
18771
  }
@@ -19286,113 +20949,650 @@ var init_parse_slpk = __esm({
19286
20949
  }
19287
20950
  });
19288
20951
 
19289
- // dist/index.js
19290
- var index_exports = {};
19291
- __export(index_exports, {
19292
- ArcGISFeatureServerSourceLoader: () => ArcGISFeatureServerSourceLoader,
19293
- ArcGISImageServerSourceLoader: () => ArcGISImageServerSourceLoader,
19294
- ArcGISImageSource: () => ArcGISImageSource,
19295
- ArcGISImageTileSource: () => ArcGISImageTileSource,
19296
- ArcGISImageTileSourceLoader: () => ArcGISImageTileSourceLoader,
19297
- ArcGISMapTileSource: () => ArcGISMapTileSource,
19298
- ArcGISMapTileSourceLoader: () => ArcGISMapTileSourceLoader,
19299
- ArcGISSceneServerQueryError: () => ArcGISSceneServerQueryError,
19300
- ArcGISSceneServerSource: () => ArcGISSceneServerSource,
19301
- ArcGISSceneServerSourceLoader: () => ArcGISSceneServerSourceLoader,
19302
- ArcGISVectorSource: () => ArcGISVectorSource,
19303
- ArcGISVectorTileServerSource: () => ArcGISVectorTileServerSource,
19304
- ArcGISVectorTileServerSourceLoader: () => ArcGISVectorTileServerSourceLoader,
19305
- SERVICE_LOADERS: () => SERVICE_LOADERS,
19306
- aggregateArcGISSceneFeatures: () => aggregateArcGISSceneFeatures,
19307
- createArcGISCredential: () => createArcGISCredential,
19308
- createCesiumIonCredential: () => createCesiumIonCredential,
19309
- createGoogleMapsCredential: () => createGoogleMapsCredential,
19310
- createMapboxCredential: () => createMapboxCredential,
19311
- discoverArcGISCapabilities: () => discoverArcGISCapabilities,
19312
- getArcGISServices: () => getArcGISServices,
19313
- getServiceLoader: () => getServiceLoader,
19314
- selectArcGISService: () => selectArcGISService
19315
- });
19316
- module.exports = __toCommonJS(index_exports);
19317
-
19318
- // dist/arcgis/arcgis-server.js
19319
- async function getArcGISServices(url, fetchFile2 = fetch) {
19320
- if (url.includes("rest/services")) {
19321
- const serverUrl = url.replace(/rest\/services.*$/i, "rest/services");
19322
- return loadServiceDirectory(serverUrl, fetchFile2, []);
20952
+ // ../i3s/src/i3s-lepcc.ts
20953
+ function readMagic(bytes) {
20954
+ if (bytes.byteLength < 10) {
20955
+ throw new Error("Truncated LEPCC blob header");
19323
20956
  }
19324
- return null;
20957
+ return new TextDecoder().decode(bytes.subarray(0, 10));
19325
20958
  }
19326
- async function loadServiceDirectory(serverUrl, fetch2, path) {
19327
- const serviceUrl = path.length ? `${serverUrl}/${path.join("/")}` : serverUrl;
19328
- const response = await fetch2(`${serviceUrl}?f=pjson`);
19329
- const directory = await response.json();
19330
- const services = extractServices(directory, serviceUrl, serverUrl);
19331
- const folders = directory.folders || [];
19332
- const promises = folders.map((folder) => loadServiceDirectory(`${serverUrl}`, fetch2, [...path, folder]));
19333
- for (const folderServices of await Promise.all(promises)) {
19334
- services.push(...folderServices);
20959
+ function readHeader(reader, expectedMagic, headerSize, verifyChecksum) {
20960
+ const magic = new TextDecoder().decode(reader.readBytes(10));
20961
+ if (magic !== expectedMagic) {
20962
+ throw new Error(`Unexpected LEPCC blob type: ${JSON.stringify(magic)}`);
19335
20963
  }
19336
- return services;
19337
- }
19338
- function extractServices(directory, url, serverUrl) {
19339
- const arcgisServices = directory.services || [];
19340
- const services = [];
19341
- for (const service of arcgisServices) {
19342
- services.push({
19343
- name: service.name,
19344
- type: `arcgis-${service.type.toLocaleLowerCase().replace("server", "-server")}`,
19345
- url: `${service.name.includes("/") ? serverUrl : url}/${service.name}/${service.type}`
19346
- });
20964
+ const version2 = reader.readUint16();
20965
+ if (version2 > 1) {
20966
+ throw new Error(`Unsupported LEPCC version: ${version2}`);
19347
20967
  }
19348
- return services;
19349
- }
19350
-
19351
- // dist/arcgis/arcgis-capability-graph.js
19352
- async function discoverArcGISCapabilities(url, options = {}) {
19353
- const fetchFile2 = options.fetch || fetch;
19354
- const services = await getArcGISServices(url, fetchFile2);
19355
- if (!services)
19356
- return null;
19357
- const nodes = await Promise.all(services.map(async (service) => {
19358
- let metadata = await fetchServiceMetadata(service.url, fetchFile2);
19359
- if (service.type.toLowerCase().includes("scene")) {
19360
- metadata = await enrichSceneServerMetadata(service.url, metadata, fetchFile2);
20968
+ const expectedChecksum = reader.readUint32();
20969
+ const blobSize = reader.readBigUint64();
20970
+ if (blobSize < headerSize || blobSize > reader.bytes.byteLength) {
20971
+ throw new Error(`Invalid LEPCC blob size: ${blobSize}`);
20972
+ }
20973
+ if (verifyChecksum) {
20974
+ const actualChecksum = computeFletcher32(reader.bytes.subarray(16, blobSize));
20975
+ if (actualChecksum !== expectedChecksum) {
20976
+ throw new Error("LEPCC checksum mismatch");
19361
20977
  }
19362
- return normalizeServiceCapabilities(service, metadata);
19363
- }));
19364
- return { rootUrl: url, nodes };
19365
- }
19366
- function selectArcGISService(graph, requirements = {}) {
19367
- return graph.nodes.find((node) => {
19368
- if (requirements.kind && node.kind !== requirements.kind)
19369
- return false;
19370
- if (requirements.format && !node.capabilities.formats.includes(requirements.format.toLowerCase()))
19371
- return false;
19372
- if (requirements.crs && !node.capabilities.crs.includes(requirements.crs))
19373
- return false;
19374
- if (requirements.profile && node.metadata.profile !== requirements.profile && !node.capabilities.layers.some((layer) => layer.profile === requirements.profile))
19375
- return false;
19376
- if (requirements.layerId !== void 0 && !node.capabilities.layers.some((layer) => layer.id === String(requirements.layerId) || layer.name === String(requirements.layerId)))
19377
- return false;
19378
- return true;
19379
- });
20978
+ }
20979
+ return { blobSize };
19380
20980
  }
19381
- async function fetchServiceMetadata(serviceUrl, fetchFile2) {
19382
- const url = new URL(serviceUrl);
19383
- url.searchParams.set("f", "pjson");
19384
- const response = await fetchFile2(url.toString());
19385
- if (!response.ok) {
19386
- throw new Error(`ArcGIS service metadata request failed: ${response.status}`);
20981
+ function assertBlobConsumed(reader, blobSize) {
20982
+ if (reader.offset !== blobSize) {
20983
+ throw new Error(`LEPCC decoder consumed ${reader.offset} bytes, expected ${blobSize}`);
19387
20984
  }
19388
- return await response.json();
19389
20985
  }
19390
- async function enrichSceneServerMetadata(serviceUrl, metadata, fetchFile2) {
19391
- const layers = Array.isArray(metadata.layers) ? metadata.layers : [];
19392
- if (!layers.length)
19393
- return metadata;
19394
- const enrichedLayers = await Promise.all(layers.map(async (value) => {
19395
- if (!value || typeof value !== "object")
20986
+ function computeFletcher32(bytes) {
20987
+ let sum1 = 65535;
20988
+ let sum2 = 65535;
20989
+ let offset = 0;
20990
+ let words = Math.floor(bytes.length / 2);
20991
+ while (words > 0) {
20992
+ const count = Math.min(words, 359);
20993
+ words -= count;
20994
+ for (let index = 0; index < count; index++) {
20995
+ sum1 += bytes[offset++] << 8;
20996
+ sum1 += bytes[offset++];
20997
+ sum2 += sum1;
20998
+ }
20999
+ sum1 = (sum1 & 65535) + (sum1 >>> 16);
21000
+ sum2 = (sum2 & 65535) + (sum2 >>> 16);
21001
+ }
21002
+ if (bytes.length & 1) {
21003
+ sum1 += bytes[offset] << 8;
21004
+ sum2 += sum1;
21005
+ }
21006
+ sum1 = (sum1 & 65535) + (sum1 >>> 16);
21007
+ sum2 = (sum2 & 65535) + (sum2 >>> 16);
21008
+ return (sum2 << 16 | sum1) >>> 0;
21009
+ }
21010
+ function decodeCutInSegments(reader) {
21011
+ const sectionMinimums = decodeSimple(reader);
21012
+ const values = [];
21013
+ for (const sectionMinimum of sectionMinimums) {
21014
+ const sectionValues = decodeSimple(reader);
21015
+ for (const sectionValue of sectionValues) {
21016
+ values.push(sectionValue + sectionMinimum);
21017
+ }
21018
+ }
21019
+ return values;
21020
+ }
21021
+ function decodeSimple(reader) {
21022
+ const header = reader.readUint8();
21023
+ const numberOfBits = header & 31;
21024
+ const encodedNumberOfBytes = header >>> 6;
21025
+ const numberOfBytes = encodedNumberOfBytes === 0 ? 4 : 3 - encodedNumberOfBytes;
21026
+ if (numberOfBytes !== 1 && numberOfBytes !== 2 && numberOfBytes !== 4) {
21027
+ throw new Error("Invalid LEPCC bit-stuffer element width");
21028
+ }
21029
+ const elementCount = numberOfBytes === 1 ? reader.readUint8() : numberOfBytes === 2 ? reader.readUint16() : reader.readUint32();
21030
+ if (header & 32) {
21031
+ throw new Error("LEPCC lookup-table bit stuffing is not supported");
21032
+ }
21033
+ if (numberOfBits === 0) {
21034
+ return new Array(elementCount).fill(0);
21035
+ }
21036
+ const bitReader = new BitReader(reader);
21037
+ const values = new Array(elementCount);
21038
+ for (let index = 0; index < elementCount; index++) {
21039
+ values[index] = bitReader.readBits(numberOfBits);
21040
+ }
21041
+ bitReader.alignToByte();
21042
+ return values;
21043
+ }
21044
+ function decodeHuffman(reader, elementCount) {
21045
+ const version2 = reader.readUint32();
21046
+ const tableSize = reader.readUint32();
21047
+ const firstSymbol = reader.readUint32();
21048
+ const lastSymbol = reader.readUint32();
21049
+ if (version2 < 2 || tableSize === 0 || tableSize > 32768 || firstSymbol >= lastSymbol) {
21050
+ throw new Error("Invalid LEPCC Huffman code table");
21051
+ }
21052
+ const codeLengths = decodeSimple(reader);
21053
+ if (codeLengths.length !== lastSymbol - firstSymbol) {
21054
+ throw new Error("LEPCC Huffman code table length mismatch");
21055
+ }
21056
+ const lengthsBySymbol = new Array(tableSize).fill(0);
21057
+ let codeBitCount = 0;
21058
+ for (let symbol = firstSymbol; symbol < lastSymbol; symbol++) {
21059
+ const tableIndex = symbol < tableSize ? symbol : symbol - tableSize;
21060
+ const codeLength = codeLengths[symbol - firstSymbol];
21061
+ if (codeLength > 32) {
21062
+ throw new Error("LEPCC Huffman code is too long");
21063
+ }
21064
+ lengthsBySymbol[tableIndex] = codeLength;
21065
+ codeBitCount += codeLength;
21066
+ }
21067
+ const symbols = lengthsBySymbol.map((codeLength, symbol) => ({ codeLength, symbol })).filter((value) => value.codeLength > 0).sort((left, right) => right.codeLength - left.codeLength || left.symbol - right.symbol);
21068
+ if (symbols.length < 2) {
21069
+ throw new Error("LEPCC Huffman table has fewer than two symbols");
21070
+ }
21071
+ const codeLookup = /* @__PURE__ */ new Map();
21072
+ let canonicalCode = 0;
21073
+ let canonicalLength = symbols[0].codeLength;
21074
+ for (const symbol of symbols) {
21075
+ const delta = canonicalLength - symbol.codeLength;
21076
+ canonicalCode = Math.floor(canonicalCode / 2 ** delta);
21077
+ canonicalLength = symbol.codeLength;
21078
+ codeLookup.set(`${canonicalLength}:${canonicalCode}`, symbol.symbol);
21079
+ canonicalCode++;
21080
+ }
21081
+ const codeReader = new MsbBitReader(reader);
21082
+ for (const codeLength of lengthsBySymbol) {
21083
+ if (codeLength > 0) {
21084
+ codeReader.readBits(codeLength);
21085
+ }
21086
+ }
21087
+ codeReader.finishWords();
21088
+ if (codeBitCount === 0) {
21089
+ throw new Error("LEPCC Huffman table has no code bits");
21090
+ }
21091
+ const valueReader = new MsbBitReader(reader);
21092
+ const values = new Array(elementCount);
21093
+ for (let index = 0; index < elementCount; index++) {
21094
+ let code = 0;
21095
+ let decodedSymbol;
21096
+ for (let codeLength = 1; codeLength <= 32; codeLength++) {
21097
+ code = code * 2 + valueReader.readBits(1);
21098
+ decodedSymbol = codeLookup.get(`${codeLength}:${code}`);
21099
+ if (decodedSymbol !== void 0) {
21100
+ break;
21101
+ }
21102
+ }
21103
+ if (decodedSymbol === void 0) {
21104
+ throw new Error("Invalid LEPCC Huffman value");
21105
+ }
21106
+ values[index] = decodedSymbol;
21107
+ }
21108
+ valueReader.finishWords(1);
21109
+ return values;
21110
+ }
21111
+ var I3SLEPCCDecoder, BinaryReader, BitReader, MsbBitReader;
21112
+ var init_i3s_lepcc = __esm({
21113
+ "../i3s/src/i3s-lepcc.ts"() {
21114
+ "use strict";
21115
+ I3SLEPCCDecoder = class {
21116
+ /** Whether blob checksums are verified before decoding. */
21117
+ verifyChecksum;
21118
+ /**
21119
+ * @param options - Optional decoder settings.
21120
+ */
21121
+ constructor(options = {}) {
21122
+ this.verifyChecksum = options.verifyChecksum ?? true;
21123
+ }
21124
+ /**
21125
+ * Identifies the attribute represented by a LEPCC blob.
21126
+ *
21127
+ * @param bytes - One standalone I3S LEPCC resource.
21128
+ * @returns The normalized I3S attribute type.
21129
+ */
21130
+ getBlobType(bytes) {
21131
+ const magic = readMagic(bytes);
21132
+ switch (magic) {
21133
+ case "LEPCC ":
21134
+ return "xyz";
21135
+ case "ClusterRGB":
21136
+ return "rgb";
21137
+ case "Intensity ":
21138
+ return "intensity";
21139
+ case "FlagBytes ":
21140
+ return "flagBytes";
21141
+ default:
21142
+ throw new Error(`Unsupported LEPCC blob magic: ${JSON.stringify(magic)}`);
21143
+ }
21144
+ }
21145
+ /**
21146
+ * Decodes an I3S LEPCC position resource.
21147
+ *
21148
+ * @param bytes - A `lepcc-xyz` resource.
21149
+ * @returns Interleaved longitude, latitude, and elevation values.
21150
+ */
21151
+ decodeXyz(bytes) {
21152
+ const reader = new BinaryReader(bytes);
21153
+ const header = readHeader(reader, "LEPCC ", 104, this.verifyChecksum);
21154
+ const extent = {
21155
+ lower: [reader.readFloat64(), reader.readFloat64(), reader.readFloat64()],
21156
+ upper: [reader.readFloat64(), reader.readFloat64(), reader.readFloat64()]
21157
+ };
21158
+ const maxError = [reader.readFloat64(), reader.readFloat64(), reader.readFloat64()];
21159
+ const pointCount = reader.readUint32();
21160
+ reader.readUint32();
21161
+ const yDelta = decodeCutInSegments(reader);
21162
+ const pointsPerRow = decodeCutInSegments(reader);
21163
+ const xDelta = decodeCutInSegments(reader);
21164
+ const zValues = decodeCutInSegments(reader);
21165
+ if (pointsPerRow.reduce((sum, value) => sum + value, 0) !== pointCount) {
21166
+ throw new Error("LEPCC XYZ row count does not match the point count");
21167
+ }
21168
+ if (yDelta.length !== pointsPerRow.length || xDelta.length !== pointCount || zValues.length !== pointCount) {
21169
+ throw new Error("LEPCC XYZ delta arrays have inconsistent lengths");
21170
+ }
21171
+ assertBlobConsumed(reader, header.blobSize);
21172
+ const output = new Float64Array(pointCount * 3);
21173
+ const cellWidth = maxError.map((value) => value * 2);
21174
+ let y = 0;
21175
+ let pointIndex = 0;
21176
+ for (let rowIndex = 0; rowIndex < yDelta.length; rowIndex++) {
21177
+ y += yDelta[rowIndex];
21178
+ let x = 0;
21179
+ for (let columnIndex = 0; columnIndex < pointsPerRow[rowIndex]; columnIndex++) {
21180
+ x += xDelta[pointIndex];
21181
+ const offset = pointIndex * 3;
21182
+ output[offset] = Math.min(extent.upper[0], extent.lower[0] + x * cellWidth[0]);
21183
+ output[offset + 1] = Math.min(extent.upper[1], extent.lower[1] + y * cellWidth[1]);
21184
+ output[offset + 2] = Math.min(
21185
+ extent.upper[2],
21186
+ extent.lower[2] + zValues[pointIndex] * cellWidth[2]
21187
+ );
21188
+ pointIndex++;
21189
+ }
21190
+ }
21191
+ return output;
21192
+ }
21193
+ /**
21194
+ * Decodes an I3S LEPCC RGB resource.
21195
+ *
21196
+ * @param bytes - A `lepcc-rgb` resource.
21197
+ * @returns Interleaved 8-bit red, green, and blue values.
21198
+ */
21199
+ decodeRgb(bytes) {
21200
+ const reader = new BinaryReader(bytes);
21201
+ const header = readHeader(reader, "ClusterRGB", 32, this.verifyChecksum);
21202
+ const pointCount = reader.readUint32();
21203
+ const colorCount = reader.readUint16();
21204
+ const lookupMethod = reader.readUint8();
21205
+ const compressionMethod = reader.readUint8();
21206
+ const output = new Uint8Array(pointCount * 3);
21207
+ if (colorCount === 0) {
21208
+ output.set(reader.readBytes(pointCount * 3));
21209
+ } else {
21210
+ const colorMap = reader.readBytes(colorCount * 3);
21211
+ if (lookupMethod !== 1 && lookupMethod !== 2) {
21212
+ throw new Error(`Unsupported LEPCC RGB lookup method: ${lookupMethod}`);
21213
+ }
21214
+ if (compressionMethod === 0) {
21215
+ for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
21216
+ const colorIndex = reader.readUint8();
21217
+ if (colorIndex >= colorCount) {
21218
+ throw new Error("LEPCC RGB color index is outside the color map");
21219
+ }
21220
+ output.set(colorMap.subarray(colorIndex * 3, colorIndex * 3 + 3), pointIndex * 3);
21221
+ }
21222
+ } else if (compressionMethod === 1) {
21223
+ for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
21224
+ output.set(colorMap.subarray(0, 3), pointIndex * 3);
21225
+ }
21226
+ } else if (compressionMethod === 2) {
21227
+ const indexes = decodeHuffman(reader, pointCount);
21228
+ for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
21229
+ const colorIndex = indexes[pointIndex];
21230
+ if (colorIndex >= colorCount) {
21231
+ throw new Error("LEPCC RGB Huffman color index is outside the color map");
21232
+ }
21233
+ output.set(colorMap.subarray(colorIndex * 3, colorIndex * 3 + 3), pointIndex * 3);
21234
+ }
21235
+ } else {
21236
+ throw new Error(`Unsupported LEPCC RGB compression method: ${compressionMethod}`);
21237
+ }
21238
+ }
21239
+ assertBlobConsumed(reader, header.blobSize);
21240
+ return output;
21241
+ }
21242
+ /**
21243
+ * Decodes an I3S LEPCC intensity resource.
21244
+ *
21245
+ * @param bytes - A `lepcc-intensity` resource.
21246
+ * @returns One unsigned 16-bit intensity value per point.
21247
+ */
21248
+ decodeIntensity(bytes) {
21249
+ const reader = new BinaryReader(bytes);
21250
+ const header = readHeader(reader, "Intensity ", 32, this.verifyChecksum);
21251
+ const pointCount = reader.readUint32();
21252
+ const scaleFactor = reader.readUint16();
21253
+ const bitsPerPoint = reader.readUint8();
21254
+ reader.readUint8();
21255
+ if (scaleFactor < 1 || bitsPerPoint > 16) {
21256
+ throw new Error("Invalid LEPCC intensity header");
21257
+ }
21258
+ const values = new Uint16Array(pointCount);
21259
+ if (bitsPerPoint === 16) {
21260
+ for (let index = 0; index < pointCount; index++) {
21261
+ values[index] = reader.readUint16();
21262
+ }
21263
+ } else if (bitsPerPoint === 8) {
21264
+ for (let index = 0; index < pointCount; index++) {
21265
+ values[index] = reader.readUint8() * scaleFactor;
21266
+ }
21267
+ } else {
21268
+ const packedValues = decodeSimple(reader);
21269
+ if (packedValues.length !== pointCount) {
21270
+ throw new Error("LEPCC intensity value count does not match the header");
21271
+ }
21272
+ for (let index = 0; index < pointCount; index++) {
21273
+ values[index] = packedValues[index] * scaleFactor;
21274
+ }
21275
+ }
21276
+ assertBlobConsumed(reader, header.blobSize);
21277
+ return values;
21278
+ }
21279
+ /**
21280
+ * Decodes an I3S LEPCC packed LAS flags resource.
21281
+ *
21282
+ * @param bytes - A LEPCC flag-bytes resource.
21283
+ * @returns One packed flag byte per point.
21284
+ */
21285
+ decodeFlagBytes(bytes) {
21286
+ const reader = new BinaryReader(bytes);
21287
+ const header = readHeader(reader, "FlagBytes ", 32, this.verifyChecksum);
21288
+ const pointCount = reader.readUint32();
21289
+ const compressionMethod = reader.readUint8();
21290
+ const minimumValue = reader.readUint8();
21291
+ reader.readUint16();
21292
+ const packedValues = compressionMethod === 0 ? decodeSimple(reader) : decodeHuffman(reader, pointCount);
21293
+ if (packedValues.length !== pointCount) {
21294
+ throw new Error("LEPCC flag-byte value count does not match the header");
21295
+ }
21296
+ const output = new Uint8Array(pointCount);
21297
+ for (let index = 0; index < pointCount; index++) {
21298
+ output[index] = packedValues[index] + minimumValue;
21299
+ }
21300
+ assertBlobConsumed(reader, header.blobSize);
21301
+ return output;
21302
+ }
21303
+ /**
21304
+ * Decodes a blob using its self-described attribute type.
21305
+ *
21306
+ * @param bytes - One standalone I3S LEPCC resource.
21307
+ * @returns The typed decoded values.
21308
+ */
21309
+ decode(bytes) {
21310
+ switch (this.getBlobType(bytes)) {
21311
+ case "xyz":
21312
+ return this.decodeXyz(bytes);
21313
+ case "rgb":
21314
+ return this.decodeRgb(bytes);
21315
+ case "intensity":
21316
+ return this.decodeIntensity(bytes);
21317
+ case "flagBytes":
21318
+ return this.decodeFlagBytes(bytes);
21319
+ }
21320
+ }
21321
+ };
21322
+ BinaryReader = class {
21323
+ bytes;
21324
+ offset = 0;
21325
+ constructor(bytes) {
21326
+ this.bytes = bytes;
21327
+ }
21328
+ readUint8() {
21329
+ this.ensure(1);
21330
+ return this.bytes[this.offset++];
21331
+ }
21332
+ readUint16() {
21333
+ this.ensure(2);
21334
+ const value = this.bytes[this.offset] | this.bytes[this.offset + 1] << 8;
21335
+ this.offset += 2;
21336
+ return value;
21337
+ }
21338
+ readUint32() {
21339
+ this.ensure(4);
21340
+ const value = this.bytes[this.offset] | this.bytes[this.offset + 1] << 8 | this.bytes[this.offset + 2] << 16 | this.bytes[this.offset + 3] << 24;
21341
+ this.offset += 4;
21342
+ return value >>> 0;
21343
+ }
21344
+ readBigUint64() {
21345
+ this.ensure(8);
21346
+ let value = 0;
21347
+ for (let index = 7; index >= 0; index--) {
21348
+ value = value * 256 + this.bytes[this.offset + index];
21349
+ }
21350
+ this.offset += 8;
21351
+ if (!Number.isSafeInteger(value)) {
21352
+ throw new Error("LEPCC blob size exceeds JavaScript safe integer range");
21353
+ }
21354
+ return value;
21355
+ }
21356
+ readFloat64() {
21357
+ this.ensure(8);
21358
+ const view = new DataView(this.bytes.buffer, this.bytes.byteOffset + this.offset, 8);
21359
+ const value = view.getFloat64(0, true);
21360
+ this.offset += 8;
21361
+ return value;
21362
+ }
21363
+ readBytes(length) {
21364
+ this.ensure(length);
21365
+ const value = this.bytes.subarray(this.offset, this.offset + length);
21366
+ this.offset += length;
21367
+ return value;
21368
+ }
21369
+ ensure(length) {
21370
+ if (length < 0 || this.offset + length > this.bytes.byteLength) {
21371
+ throw new Error("Truncated LEPCC blob");
21372
+ }
21373
+ }
21374
+ };
21375
+ BitReader = class {
21376
+ reader;
21377
+ bitOffset = 0;
21378
+ constructor(reader) {
21379
+ this.reader = reader;
21380
+ }
21381
+ readBits(numberOfBits) {
21382
+ let value = 0;
21383
+ for (let bitIndex = 0; bitIndex < numberOfBits; bitIndex++) {
21384
+ if (this.bitOffset === 0) {
21385
+ this.reader.ensure(1);
21386
+ }
21387
+ const currentByte = this.reader.bytes[this.reader.offset];
21388
+ value += (currentByte >>> this.bitOffset & 1) * 2 ** bitIndex;
21389
+ this.bitOffset++;
21390
+ if (this.bitOffset === 8) {
21391
+ this.bitOffset = 0;
21392
+ this.reader.offset++;
21393
+ }
21394
+ }
21395
+ return value;
21396
+ }
21397
+ alignToByte() {
21398
+ if (this.bitOffset !== 0) {
21399
+ this.reader.offset++;
21400
+ this.bitOffset = 0;
21401
+ }
21402
+ }
21403
+ };
21404
+ MsbBitReader = class {
21405
+ reader;
21406
+ startOffset;
21407
+ bitOffset = 0;
21408
+ bitsRead = 0;
21409
+ constructor(reader) {
21410
+ this.reader = reader;
21411
+ this.startOffset = reader.offset;
21412
+ }
21413
+ readBits(numberOfBits) {
21414
+ let value = 0;
21415
+ for (let bitIndex = 0; bitIndex < numberOfBits; bitIndex++) {
21416
+ if (this.bitOffset === 0) {
21417
+ this.reader.ensure(4);
21418
+ }
21419
+ const word = this.reader.bytes[this.reader.offset] | this.reader.bytes[this.reader.offset + 1] << 8 | this.reader.bytes[this.reader.offset + 2] << 16 | this.reader.bytes[this.reader.offset + 3] << 24;
21420
+ value = value * 2 + (word >>> 31 - this.bitOffset & 1);
21421
+ this.bitOffset++;
21422
+ this.bitsRead++;
21423
+ if (this.bitOffset === 32) {
21424
+ this.bitOffset = 0;
21425
+ this.reader.offset += 4;
21426
+ }
21427
+ }
21428
+ return value;
21429
+ }
21430
+ finishWords(extraWords = 0) {
21431
+ this.reader.offset = this.startOffset + Math.ceil(this.bitsRead / 32) * 4 + extraWords * 4;
21432
+ this.bitOffset = 0;
21433
+ }
21434
+ };
21435
+ }
21436
+ });
21437
+
21438
+ // ../i3s/src/i3s-lepcc-loader.ts
21439
+ var i3s_lepcc_loader_exports = {};
21440
+ __export(i3s_lepcc_loader_exports, {
21441
+ I3SLEPCCLoaderWithParser: () => I3SLEPCCLoaderWithParser
21442
+ });
21443
+ var I3SLEPCCLoaderWithParser;
21444
+ var init_i3s_lepcc_loader = __esm({
21445
+ "../i3s/src/i3s-lepcc-loader.ts"() {
21446
+ "use strict";
21447
+ init_i3s_lepcc();
21448
+ init_i3s_lepcc_loader_types();
21449
+ I3SLEPCCLoaderWithParser = {
21450
+ ...I3SLEPCCLoader,
21451
+ parse: async (arrayBuffer, options) => {
21452
+ var _a2;
21453
+ const decoder = new I3SLEPCCDecoder({
21454
+ verifyChecksum: (_a2 = options == null ? void 0 : options["i3s-lepcc"]) == null ? void 0 : _a2.verifyChecksum
21455
+ });
21456
+ const bytes = new Uint8Array(arrayBuffer);
21457
+ return {
21458
+ type: decoder.getBlobType(bytes),
21459
+ value: decoder.decode(bytes)
21460
+ };
21461
+ }
21462
+ };
21463
+ }
21464
+ });
21465
+
21466
+ // ../i3s/src/i3s-lepcc-loader-types.ts
21467
+ var VERSION11, I3SLEPCCLoader;
21468
+ var init_i3s_lepcc_loader_types = __esm({
21469
+ "../i3s/src/i3s-lepcc-loader-types.ts"() {
21470
+ "use strict";
21471
+ init_i3s_format();
21472
+ VERSION11 = typeof __VERSION__ !== "undefined" ? __VERSION__ : "latest";
21473
+ I3SLEPCCLoader = {
21474
+ ...I3SLEPCCFormat,
21475
+ dataType: null,
21476
+ batchType: null,
21477
+ version: VERSION11,
21478
+ worker: true,
21479
+ options: {
21480
+ "i3s-lepcc": {
21481
+ verifyChecksum: true
21482
+ }
21483
+ },
21484
+ preload: async () => (await Promise.resolve().then(() => (init_i3s_lepcc_loader(), i3s_lepcc_loader_exports))).I3SLEPCCLoaderWithParser
21485
+ };
21486
+ }
21487
+ });
21488
+
21489
+ // dist/index.js
21490
+ var index_exports = {};
21491
+ __export(index_exports, {
21492
+ ArcGISFeatureServerSourceLoader: () => ArcGISFeatureServerSourceLoader,
21493
+ ArcGISImageServerSourceLoader: () => ArcGISImageServerSourceLoader,
21494
+ ArcGISImageSource: () => ArcGISImageSource,
21495
+ ArcGISImageTileSource: () => ArcGISImageTileSource,
21496
+ ArcGISImageTileSourceLoader: () => ArcGISImageTileSourceLoader,
21497
+ ArcGISMapTileSource: () => ArcGISMapTileSource,
21498
+ ArcGISMapTileSourceLoader: () => ArcGISMapTileSourceLoader,
21499
+ ArcGISSceneServerQueryError: () => ArcGISSceneServerQueryError,
21500
+ ArcGISSceneServerSource: () => ArcGISSceneServerSource,
21501
+ ArcGISSceneServerSourceLoader: () => ArcGISSceneServerSourceLoader,
21502
+ ArcGISVectorSource: () => ArcGISVectorSource,
21503
+ ArcGISVectorTileServerSource: () => ArcGISVectorTileServerSource,
21504
+ ArcGISVectorTileServerSourceLoader: () => ArcGISVectorTileServerSourceLoader,
21505
+ SERVICE_LOADERS: () => SERVICE_LOADERS,
21506
+ aggregateArcGISSceneFeatures: () => aggregateArcGISSceneFeatures,
21507
+ createArcGISCredential: () => createArcGISCredential,
21508
+ createCesiumIonCredential: () => createCesiumIonCredential,
21509
+ createGoogleMapsCredential: () => createGoogleMapsCredential,
21510
+ createMapboxCredential: () => createMapboxCredential,
21511
+ discoverArcGISCapabilities: () => discoverArcGISCapabilities,
21512
+ getArcGISServices: () => getArcGISServices,
21513
+ getServiceLoader: () => getServiceLoader,
21514
+ selectArcGISService: () => selectArcGISService
21515
+ });
21516
+ module.exports = __toCommonJS(index_exports);
21517
+
21518
+ // dist/arcgis/arcgis-server.js
21519
+ async function getArcGISServices(url, fetchFile2 = fetch) {
21520
+ if (url.includes("rest/services")) {
21521
+ const serverUrl = url.replace(/rest\/services.*$/i, "rest/services");
21522
+ return loadServiceDirectory(serverUrl, fetchFile2, []);
21523
+ }
21524
+ return null;
21525
+ }
21526
+ async function loadServiceDirectory(serverUrl, fetch2, path) {
21527
+ const serviceUrl = path.length ? `${serverUrl}/${path.join("/")}` : serverUrl;
21528
+ const response = await fetch2(`${serviceUrl}?f=pjson`);
21529
+ const directory = await response.json();
21530
+ const services = extractServices(directory, serviceUrl, serverUrl);
21531
+ const folders = directory.folders || [];
21532
+ const promises = folders.map((folder) => loadServiceDirectory(`${serverUrl}`, fetch2, [...path, folder]));
21533
+ for (const folderServices of await Promise.all(promises)) {
21534
+ services.push(...folderServices);
21535
+ }
21536
+ return services;
21537
+ }
21538
+ function extractServices(directory, url, serverUrl) {
21539
+ const arcgisServices = directory.services || [];
21540
+ const services = [];
21541
+ for (const service of arcgisServices) {
21542
+ services.push({
21543
+ name: service.name,
21544
+ type: `arcgis-${service.type.toLocaleLowerCase().replace("server", "-server")}`,
21545
+ url: `${service.name.includes("/") ? serverUrl : url}/${service.name}/${service.type}`
21546
+ });
21547
+ }
21548
+ return services;
21549
+ }
21550
+
21551
+ // dist/arcgis/arcgis-capability-graph.js
21552
+ async function discoverArcGISCapabilities(url, options = {}) {
21553
+ const fetchFile2 = options.fetch || fetch;
21554
+ const services = await getArcGISServices(url, fetchFile2);
21555
+ if (!services)
21556
+ return null;
21557
+ const nodes = await Promise.all(services.map(async (service) => {
21558
+ let metadata = await fetchServiceMetadata(service.url, fetchFile2);
21559
+ if (service.type.toLowerCase().includes("scene")) {
21560
+ metadata = await enrichSceneServerMetadata(service.url, metadata, fetchFile2);
21561
+ }
21562
+ return normalizeServiceCapabilities(service, metadata);
21563
+ }));
21564
+ return { rootUrl: url, nodes };
21565
+ }
21566
+ function selectArcGISService(graph, requirements = {}) {
21567
+ return graph.nodes.find((node) => {
21568
+ if (requirements.kind && node.kind !== requirements.kind)
21569
+ return false;
21570
+ if (requirements.format && !node.capabilities.formats.includes(requirements.format.toLowerCase()))
21571
+ return false;
21572
+ if (requirements.crs && !node.capabilities.crs.includes(requirements.crs))
21573
+ return false;
21574
+ if (requirements.profile && node.metadata.profile !== requirements.profile && !node.capabilities.layers.some((layer) => layer.profile === requirements.profile))
21575
+ return false;
21576
+ if (requirements.layerId !== void 0 && !node.capabilities.layers.some((layer) => layer.id === String(requirements.layerId) || layer.name === String(requirements.layerId)))
21577
+ return false;
21578
+ return true;
21579
+ });
21580
+ }
21581
+ async function fetchServiceMetadata(serviceUrl, fetchFile2) {
21582
+ const url = new URL(serviceUrl);
21583
+ url.searchParams.set("f", "pjson");
21584
+ const response = await fetchFile2(url.toString());
21585
+ if (!response.ok) {
21586
+ throw new Error(`ArcGIS service metadata request failed: ${response.status}`);
21587
+ }
21588
+ return await response.json();
21589
+ }
21590
+ async function enrichSceneServerMetadata(serviceUrl, metadata, fetchFile2) {
21591
+ const layers = Array.isArray(metadata.layers) ? metadata.layers : [];
21592
+ if (!layers.length)
21593
+ return metadata;
21594
+ const enrichedLayers = await Promise.all(layers.map(async (value) => {
21595
+ if (!value || typeof value !== "object")
19396
21596
  return value;
19397
21597
  const layer = value;
19398
21598
  if (layer.id === void 0)
@@ -19589,6 +21789,7 @@ var ArcGISVectorSource = class extends DataSource {
19589
21789
  }
19590
21790
  /** Requests features from the ArcGIS FeatureServer query endpoint. */
19591
21791
  async getFeatures(parameters) {
21792
+ var _a2;
19592
21793
  const url = this.getFeaturesURL(parameters);
19593
21794
  const response = await this.fetch(url, parameters.signal ? { signal: parameters.signal } : void 0);
19594
21795
  await this.checkResponse(response);
@@ -19601,7 +21802,9 @@ var ArcGISVectorSource = class extends DataSource {
19601
21802
  return geoJsonTable;
19602
21803
  case "arrow":
19603
21804
  default:
19604
- return convertFeaturesToWKBArrowTable(geoJsonTable.features);
21805
+ return convertFeaturesToWKBArrowTable(geoJsonTable.features, {
21806
+ encodingPreference: (_a2 = parameters.geoarrow) == null ? void 0 : _a2.encodingPreference
21807
+ });
19605
21808
  }
19606
21809
  }
19607
21810
  /** Requests the raw ArcGIS FeatureServer metadata document. */
@@ -19899,257 +22102,107 @@ var ArcGISMapTileSource = class extends DataSource {
19899
22102
  super(url.replace(/\/$/, ""), options, ArcGISMapTileSourceLoader.defaultOptions, coreApi2);
19900
22103
  this.getTileData = this.getTileData.bind(this);
19901
22104
  }
19902
- /** Loads and normalizes ArcGIS service metadata. */
19903
- async getMetadata() {
19904
- var _a2, _b, _c, _d;
19905
- const metadata = await this._getMetadata();
19906
- const extent = metadata.fullExtent;
19907
- const spatialReference = metadata.spatialReference || (extent == null ? void 0 : extent.spatialReference);
19908
- const spatialReferenceWkid = spatialReference == null ? void 0 : spatialReference.wkid;
19909
- return {
19910
- name: metadata.name || "",
19911
- title: metadata.name || "",
19912
- abstract: metadata.description || metadata.serviceDescription || "",
19913
- attributions: metadata.copyrightText ? [metadata.copyrightText] : void 0,
19914
- minZoom: 0,
19915
- maxZoom: ((_b = (_a2 = metadata.tileInfo) == null ? void 0 : _a2.lods) == null ? void 0 : _b.length) ? Math.max(...metadata.tileInfo.lods.map((lod) => lod.level)) : void 0,
19916
- boundingBox: extent ? [
19917
- [extent.xmin, extent.ymin],
19918
- [extent.xmax, extent.ymax]
19919
- ] : void 0,
19920
- layer: {
19921
- name: metadata.name || "",
19922
- srs: spatialReferenceWkid ? [`EPSG:${spatialReferenceWkid}`] : [],
19923
- layers: []
19924
- },
19925
- tileGrid: metadata.tileInfo ? {
19926
- crs: ((_c = metadata.tileInfo.spatialReference) == null ? void 0 : _c.wkid) ? `EPSG:${metadata.tileInfo.spatialReference.wkid}` : void 0,
19927
- tileSize: metadata.tileInfo.rows && metadata.tileInfo.cols ? [metadata.tileInfo.cols, metadata.tileInfo.rows] : void 0,
19928
- origin: metadata.tileInfo.origin ? [metadata.tileInfo.origin.x, metadata.tileInfo.origin.y] : void 0,
19929
- matrixIds: (_d = metadata.tileInfo.lods) == null ? void 0 : _d.map((lod) => String(lod.level))
19930
- } : void 0
19931
- };
19932
- }
19933
- /** Fetches and decodes one cached ArcGIS tile. */
19934
- async getTile(parameters, signal) {
19935
- const options = this.options["arcgis-map-server"] || {};
19936
- const mode = options.mode || "auto";
19937
- const metadata = mode === "auto" ? await this._getMetadata() : null;
19938
- const useCachedTiles = mode === "cached" || mode === "auto" && isCompatibleCache(metadata);
19939
- const tileURL = useCachedTiles ? this.getTileURL(parameters) : this.getExportTileURL(parameters, options.tileSize || 256);
19940
- const response = await this.fetch(tileURL, signal ? { signal } : void 0);
19941
- if (!response.ok) {
19942
- throw new Error(`ArcGIS MapServer tile request failed: ${response.status} ${response.statusText}`);
19943
- }
19944
- return await this.coreApi.parse(await response.arrayBuffer(), ImageLoader, this.loadOptions);
19945
- }
19946
- /** Fetches a tile using the deck.gl-compatible request shape. */
19947
- async getTileData(parameters) {
19948
- return this.getTile(parameters.index, parameters.signal);
19949
- }
19950
- /** Builds the standard ArcGIS cached tile URL. */
19951
- getTileURL(parameters) {
19952
- var _a2;
19953
- const template = (_a2 = this.options["arcgis-map-server"]) == null ? void 0 : _a2.urlTemplate;
19954
- if (template) {
19955
- const templateURL = new URL(template.replaceAll("{z}", String(parameters.z)).replaceAll("{y}", String(parameters.y)).replaceAll("{x}", String(parameters.x)));
19956
- return templateURL.toString();
19957
- }
19958
- const url = new URL(this.getServiceURL(parameters));
19959
- url.pathname = `${url.pathname.replace(/\/$/, "")}/tile/${parameters.z}/${parameters.y}/${parameters.x}`;
19960
- return url.toString();
19961
- }
19962
- /** Updates parameters applied to subsequent dynamic MapServer export requests. */
19963
- updateParameters(parameters) {
19964
- this._runtimeParameters = { ...this._runtimeParameters, ...parameters };
19965
- }
19966
- /** Builds a dynamic MapServer `export` request for one web-mercator tile. */
19967
- getExportTileURL(parameters, tileSize) {
19968
- const options = this.options["arcgis-map-server"] || {};
19969
- const resolvedTileSize = tileSize || options.tileSize || 256;
19970
- const [west, south, east, north] = getWebMercatorTileBounds(parameters);
19971
- const url = new URL(this.getServiceURL(parameters));
19972
- url.pathname = `${url.pathname.replace(/\/$/, "")}/export`;
19973
- const searchParameters = {
19974
- f: "image",
19975
- bbox: `${west},${south},${east},${north}`,
19976
- bboxSR: 3857,
19977
- imageSR: 3857,
19978
- size: `${resolvedTileSize},${resolvedTileSize}`,
19979
- format: "png32",
19980
- transparent: true,
19981
- ...options.exportParameters,
19982
- ...this._runtimeParameters
19983
- };
19984
- for (const [key, value] of Object.entries(searchParameters)) {
19985
- url.searchParams.set(key, String(value));
19986
- }
19987
- return url.toString();
19988
- }
19989
- /** Fetches the MapServer metadata document and applies configured parameters. */
19990
- async _loadMetadata() {
19991
- var _a2, _b;
19992
- const configuredMetadata = (_a2 = this.options["arcgis-map-server"]) == null ? void 0 : _a2.metadata;
19993
- if (configuredMetadata)
19994
- return configuredMetadata;
19995
- const url = new URL(this.url);
19996
- url.searchParams.set("f", "pjson");
19997
- for (const [key, value] of Object.entries(((_b = this.options["arcgis-map-server"]) == null ? void 0 : _b.parameters) || {})) {
19998
- url.searchParams.set(key, value);
19999
- }
20000
- const response = await this.fetch(url.toString());
20001
- if (!response.ok) {
20002
- throw new Error(`ArcGIS MapServer metadata request failed: ${response.status} ${response.statusText}`);
20003
- }
20004
- return response.json();
20005
- }
20006
- /** Returns cached metadata and shares a single request among concurrent callers. */
20007
- async _getMetadata() {
20008
- if (this._metadata)
20009
- return this._metadata;
20010
- if (!this._metadataPromise) {
20011
- this._metadataPromise = this._loadMetadata();
20012
- }
20013
- try {
20014
- const metadata = await this._metadataPromise;
20015
- this._metadata = metadata;
20016
- return metadata;
20017
- } finally {
20018
- this._metadataPromise = null;
20019
- }
20020
- }
20021
- /** Selects a service endpoint for a tile using a stable URL-pool mapping. */
20022
- getServiceURL(parameters) {
20023
- var _a2;
20024
- const urls = (_a2 = this.options["arcgis-map-server"]) == null ? void 0 : _a2.urls;
20025
- return (urls == null ? void 0 : urls.length) ? urls[(parameters.x + parameters.y) % urls.length] : this.url;
20026
- }
20027
- };
20028
- function isCompatibleCache(metadata) {
20029
- const tileInfo = metadata == null ? void 0 : metadata.tileInfo;
20030
- if (!tileInfo || tileInfo.rows !== 256 || tileInfo.cols !== 256)
20031
- return false;
20032
- const spatialReference = tileInfo.spatialReference || (metadata == null ? void 0 : metadata.spatialReference);
20033
- const wkid = spatialReference == null ? void 0 : spatialReference.wkid;
20034
- if (wkid !== 3857 && wkid !== 102100 && wkid !== 102113)
20035
- return false;
20036
- const origin = tileInfo.origin;
20037
- return !origin || Math.abs(origin.x + 20037508342789244e-9) < 1 && Math.abs(origin.y - 20037508342789244e-9) < 1;
20038
- }
20039
- function getWebMercatorTileBounds(parameters) {
20040
- const worldSize = 20037508342789244e-9;
20041
- const tileCount = 2 ** parameters.z;
20042
- const tileSize = worldSize * 2 / tileCount;
20043
- const west = -worldSize + parameters.x * tileSize;
20044
- const east = west + tileSize;
20045
- const north = worldSize - parameters.y * tileSize;
20046
- const south = north - tileSize;
20047
- return [west, south, east, north];
20048
- }
20049
- var ArcGISMapTileSourceLoader = {
20050
- dataType: null,
20051
- batchType: null,
20052
- name: "ArcGIS MapServer tiles",
20053
- id: "arcgis-map-server",
20054
- module: "services",
20055
- version: "0.0.0",
20056
- extensions: [],
20057
- mimeTypes: [],
20058
- type: "arcgis-map-server",
20059
- fromUrl: true,
20060
- fromBlob: false,
20061
- options: { "arcgis-map-server": {} },
20062
- defaultOptions: { "arcgis-map-server": {} },
20063
- testURL: (url) => /mapserver/i.test(url) && !/imageserver|featureserver/i.test(url),
20064
- createDataSource: (url, options = {}, coreApi2) => new ArcGISMapTileSource(url, options, coreApi2)
20065
- };
20066
-
20067
- // dist/arcgis/arcgis-image-tile-source-loader.js
20068
- init_src6();
20069
- init_src5();
20070
- var ArcGISImageTileSource = class extends DataSource {
20071
- /** MIME type represented by the tile response. */
20072
- mimeType;
20073
- /** Cached ImageServer metadata. */
20074
- _metadata = null;
20075
- /** In-flight metadata request shared by concurrent callers. */
20076
- _metadataPromise = null;
20077
- /** Parameters applied to subsequent export requests. */
20078
- _runtimeParameters = {};
20079
- /** Creates an ArcGIS ImageServer tile source. */
20080
- constructor(url, options = {}, coreApi2) {
20081
- super(url.replace(/\/$/, ""), options, ArcGISImageTileSourceLoader.defaultOptions, coreApi2);
20082
- this.mimeType = this._getResponseFormat() === "lerc" ? "application/octet-stream" : "image/png";
20083
- this.getTileData = this.getTileData.bind(this);
20084
- }
20085
- /** Returns normalized ImageServer metadata. */
22105
+ /** Loads and normalizes ArcGIS service metadata. */
20086
22106
  async getMetadata() {
22107
+ var _a2, _b, _c, _d;
20087
22108
  const metadata = await this._getMetadata();
20088
- const extent = metadata.fullExtent || metadata.extent;
22109
+ const extent = metadata.fullExtent;
20089
22110
  const spatialReference = metadata.spatialReference || (extent == null ? void 0 : extent.spatialReference);
22111
+ const spatialReferenceWkid = spatialReference == null ? void 0 : spatialReference.wkid;
20090
22112
  return {
20091
- name: metadata.name || metadata.serviceDescription || "",
20092
- title: metadata.name || metadata.serviceDescription || "",
22113
+ name: metadata.name || "",
22114
+ title: metadata.name || "",
20093
22115
  abstract: metadata.description || metadata.serviceDescription || "",
20094
22116
  attributions: metadata.copyrightText ? [metadata.copyrightText] : void 0,
22117
+ minZoom: 0,
22118
+ maxZoom: ((_b = (_a2 = metadata.tileInfo) == null ? void 0 : _a2.lods) == null ? void 0 : _b.length) ? Math.max(...metadata.tileInfo.lods.map((lod) => lod.level)) : void 0,
20095
22119
  boundingBox: extent ? [
20096
22120
  [extent.xmin, extent.ymin],
20097
22121
  [extent.xmax, extent.ymax]
20098
22122
  ] : void 0,
20099
22123
  layer: {
20100
22124
  name: metadata.name || "",
20101
- srs: (spatialReference == null ? void 0 : spatialReference.wkid) ? [`EPSG:${spatialReference.wkid}`] : [],
22125
+ srs: spatialReferenceWkid ? [`EPSG:${spatialReferenceWkid}`] : [],
20102
22126
  layers: []
20103
- }
22127
+ },
22128
+ tileGrid: metadata.tileInfo ? {
22129
+ crs: ((_c = metadata.tileInfo.spatialReference) == null ? void 0 : _c.wkid) ? `EPSG:${metadata.tileInfo.spatialReference.wkid}` : void 0,
22130
+ tileSize: metadata.tileInfo.rows && metadata.tileInfo.cols ? [metadata.tileInfo.cols, metadata.tileInfo.rows] : void 0,
22131
+ origin: metadata.tileInfo.origin ? [metadata.tileInfo.origin.x, metadata.tileInfo.origin.y] : void 0,
22132
+ matrixIds: (_d = metadata.tileInfo.lods) == null ? void 0 : _d.map((lod) => String(lod.level))
22133
+ } : void 0
20104
22134
  };
20105
22135
  }
20106
- /** Fetches one ImageServer export tile. */
22136
+ /** Fetches and decodes one cached ArcGIS tile. */
20107
22137
  async getTile(parameters, signal) {
20108
- const response = await this.fetch(this.getTileURL(parameters), signal ? { signal } : void 0);
22138
+ const options = this.options["arcgis-map-server"] || {};
22139
+ const mode = options.mode || "auto";
22140
+ const metadata = mode === "auto" ? await this._getMetadata() : null;
22141
+ const useCachedTiles = mode === "cached" || mode === "auto" && isCompatibleCache(metadata);
22142
+ const tileURL = useCachedTiles ? this.getTileURL(parameters) : this.getExportTileURL(parameters, options.tileSize || 256);
22143
+ const response = await this.fetch(tileURL, signal ? { signal } : void 0);
20109
22144
  if (!response.ok) {
20110
- throw new Error(`ArcGIS ImageServer tile request failed: ${response.status} ${response.statusText}`);
22145
+ throw new Error(`ArcGIS MapServer tile request failed: ${response.status} ${response.statusText}`);
20111
22146
  }
20112
- const loader = this._getResponseFormat() === "lerc" ? LERCLoader : ImageLoader;
20113
- return await this.coreApi.parse(await response.arrayBuffer(), loader, this.loadOptions);
22147
+ return await this.coreApi.parse(await response.arrayBuffer(), ImageLoader, this.loadOptions);
20114
22148
  }
20115
22149
  /** Fetches a tile using the deck.gl-compatible request shape. */
20116
22150
  async getTileData(parameters) {
20117
22151
  return this.getTile(parameters.index, parameters.signal);
20118
22152
  }
20119
- /** Updates parameters applied to subsequent ImageServer export requests. */
22153
+ /** Builds the standard ArcGIS cached tile URL. */
22154
+ getTileURL(parameters) {
22155
+ var _a2;
22156
+ const template = (_a2 = this.options["arcgis-map-server"]) == null ? void 0 : _a2.urlTemplate;
22157
+ if (template) {
22158
+ const templateURL = new URL(template.replaceAll("{z}", String(parameters.z)).replaceAll("{y}", String(parameters.y)).replaceAll("{x}", String(parameters.x)));
22159
+ return templateURL.toString();
22160
+ }
22161
+ const url = new URL(this.getServiceURL(parameters));
22162
+ url.pathname = `${url.pathname.replace(/\/$/, "")}/tile/${parameters.z}/${parameters.y}/${parameters.x}`;
22163
+ return url.toString();
22164
+ }
22165
+ /** Updates parameters applied to subsequent dynamic MapServer export requests. */
20120
22166
  updateParameters(parameters) {
20121
22167
  this._runtimeParameters = { ...this._runtimeParameters, ...parameters };
20122
22168
  }
20123
- /** Builds an ImageServer exportImage URL for one web-mercator tile. */
20124
- getTileURL(parameters, tileSize) {
20125
- const options = this.options["arcgis-image-server-tiles"] || {};
22169
+ /** Builds a dynamic MapServer `export` request for one web-mercator tile. */
22170
+ getExportTileURL(parameters, tileSize) {
22171
+ const options = this.options["arcgis-map-server"] || {};
20126
22172
  const resolvedTileSize = tileSize || options.tileSize || 256;
20127
- const [west, south, east, north] = getWebMercatorTileBounds2(parameters);
22173
+ const [west, south, east, north] = getWebMercatorTileBounds(parameters);
20128
22174
  const url = new URL(this.getServiceURL(parameters));
20129
- url.pathname = `${url.pathname.replace(/\/$/, "")}/exportImage`;
20130
- const requestParameters = {
22175
+ url.pathname = `${url.pathname.replace(/\/$/, "")}/export`;
22176
+ const searchParameters = {
20131
22177
  f: "image",
20132
22178
  bbox: `${west},${south},${east},${north}`,
20133
22179
  bboxSR: 3857,
20134
22180
  imageSR: 3857,
20135
22181
  size: `${resolvedTileSize},${resolvedTileSize}`,
20136
- format: this._getResponseFormat(),
22182
+ format: "png32",
20137
22183
  transparent: true,
20138
- ...options.parameters,
22184
+ ...options.exportParameters,
20139
22185
  ...this._runtimeParameters
20140
22186
  };
20141
- for (const [key, value] of Object.entries(requestParameters)) {
22187
+ for (const [key, value] of Object.entries(searchParameters)) {
20142
22188
  url.searchParams.set(key, String(value));
20143
22189
  }
20144
22190
  return url.toString();
20145
22191
  }
20146
- /** Fetches the ImageServer metadata document. */
22192
+ /** Fetches the MapServer metadata document and applies configured parameters. */
20147
22193
  async _loadMetadata() {
22194
+ var _a2, _b;
22195
+ const configuredMetadata = (_a2 = this.options["arcgis-map-server"]) == null ? void 0 : _a2.metadata;
22196
+ if (configuredMetadata)
22197
+ return configuredMetadata;
20148
22198
  const url = new URL(this.url);
20149
22199
  url.searchParams.set("f", "pjson");
22200
+ for (const [key, value] of Object.entries(((_b = this.options["arcgis-map-server"]) == null ? void 0 : _b.parameters) || {})) {
22201
+ url.searchParams.set(key, value);
22202
+ }
20150
22203
  const response = await this.fetch(url.toString());
20151
22204
  if (!response.ok) {
20152
- throw new Error(`ArcGIS ImageServer metadata request failed: ${response.status}`);
22205
+ throw new Error(`ArcGIS MapServer metadata request failed: ${response.status} ${response.statusText}`);
20153
22206
  }
20154
22207
  return response.json();
20155
22208
  }
@@ -20171,35 +22224,22 @@ var ArcGISImageTileSource = class extends DataSource {
20171
22224
  /** Selects a service endpoint for a tile using a stable URL-pool mapping. */
20172
22225
  getServiceURL(parameters) {
20173
22226
  var _a2;
20174
- const urls = (_a2 = this.options["arcgis-image-server-tiles"]) == null ? void 0 : _a2.urls;
22227
+ const urls = (_a2 = this.options["arcgis-map-server"]) == null ? void 0 : _a2.urls;
20175
22228
  return (urls == null ? void 0 : urls.length) ? urls[(parameters.x + parameters.y) % urls.length] : this.url;
20176
22229
  }
20177
- /** Returns the response format after applying configured and runtime overrides. */
20178
- _getResponseFormat() {
20179
- var _a2;
20180
- const options = this.options["arcgis-image-server-tiles"] || {};
20181
- const format = this._runtimeParameters.format || ((_a2 = options.parameters) == null ? void 0 : _a2.format) || options.format;
20182
- return format === "lerc" ? "lerc" : "png32";
20183
- }
20184
- };
20185
- var ArcGISImageTileSourceLoader = {
20186
- dataType: null,
20187
- batchType: null,
20188
- name: "ArcGIS ImageServer tiles",
20189
- id: "arcgis-image-server-tiles",
20190
- module: "services",
20191
- version: "0.0.0",
20192
- extensions: [],
20193
- mimeTypes: [],
20194
- type: "arcgis-image-server-tiles",
20195
- fromUrl: true,
20196
- fromBlob: false,
20197
- options: { "arcgis-image-server-tiles": {} },
20198
- defaultOptions: { "arcgis-image-server-tiles": {} },
20199
- testURL: (url) => /imageserver/i.test(url),
20200
- createDataSource: (url, options = {}, coreApi2) => new ArcGISImageTileSource(url, options, coreApi2)
20201
22230
  };
20202
- function getWebMercatorTileBounds2(parameters) {
22231
+ function isCompatibleCache(metadata) {
22232
+ const tileInfo = metadata == null ? void 0 : metadata.tileInfo;
22233
+ if (!tileInfo || tileInfo.rows !== 256 || tileInfo.cols !== 256)
22234
+ return false;
22235
+ const spatialReference = tileInfo.spatialReference || (metadata == null ? void 0 : metadata.spatialReference);
22236
+ const wkid = spatialReference == null ? void 0 : spatialReference.wkid;
22237
+ if (wkid !== 3857 && wkid !== 102100 && wkid !== 102113)
22238
+ return false;
22239
+ const origin = tileInfo.origin;
22240
+ return !origin || Math.abs(origin.x + 20037508342789244e-9) < 1 && Math.abs(origin.y - 20037508342789244e-9) < 1;
22241
+ }
22242
+ function getWebMercatorTileBounds(parameters) {
20203
22243
  const worldSize = 20037508342789244e-9;
20204
22244
  const tileCount = 2 ** parameters.z;
20205
22245
  const tileSize = worldSize * 2 / tileCount;
@@ -20209,643 +22249,326 @@ function getWebMercatorTileBounds2(parameters) {
20209
22249
  const south = north - tileSize;
20210
22250
  return [west, south, east, north];
20211
22251
  }
20212
-
20213
- // dist/arcgis/arcgis-vector-tile-server-source-loader.js
20214
- init_src5();
20215
-
20216
- // ../mvt/src/index.ts
20217
- init_mvt_loader();
20218
-
20219
- // dist/arcgis/arcgis-vector-tile-server-source-loader.js
20220
- var ArcGISVectorTileServerSource = class extends DataSource {
20221
- /** Decoded tile family consumed by generic tile renderers. */
20222
- mimeType = "application/vnd.mapbox-vector-tile";
20223
- /** ArcGIS tiles are decoded to WGS84 coordinates before rendering. */
20224
- localCoordinates = false;
20225
- /** Cached service metadata request. */
20226
- serviceMetadata = null;
20227
- /** Query parameters supplied with the service URL, such as an access token. */
20228
- serviceQueryParameters;
20229
- /** Creates an ArcGIS VectorTileServer source. */
20230
- constructor(url, options = {}, coreApi2) {
20231
- const serviceURL = new URL(url);
20232
- serviceURL.pathname = serviceURL.pathname.replace(/\/$/, "");
20233
- super(`${serviceURL.origin}${serviceURL.pathname}`, options, ArcGISVectorTileServerSourceLoader.defaultOptions, coreApi2);
20234
- this.serviceQueryParameters = new URLSearchParams(serviceURL.search);
20235
- }
20236
- /** Returns normalized service and tile-grid metadata. */
20237
- async getMetadata() {
20238
- var _a2, _b;
20239
- const metadata = await this.getServiceMetadata();
20240
- const tileInfo = metadata.tileInfo;
20241
- const lods = (tileInfo == null ? void 0 : tileInfo.lods) || [];
20242
- const extent = metadata.fullExtent || metadata.initialExtent;
20243
- return {
20244
- name: metadata.mapName || this.url.split("/").pop() || "",
20245
- title: metadata.mapName,
20246
- abstract: metadata.serviceDescription,
20247
- format: "application/vnd.mapbox-vector-tile",
20248
- minZoom: (_a2 = lods[0]) == null ? void 0 : _a2.level,
20249
- maxZoom: (_b = lods.at(-1)) == null ? void 0 : _b.level,
20250
- boundingBox: extent ? [
20251
- [extent.xmin, extent.ymin],
20252
- [extent.xmax, extent.ymax]
20253
- ] : void 0,
20254
- layer: {
20255
- name: metadata.mapName || "",
20256
- srs: (tileInfo == null ? void 0 : tileInfo.spatialReference) ? [getSpatialReference(tileInfo.spatialReference)] : [],
20257
- layers: []
20258
- },
20259
- formatHeader: {
20260
- tileInfo,
20261
- styleURL: this.getStyleURL(),
20262
- spriteURL: this.getSpriteURL()
20263
- }
20264
- };
20265
- }
20266
- /** Fetches one raw PBF tile from the ArcGIS tile endpoint. */
20267
- async getTile(parameters, signal) {
20268
- const response = await this.fetch(this.getTileURL(parameters), {
20269
- signal,
20270
- headers: { Accept: "application/vnd.mapbox-vector-tile, application/x-protobuf" }
20271
- });
20272
- if (!response.ok)
20273
- return null;
20274
- return response.arrayBuffer();
20275
- }
20276
- /** Returns the schema advertised by decoded vector tiles. */
20277
- async getSchema() {
20278
- return { fields: [], metadata: {} };
20279
- }
20280
- /** Fetches and decodes one ArcGIS vector tile to geographic coordinates. */
20281
- async getVectorTile(parameters) {
20282
- var _a2;
20283
- const arrayBuffer = await this.getTile(parameters, parameters.signal);
20284
- if (!arrayBuffer) {
20285
- return null;
20286
- }
20287
- const inheritedOptions = this.loadOptions.mvt;
20288
- const sourceOptions = (_a2 = this.options["arcgis-vector-tile-server"]) == null ? void 0 : _a2.mvt;
20289
- return await this.coreApi.parse(arrayBuffer, MVTLoader, {
20290
- ...this.loadOptions,
20291
- mvt: {
20292
- ...inheritedOptions,
20293
- ...sourceOptions,
20294
- coordinates: "wgs84",
20295
- tileIndex: { x: parameters.x, y: parameters.y, z: parameters.z },
20296
- layers: normalizeLayers(parameters.layers) || (sourceOptions == null ? void 0 : sourceOptions.layers) || (inheritedOptions == null ? void 0 : inheritedOptions.layers)
20297
- }
20298
- });
20299
- }
20300
- /** Provides decoded vector tiles through the deck.gl source interface. */
20301
- async getTileData(parameters) {
20302
- return this.getVectorTile({ ...parameters.index, signal: parameters.signal });
20303
- }
20304
- /** Builds the ArcGIS cached vector tile URL. */
20305
- getTileURL(parameters) {
20306
- return this.getResourceURL(`/tile/${parameters.z}/${parameters.y}/${parameters.x}.pbf`);
20307
- }
20308
- /** Returns the service metadata URL. */
20309
- getMetadataURL() {
20310
- const url = new URL(this.getResourceURL(""));
20311
- url.searchParams.set("f", "pjson");
20312
- return url.toString();
20313
- }
20314
- /** Returns the ArcGIS Mapbox style resource URL. */
20315
- getStyleURL() {
20316
- return this.getResourceURL("/resources/styles/root.json");
20317
- }
20318
- /** Returns the ArcGIS sprite resource base URL. */
20319
- getSpriteURL() {
20320
- return this.getResourceURL("/resources/sprites/sprite");
20321
- }
20322
- /** Loads and caches the ArcGIS VectorTileServer metadata document. */
20323
- async getServiceMetadata() {
20324
- this.serviceMetadata ||= this.fetch(this.getMetadataURL()).then(async (response) => {
20325
- if (!response.ok)
20326
- throw new Error(`ArcGIS VectorTileServer request failed: ${response.status}`);
20327
- return await response.json();
20328
- });
20329
- return this.serviceMetadata;
20330
- }
20331
- /** Builds a resource URL while retaining service query parameters. */
20332
- getResourceURL(resourcePath) {
20333
- const url = new URL(this.url);
20334
- url.pathname = `${url.pathname.replace(/\/$/, "")}${resourcePath}`;
20335
- for (const [key, value] of this.serviceQueryParameters) {
20336
- url.searchParams.set(key, value);
20337
- }
20338
- return url.toString();
20339
- }
20340
- };
20341
- var ArcGISVectorTileServerSourceLoader = {
22252
+ var ArcGISMapTileSourceLoader = {
20342
22253
  dataType: null,
20343
22254
  batchType: null,
20344
- name: "ArcGIS VectorTileServer",
20345
- id: "arcgis-vector-tile-server",
22255
+ name: "ArcGIS MapServer tiles",
22256
+ id: "arcgis-map-server",
20346
22257
  module: "services",
20347
22258
  version: "0.0.0",
20348
22259
  extensions: [],
20349
- mimeTypes: ["application/vnd.mapbox-vector-tile", "application/x-protobuf"],
20350
- type: "arcgis-vector-tile-server",
22260
+ mimeTypes: [],
22261
+ type: "arcgis-map-server",
20351
22262
  fromUrl: true,
20352
22263
  fromBlob: false,
20353
- options: { "arcgis-vector-tile-server": {} },
20354
- defaultOptions: { "arcgis-vector-tile-server": {} },
20355
- testURL: (url) => /\/vectortileserver(?:[\/?#]|$)/i.test(url),
20356
- createDataSource: (url, options = {}, coreApi2) => new ArcGISVectorTileServerSource(url, options, coreApi2)
22264
+ options: { "arcgis-map-server": {} },
22265
+ defaultOptions: { "arcgis-map-server": {} },
22266
+ testURL: (url) => /mapserver/i.test(url) && !/imageserver|featureserver/i.test(url),
22267
+ createDataSource: (url, options = {}, coreApi2) => new ArcGISMapTileSource(url, options, coreApi2)
20357
22268
  };
20358
- function getSpatialReference(spatialReference) {
20359
- return `EPSG:${spatialReference.latestWkid || spatialReference.wkid}`;
20360
- }
20361
- function normalizeLayers(layers) {
20362
- if (!layers)
20363
- return void 0;
20364
- return Array.isArray(layers) ? layers : [layers];
20365
- }
20366
22269
 
20367
- // dist/arcgis/arcgis-scene-server-source-loader.js
22270
+ // dist/arcgis/arcgis-image-tile-source-loader.js
22271
+ init_src6();
20368
22272
  init_src5();
20369
-
20370
- // ../i3s/src/i3s-lepcc.ts
20371
- var I3SLEPCCDecoder = class {
20372
- /** Whether blob checksums are verified before decoding. */
20373
- verifyChecksum;
20374
- /**
20375
- * @param options - Optional decoder settings.
20376
- */
20377
- constructor(options = {}) {
20378
- this.verifyChecksum = options.verifyChecksum ?? true;
20379
- }
20380
- /**
20381
- * Identifies the attribute represented by a LEPCC blob.
20382
- *
20383
- * @param bytes - One standalone I3S LEPCC resource.
20384
- * @returns The normalized I3S attribute type.
20385
- */
20386
- getBlobType(bytes) {
20387
- const magic = readMagic(bytes);
20388
- switch (magic) {
20389
- case "LEPCC ":
20390
- return "xyz";
20391
- case "ClusterRGB":
20392
- return "rgb";
20393
- case "Intensity ":
20394
- return "intensity";
20395
- case "FlagBytes ":
20396
- return "flagBytes";
20397
- default:
20398
- throw new Error(`Unsupported LEPCC blob magic: ${JSON.stringify(magic)}`);
20399
- }
22273
+ var ArcGISImageTileSource = class extends DataSource {
22274
+ /** MIME type represented by the tile response. */
22275
+ mimeType;
22276
+ /** Cached ImageServer metadata. */
22277
+ _metadata = null;
22278
+ /** In-flight metadata request shared by concurrent callers. */
22279
+ _metadataPromise = null;
22280
+ /** Parameters applied to subsequent export requests. */
22281
+ _runtimeParameters = {};
22282
+ /** Creates an ArcGIS ImageServer tile source. */
22283
+ constructor(url, options = {}, coreApi2) {
22284
+ super(url.replace(/\/$/, ""), options, ArcGISImageTileSourceLoader.defaultOptions, coreApi2);
22285
+ this.mimeType = this._getResponseFormat() === "lerc" ? "application/octet-stream" : "image/png";
22286
+ this.getTileData = this.getTileData.bind(this);
20400
22287
  }
20401
- /**
20402
- * Decodes an I3S LEPCC position resource.
20403
- *
20404
- * @param bytes - A `lepcc-xyz` resource.
20405
- * @returns Interleaved longitude, latitude, and elevation values.
20406
- */
20407
- decodeXyz(bytes) {
20408
- const reader = new BinaryReader(bytes);
20409
- const header = readHeader(reader, "LEPCC ", 104, this.verifyChecksum);
20410
- const extent = {
20411
- lower: [reader.readFloat64(), reader.readFloat64(), reader.readFloat64()],
20412
- upper: [reader.readFloat64(), reader.readFloat64(), reader.readFloat64()]
20413
- };
20414
- const maxError = [reader.readFloat64(), reader.readFloat64(), reader.readFloat64()];
20415
- const pointCount = reader.readUint32();
20416
- reader.readUint32();
20417
- const yDelta = decodeCutInSegments(reader);
20418
- const pointsPerRow = decodeCutInSegments(reader);
20419
- const xDelta = decodeCutInSegments(reader);
20420
- const zValues = decodeCutInSegments(reader);
20421
- if (pointsPerRow.reduce((sum, value) => sum + value, 0) !== pointCount) {
20422
- throw new Error("LEPCC XYZ row count does not match the point count");
20423
- }
20424
- if (yDelta.length !== pointsPerRow.length || xDelta.length !== pointCount || zValues.length !== pointCount) {
20425
- throw new Error("LEPCC XYZ delta arrays have inconsistent lengths");
20426
- }
20427
- assertBlobConsumed(reader, header.blobSize);
20428
- const output = new Float64Array(pointCount * 3);
20429
- const cellWidth = maxError.map((value) => value * 2);
20430
- let y = 0;
20431
- let pointIndex = 0;
20432
- for (let rowIndex = 0; rowIndex < yDelta.length; rowIndex++) {
20433
- y += yDelta[rowIndex];
20434
- let x = 0;
20435
- for (let columnIndex = 0; columnIndex < pointsPerRow[rowIndex]; columnIndex++) {
20436
- x += xDelta[pointIndex];
20437
- const offset = pointIndex * 3;
20438
- output[offset] = Math.min(extent.upper[0], extent.lower[0] + x * cellWidth[0]);
20439
- output[offset + 1] = Math.min(extent.upper[1], extent.lower[1] + y * cellWidth[1]);
20440
- output[offset + 2] = Math.min(
20441
- extent.upper[2],
20442
- extent.lower[2] + zValues[pointIndex] * cellWidth[2]
20443
- );
20444
- pointIndex++;
22288
+ /** Returns normalized ImageServer metadata. */
22289
+ async getMetadata() {
22290
+ const metadata = await this._getMetadata();
22291
+ const extent = metadata.fullExtent || metadata.extent;
22292
+ const spatialReference = metadata.spatialReference || (extent == null ? void 0 : extent.spatialReference);
22293
+ return {
22294
+ name: metadata.name || metadata.serviceDescription || "",
22295
+ title: metadata.name || metadata.serviceDescription || "",
22296
+ abstract: metadata.description || metadata.serviceDescription || "",
22297
+ attributions: metadata.copyrightText ? [metadata.copyrightText] : void 0,
22298
+ boundingBox: extent ? [
22299
+ [extent.xmin, extent.ymin],
22300
+ [extent.xmax, extent.ymax]
22301
+ ] : void 0,
22302
+ layer: {
22303
+ name: metadata.name || "",
22304
+ srs: (spatialReference == null ? void 0 : spatialReference.wkid) ? [`EPSG:${spatialReference.wkid}`] : [],
22305
+ layers: []
20445
22306
  }
20446
- }
20447
- return output;
22307
+ };
20448
22308
  }
20449
- /**
20450
- * Decodes an I3S LEPCC RGB resource.
20451
- *
20452
- * @param bytes - A `lepcc-rgb` resource.
20453
- * @returns Interleaved 8-bit red, green, and blue values.
20454
- */
20455
- decodeRgb(bytes) {
20456
- const reader = new BinaryReader(bytes);
20457
- const header = readHeader(reader, "ClusterRGB", 32, this.verifyChecksum);
20458
- const pointCount = reader.readUint32();
20459
- const colorCount = reader.readUint16();
20460
- const lookupMethod = reader.readUint8();
20461
- const compressionMethod = reader.readUint8();
20462
- const output = new Uint8Array(pointCount * 3);
20463
- if (colorCount === 0) {
20464
- output.set(reader.readBytes(pointCount * 3));
20465
- } else {
20466
- const colorMap = reader.readBytes(colorCount * 3);
20467
- if (lookupMethod !== 1 && lookupMethod !== 2) {
20468
- throw new Error(`Unsupported LEPCC RGB lookup method: ${lookupMethod}`);
20469
- }
20470
- if (compressionMethod === 0) {
20471
- for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
20472
- const colorIndex = reader.readUint8();
20473
- if (colorIndex >= colorCount) {
20474
- throw new Error("LEPCC RGB color index is outside the color map");
20475
- }
20476
- output.set(colorMap.subarray(colorIndex * 3, colorIndex * 3 + 3), pointIndex * 3);
20477
- }
20478
- } else if (compressionMethod === 1) {
20479
- for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
20480
- output.set(colorMap.subarray(0, 3), pointIndex * 3);
20481
- }
20482
- } else if (compressionMethod === 2) {
20483
- const indexes = decodeHuffman(reader, pointCount);
20484
- for (let pointIndex = 0; pointIndex < pointCount; pointIndex++) {
20485
- const colorIndex = indexes[pointIndex];
20486
- if (colorIndex >= colorCount) {
20487
- throw new Error("LEPCC RGB Huffman color index is outside the color map");
20488
- }
20489
- output.set(colorMap.subarray(colorIndex * 3, colorIndex * 3 + 3), pointIndex * 3);
20490
- }
20491
- } else {
20492
- throw new Error(`Unsupported LEPCC RGB compression method: ${compressionMethod}`);
20493
- }
22309
+ /** Fetches one ImageServer export tile. */
22310
+ async getTile(parameters, signal) {
22311
+ const response = await this.fetch(this.getTileURL(parameters), signal ? { signal } : void 0);
22312
+ if (!response.ok) {
22313
+ throw new Error(`ArcGIS ImageServer tile request failed: ${response.status} ${response.statusText}`);
20494
22314
  }
20495
- assertBlobConsumed(reader, header.blobSize);
20496
- return output;
22315
+ const loader = this._getResponseFormat() === "lerc" ? LERCLoader : ImageLoader;
22316
+ return await this.coreApi.parse(await response.arrayBuffer(), loader, this.loadOptions);
20497
22317
  }
20498
- /**
20499
- * Decodes an I3S LEPCC intensity resource.
20500
- *
20501
- * @param bytes - A `lepcc-intensity` resource.
20502
- * @returns One unsigned 16-bit intensity value per point.
20503
- */
20504
- decodeIntensity(bytes) {
20505
- const reader = new BinaryReader(bytes);
20506
- const header = readHeader(reader, "Intensity ", 32, this.verifyChecksum);
20507
- const pointCount = reader.readUint32();
20508
- const scaleFactor = reader.readUint16();
20509
- const bitsPerPoint = reader.readUint8();
20510
- reader.readUint8();
20511
- if (scaleFactor < 1 || bitsPerPoint > 16) {
20512
- throw new Error("Invalid LEPCC intensity header");
20513
- }
20514
- const values = new Uint16Array(pointCount);
20515
- if (bitsPerPoint === 16) {
20516
- for (let index = 0; index < pointCount; index++) {
20517
- values[index] = reader.readUint16();
20518
- }
20519
- } else if (bitsPerPoint === 8) {
20520
- for (let index = 0; index < pointCount; index++) {
20521
- values[index] = reader.readUint8() * scaleFactor;
20522
- }
20523
- } else {
20524
- const packedValues = decodeSimple(reader);
20525
- if (packedValues.length !== pointCount) {
20526
- throw new Error("LEPCC intensity value count does not match the header");
20527
- }
20528
- for (let index = 0; index < pointCount; index++) {
20529
- values[index] = packedValues[index] * scaleFactor;
20530
- }
20531
- }
20532
- assertBlobConsumed(reader, header.blobSize);
20533
- return values;
22318
+ /** Fetches a tile using the deck.gl-compatible request shape. */
22319
+ async getTileData(parameters) {
22320
+ return this.getTile(parameters.index, parameters.signal);
20534
22321
  }
20535
- /**
20536
- * Decodes an I3S LEPCC packed LAS flags resource.
20537
- *
20538
- * @param bytes - A LEPCC flag-bytes resource.
20539
- * @returns One packed flag byte per point.
20540
- */
20541
- decodeFlagBytes(bytes) {
20542
- const reader = new BinaryReader(bytes);
20543
- const header = readHeader(reader, "FlagBytes ", 32, this.verifyChecksum);
20544
- const pointCount = reader.readUint32();
20545
- const compressionMethod = reader.readUint8();
20546
- const minimumValue = reader.readUint8();
20547
- reader.readUint16();
20548
- const packedValues = compressionMethod === 0 ? decodeSimple(reader) : decodeHuffman(reader, pointCount);
20549
- if (packedValues.length !== pointCount) {
20550
- throw new Error("LEPCC flag-byte value count does not match the header");
20551
- }
20552
- const output = new Uint8Array(pointCount);
20553
- for (let index = 0; index < pointCount; index++) {
20554
- output[index] = packedValues[index] + minimumValue;
20555
- }
20556
- assertBlobConsumed(reader, header.blobSize);
20557
- return output;
22322
+ /** Updates parameters applied to subsequent ImageServer export requests. */
22323
+ updateParameters(parameters) {
22324
+ this._runtimeParameters = { ...this._runtimeParameters, ...parameters };
20558
22325
  }
20559
- /**
20560
- * Decodes a blob using its self-described attribute type.
20561
- *
20562
- * @param bytes - One standalone I3S LEPCC resource.
20563
- * @returns The typed decoded values.
20564
- */
20565
- decode(bytes) {
20566
- switch (this.getBlobType(bytes)) {
20567
- case "xyz":
20568
- return this.decodeXyz(bytes);
20569
- case "rgb":
20570
- return this.decodeRgb(bytes);
20571
- case "intensity":
20572
- return this.decodeIntensity(bytes);
20573
- case "flagBytes":
20574
- return this.decodeFlagBytes(bytes);
22326
+ /** Builds an ImageServer exportImage URL for one web-mercator tile. */
22327
+ getTileURL(parameters, tileSize) {
22328
+ const options = this.options["arcgis-image-server-tiles"] || {};
22329
+ const resolvedTileSize = tileSize || options.tileSize || 256;
22330
+ const [west, south, east, north] = getWebMercatorTileBounds2(parameters);
22331
+ const url = new URL(this.getServiceURL(parameters));
22332
+ url.pathname = `${url.pathname.replace(/\/$/, "")}/exportImage`;
22333
+ const requestParameters = {
22334
+ f: "image",
22335
+ bbox: `${west},${south},${east},${north}`,
22336
+ bboxSR: 3857,
22337
+ imageSR: 3857,
22338
+ size: `${resolvedTileSize},${resolvedTileSize}`,
22339
+ format: this._getResponseFormat(),
22340
+ transparent: true,
22341
+ ...options.parameters,
22342
+ ...this._runtimeParameters
22343
+ };
22344
+ for (const [key, value] of Object.entries(requestParameters)) {
22345
+ url.searchParams.set(key, String(value));
20575
22346
  }
22347
+ return url.toString();
20576
22348
  }
20577
- };
20578
- var BinaryReader = class {
20579
- bytes;
20580
- offset = 0;
20581
- constructor(bytes) {
20582
- this.bytes = bytes;
20583
- }
20584
- readUint8() {
20585
- this.ensure(1);
20586
- return this.bytes[this.offset++];
20587
- }
20588
- readUint16() {
20589
- this.ensure(2);
20590
- const value = this.bytes[this.offset] | this.bytes[this.offset + 1] << 8;
20591
- this.offset += 2;
20592
- return value;
20593
- }
20594
- readUint32() {
20595
- this.ensure(4);
20596
- const value = this.bytes[this.offset] | this.bytes[this.offset + 1] << 8 | this.bytes[this.offset + 2] << 16 | this.bytes[this.offset + 3] << 24;
20597
- this.offset += 4;
20598
- return value >>> 0;
20599
- }
20600
- readBigUint64() {
20601
- this.ensure(8);
20602
- let value = 0;
20603
- for (let index = 7; index >= 0; index--) {
20604
- value = value * 256 + this.bytes[this.offset + index];
20605
- }
20606
- this.offset += 8;
20607
- if (!Number.isSafeInteger(value)) {
20608
- throw new Error("LEPCC blob size exceeds JavaScript safe integer range");
20609
- }
20610
- return value;
20611
- }
20612
- readFloat64() {
20613
- this.ensure(8);
20614
- const view = new DataView(this.bytes.buffer, this.bytes.byteOffset + this.offset, 8);
20615
- const value = view.getFloat64(0, true);
20616
- this.offset += 8;
20617
- return value;
20618
- }
20619
- readBytes(length) {
20620
- this.ensure(length);
20621
- const value = this.bytes.subarray(this.offset, this.offset + length);
20622
- this.offset += length;
20623
- return value;
20624
- }
20625
- ensure(length) {
20626
- if (length < 0 || this.offset + length > this.bytes.byteLength) {
20627
- throw new Error("Truncated LEPCC blob");
22349
+ /** Fetches the ImageServer metadata document. */
22350
+ async _loadMetadata() {
22351
+ const url = new URL(this.url);
22352
+ url.searchParams.set("f", "pjson");
22353
+ const response = await this.fetch(url.toString());
22354
+ if (!response.ok) {
22355
+ throw new Error(`ArcGIS ImageServer metadata request failed: ${response.status}`);
20628
22356
  }
22357
+ return response.json();
20629
22358
  }
20630
- };
20631
- function readMagic(bytes) {
20632
- if (bytes.byteLength < 10) {
20633
- throw new Error("Truncated LEPCC blob header");
20634
- }
20635
- return new TextDecoder().decode(bytes.subarray(0, 10));
20636
- }
20637
- function readHeader(reader, expectedMagic, headerSize, verifyChecksum) {
20638
- const magic = new TextDecoder().decode(reader.readBytes(10));
20639
- if (magic !== expectedMagic) {
20640
- throw new Error(`Unexpected LEPCC blob type: ${JSON.stringify(magic)}`);
20641
- }
20642
- const version2 = reader.readUint16();
20643
- if (version2 > 1) {
20644
- throw new Error(`Unsupported LEPCC version: ${version2}`);
20645
- }
20646
- const expectedChecksum = reader.readUint32();
20647
- const blobSize = reader.readBigUint64();
20648
- if (blobSize < headerSize || blobSize > reader.bytes.byteLength) {
20649
- throw new Error(`Invalid LEPCC blob size: ${blobSize}`);
20650
- }
20651
- if (verifyChecksum) {
20652
- const actualChecksum = computeFletcher32(reader.bytes.subarray(16, blobSize));
20653
- if (actualChecksum !== expectedChecksum) {
20654
- throw new Error("LEPCC checksum mismatch");
22359
+ /** Returns cached metadata and shares a single request among concurrent callers. */
22360
+ async _getMetadata() {
22361
+ if (this._metadata)
22362
+ return this._metadata;
22363
+ if (!this._metadataPromise) {
22364
+ this._metadataPromise = this._loadMetadata();
20655
22365
  }
20656
- }
20657
- return { blobSize };
20658
- }
20659
- function assertBlobConsumed(reader, blobSize) {
20660
- if (reader.offset !== blobSize) {
20661
- throw new Error(`LEPCC decoder consumed ${reader.offset} bytes, expected ${blobSize}`);
20662
- }
20663
- }
20664
- function computeFletcher32(bytes) {
20665
- let sum1 = 65535;
20666
- let sum2 = 65535;
20667
- let offset = 0;
20668
- let words = Math.floor(bytes.length / 2);
20669
- while (words > 0) {
20670
- const count = Math.min(words, 359);
20671
- words -= count;
20672
- for (let index = 0; index < count; index++) {
20673
- sum1 += bytes[offset++] << 8;
20674
- sum1 += bytes[offset++];
20675
- sum2 += sum1;
22366
+ try {
22367
+ const metadata = await this._metadataPromise;
22368
+ this._metadata = metadata;
22369
+ return metadata;
22370
+ } finally {
22371
+ this._metadataPromise = null;
20676
22372
  }
20677
- sum1 = (sum1 & 65535) + (sum1 >>> 16);
20678
- sum2 = (sum2 & 65535) + (sum2 >>> 16);
20679
22373
  }
20680
- if (bytes.length & 1) {
20681
- sum1 += bytes[offset] << 8;
20682
- sum2 += sum1;
22374
+ /** Selects a service endpoint for a tile using a stable URL-pool mapping. */
22375
+ getServiceURL(parameters) {
22376
+ var _a2;
22377
+ const urls = (_a2 = this.options["arcgis-image-server-tiles"]) == null ? void 0 : _a2.urls;
22378
+ return (urls == null ? void 0 : urls.length) ? urls[(parameters.x + parameters.y) % urls.length] : this.url;
20683
22379
  }
20684
- sum1 = (sum1 & 65535) + (sum1 >>> 16);
20685
- sum2 = (sum2 & 65535) + (sum2 >>> 16);
20686
- return (sum2 << 16 | sum1) >>> 0;
20687
- }
20688
- function decodeCutInSegments(reader) {
20689
- const sectionMinimums = decodeSimple(reader);
20690
- const values = [];
20691
- for (const sectionMinimum of sectionMinimums) {
20692
- const sectionValues = decodeSimple(reader);
20693
- for (const sectionValue of sectionValues) {
20694
- values.push(sectionValue + sectionMinimum);
20695
- }
22380
+ /** Returns the response format after applying configured and runtime overrides. */
22381
+ _getResponseFormat() {
22382
+ var _a2;
22383
+ const options = this.options["arcgis-image-server-tiles"] || {};
22384
+ const format = this._runtimeParameters.format || ((_a2 = options.parameters) == null ? void 0 : _a2.format) || options.format;
22385
+ return format === "lerc" ? "lerc" : "png32";
20696
22386
  }
20697
- return values;
22387
+ };
22388
+ var ArcGISImageTileSourceLoader = {
22389
+ dataType: null,
22390
+ batchType: null,
22391
+ name: "ArcGIS ImageServer tiles",
22392
+ id: "arcgis-image-server-tiles",
22393
+ module: "services",
22394
+ version: "0.0.0",
22395
+ extensions: [],
22396
+ mimeTypes: [],
22397
+ type: "arcgis-image-server-tiles",
22398
+ fromUrl: true,
22399
+ fromBlob: false,
22400
+ options: { "arcgis-image-server-tiles": {} },
22401
+ defaultOptions: { "arcgis-image-server-tiles": {} },
22402
+ testURL: (url) => /imageserver/i.test(url),
22403
+ createDataSource: (url, options = {}, coreApi2) => new ArcGISImageTileSource(url, options, coreApi2)
22404
+ };
22405
+ function getWebMercatorTileBounds2(parameters) {
22406
+ const worldSize = 20037508342789244e-9;
22407
+ const tileCount = 2 ** parameters.z;
22408
+ const tileSize = worldSize * 2 / tileCount;
22409
+ const west = -worldSize + parameters.x * tileSize;
22410
+ const east = west + tileSize;
22411
+ const north = worldSize - parameters.y * tileSize;
22412
+ const south = north - tileSize;
22413
+ return [west, south, east, north];
20698
22414
  }
20699
- function decodeSimple(reader) {
20700
- const header = reader.readUint8();
20701
- const numberOfBits = header & 31;
20702
- const encodedNumberOfBytes = header >>> 6;
20703
- const numberOfBytes = encodedNumberOfBytes === 0 ? 4 : 3 - encodedNumberOfBytes;
20704
- if (numberOfBytes !== 1 && numberOfBytes !== 2 && numberOfBytes !== 4) {
20705
- throw new Error("Invalid LEPCC bit-stuffer element width");
20706
- }
20707
- const elementCount = numberOfBytes === 1 ? reader.readUint8() : numberOfBytes === 2 ? reader.readUint16() : reader.readUint32();
20708
- if (header & 32) {
20709
- throw new Error("LEPCC lookup-table bit stuffing is not supported");
20710
- }
20711
- if (numberOfBits === 0) {
20712
- return new Array(elementCount).fill(0);
22415
+
22416
+ // dist/arcgis/arcgis-vector-tile-server-source-loader.js
22417
+ init_src5();
22418
+
22419
+ // ../mvt/src/index.ts
22420
+ init_mvt_loader();
22421
+
22422
+ // dist/arcgis/arcgis-vector-tile-server-source-loader.js
22423
+ var ArcGISVectorTileServerSource = class extends DataSource {
22424
+ /** Decoded tile family consumed by generic tile renderers. */
22425
+ mimeType = "application/vnd.mapbox-vector-tile";
22426
+ /** ArcGIS tiles are decoded to WGS84 coordinates before rendering. */
22427
+ localCoordinates = false;
22428
+ /** Cached service metadata request. */
22429
+ serviceMetadata = null;
22430
+ /** Query parameters supplied with the service URL, such as an access token. */
22431
+ serviceQueryParameters;
22432
+ /** Creates an ArcGIS VectorTileServer source. */
22433
+ constructor(url, options = {}, coreApi2) {
22434
+ const serviceURL = new URL(url);
22435
+ serviceURL.pathname = serviceURL.pathname.replace(/\/$/, "");
22436
+ super(`${serviceURL.origin}${serviceURL.pathname}`, options, ArcGISVectorTileServerSourceLoader.defaultOptions, coreApi2);
22437
+ this.serviceQueryParameters = new URLSearchParams(serviceURL.search);
20713
22438
  }
20714
- const bitReader = new BitReader(reader);
20715
- const values = new Array(elementCount);
20716
- for (let index = 0; index < elementCount; index++) {
20717
- values[index] = bitReader.readBits(numberOfBits);
22439
+ /** Returns normalized service and tile-grid metadata. */
22440
+ async getMetadata() {
22441
+ var _a2, _b;
22442
+ const metadata = await this.getServiceMetadata();
22443
+ const tileInfo = metadata.tileInfo;
22444
+ const lods = (tileInfo == null ? void 0 : tileInfo.lods) || [];
22445
+ const extent = metadata.fullExtent || metadata.initialExtent;
22446
+ return {
22447
+ name: metadata.mapName || this.url.split("/").pop() || "",
22448
+ title: metadata.mapName,
22449
+ abstract: metadata.serviceDescription,
22450
+ format: "application/vnd.mapbox-vector-tile",
22451
+ minZoom: (_a2 = lods[0]) == null ? void 0 : _a2.level,
22452
+ maxZoom: (_b = lods.at(-1)) == null ? void 0 : _b.level,
22453
+ boundingBox: extent ? [
22454
+ [extent.xmin, extent.ymin],
22455
+ [extent.xmax, extent.ymax]
22456
+ ] : void 0,
22457
+ layer: {
22458
+ name: metadata.mapName || "",
22459
+ srs: (tileInfo == null ? void 0 : tileInfo.spatialReference) ? [getSpatialReference(tileInfo.spatialReference)] : [],
22460
+ layers: []
22461
+ },
22462
+ formatHeader: {
22463
+ tileInfo,
22464
+ styleURL: this.getStyleURL(),
22465
+ spriteURL: this.getSpriteURL()
22466
+ }
22467
+ };
20718
22468
  }
20719
- bitReader.alignToByte();
20720
- return values;
20721
- }
20722
- function decodeHuffman(reader, elementCount) {
20723
- const version2 = reader.readUint32();
20724
- const tableSize = reader.readUint32();
20725
- const firstSymbol = reader.readUint32();
20726
- const lastSymbol = reader.readUint32();
20727
- if (version2 < 2 || tableSize === 0 || tableSize > 32768 || firstSymbol >= lastSymbol) {
20728
- throw new Error("Invalid LEPCC Huffman code table");
22469
+ /** Fetches one raw PBF tile from the ArcGIS tile endpoint. */
22470
+ async getTile(parameters, signal) {
22471
+ const response = await this.fetch(this.getTileURL(parameters), {
22472
+ signal,
22473
+ headers: { Accept: "application/vnd.mapbox-vector-tile, application/x-protobuf" }
22474
+ });
22475
+ if (!response.ok)
22476
+ return null;
22477
+ return response.arrayBuffer();
20729
22478
  }
20730
- const codeLengths = decodeSimple(reader);
20731
- if (codeLengths.length !== lastSymbol - firstSymbol) {
20732
- throw new Error("LEPCC Huffman code table length mismatch");
22479
+ /** Returns the schema advertised by decoded vector tiles. */
22480
+ async getSchema() {
22481
+ return { fields: [], metadata: {} };
20733
22482
  }
20734
- const lengthsBySymbol = new Array(tableSize).fill(0);
20735
- let codeBitCount = 0;
20736
- for (let symbol = firstSymbol; symbol < lastSymbol; symbol++) {
20737
- const tableIndex = symbol < tableSize ? symbol : symbol - tableSize;
20738
- const codeLength = codeLengths[symbol - firstSymbol];
20739
- if (codeLength > 32) {
20740
- throw new Error("LEPCC Huffman code is too long");
22483
+ /** Fetches and decodes one ArcGIS vector tile to geographic coordinates. */
22484
+ async getVectorTile(parameters) {
22485
+ var _a2;
22486
+ const arrayBuffer = await this.getTile(parameters, parameters.signal);
22487
+ if (!arrayBuffer) {
22488
+ return null;
20741
22489
  }
20742
- lengthsBySymbol[tableIndex] = codeLength;
20743
- codeBitCount += codeLength;
22490
+ const inheritedOptions = this.loadOptions.mvt;
22491
+ const sourceOptions = (_a2 = this.options["arcgis-vector-tile-server"]) == null ? void 0 : _a2.mvt;
22492
+ return await this.coreApi.parse(arrayBuffer, MVTLoader, {
22493
+ ...this.loadOptions,
22494
+ mvt: {
22495
+ ...inheritedOptions,
22496
+ ...sourceOptions,
22497
+ coordinates: "wgs84",
22498
+ tileIndex: { x: parameters.x, y: parameters.y, z: parameters.z },
22499
+ layers: normalizeLayers(parameters.layers) || (sourceOptions == null ? void 0 : sourceOptions.layers) || (inheritedOptions == null ? void 0 : inheritedOptions.layers)
22500
+ }
22501
+ });
20744
22502
  }
20745
- const symbols = lengthsBySymbol.map((codeLength, symbol) => ({ codeLength, symbol })).filter((value) => value.codeLength > 0).sort((left, right) => right.codeLength - left.codeLength || left.symbol - right.symbol);
20746
- if (symbols.length < 2) {
20747
- throw new Error("LEPCC Huffman table has fewer than two symbols");
22503
+ /** Provides decoded vector tiles through the deck.gl source interface. */
22504
+ async getTileData(parameters) {
22505
+ return this.getVectorTile({ ...parameters.index, signal: parameters.signal });
20748
22506
  }
20749
- const codeLookup = /* @__PURE__ */ new Map();
20750
- let canonicalCode = 0;
20751
- let canonicalLength = symbols[0].codeLength;
20752
- for (const symbol of symbols) {
20753
- const delta = canonicalLength - symbol.codeLength;
20754
- canonicalCode = Math.floor(canonicalCode / 2 ** delta);
20755
- canonicalLength = symbol.codeLength;
20756
- codeLookup.set(`${canonicalLength}:${canonicalCode}`, symbol.symbol);
20757
- canonicalCode++;
22507
+ /** Builds the ArcGIS cached vector tile URL. */
22508
+ getTileURL(parameters) {
22509
+ return this.getResourceURL(`/tile/${parameters.z}/${parameters.y}/${parameters.x}.pbf`);
20758
22510
  }
20759
- const codeReader = new MsbBitReader(reader);
20760
- for (const codeLength of lengthsBySymbol) {
20761
- if (codeLength > 0) {
20762
- codeReader.readBits(codeLength);
20763
- }
22511
+ /** Returns the service metadata URL. */
22512
+ getMetadataURL() {
22513
+ const url = new URL(this.getResourceURL(""));
22514
+ url.searchParams.set("f", "pjson");
22515
+ return url.toString();
20764
22516
  }
20765
- codeReader.finishWords();
20766
- if (codeBitCount === 0) {
20767
- throw new Error("LEPCC Huffman table has no code bits");
22517
+ /** Returns the ArcGIS Mapbox style resource URL. */
22518
+ getStyleURL() {
22519
+ return this.getResourceURL("/resources/styles/root.json");
20768
22520
  }
20769
- const valueReader = new MsbBitReader(reader);
20770
- const values = new Array(elementCount);
20771
- for (let index = 0; index < elementCount; index++) {
20772
- let code = 0;
20773
- let decodedSymbol;
20774
- for (let codeLength = 1; codeLength <= 32; codeLength++) {
20775
- code = code * 2 + valueReader.readBits(1);
20776
- decodedSymbol = codeLookup.get(`${codeLength}:${code}`);
20777
- if (decodedSymbol !== void 0) {
20778
- break;
20779
- }
20780
- }
20781
- if (decodedSymbol === void 0) {
20782
- throw new Error("Invalid LEPCC Huffman value");
20783
- }
20784
- values[index] = decodedSymbol;
22521
+ /** Returns the ArcGIS sprite resource base URL. */
22522
+ getSpriteURL() {
22523
+ return this.getResourceURL("/resources/sprites/sprite");
20785
22524
  }
20786
- valueReader.finishWords(1);
20787
- return values;
20788
- }
20789
- var BitReader = class {
20790
- reader;
20791
- bitOffset = 0;
20792
- constructor(reader) {
20793
- this.reader = reader;
20794
- }
20795
- readBits(numberOfBits) {
20796
- let value = 0;
20797
- for (let bitIndex = 0; bitIndex < numberOfBits; bitIndex++) {
20798
- if (this.bitOffset === 0) {
20799
- this.reader.ensure(1);
20800
- }
20801
- const currentByte = this.reader.bytes[this.reader.offset];
20802
- value += (currentByte >>> this.bitOffset & 1) * 2 ** bitIndex;
20803
- this.bitOffset++;
20804
- if (this.bitOffset === 8) {
20805
- this.bitOffset = 0;
20806
- this.reader.offset++;
20807
- }
20808
- }
20809
- return value;
22525
+ /** Loads and caches the ArcGIS VectorTileServer metadata document. */
22526
+ async getServiceMetadata() {
22527
+ this.serviceMetadata ||= this.fetch(this.getMetadataURL()).then(async (response) => {
22528
+ if (!response.ok)
22529
+ throw new Error(`ArcGIS VectorTileServer request failed: ${response.status}`);
22530
+ return await response.json();
22531
+ });
22532
+ return this.serviceMetadata;
20810
22533
  }
20811
- alignToByte() {
20812
- if (this.bitOffset !== 0) {
20813
- this.reader.offset++;
20814
- this.bitOffset = 0;
22534
+ /** Builds a resource URL while retaining service query parameters. */
22535
+ getResourceURL(resourcePath) {
22536
+ const url = new URL(this.url);
22537
+ url.pathname = `${url.pathname.replace(/\/$/, "")}${resourcePath}`;
22538
+ for (const [key, value] of this.serviceQueryParameters) {
22539
+ url.searchParams.set(key, value);
20815
22540
  }
22541
+ return url.toString();
20816
22542
  }
20817
22543
  };
20818
- var MsbBitReader = class {
20819
- reader;
20820
- startOffset;
20821
- bitOffset = 0;
20822
- bitsRead = 0;
20823
- constructor(reader) {
20824
- this.reader = reader;
20825
- this.startOffset = reader.offset;
20826
- }
20827
- readBits(numberOfBits) {
20828
- let value = 0;
20829
- for (let bitIndex = 0; bitIndex < numberOfBits; bitIndex++) {
20830
- if (this.bitOffset === 0) {
20831
- this.reader.ensure(4);
20832
- }
20833
- const word = this.reader.bytes[this.reader.offset] | this.reader.bytes[this.reader.offset + 1] << 8 | this.reader.bytes[this.reader.offset + 2] << 16 | this.reader.bytes[this.reader.offset + 3] << 24;
20834
- value = value * 2 + (word >>> 31 - this.bitOffset & 1);
20835
- this.bitOffset++;
20836
- this.bitsRead++;
20837
- if (this.bitOffset === 32) {
20838
- this.bitOffset = 0;
20839
- this.reader.offset += 4;
20840
- }
20841
- }
20842
- return value;
20843
- }
20844
- finishWords(extraWords = 0) {
20845
- this.reader.offset = this.startOffset + Math.ceil(this.bitsRead / 32) * 4 + extraWords * 4;
20846
- this.bitOffset = 0;
20847
- }
22544
+ var ArcGISVectorTileServerSourceLoader = {
22545
+ dataType: null,
22546
+ batchType: null,
22547
+ name: "ArcGIS VectorTileServer",
22548
+ id: "arcgis-vector-tile-server",
22549
+ module: "services",
22550
+ version: "0.0.0",
22551
+ extensions: [],
22552
+ mimeTypes: ["application/vnd.mapbox-vector-tile", "application/x-protobuf"],
22553
+ type: "arcgis-vector-tile-server",
22554
+ fromUrl: true,
22555
+ fromBlob: false,
22556
+ options: { "arcgis-vector-tile-server": {} },
22557
+ defaultOptions: { "arcgis-vector-tile-server": {} },
22558
+ testURL: (url) => /\/vectortileserver(?:[\/?#]|$)/i.test(url),
22559
+ createDataSource: (url, options = {}, coreApi2) => new ArcGISVectorTileServerSource(url, options, coreApi2)
20848
22560
  };
22561
+ function getSpatialReference(spatialReference) {
22562
+ return `EPSG:${spatialReference.latestWkid || spatialReference.wkid}`;
22563
+ }
22564
+ function normalizeLayers(layers) {
22565
+ if (!layers)
22566
+ return void 0;
22567
+ return Array.isArray(layers) ? layers : [layers];
22568
+ }
22569
+
22570
+ // dist/arcgis/arcgis-scene-server-source-loader.js
22571
+ init_src5();
20849
22572
 
20850
22573
  // ../i3s/src/i3s-point-cloud-source.ts
20851
22574
  init_src5();
@@ -20855,6 +22578,8 @@ var import_geospatial9 = require("@math.gl/geospatial");
20855
22578
  init_src9();
20856
22579
  init_src5();
20857
22580
  init_parse_slpk();
22581
+ init_i3s_lepcc();
22582
+ init_i3s_lepcc_loader_types();
20858
22583
  init_i3s_zod_schema();
20859
22584
  init_url_utils();
20860
22585
  var I3SPointCloudSource = class extends DataSource {
@@ -20887,9 +22612,9 @@ var I3SPointCloudSource = class extends DataSource {
20887
22612
  * @param data Layer REST URL or an SLPK Blob/URL.
20888
22613
  * @param options Source and loader options.
20889
22614
  */
20890
- constructor(data, options = {}) {
22615
+ constructor(data, options = {}, coreApi2) {
20891
22616
  var _a2;
20892
- super(data, options);
22617
+ super(data, options, void 0, coreApi2);
20893
22618
  this.decoder = new I3SLEPCCDecoder({ verifyChecksum: (_a2 = options.i3s) == null ? void 0 : _a2.verifyChecksum });
20894
22619
  }
20895
22620
  /** Load and validate the scene-layer metadata. */
@@ -20969,7 +22694,11 @@ var I3SPointCloudSource = class extends DataSource {
20969
22694
  const geometryBytes = await this.readBinary(
20970
22695
  this.resourceCandidates(`nodes/${resourceId}/geometries/${geometryResource}`)
20971
22696
  );
20972
- const positions = this.decoder.decodeXyz(new Uint8Array(geometryBytes));
22697
+ const geometry = await this.decodeLEPCC(geometryBytes, "xyz");
22698
+ if (geometry.type !== "xyz" || !(geometry.value instanceof Float64Array)) {
22699
+ throw new Error(`I3S PointCloud geometry resource decoded as ${geometry.type}, expected xyz`);
22700
+ }
22701
+ const positions = geometry.value;
20973
22702
  const pointCount = positions.length / 3;
20974
22703
  if (node.vertexCount && node.vertexCount !== pointCount) {
20975
22704
  throw new Error(
@@ -20997,7 +22726,7 @@ var I3SPointCloudSource = class extends DataSource {
20997
22726
  if (!bytes) {
20998
22727
  return;
20999
22728
  }
21000
- const decoded = this.decodeAttribute(bytes, descriptor);
22729
+ const decoded = await this.decodeAttribute(bytes, descriptor);
21001
22730
  if (decoded.value.length !== pointCount * decoded.size) {
21002
22731
  throw new Error(
21003
22732
  `I3S PointCloud attribute ${descriptor.name || descriptor.key || "unknown"} count mismatch`
@@ -21143,7 +22872,7 @@ var I3SPointCloudSource = class extends DataSource {
21143
22872
  return (layer == null ? void 0 : layer.attributeInfo) || (layer == null ? void 0 : layer.attributeStorageInfo) || [];
21144
22873
  }
21145
22874
  decodeAttribute(bytes, descriptor) {
21146
- var _a2, _b;
22875
+ var _a2, _b, _c, _d, _e;
21147
22876
  const data = new Uint8Array(bytes);
21148
22877
  const encoding = String(descriptor.encoding || "").toLowerCase();
21149
22878
  let magic = "";
@@ -21153,18 +22882,51 @@ var I3SPointCloudSource = class extends DataSource {
21153
22882
  }
21154
22883
  const kind = encoding || magic;
21155
22884
  if (magic === "rgb" || encoding.includes("rgb")) {
21156
- return { value: this.decoder.decodeRgb(data), size: 3, kind: "rgb" };
22885
+ if (magic && this.hasCoreApi && ((_a2 = this.loadOptions.core) == null ? void 0 : _a2.worker) !== false) {
22886
+ return this.decodeLEPCC(bytes).then((decoded) => ({
22887
+ value: decoded.value instanceof Uint8Array ? decoded.value : this.decoder.decodeRgb(data),
22888
+ size: 3,
22889
+ kind: "rgb"
22890
+ }));
22891
+ }
22892
+ return {
22893
+ value: this.decoder.decodeRgb(data),
22894
+ size: 3,
22895
+ kind: "rgb"
22896
+ };
21157
22897
  }
21158
22898
  if (magic === "intensity" || encoding.includes("intensity")) {
21159
- return { value: this.decoder.decodeIntensity(data), size: 1, kind: "intensity" };
22899
+ if (magic && this.hasCoreApi && ((_b = this.loadOptions.core) == null ? void 0 : _b.worker) !== false) {
22900
+ return this.decodeLEPCC(bytes).then((decoded) => ({
22901
+ value: decoded.value instanceof Uint16Array ? decoded.value : this.decoder.decodeIntensity(data),
22902
+ size: 1,
22903
+ kind: "intensity"
22904
+ }));
22905
+ }
22906
+ return {
22907
+ value: this.decoder.decodeIntensity(data),
22908
+ size: 1,
22909
+ kind: "intensity"
22910
+ };
21160
22911
  }
21161
22912
  if (magic === "flagBytes" || encoding.includes("flag")) {
21162
- return { value: this.decoder.decodeFlagBytes(data), size: 1, kind: "flags" };
22913
+ if (magic && this.hasCoreApi && ((_c = this.loadOptions.core) == null ? void 0 : _c.worker) !== false) {
22914
+ return this.decodeLEPCC(bytes).then((decoded) => ({
22915
+ value: decoded.value instanceof Uint8Array ? decoded.value : this.decoder.decodeFlagBytes(data),
22916
+ size: 1,
22917
+ kind: "flags"
22918
+ }));
22919
+ }
22920
+ return {
22921
+ value: this.decoder.decodeFlagBytes(data),
22922
+ size: 1,
22923
+ kind: "flags"
22924
+ };
21163
22925
  }
21164
22926
  const valueType = String(
21165
- ((_a2 = descriptor.attributeValues) == null ? void 0 : _a2.valueType) || descriptor.valueType || "UInt8"
22927
+ ((_d = descriptor.attributeValues) == null ? void 0 : _d.valueType) || descriptor.valueType || "UInt8"
21166
22928
  ).toLowerCase();
21167
- const valueSize = ((_b = descriptor.attributeValues) == null ? void 0 : _b.valuesPerElement) || descriptor.valueSize || 1;
22929
+ const valueSize = ((_e = descriptor.attributeValues) == null ? void 0 : _e.valuesPerElement) || descriptor.valueSize || 1;
21168
22930
  if (valueType.includes("float32")) {
21169
22931
  return { value: new Float32Array(bytes), size: valueSize, kind };
21170
22932
  }
@@ -21179,6 +22941,27 @@ var I3SPointCloudSource = class extends DataSource {
21179
22941
  }
21180
22942
  return { value: new Uint8Array(bytes), size: valueSize, kind };
21181
22943
  }
22944
+ /** Decode a LEPCC resource using the shared worker pool when one is available. */
22945
+ async decodeLEPCC(bytes, expectedType) {
22946
+ var _a2, _b;
22947
+ const loaderOptions = {
22948
+ ...this.loadOptions,
22949
+ "i3s-lepcc": {
22950
+ verifyChecksum: (_a2 = this.options.i3s) == null ? void 0 : _a2.verifyChecksum
22951
+ }
22952
+ };
22953
+ if (this.hasCoreApi && ((_b = loaderOptions.core) == null ? void 0 : _b.worker) !== false) {
22954
+ return await this.coreApi.parse(bytes, I3SLEPCCLoader, {
22955
+ ...loaderOptions
22956
+ });
22957
+ }
22958
+ const data = new Uint8Array(bytes);
22959
+ const type = expectedType || this.decoder.getBlobType(data);
22960
+ return {
22961
+ type,
22962
+ value: type === "xyz" ? this.decoder.decodeXyz(data) : type === "rgb" ? this.decoder.decodeRgb(data) : type === "intensity" ? this.decoder.decodeIntensity(data) : this.decoder.decodeFlagBytes(data)
22963
+ };
22964
+ }
21182
22965
  getAttributeName(descriptor, kind) {
21183
22966
  if (kind.includes("rgb")) return "COLOR_0";
21184
22967
  if (kind.includes("intensity")) return "intensity";
@@ -21420,7 +23203,7 @@ function normalizeI3SRendererMetadata(layer) {
21420
23203
  function createI3SLayerSource(url, layer, options = {}, coreApi2) {
21421
23204
  var _a2, _b, _c;
21422
23205
  if (layer.layerType === "PointCloud") {
21423
- return new I3SPointCloudSource(url, options);
23206
+ return new I3SPointCloudSource(url, options, coreApi2);
21424
23207
  }
21425
23208
  const loadOptions = {
21426
23209
  ...((_a2 = options.core) == null ? void 0 : _a2.loadOptions) || {},
@@ -21642,6 +23425,11 @@ function getServiceLoader(serviceType) {
21642
23425
 
21643
23426
  // dist/authentication.js
21644
23427
  init_src5();
23428
+ var CESIUM_ION_API_ORIGIN = "https://api.cesium.com";
23429
+ var CESIUM_ION_ASSET_ORIGINS = [
23430
+ "https://assets.ion.cesium.com",
23431
+ "https://assets.cesium.com"
23432
+ ];
21645
23433
  function createArcGISCredential(options) {
21646
23434
  return createQueryParameterCredential({
21647
23435
  id: "arcgis-token",
@@ -21668,10 +23456,70 @@ function createGoogleMapsCredential(options) {
21668
23456
  });
21669
23457
  }
21670
23458
  function createCesiumIonCredential(options) {
23459
+ if (options.assetId === void 0 || options.assetId === null) {
23460
+ return createBearerTokenCredential({
23461
+ id: "cesium-ion-access-token",
23462
+ origins: options.origins || [CESIUM_ION_API_ORIGIN],
23463
+ token: options.accessToken
23464
+ });
23465
+ }
23466
+ const assetId = options.assetId;
23467
+ const origins = options.origins || CESIUM_ION_ASSET_ORIGINS;
23468
+ let endpointTokenPromise = null;
21671
23469
  return createBearerTokenCredential({
21672
- id: "cesium-ion-access-token",
21673
- origins: options.origins || ["https://api.cesium.com"],
21674
- token: options.accessToken
23470
+ id: `cesium-ion-asset-${assetId}`,
23471
+ origins,
23472
+ token: (context) => {
23473
+ if (context.reason === "refresh") {
23474
+ endpointTokenPromise = null;
23475
+ }
23476
+ endpointTokenPromise ||= resolveCesiumIonAssetToken(options, assetId, origins, context);
23477
+ return endpointTokenPromise;
23478
+ }
23479
+ });
23480
+ }
23481
+ async function resolveCesiumIonAssetToken(options, assetId, origins, context) {
23482
+ const endpointURL = `${CESIUM_ION_API_ORIGIN}/v1/assets/${assetId}/endpoint`;
23483
+ const accessToken = typeof options.accessToken === "function" ? await options.accessToken({ ...context, url: endpointURL }) : options.accessToken;
23484
+ if (!accessToken)
23485
+ return null;
23486
+ const tokenType = options.tokenType || "auto";
23487
+ if (tokenType === "asset" || tokenType === "auto" && isCesiumIonAssetToken(accessToken, assetId)) {
23488
+ return accessToken;
23489
+ }
23490
+ const apiCredential = createBearerTokenCredential({
23491
+ id: `cesium-ion-api-${assetId}`,
23492
+ origins: [CESIUM_ION_API_ORIGIN],
23493
+ token: accessToken
23494
+ });
23495
+ const ionFetch = createAuthenticatedFetch({
23496
+ fetch: options.fetch,
23497
+ credentials: [apiCredential]
21675
23498
  });
23499
+ const response = await ionFetch(endpointURL);
23500
+ if (!response.ok) {
23501
+ throw new Error(`Cesium ion asset ${assetId} endpoint request failed: ${response.status}`);
23502
+ }
23503
+ const endpoint = await response.json();
23504
+ if (typeof endpoint.url !== "string" || !origins.includes(new URL(endpoint.url).origin)) {
23505
+ throw new Error(`Cesium ion asset ${assetId} resolved to an unconfigured origin.`);
23506
+ }
23507
+ if (typeof endpoint.accessToken !== "string" || !endpoint.accessToken) {
23508
+ throw new Error(`Cesium ion did not return an endpoint token for asset ${assetId}.`);
23509
+ }
23510
+ return endpoint.accessToken;
23511
+ }
23512
+ function isCesiumIonAssetToken(token, assetId) {
23513
+ try {
23514
+ const encodedClaims = token.split(".")[1];
23515
+ if (!encodedClaims)
23516
+ return false;
23517
+ const base64 = encodedClaims.replace(/-/g, "+").replace(/_/g, "/");
23518
+ const paddedBase64 = base64.padEnd(Math.ceil(base64.length / 4) * 4, "=");
23519
+ const claims = JSON.parse(atob(paddedBase64));
23520
+ return Array.isArray(claims.assets) && claims.assets.some((claimAssetId) => String(claimAssetId) === String(assetId));
23521
+ } catch {
23522
+ return false;
23523
+ }
21676
23524
  }
21677
23525
  //# sourceMappingURL=index.cjs.map