maplibre-gl-layers 0.2.0 → 0.4.0

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.
@@ -1,11 +1,11 @@
1
1
  /*!
2
2
  * name: maplibre-gl-layers
3
- * version: 0.2.0
3
+ * version: 0.4.0
4
4
  * description: MapLibre's layer extension library enabling the display, movement, and modification of large numbers of dynamic sprite images
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/maplibre-gl-layers.git
8
- * git.commit.hash: 4fe3389ad068a5950d4f01e01ec9d3b34c049fb2
8
+ * git.commit.hash: 366a9e1190bfe770b4002a06284ff627188b5c76
9
9
  */
10
10
 
11
11
  import { Map as MapLibreMap } from 'maplibre-gl';
package/dist/easing.d.ts CHANGED
@@ -1,11 +1,11 @@
1
1
  /*!
2
2
  * name: maplibre-gl-layers
3
- * version: 0.2.0
3
+ * version: 0.4.0
4
4
  * description: MapLibre's layer extension library enabling the display, movement, and modification of large numbers of dynamic sprite images
5
5
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
6
6
  * license: MIT
7
7
  * repository.url: https://github.com/kekyo/maplibre-gl-layers.git
8
- * git.commit.hash: 4fe3389ad068a5950d4f01e01ec9d3b34c049fb2
8
+ * git.commit.hash: 366a9e1190bfe770b4002a06284ff627188b5c76
9
9
  */
10
10
 
11
11
  import { EasingFunction } from './types';
package/dist/index.cjs CHANGED
@@ -1,14 +1,32 @@
1
1
  "use strict";
2
2
  /*!
3
3
  * name: maplibre-gl-layers
4
- * version: 0.2.0
4
+ * version: 0.4.0
5
5
  * description: MapLibre's layer extension library enabling the display, movement, and modification of large numbers of dynamic sprite images
6
6
  * author: Kouji Matsui (@kekyo@mi.kekyo.net)
7
7
  * license: MIT
8
8
  * repository.url: https://github.com/kekyo/maplibre-gl-layers.git
9
- * git.commit.hash: 4fe3389ad068a5950d4f01e01ec9d3b34c049fb2
9
+ * git.commit.hash: 366a9e1190bfe770b4002a06284ff627188b5c76
10
10
  */
11
11
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
12
+ const UNLIMITED_SPRITE_SCALING_OPTIONS = {
13
+ metersPerPixel: 1,
14
+ zoomMin: 0,
15
+ zoomMax: 30,
16
+ scaleMin: 1,
17
+ scaleMax: 1,
18
+ spriteMinPixel: 0,
19
+ spriteMaxPixel: 1e5
20
+ };
21
+ const STANDARD_SPRITE_SCALING_OPTIONS = {
22
+ metersPerPixel: 1,
23
+ zoomMin: 8,
24
+ zoomMax: 20,
25
+ scaleMin: 0.1,
26
+ scaleMax: 1,
27
+ spriteMinPixel: 24,
28
+ spriteMaxPixel: 100
29
+ };
12
30
  var maplibreGl$1 = { exports: {} };
