maplibre-gl-raster 0.9.1 → 0.10.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.
@@ -18206,6 +18206,7 @@ function toLayerInfo(layer) {
18206
18206
  bandCount: layer.bandCount,
18207
18207
  bandNames: layer.bandNames ? new Map(layer.bandNames) : null,
18208
18208
  beforeId: layer.beforeId,
18209
+ attribution: layer.attribution,
18209
18210
  bounds: layer.bounds ? { ...layer.bounds } : null,
18210
18211
  loading: layer.loading,
18211
18212
  error: layer.error,
@@ -18378,6 +18379,9 @@ var LayerManager = class {
18378
18379
  _colormapTexture = null;
18379
18380
  _handlers = new globalThis.Map();
18380
18381
  _crsFailed = /* @__PURE__ */ new Set();
18382
+ _attributions = new globalThis.Map();
18383
+ _attribStyleReady = false;
18384
+ _onAttribStyleLoad = null;
18381
18385
  _destroyed = false;
18382
18386
  /**
18383
18387
  * Creates a LayerManager bound to a map.
@@ -18464,6 +18468,7 @@ var LayerManager = class {
18464
18468
  palette: null,
18465
18469
  paletteTexture: null,
18466
18470
  beforeId: options?.beforeId?.trim() || null,
18471
+ attribution: options?.attribution?.trim() || null,
18467
18472
  bounds: null,
18468
18473
  zoomTo: options?.zoomTo ?? true,
18469
18474
  loading: true,
@@ -18669,6 +18674,11 @@ var LayerManager = class {
18669
18674
  }
18670
18675
  this._layers = [];
18671
18676
  this._selectedId = null;
18677
+ for (const id of [...this._attributions.keys()]) this._removeAttribution(id);
18678
+ if (this._onAttribStyleLoad) {
18679
+ this._map.off("load", this._onAttribStyleLoad);
18680
+ this._onAttribStyleLoad = null;
18681
+ }
18672
18682
  if (this._overlay) {
18673
18683
  this._deps.removeOverlay(this._map, this._overlay);
18674
18684
  this._overlay = null;
@@ -18813,10 +18823,66 @@ var LayerManager = class {
18813
18823
  duration: 800
18814
18824
  });
18815
18825
  }
18826
+ /** Reconciles per-layer attributions with the map's attribution control.
18827
+ *
18828
+ * Neither engine gives every raster a MapLibre source the control could read
18829
+ * an attribution from (the deck.gl path renders through an overlay with no
18830
+ * source at all), so each attributed, visible layer gets a helper: an empty
18831
+ * GeoJSON source carrying the attribution string plus a no-op circle layer
18832
+ * referencing it. The layer marks the source as used, which is what makes
18833
+ * the stock AttributionControl display (and de-duplicate) the string; the
18834
+ * empty feature collection means nothing is ever drawn or fetched. */
18835
+ _syncAttributions() {
18836
+ if (!this._attribStyleReady) if (this._map.isStyleLoaded()) this._attribStyleReady = true;
18837
+ else {
18838
+ if (!this._onAttribStyleLoad) {
18839
+ this._onAttribStyleLoad = () => {
18840
+ this._onAttribStyleLoad = null;
18841
+ this._attribStyleReady = true;
18842
+ this._syncAttributions();
18843
+ };
18844
+ this._map.once("load", this._onAttribStyleLoad);
18845
+ }
18846
+ return;
18847
+ }
18848
+ const desired = /* @__PURE__ */ new Map();
18849
+ for (const l of this._layers) if (l.attribution && l.geotiff && l.state.visible && !l.error && !this._crsFailed.has(l.id)) desired.set(l.id, l.attribution);
18850
+ for (const [id, applied] of this._attributions) if (desired.get(id) !== applied) this._removeAttribution(id);
18851
+ for (const [id, attribution] of desired) {
18852
+ if (this._attributions.has(id)) continue;
18853
+ const helperId = `mlr-attribution-${id}`;
18854
+ try {
18855
+ this._map.addSource(helperId, {
18856
+ type: "geojson",
18857
+ data: {
18858
+ type: "FeatureCollection",
18859
+ features: []
18860
+ },
18861
+ attribution
18862
+ });
18863
+ this._map.addLayer({
18864
+ id: helperId,
18865
+ type: "circle",
18866
+ source: helperId
18867
+ });
18868
+ this._attributions.set(id, attribution);
18869
+ } catch {}
18870
+ }
18871
+ }
18872
+ /** Removes a layer's attribution helper source/layer, if present. */
18873
+ _removeAttribution(id) {
18874
+ if (!this._attributions.delete(id)) return;
18875
+ const helperId = `mlr-attribution-${id}`;
18876
+ try {
18877
+ if (this._map.getLayer(helperId)) this._map.removeLayer(helperId);
18878
+ if (this._map.getSource(helperId)) this._map.removeSource(helperId);
18879
+ } catch {}
18880
+ }
18816
18881
  /** Re-derives the deck.gl layer array from current layer states and pushes
18817
18882
  * it to the overlay. Layer ids are stable so deck.gl preserves each
18818
18883
  * layer's tile cache across rebuilds. */
18819
18884
  _rebuild() {
18885
+ this._syncAttributions();
18820
18886
  if (this._engine === "cog-tiler-wasm") {
18821
18887
  this._overlay?.setProps({ layers: [] });
18822
18888
  this._ensureCogEngine().sync(this._cogRenderableLayers());
@@ -19172,7 +19238,8 @@ var AddDataSection = class {
19172
19238
  const addFiles = (files) => {
19173
19239
  if (!files) return;
19174
19240
  const beforeId = currentBeforeId();
19175
- for (const file of Array.from(files)) if (isTiff(file)) options.onAddFile(file, beforeId);
19241
+ const attribution = currentAttribution();
19242
+ for (const file of Array.from(files)) if (isTiff(file)) options.onAddFile(file, beforeId, attribution);
19176
19243
  };
19177
19244
  const input = el("input", {
19178
19245
  className: "mlr-input",
@@ -19199,10 +19266,18 @@ var AddDataSection = class {
19199
19266
  title: "Id of an existing map layer to insert the raster beneath (e.g. a label layer). Leave empty to draw on top."
19200
19267
  });
19201
19268
  const currentBeforeId = () => beforeIdInput.value.trim() || void 0;
19269
+ const attributionInput = el("input", {
19270
+ className: "mlr-input",
19271
+ type: "text",
19272
+ placeholder: "Attribution (optional)",
19273
+ ariaLabel: "attribution",
19274
+ title: "Data credit shown in the map's attribution control while the layer is visible (plain text or an HTML link)."
19275
+ });
19276
+ const currentAttribution = () => attributionInput.value.trim() || void 0;
19202
19277
  const submitUrl = () => {
19203
19278
  const url = input.value.trim();
19204
19279
  if (!url) return;
19205
- options.onAddUrl(url, currentBeforeId());
19280
+ options.onAddUrl(url, currentBeforeId(), currentAttribution());
19206
19281
  };
19207
19282
  loadBtn.addEventListener("click", submitUrl);
19208
19283
  input.addEventListener("keydown", (e) => {
@@ -19254,6 +19329,7 @@ var AddDataSection = class {
19254
19329
  setMenuOpen(false);
19255
19330
  trigger.focus();
19256
19331
  input.value = sample.url;
19332
+ if (sample.attribution) attributionInput.value = sample.attribution;
19257
19333
  loadBtn.disabled = input.value.trim().length === 0;
19258
19334
  submitUrl();
19259
19335
  });
@@ -19315,7 +19391,7 @@ var AddDataSection = class {
19315
19391
  this.el = el("div", { className: "mlr-section mlr-add-data" }, el("div", {
19316
19392
  className: "mlr-section-title",
19317
19393
  text: "Add data"
19318
- }), urlRow, dropZone, beforeIdInput, ...sampleRow ? [sampleRow] : []);
19394
+ }), urlRow, dropZone, beforeIdInput, attributionInput, ...sampleRow ? [sampleRow] : []);
19319
19395
  }
19320
19396
  };
19321
19397
  //#endregion
@@ -20481,11 +20557,17 @@ var PanelUI = class {
20481
20557
  initialUrl: options?.defaultUrl,
20482
20558
  sampleData: options?.sampleData,
20483
20559
  sampleDataLabel: options?.sampleDataLabel,
20484
- onAddUrl: (url, beforeId) => {
20485
- this._manager.addRaster(url, { beforeId }).catch(() => {});
20560
+ onAddUrl: (url, beforeId, attribution) => {
20561
+ this._manager.addRaster(url, {
20562
+ beforeId,
20563
+ attribution
20564
+ }).catch(() => {});
20486
20565
  },
20487
- onAddFile: (file, beforeId) => {
20488
- this._manager.addRaster(file, { beforeId }).catch(() => {});
20566
+ onAddFile: (file, beforeId, attribution) => {
20567
+ this._manager.addRaster(file, {
20568
+ beforeId,
20569
+ attribution
20570
+ }).catch(() => {});
20489
20571
  }
20490
20572
  });
20491
20573
  this._layerList = new LayerList({
@@ -21450,4 +21532,4 @@ var RasterControl = class {
21450
21532
  //#endregion
21451
21533
  export { statsForBand as A, COLORMAP_NAMES as C, colormaps_default as D, colormapDisplayName as E, createResilientEpsgResolver as F, computeAutoStats as M, percentileFromHistogram as N, DEFAULT_INDEX_RANGE as O, readBandNames as P, COLORMAP_DISPLAY_NAMES as S, COLORMAP_ROW_COUNT as T, debounce as _, NORMALIZED_DIFFERENCE_INDICES as a, throttle as b, readPixelValues as c, PALETTE_COLORMAP as d, isKnownColormap as f, classNames as g, clamp as h, CUSTOM_NORMALIZED_DIFFERENCE as i, MAX_SAMPLE_TILES as j, autoRangeFor as k, DEFAULT_ENGINE as l, sampleColormapStops as m, Colorbar as n, guessBandForRole as o, loadColormapSprite as p, CUSTOM_INDEX_ID as r, indexById as s, RasterControl as t, LayerManager as u, formatNumericValue as v, COLORMAP_OPTIONS as w, loadGeoTIFF as x, generateId as y };
21452
21534
 
21453
- //# sourceMappingURL=RasterControl-B2cGQaYt.js.map
21535
+ //# sourceMappingURL=RasterControl-D9JDQUVb.js.map