maplibre-gl-layers 0.4.0 → 0.6.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.4.0
3
+ * version: 0.6.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: 366a9e1190bfe770b4002a06284ff627188b5c76
8
+ * git.commit.hash: 481f544de02fd3e71a2ba6c28bbb7eeb98b49eff
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.4.0
3
+ * version: 0.6.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: 366a9e1190bfe770b4002a06284ff627188b5c76
8
+ * git.commit.hash: 481f544de02fd3e71a2ba6c28bbb7eeb98b49eff
9
9
  */
10
10
 
11
11
  import { EasingFunction } from './types';
package/dist/index.cjs CHANGED
@@ -1,12 +1,12 @@
1
1
  "use strict";
2
2
  /*!
3
3
  * name: maplibre-gl-layers
4
- * version: 0.4.0
4
+ * version: 0.6.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: 366a9e1190bfe770b4002a06284ff627188b5c76
9
+ * git.commit.hash: 481f544de02fd3e71a2ba6c28bbb7eeb98b49eff
10
10
  */
11
11
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
12
12
  const UNLIMITED_SPRITE_SCALING_OPTIONS = {
@@ -27,6 +27,18 @@ const STANDARD_SPRITE_SCALING_OPTIONS = {
27
27
  spriteMinPixel: 24,
28
28
  spriteMaxPixel: 100
29
29
  };
30
+ const DEFAULT_TEXTURE_FILTERING_OPTIONS = {
31
+ minFilter: "linear",
32
+ magFilter: "linear",
33
+ generateMipmaps: false,
34
+ maxAnisotropy: 1
35
+ };
36
+ const BETTER_TEXTURE_FILTERING_OPTIONS = {
37
+ minFilter: "linear-mipmap-linear",
38
+ magFilter: "linear",
39
+ generateMipmaps: true,
40
+ maxAnisotropy: 8
41
+ };
30
42
  var maplibreGl$1 = { exports: {} };
31
43
  /**
32
44
  * MapLibre GL JS
@@ -21519,25 +21531,30 @@ const calculateDistanceAndBearingMeters = (from, to) => {
21519
21531
  const clampSpritePixelSize = (width, height, spriteMinPixel, spriteMaxPixel) => {
21520
21532
  const largest = Math.max(width, height);
21521
21533
  if (!Number.isFinite(largest) || largest <= 0) {
21522
- return { width, height };
21534
+ return { width, height, scaleAdjustment: 1 };
21523
21535
  }
21524
21536
  let nextWidth = width;
21525
21537
  let nextHeight = height;
21538
+ let scaleAdjustment = 1;
21539
+ let adjustedLargest = largest;
21526
21540
  if (spriteMinPixel > 0 && largest < spriteMinPixel) {
21527
21541
  const factor = spriteMinPixel / largest;
21528
21542
  nextWidth *= factor;
21529
21543
  nextHeight *= factor;
21544
+ scaleAdjustment *= factor;
21545
+ adjustedLargest *= factor;
21530
21546
  }
21531
- if (spriteMaxPixel > 0 && largest > spriteMaxPixel) {
21532
- const factor = spriteMaxPixel / largest;
21547
+ if (spriteMaxPixel > 0 && adjustedLargest > spriteMaxPixel) {
21548
+ const factor = spriteMaxPixel / adjustedLargest;
21533
21549
  nextWidth *= factor;
21534
21550
  nextHeight *= factor;
21551
+ scaleAdjustment *= factor;
21535
21552
  }
21536
- return { width: nextWidth, height: nextHeight };
21553
+ return { width: nextWidth, height: nextHeight, scaleAdjustment };
21537
21554
  };
21538
21555
  const calculateBillboardPixelDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, zoomScaleFactor, effectivePixelsPerMeter, spriteMinPixel, spriteMaxPixel) => {
21539
21556
  if (!imageWidth || !imageHeight || imageWidth <= 0 || imageHeight <= 0 || baseMetersPerPixel <= 0 || effectivePixelsPerMeter <= 0) {
21540
- return { width: 0, height: 0 };
21557
+ return { width: 0, height: 0, scaleAdjustment: 1 };
21541
21558
  }
21542
21559
  const scaleFactor = baseMetersPerPixel * imageScale * zoomScaleFactor * effectivePixelsPerMeter;
21543
21560
  const rawWidth = ensureFinite(imageWidth * scaleFactor);
@@ -21549,10 +21566,10 @@ const calculateBillboardPixelDimensions = (imageWidth, imageHeight, baseMetersPe
21549
21566
  spriteMaxPixel
21550
21567
  );
21551
21568
  };
21552
- const calculateBillboardOffsetPixels = (offset, imageScale, zoomScaleFactor, effectivePixelsPerMeter) => {
21569
+ const calculateBillboardOffsetPixels = (offset, imageScale, zoomScaleFactor, effectivePixelsPerMeter, sizeScaleAdjustment = 1) => {
21553
21570
  var _a, _b;
21554
21571
  const offsetMeters = ((_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : 0) * imageScale * zoomScaleFactor;
21555
- const offsetPixels = offsetMeters * effectivePixelsPerMeter;
21572
+ const offsetPixels = offsetMeters * effectivePixelsPerMeter * sizeScaleAdjustment;
21556
21573
  const offsetRad = ((_b = offset == null ? void 0 : offset.offsetDeg) != null ? _b : 0) * DEG2RAD;
21557
21574
  return {
21558
21575
  x: offsetPixels * Math.sin(offsetRad),
@@ -21579,11 +21596,12 @@ const calculateBillboardAnchorShiftPixels = (halfWidth, halfHeight, anchor, tota
21579
21596
  const calculateSurfaceWorldDimensions = (imageWidth, imageHeight, baseMetersPerPixel, imageScale, zoomScaleFactor, options) => {
21580
21597
  var _a, _b;
21581
21598
  if (!imageWidth || !imageHeight || imageWidth <= 0 || imageHeight <= 0 || baseMetersPerPixel <= 0) {
21582
- return { width: 0, height: 0 };
21599
+ return { width: 0, height: 0, scaleAdjustment: 1 };
21583
21600
  }
21584
21601
  const scaleFactor = baseMetersPerPixel * imageScale * zoomScaleFactor;
21585
21602
  let width = ensureFinite(imageWidth * scaleFactor);
21586
21603
  let height = ensureFinite(imageHeight * scaleFactor);
21604
+ let scaleAdjustment = 1;
21587
21605
  const effectivePixelsPerMeter = (options == null ? void 0 : options.effectivePixelsPerMeter) !== void 0 ? options.effectivePixelsPerMeter : 0;
21588
21606
  const spriteMinPixel = (_a = options == null ? void 0 : options.spriteMinPixel) != null ? _a : 0;
21589
21607
  const spriteMaxPixel = (_b = options == null ? void 0 : options.spriteMaxPixel) != null ? _b : 0;
@@ -21603,11 +21621,12 @@ const calculateSurfaceWorldDimensions = (imageWidth, imageHeight, baseMetersPerP
21603
21621
  if (scale !== 1) {
21604
21622
  width *= scale;
21605
21623
  height *= scale;
21624
+ scaleAdjustment *= scale;
21606
21625
  }
21607
21626
  }
21608
21627
  }
21609
21628
  }
21610
- return { width, height };
21629
+ return { width, height, scaleAdjustment };
21611
21630
  };
21612
21631
  const calculateSurfaceAnchorShiftMeters = (halfWidthMeters, halfHeightMeters, anchor, totalRotateDeg) => {
21613
21632
  var _a, _b;
@@ -21626,7 +21645,7 @@ const calculateSurfaceAnchorShiftMeters = (halfWidthMeters, halfHeightMeters, an
21626
21645
  const north = -anchorEast * sinR - anchorNorth * cosR;
21627
21646
  return { east, north };
21628
21647
  };
21629
- const calculateSurfaceOffsetMeters = (offset, imageScale, zoomScaleFactor) => {
21648
+ const calculateSurfaceOffsetMeters = (offset, imageScale, zoomScaleFactor, sizeScaleAdjustment = 1) => {
21630
21649
  var _a, _b;
21631
21650
  const offsetMeters = ((_a = offset == null ? void 0 : offset.offsetMeters) != null ? _a : 0) * imageScale * zoomScaleFactor;
21632
21651
  if (offsetMeters === 0) {
@@ -21634,8 +21653,8 @@ const calculateSurfaceOffsetMeters = (offset, imageScale, zoomScaleFactor) => {
21634
21653
  }
21635
21654
  const rad = ((_b = offset == null ? void 0 : offset.offsetDeg) != null ? _b : 0) * DEG2RAD;
21636
21655
  return {
21637
- east: offsetMeters * Math.sin(rad),
21638
- north: offsetMeters * Math.cos(rad)
21656
+ east: offsetMeters * Math.sin(rad) * sizeScaleAdjustment,
21657
+ north: offsetMeters * Math.cos(rad) * sizeScaleAdjustment
21639
21658
  };
21640
21659
  };
21641
21660
  const MIN_COS_LAT = 1e-6;
@@ -21783,7 +21802,8 @@ const calculateBillboardCenterPosition = (params) => {
21783
21802
  offset,
21784
21803
  imageScale,
21785
21804
  zoomScaleFactor,
21786
- effectivePixelsPerMeter
21805
+ effectivePixelsPerMeter,
21806
+ pixelDims.scaleAdjustment
21787
21807
  );
21788
21808
  const centerX = base.x + offsetShift.x;
21789
21809
  const centerY = base.y - offsetShift.y;
@@ -21904,7 +21924,8 @@ const calculateSurfaceCenterPosition = (params) => {
21904
21924
  const offsetMeters = calculateSurfaceOffsetMeters(
21905
21925
  offset,
21906
21926
  imageScale,
21907
- zoomScaleFactor
21927
+ zoomScaleFactor,
21928
+ worldDims.scaleAdjustment
21908
21929
  );
21909
21930
  const totalEast = anchorShiftMeters.east + offsetMeters.east;
21910
21931
  const totalNorth = anchorShiftMeters.north + offsetMeters.north;
@@ -21995,6 +22016,91 @@ const MIN_CLIP_Z_EPSILON = 1e-7;
21995
22016
  const EPS_NDC = 1e-6;
21996
22017
  const ORDER_MAX = 16;
21997
22018
  const ORDER_BUCKET = 16;
22019
+ const MIN_FILTER_VALUES = [
22020
+ "nearest",
22021
+ "linear",
22022
+ "nearest-mipmap-nearest",
22023
+ "nearest-mipmap-linear",
22024
+ "linear-mipmap-nearest",
22025
+ "linear-mipmap-linear"
22026
+ ];
22027
+ const MAG_FILTER_VALUES = [
22028
+ "nearest",
22029
+ "linear"
22030
+ ];
22031
+ const MIPMAP_MIN_FILTERS = /* @__PURE__ */ new Set([
22032
+ "nearest-mipmap-nearest",
22033
+ "nearest-mipmap-linear",
22034
+ "linear-mipmap-nearest",
22035
+ "linear-mipmap-linear"
22036
+ ]);
22037
+ const filterRequiresMipmaps = (filter) => MIPMAP_MIN_FILTERS.has(filter);
22038
+ const resolveTextureFilteringOptions = (options) => {
22039
+ var _a, _b;
22040
+ const minCandidate = options == null ? void 0 : options.minFilter;
22041
+ const minFilter = MIN_FILTER_VALUES.includes(
22042
+ minCandidate
22043
+ ) ? minCandidate : DEFAULT_TEXTURE_FILTERING_OPTIONS.minFilter;
22044
+ const magCandidate = options == null ? void 0 : options.magFilter;
22045
+ const magFilter = MAG_FILTER_VALUES.includes(
22046
+ magCandidate
22047
+ ) ? magCandidate : DEFAULT_TEXTURE_FILTERING_OPTIONS.magFilter;
22048
+ let generateMipmaps = (_a = options == null ? void 0 : options.generateMipmaps) != null ? _a : DEFAULT_TEXTURE_FILTERING_OPTIONS.generateMipmaps;
22049
+ if (filterRequiresMipmaps(minFilter)) {
22050
+ generateMipmaps = true;
22051
+ }
22052
+ let maxAnisotropy = (_b = options == null ? void 0 : options.maxAnisotropy) != null ? _b : DEFAULT_TEXTURE_FILTERING_OPTIONS.maxAnisotropy;
22053
+ if (!Number.isFinite(maxAnisotropy) || maxAnisotropy < 1) {
22054
+ maxAnisotropy = 1;
22055
+ }
22056
+ return {
22057
+ minFilter,
22058
+ magFilter,
22059
+ generateMipmaps,
22060
+ maxAnisotropy
22061
+ };
22062
+ };
22063
+ const ANISOTROPY_EXTENSION_NAMES = [
22064
+ "EXT_texture_filter_anisotropic",
22065
+ "WEBKIT_EXT_texture_filter_anisotropic",
22066
+ "MOZ_EXT_texture_filter_anisotropic"
22067
+ ];
22068
+ const resolveAnisotropyExtension = (glContext) => {
22069
+ for (const name of ANISOTROPY_EXTENSION_NAMES) {
22070
+ const extension = glContext.getExtension(name);
22071
+ if (extension) {
22072
+ return extension;
22073
+ }
22074
+ }
22075
+ return null;
22076
+ };
22077
+ const isPowerOfTwo = (value) => value > 0 && (value & value - 1) === 0;
22078
+ const resolveGlMinFilter = (glContext, filter) => {
22079
+ switch (filter) {
22080
+ case "nearest":
22081
+ return glContext.NEAREST;
22082
+ case "nearest-mipmap-nearest":
22083
+ return glContext.NEAREST_MIPMAP_NEAREST;
22084
+ case "nearest-mipmap-linear":
22085
+ return glContext.NEAREST_MIPMAP_LINEAR;
22086
+ case "linear-mipmap-nearest":
22087
+ return glContext.LINEAR_MIPMAP_NEAREST;
22088
+ case "linear-mipmap-linear":
22089
+ return glContext.LINEAR_MIPMAP_LINEAR;
22090
+ case "linear":
22091
+ default:
22092
+ return glContext.LINEAR;
22093
+ }
22094
+ };
22095
+ const resolveGlMagFilter = (glContext, filter) => {
22096
+ switch (filter) {
22097
+ case "nearest":
22098
+ return glContext.NEAREST;
22099
+ case "linear":
22100
+ default:
22101
+ return glContext.LINEAR;
22102
+ }
22103
+ };
21998
22104
  const calculatePerspectiveRatio = (mapInstance, location2) => {
21999
22105
  var _a, _b, _c;
22000
22106
  const transform = mapInstance.transform;
@@ -22623,6 +22729,9 @@ const createSpriteLayer = (options) => {
22623
22729
  var _a;
22624
22730
  const id = (_a = options == null ? void 0 : options.id) != null ? _a : "sprite-layer";
22625
22731
  const resolvedScaling = resolveScalingOptions(options == null ? void 0 : options.spriteScaling);
22732
+ const resolvedTextureFiltering = resolveTextureFilteringOptions(
22733
+ options == null ? void 0 : options.textureFiltering
22734
+ );
22626
22735
  let gl = null;
22627
22736
  let map = null;
22628
22737
  let program = null;
@@ -22631,6 +22740,8 @@ const createSpriteLayer = (options) => {
22631
22740
  let attribUvLocation = -1;
22632
22741
  let uniformTextureLocation = null;
22633
22742
  let uniformOpacityLocation = null;
22743
+ let anisotropyExtension = null;
22744
+ let maxSupportedAnisotropy = 1;
22634
22745
  const images = /* @__PURE__ */ new Map();
22635
22746
  const queuedTextureIds = /* @__PURE__ */ new Set();
22636
22747
  const queueTextureUpload = (image) => {
@@ -23013,16 +23124,6 @@ const createSpriteLayer = (options) => {
23013
23124
  glContext.TEXTURE_WRAP_T,
23014
23125
  glContext.CLAMP_TO_EDGE
23015
23126
  );
23016
- glContext.texParameteri(
23017
- glContext.TEXTURE_2D,
23018
- glContext.TEXTURE_MIN_FILTER,
23019
- glContext.LINEAR
23020
- );
23021
- glContext.texParameteri(
23022
- glContext.TEXTURE_2D,
23023
- glContext.TEXTURE_MAG_FILTER,
23024
- glContext.LINEAR
23025
- );
23026
23127
  glContext.pixelStorei(glContext.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1);
23027
23128
  glContext.texImage2D(
23028
23129
  glContext.TEXTURE_2D,
@@ -23032,6 +23133,52 @@ const createSpriteLayer = (options) => {
23032
23133
  glContext.UNSIGNED_BYTE,
23033
23134
  image.bitmap
23034
23135
  );
23136
+ let minFilterEnum = resolveGlMinFilter(
23137
+ glContext,
23138
+ resolvedTextureFiltering.minFilter
23139
+ );
23140
+ const magFilterEnum = resolveGlMagFilter(
23141
+ glContext,
23142
+ resolvedTextureFiltering.magFilter
23143
+ );
23144
+ let usedMipmaps = false;
23145
+ if (resolvedTextureFiltering.generateMipmaps) {
23146
+ const isWebGL2 = typeof WebGL2RenderingContext !== "undefined" && glContext instanceof WebGL2RenderingContext;
23147
+ const canUseMipmaps = isWebGL2 || isPowerOfTwo(image.width) && isPowerOfTwo(image.height);
23148
+ if (canUseMipmaps) {
23149
+ glContext.generateMipmap(glContext.TEXTURE_2D);
23150
+ usedMipmaps = true;
23151
+ } else {
23152
+ minFilterEnum = glContext.LINEAR;
23153
+ }
23154
+ }
23155
+ if (!usedMipmaps && filterRequiresMipmaps(resolvedTextureFiltering.minFilter)) {
23156
+ minFilterEnum = glContext.LINEAR;
23157
+ }
23158
+ glContext.texParameteri(
23159
+ glContext.TEXTURE_2D,
23160
+ glContext.TEXTURE_MIN_FILTER,
23161
+ minFilterEnum
23162
+ );
23163
+ glContext.texParameteri(
23164
+ glContext.TEXTURE_2D,
23165
+ glContext.TEXTURE_MAG_FILTER,
23166
+ magFilterEnum
23167
+ );
23168
+ if (usedMipmaps && anisotropyExtension && resolvedTextureFiltering.maxAnisotropy > 1) {
23169
+ const ext = anisotropyExtension;
23170
+ const targetAnisotropy = Math.min(
23171
+ resolvedTextureFiltering.maxAnisotropy,
23172
+ maxSupportedAnisotropy
23173
+ );
23174
+ if (targetAnisotropy > 1) {
23175
+ glContext.texParameterf(
23176
+ glContext.TEXTURE_2D,
23177
+ ext.TEXTURE_MAX_ANISOTROPY_EXT,
23178
+ targetAnisotropy
23179
+ );
23180
+ }
23181
+ }
23035
23182
  image.texture = texture;
23036
23183
  });
23037
23184
  };
@@ -23074,6 +23221,20 @@ const createSpriteLayer = (options) => {
23074
23221
  const onAdd = (mapInstance, glContext) => {
23075
23222
  map = mapInstance;
23076
23223
  gl = glContext;
23224
+ anisotropyExtension = resolveAnisotropyExtension(glContext);
23225
+ if (anisotropyExtension) {
23226
+ const ext = anisotropyExtension;
23227
+ const supported = glContext.getParameter(
23228
+ ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT
23229
+ );
23230
+ if (typeof supported === "number" && Number.isFinite(supported) && supported >= 1) {
23231
+ maxSupportedAnisotropy = supported;
23232
+ } else {
23233
+ maxSupportedAnisotropy = 1;
23234
+ }
23235
+ } else {
23236
+ maxSupportedAnisotropy = 1;
23237
+ }
23077
23238
  canvasElement = mapInstance.getCanvas();
23078
23239
  const registerDisposer = (disposer) => {
23079
23240
  inputListenerDisposers.push(disposer);
@@ -23208,6 +23369,8 @@ const createSpriteLayer = (options) => {
23208
23369
  attribUvLocation = -1;
23209
23370
  uniformTextureLocation = null;
23210
23371
  uniformOpacityLocation = null;
23372
+ anisotropyExtension = null;
23373
+ maxSupportedAnisotropy = 1;
23211
23374
  };
23212
23375
  const render = (glContext, _options) => {
23213
23376
  hitTestEntries.length = 0;
@@ -23435,7 +23598,8 @@ const createSpriteLayer = (options) => {
23435
23598
  const offsetMeters = calculateSurfaceOffsetMeters(
23436
23599
  offsetDef,
23437
23600
  imageScale,
23438
- zoomScaleFactor
23601
+ zoomScaleFactor,
23602
+ surfaceCenter.worldDimensions.scaleAdjustment
23439
23603
  );
23440
23604
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
23441
23605
  worldWidthMeters: surfaceCenter.worldDimensions.width,
@@ -23643,7 +23807,8 @@ const createSpriteLayer = (options) => {
23643
23807
  const offsetMeters = calculateSurfaceOffsetMeters(
23644
23808
  offsetResolved,
23645
23809
  imageScale,
23646
- zoomScaleFactor
23810
+ zoomScaleFactor,
23811
+ worldDims.scaleAdjustment
23647
23812
  );
23648
23813
  const cornerDisplacements = calculateSurfaceCornerDisplacements({
23649
23814
  worldWidthMeters: worldDims.width,
@@ -24729,6 +24894,8 @@ const createSpriteLayer = (options) => {
24729
24894
  };
24730
24895
  return spriteLayout;
24731
24896
  };
24897
+ exports.BETTER_TEXTURE_FILTERING_OPTIONS = BETTER_TEXTURE_FILTERING_OPTIONS;
24898
+ exports.DEFAULT_TEXTURE_FILTERING_OPTIONS = DEFAULT_TEXTURE_FILTERING_OPTIONS;
24732
24899
  exports.STANDARD_SPRITE_SCALING_OPTIONS = STANDARD_SPRITE_SCALING_OPTIONS;
24733
24900
  exports.UNLIMITED_SPRITE_SCALING_OPTIONS = UNLIMITED_SPRITE_SCALING_OPTIONS;
24734
24901
  exports.applyAutoRotation = applyAutoRotation;