13
31
  /**
14
32
  * MapLibre GL JS
@@ -21313,26 +21331,134 @@ const EARTH_RADIUS_METERS = 6378137;
21313
21331
  const DEG2RAD = Math.PI / 180;
21314
21332
  const RAD2DEG = 180 / Math.PI;
21315
21333
  const TILE_SIZE = 512;
21316
- const DEFAULT_SPRITE_SCALING_OPTIONS = {
21317
- metersPerPixel: 1,
21318
- zoomMin: 0,
21319
- zoomMax: 30,
21320
- scaleMin: 1,
21321
- scaleMax: 1,
21322
- spriteMinPixel: 0,
21323
- spriteMaxPixel: 1e4
21324
- };
21325
21334
  const resolveScalingOptions = (options) => {
21326
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
21327
- const base = DEFAULT_SPRITE_SCALING_OPTIONS;
21335
+ var _a, _b;
21336
+ const base = UNLIMITED_SPRITE_SCALING_OPTIONS;
21337
+ const warnings = [];
21338
+ const fallbackMetersPerPixel = Number.isFinite(base.metersPerPixel) && ((_a = base.metersPerPixel) != null ? _a : 0) > 0 ? base.metersPerPixel : 1;
21339
+ let metersPerPixel = (options == null ? void 0 : options.metersPerPixel) !== void 0 ? options.metersPerPixel : fallbackMetersPerPixel;
21340
+ if (!Number.isFinite(metersPerPixel) || metersPerPixel <= 0) {
21341
+ if ((options == null ? void 0 : options.metersPerPixel) !== void 0) {
21342
+ warnings.push(
21343
+ `metersPerPixel(${String(options.metersPerPixel)}) is invalid; using ${fallbackMetersPerPixel}`
21344
+ );
21345
+ }
21346
+ metersPerPixel = fallbackMetersPerPixel;
21347
+ }
21348
+ const fallbackZoomMin = Number.isFinite(base.zoomMin) ? base.zoomMin : 0;
21349
+ let zoomMin = (options == null ? void 0 : options.zoomMin) !== void 0 ? options.zoomMin : fallbackZoomMin;
21350
+ if (!Number.isFinite(zoomMin)) {
21351
+ if ((options == null ? void 0 : options.zoomMin) !== void 0) {
21352
+ warnings.push(
21353
+ `zoomMin(${String(options.zoomMin)}) is not finite; using ${fallbackZoomMin}`
21354
+ );
21355
+ }
21356
+ zoomMin = fallbackZoomMin;
21357
+ }
21358
+ const fallbackZoomMax = Number.isFinite(base.zoomMax) && base.zoomMax > fallbackZoomMin ? base.zoomMax : fallbackZoomMin;
21359
+ let zoomMax = (options == null ? void 0 : options.zoomMax) !== void 0 ? options.zoomMax : fallbackZoomMax;
21360
+ if (!Number.isFinite(zoomMax)) {
21361
+ if ((options == null ? void 0 : options.zoomMax) !== void 0) {
21362
+ warnings.push(
21363
+ `zoomMax(${String(options.zoomMax)}) is not finite; using ${fallbackZoomMax}`
21364
+ );
21365
+ }
21366
+ zoomMax = fallbackZoomMax;
21367
+ }
21368
+ if (zoomMax < zoomMin) {
21369
+ warnings.push(
21370
+ `zoomMax(${zoomMax}) < zoomMin(${zoomMin}); swapped values to maintain ascending order`
21371
+ );
21372
+ [zoomMin, zoomMax] = [zoomMax, zoomMin];
21373
+ }
21374
+ const fallbackScaleMin = Number.isFinite(base.scaleMin) ? base.scaleMin : 1;
21375
+ let scaleMin = (options == null ? void 0 : options.scaleMin) !== void 0 ? options.scaleMin : fallbackScaleMin;
21376
+ if (!Number.isFinite(scaleMin)) {
21377
+ if ((options == null ? void 0 : options.scaleMin) !== void 0) {
21378
+ warnings.push(
21379
+ `scaleMin(${String(options.scaleMin)}) is not finite; using ${fallbackScaleMin}`
21380
+ );
21381
+ }
21382
+ scaleMin = fallbackScaleMin;
21383
+ }
21384
+ if (scaleMin < 0) {
21385
+ warnings.push(`scaleMin(${scaleMin}) is negative; clamped to 0`);
21386
+ scaleMin = 0;
21387
+ }
21388
+ const fallbackScaleMax = Number.isFinite(base.scaleMax) ? base.scaleMax : 1;
21389
+ let scaleMax = (options == null ? void 0 : options.scaleMax) !== void 0 ? options.scaleMax : fallbackScaleMax;
21390
+ if (!Number.isFinite(scaleMax)) {
21391
+ if ((options == null ? void 0 : options.scaleMax) !== void 0) {
21392
+ warnings.push(
21393
+ `scaleMax(${String(options.scaleMax)}) is not finite; using ${fallbackScaleMax}`
21394
+ );
21395
+ }
21396
+ scaleMax = fallbackScaleMax;
21397
+ }
21398
+ if (scaleMax < 0) {
21399
+ warnings.push(`scaleMax(${scaleMax}) is negative; clamped to 0`);
21400
+ scaleMax = 0;
21401
+ }
21402
+ if (scaleMax < scaleMin) {
21403
+ warnings.push(
21404
+ `scaleMax(${scaleMax}) < scaleMin(${scaleMin}); swapped values to maintain ascending order`
21405
+ );
21406
+ [scaleMin, scaleMax] = [scaleMax, scaleMin];
21407
+ }
21408
+ const fallbackSpriteMin = Number.isFinite(base.spriteMinPixel) && base.spriteMinPixel >= 0 ? base.spriteMinPixel : 0;
21409
+ let spriteMinPixel = (options == null ? void 0 : options.spriteMinPixel) !== void 0 ? options.spriteMinPixel : fallbackSpriteMin;
21410
+ if (!Number.isFinite(spriteMinPixel)) {
21411
+ if ((options == null ? void 0 : options.spriteMinPixel) !== void 0) {
21412
+ warnings.push(
21413
+ `spriteMinPixel(${String(
21414
+ options.spriteMinPixel
21415
+ )}) is not finite; using ${fallbackSpriteMin}`
21416
+ );
21417
+ }
21418
+ spriteMinPixel = fallbackSpriteMin;
21419
+ } else if (spriteMinPixel < 0) {
21420
+ warnings.push(
21421
+ `spriteMinPixel(${spriteMinPixel}) is negative; clamped to 0`
21422
+ );
21423
+ spriteMinPixel = 0;
21424
+ }
21425
+ const fallbackSpriteMax = Number.isFinite(base.spriteMaxPixel) && base.spriteMaxPixel >= 0 ? base.spriteMaxPixel : 0;
21426
+ let spriteMaxPixel = (options == null ? void 0 : options.spriteMaxPixel) !== void 0 ? options.spriteMaxPixel : fallbackSpriteMax;
21427
+ if (!Number.isFinite(spriteMaxPixel)) {
21428
+ if ((options == null ? void 0 : options.spriteMaxPixel) !== void 0) {
21429
+ warnings.push(
21430
+ `spriteMaxPixel(${String(
21431
+ options.spriteMaxPixel
21432
+ )}) is not finite; using ${fallbackSpriteMax}`
21433
+ );
21434
+ }
21435
+ spriteMaxPixel = fallbackSpriteMax;
21436
+ } else if (spriteMaxPixel < 0) {
21437
+ warnings.push(
21438
+ `spriteMaxPixel(${spriteMaxPixel}) is negative; clamped to 0`
21439
+ );
21440
+ spriteMaxPixel = 0;
21441
+ }
21442
+ if (spriteMinPixel > 0 && spriteMaxPixel > 0 && spriteMaxPixel < spriteMinPixel) {
21443
+ warnings.push(
21444
+ `spriteMaxPixel(${spriteMaxPixel}) < spriteMinPixel(${spriteMinPixel}); swapped values to maintain ascending order`
21445
+ );
21446
+ [spriteMinPixel, spriteMaxPixel] = [spriteMaxPixel, spriteMinPixel];
21447
+ }
21448
+ if (warnings.length > 0 && typeof console !== "undefined") {
21449
+ const warn = (_b = console.warn) != null ? _b : null;
21450
+ if (typeof warn === "function") {
21451
+ warn(`[SpriteScalingOptions] ${warnings.join("; ")}`);
21452
+ }
21453
+ }
21328
21454
  return {
21329
- metersPerPixel: (_b = (_a = options == null ? void 0 : options.metersPerPixel) != null ? _a : base.metersPerPixel) != null ? _b : 1,
21330
- zoomMin: (_d = (_c = options == null ? void 0 : options.zoomMin) != null ? _c : base.zoomMin) != null ? _d : 0,
21331
- zoomMax: (_f = (_e = options == null ? void 0 : options.zoomMax) != null ? _e : base.zoomMax) != null ? _f : 24,
21332
- scaleMin: (_h = (_g = options == null ? void 0 : options.scaleMin) != null ? _g : base.scaleMin) != null ? _h : 1,
21333
- scaleMax: (_j = (_i = options == null ? void 0 : options.scaleMax) != null ? _i : base.scaleMax) != null ? _j : 1,
21334
- spriteMinPixel: (_l = (_k = options == null ? void 0 : options.spriteMinPixel) != null ? _k : base.spriteMinPixel) != null ? _l : 0,
21335
- spriteMaxPixel: (_n = (_m = options == null ? void 0 : options.spriteMaxPixel) != null ? _m : base.spriteMaxPixel) != null ? _n : 0
21455
+ metersPerPixel,
21456
+ zoomMin,
21457
+ zoomMax,
21458
+ scaleMin,
21459
+ scaleMax,
21460
+ spriteMinPixel,
21461
+ spriteMaxPixel
21336
21462
  };
21337
21463
  };
21338
21464
  const calculateZoomScaleFactor = (zoom, scaling) => {
@@ -21450,13 +21576,37 @@ const calculateBillboardAnchorShiftPixels = (halfWidth, halfHeight, anchor, tota
21450
21576
  const shiftY = -anchorX * sinR - anchorY * cosR;
21451
21577
  return { x: shiftX, y: shiftY };
21452
21578
  };
21453
- const calculateSurfaceWorldDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, zoomScaleFactor) => {
21579
+ const calculateSurfaceWorldDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, zoomScaleFactor, options) => {
21580
+ var _a, _b;
21454
21581
  if (!imageWidth || !imageHeight || imageWidth <= 0 || imageHeight <= 0 || baseMetersPerPixel <= 0) {
21455
21582
  return { width: 0, height: 0 };
21456
21583
  }
21457
21584
  const scaleFactor = baseMetersPerPixel * imageScale * zoomScaleFactor;
21458
- const width = ensureFinite(imageWidth * scaleFactor);
21459
- const height = ensureFinite(imageHeight * scaleFactor);
21585
+ let width = ensureFinite(imageWidth * scaleFactor);
21586
+ let height = ensureFinite(imageHeight * scaleFactor);
21587
+ const effectivePixelsPerMeter = (options == null ? void 0 : options.effectivePixelsPerMeter) !== void 0 ? options.effectivePixelsPerMeter : 0;
21588
+ const spriteMinPixel = (_a = options == null ? void 0 : options.spriteMinPixel) != null ? _a : 0;
21589
+ const spriteMaxPixel = (_b = options == null ? void 0 : options.spriteMaxPixel) != null ? _b : 0;
21590
+ if (effectivePixelsPerMeter > 0 && Number.isFinite(effectivePixelsPerMeter) && (spriteMinPixel > 0 || spriteMaxPixel > 0)) {
21591
+ const largestMeters = Math.max(width, height);
21592
+ if (largestMeters > 0 && Number.isFinite(largestMeters)) {
21593
+ const largestPixels = largestMeters * effectivePixelsPerMeter;
21594
+ if (Number.isFinite(largestPixels) && largestPixels > 0) {
21595
+ let scale = 1;
21596
+ if (spriteMinPixel > 0 && largestPixels < spriteMinPixel) {
21597
+ scale = spriteMinPixel / largestPixels;
21598
+ }
21599
+ const scaledLargest = largestPixels * scale;
21600
+ if (spriteMaxPixel > 0 && scaledLargest > spriteMaxPixel) {
21601
+ scale = spriteMaxPixel / largestPixels;
21602
+ }
21603
+ if (scale !== 1) {
21604
+ width *= scale;
21605
+ height *= scale;
21606
+ }
21607
+ }
21608
+ }
21609
+ }
21460
21610
  return { width, height };
21461
21611
  };
21462
21612
  const calculateSurfaceAnchorShiftMeters = (halfWidthMeters, halfHeightMeters, anchor, totalRotateDeg) => {
@@ -21476,9 +21626,9 @@ const calculateSurfaceAnchorShiftMeters = (halfWidthMeters, halfHeightMeters, an
21476
21626
  const north = -anchorEast * sinR - anchorNorth * cosR;
21477
21627
  return { east, north };
21478
21628
  };
21479
- const calculateSurfaceOffsetMeters = (offset, imageScale) => {
21629
+ const calculateSurfaceOffsetMeters = (offset, imageScale, zoomScaleFactor) => {
21480
21630
  var _a, _b;
21481
- const offsetMeters = ((_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : 0) * imageScale;
21631
+ const offsetMeters = ((_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : 0) * imageScale * zoomScaleFactor;
21482
21632
  if (offsetMeters === 0) {
21483
21633
  return { east: 0, north: 0 };
21484
21634
  }
@@ -21696,6 +21846,9 @@ const calculateSurfaceCenterPosition = (params) => {
21696
21846
  totalRotateDeg,
21697
21847
  anchor,
21698
21848
  offset,
21849
+ effectivePixelsPerMeter = 0,
21850
+ spriteMinPixel = 0,
21851
+ spriteMaxPixel = 0,
21699
21852
  project,
21700
21853
  projectToClipSpace,
21701
21854
  drawingBufferWidth,
@@ -21733,7 +21886,12 @@ const calculateSurfaceCenterPosition = (params) => {
21733
21886
  imageHeight,
21734
21887
  baseMetersPerPixel,
21735
21888
  imageScale,
21736
- zoomScaleFactor
21889
+ zoomScaleFactor,
21890
+ {
21891
+ effectivePixelsPerMeter,
21892
+ spriteMinPixel,
21893
+ spriteMaxPixel
21894
+ }
21737
21895
  );
21738
21896
  const halfWidthMeters = worldDims.width / 2;
21739
21897
  const halfHeightMeters = worldDims.height / 2;
@@ -21743,7 +21901,11 @@ const calculateSurfaceCenterPosition = (params) => {
21743
21901
  anchor,
21744
21902
  totalRotateDeg
21745
21903
  );
21746
- const offsetMeters = calculateSurfaceOffsetMeters(offset, imageScale);
21904
+ const offsetMeters = calculateSurfaceOffsetMeters(
21905
+ offset,
21906
+ imageScale,
21907
+ zoomScaleFactor
21908
+ );
21747
21909
  const totalEast = anchorShiftMeters.east + offsetMeters.east;
21748
21910
  const totalNorth = anchorShiftMeters.north + offsetMeters.north;
21749
21911
  const displaced = applySurfaceDisplacement(
@@ -22075,6 +22237,35 @@ const resolveTextGlyphPadding = (padding) => {
22075
22237
  }
22076
22238
  return { top: 0, right: 0, bottom: 0, left: 0 };
22077
22239
  };
22240
+ const resolveBorderSides = (sides) => {
22241
+ if (!Array.isArray(sides) || sides.length === 0) {
22242
+ return { top: true, right: true, bottom: true, left: true };
22243
+ }
22244
+ let top = false;
22245
+ let right = false;
22246
+ let bottom = false;
22247
+ let left = false;
22248
+ for (const side of sides) {
22249
+ switch (side) {
22250
+ case "top":
22251
+ top = true;
22252
+ break;
22253
+ case "right":
22254
+ right = true;
22255
+ break;
22256
+ case "bottom":
22257
+ bottom = true;
22258
+ break;
22259
+ case "left":
22260
+ left = true;
22261
+ break;
22262
+ }
22263
+ }
22264
+ if (!top && !right && !bottom && !left) {
22265
+ return { top: true, right: true, bottom: true, left: true };
22266
+ }
22267
+ return { top, right, bottom, left };
22268
+ };
22078
22269
  const resolveTextAlign = (align) => {
22079
22270
  switch (align) {
22080
22271
  case "left":
@@ -22118,7 +22309,7 @@ const resolveTextGlyphOptions = (options, preferredLineHeight) => {
22118
22309
  DEFAULT_TEXT_GLYPH_FONT_SIZE
22119
22310
  );
22120
22311
  const resolvedFontSize = resolvePositiveFinite(
22121
- options == null ? void 0 : options.fontSizePixel,
22312
+ options == null ? void 0 : options.fontSizePixelHint,
22122
22313
  fallbackFontSize
22123
22314
  );
22124
22315
  return {
@@ -22133,6 +22324,7 @@ const resolveTextGlyphOptions = (options, preferredLineHeight) => {
22133
22324
  borderColor: options == null ? void 0 : options.borderColor,
22134
22325
  borderWidthPixel: resolveNonNegativeFinite(options == null ? void 0 : options.borderWidthPixel, 0),
22135
22326
  borderRadiusPixel: resolveNonNegativeFinite(options == null ? void 0 : options.borderRadiusPixel, 0),
22327
+ borderSides: resolveBorderSides(options == null ? void 0 : options.borderSides),
22136
22328
  textAlign: resolveTextAlign(options == null ? void 0 : options.textAlign),
22137
22329
  renderPixelRatio: resolveRenderPixelRatio(options == null ? void 0 : options.renderPixelRatio)
22138
22330
  };
@@ -22244,13 +22436,58 @@ const fillRoundedRect = (ctx, width, height, radius, color) => {
22244
22436
  ctx.fill();
22245
22437
  ctx.restore();
22246
22438
  };
22247
- const strokeRoundedRect = (ctx, width, height, radius, color, lineWidth) => {
22439
+ const strokeRoundedRect = (ctx, width, height, radius, color, lineWidth, sides) => {
22440
+ const { top, right, bottom, left } = sides;
22441
+ if (lineWidth <= 0 || !top && !right && !bottom && !left) {
22442
+ return;
22443
+ }
22248
22444
  ctx.save();
22249
- ctx.beginPath();
22250
- drawRoundedRectPath(ctx, 0, 0, width, height, radius);
22251
22445
  ctx.strokeStyle = color;
22252
22446
  ctx.lineWidth = lineWidth;
22253
- ctx.stroke();
22447
+ const cornerRadius = Math.max(0, Math.min(radius, width / 2, height / 2));
22448
+ const previousCap = ctx.lineCap;
22449
+ ctx.lineCap = cornerRadius === 0 ? "square" : "butt";
22450
+ if (top) {
22451
+ const startX = cornerRadius;
22452
+ const endX = width - cornerRadius;
22453
+ if (endX > startX) {
22454
+ ctx.beginPath();
22455
+ ctx.moveTo(startX, 0);
22456
+ ctx.lineTo(endX, 0);
22457
+ ctx.stroke();
22458
+ }
22459
+ }
22460
+ if (right) {
22461
+ const startY = cornerRadius;
22462
+ const endY = height - cornerRadius;
22463
+ if (endY > startY) {
22464
+ ctx.beginPath();
22465
+ ctx.moveTo(width, startY);
22466
+ ctx.lineTo(width, endY);
22467
+ ctx.stroke();
22468
+ }
22469
+ }
22470
+ if (bottom) {
22471
+ const startX = width - cornerRadius;
22472
+ const endX = cornerRadius;
22473
+ if (startX > endX) {
22474
+ ctx.beginPath();
22475
+ ctx.moveTo(startX, height);
22476
+ ctx.lineTo(endX, height);
22477
+ ctx.stroke();
22478
+ }
22479
+ }
22480
+ if (left) {
22481
+ const startY = height - cornerRadius;
22482
+ const endY = cornerRadius;
22483
+ if (startY > endY) {
22484
+ ctx.beginPath();
22485
+ ctx.moveTo(0, startY);
22486
+ ctx.lineTo(0, endY);
22487
+ ctx.stroke();
22488
+ }
22489
+ }
22490
+ ctx.lineCap = previousCap;
22254
22491
  ctx.restore();
22255
22492
  };
22256
22493
  const measureTextWidthWithSpacing = (ctx, text, letterSpacing) => {
@@ -22576,6 +22813,9 @@ const createSpriteLayer = (options) => {
22576
22813
  totalRotateDeg: totalRotDeg,
22577
22814
  anchor: img.anchor,
22578
22815
  offset: img.offset,
22816
+ effectivePixelsPerMeter,
22817
+ spriteMinPixel,
22818
+ spriteMaxPixel,
22579
22819
  projectToClipSpace,
22580
22820
  drawingBufferWidth,
22581
22821
  drawingBufferHeight,
@@ -23176,6 +23416,9 @@ const createSpriteLayer = (options) => {
23176
23416
  totalRotateDeg,
23177
23417
  anchor,
23178
23418
  offset: offsetDef,
23419
+ effectivePixelsPerMeter,
23420
+ spriteMinPixel,
23421
+ spriteMaxPixel,
23179
23422
  projectToClipSpace: (lng, lat, elevation) => projectLngLatToClipSpace(lng, lat, elevation, clipContext),
23180
23423
  drawingBufferWidth,
23181
23424
  drawingBufferHeight,
@@ -23191,7 +23434,8 @@ const createSpriteLayer = (options) => {
23191
23434
  }
23192
23435
  const offsetMeters = calculateSurfaceOffsetMeters(
23193
23436
  offsetDef,
23194
- imageScale
23437
+ imageScale,
23438
+ zoomScaleFactor
23195
23439
  );
23196
23440
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
23197
23441
  worldWidthMeters: surfaceCenter.worldDimensions.width,
@@ -23386,14 +23630,20 @@ const createSpriteLayer = (options) => {
23386
23630
  imageResource.height,
23387
23631
  baseMetersPerPixel,
23388
23632
  imageScale,
23389
- zoomScaleFactor
23633
+ zoomScaleFactor,
23634
+ {
23635
+ effectivePixelsPerMeter,
23636
+ spriteMinPixel,
23637
+ spriteMaxPixel
23638
+ }
23390
23639
  );
23391
23640
  const totalRotateDeg = Number.isFinite(imageEntry.displayedRotateDeg) ? imageEntry.displayedRotateDeg : normaliseAngleDeg(
23392
23641
  ((_e = imageEntry.resolvedBaseRotateDeg) != null ? _e : 0) + ((_f = imageEntry.rotateDeg) != null ? _f : 0)
23393
23642
  );
23394
23643
  const offsetMeters = calculateSurfaceOffsetMeters(
23395
23644
  offsetResolved,
23396
- imageScale
23645
+ imageScale,
23646
+ zoomScaleFactor
23397
23647
  );
23398
23648
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
23399
23649
  worldWidthMeters: worldDims.width,
@@ -23656,7 +23906,8 @@ const createSpriteLayer = (options) => {
23656
23906
  strokeHeight,
23657
23907
  strokeRadius,
23658
23908
  resolved.borderColor,
23659
- borderWidth
23909
+ borderWidth,
23910
+ resolved.borderSides
23660
23911
  );
23661
23912
  ctx.restore();
23662
23913
  }
@@ -24265,6 +24516,124 @@ const createSpriteLayer = (options) => {
24265
24516
  }
24266
24517
  return updatedCount;
24267
24518
  };
24519
+ const mutateSprites = (sourceItems, mutator) => {
24520
+ if (sourceItems.length === 0) {
24521
+ return 0;
24522
+ }
24523
+ let changedCount = 0;
24524
+ let isRequiredRender = false;
24525
+ let currentSprite = void 0;
24526
+ let didMutateImages = false;
24527
+ const operationResult = {
24528
+ isUpdated: false
24529
+ };
24530
+ const updateObject = {
24531
+ getImageIndexMap: () => {
24532
+ const map2 = /* @__PURE__ */ new Map();
24533
+ currentSprite.images.forEach((inner, subLayer) => {
24534
+ map2.set(subLayer, new Set(inner.keys()));
24535
+ });
24536
+ return map2;
24537
+ },
24538
+ addImage: (subLayer, order, imageInit) => {
24539
+ const added = addSpriteImageInternal(
24540
+ currentSprite,
24541
+ subLayer,
24542
+ order,
24543
+ imageInit,
24544
+ operationResult
24545
+ );
24546
+ if (added) {
24547
+ didMutateImages = true;
24548
+ }
24549
+ return added;
24550
+ },
24551
+ updateImage: (subLayer, order, imageUpdate) => {
24552
+ const updated = updateSpriteImageInternal(
24553
+ currentSprite,
24554
+ subLayer,
24555
+ order,
24556
+ imageUpdate,
24557
+ operationResult
24558
+ );
24559
+ if (updated) {
24560
+ didMutateImages = true;
24561
+ }
24562
+ return updated;
24563
+ },
24564
+ removeImage: (subLayer, order) => {
24565
+ const removed = removeSpriteImageInternal(
24566
+ currentSprite,
24567
+ subLayer,
24568
+ order,
24569
+ operationResult
24570
+ );
24571
+ if (removed) {
24572
+ didMutateImages = true;
24573
+ }
24574
+ return removed;
24575
+ }
24576
+ };
24577
+ for (const sourceItem of sourceItems) {
24578
+ const spriteId = sourceItem.spriteId;
24579
+ const sprite = sprites.get(spriteId);
24580
+ if (!sprite) {
24581
+ const init = mutator.add(sourceItem);
24582
+ if (!init) {
24583
+ continue;
24584
+ }
24585
+ if (addSpriteInternal(spriteId, init)) {
24586
+ changedCount++;
24587
+ isRequiredRender = true;
24588
+ }
24589
+ continue;
24590
+ }
24591
+ currentSprite = sprite;
24592
+ operationResult.isUpdated = false;
24593
+ didMutateImages = false;
24594
+ const decision = mutator.modify(
24595
+ sourceItem,
24596
+ sprite,
24597
+ updateObject
24598
+ );
24599
+ if (decision === "remove") {
24600
+ if (removeSpriteInternal(spriteId)) {
24601
+ changedCount++;
24602
+ isRequiredRender = true;
24603
+ }
24604
+ } else {
24605
+ const updateResult = updateSpriteInternal(spriteId, updateObject);
24606
+ let spriteChanged = false;
24607
+ switch (updateResult) {
24608
+ case "updated":
24609
+ spriteChanged = true;
24610
+ break;
24611
+ case "isRequiredRender":
24612
+ spriteChanged = true;
24613
+ isRequiredRender = true;
24614
+ break;
24615
+ }
24616
+ if (didMutateImages) {
24617
+ spriteChanged = true;
24618
+ isRequiredRender = true;
24619
+ }
24620
+ if (spriteChanged) {
24621
+ changedCount++;
24622
+ }
24623
+ }
24624
+ updateObject.isEnabled = void 0;
24625
+ updateObject.location = void 0;
24626
+ updateObject.interpolation = void 0;
24627
+ updateObject.tag = void 0;
24628
+ operationResult.isUpdated = false;
24629
+ didMutateImages = false;
24630
+ }
24631
+ if (isRequiredRender) {
24632
+ ensureRenderTargetEntries();
24633
+ scheduleRender();
24634
+ }
24635
+ return changedCount;
24636
+ };
24268
24637
  const updateForEach = (updater) => {
24269
24638
  let updatedCount = 0;
24270
24639
  let isRequiredRender = false;
@@ -24353,12 +24722,15 @@ const createSpriteLayer = (options) => {
24353
24722
  removeSpriteImage,
24354
24723
  updateSprite,
24355
24724
  updateBulk,
24725
+ mutateSprites,
24356
24726
  updateForEach,
24357
24727
  on: addEventListener2,
24358
24728
  off: removeEventListener2
24359
24729
  };
24360
24730
  return spriteLayout;
24361
24731
  };
24732
+ exports.STANDARD_SPRITE_SCALING_OPTIONS = STANDARD_SPRITE_SCALING_OPTIONS;
24733
+ exports.UNLIMITED_SPRITE_SCALING_OPTIONS = UNLIMITED_SPRITE_SCALING_OPTIONS;
24362
24734
  exports.applyAutoRotation = applyAutoRotation;
24363
24735
  exports.calculatePerspectiveRatio = calculatePerspectiveRatio;
24364
24736
  exports.cloneAnchor = cloneAnchor;