maplibre-gl-raster 0.6.0 → 0.6.2
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/README.md +3 -0
- package/dist/{RasterControl-BRFVTd2x.js → RasterControl-CjnDWQDU.js} +137 -11
- package/dist/RasterControl-CjnDWQDU.js.map +1 -0
- package/dist/index.mjs +12 -2
- package/dist/index.mjs.map +1 -1
- package/dist/maplibre-gl-raster.css +87 -0
- package/dist/react.mjs +1 -1
- package/dist/types/index.d.ts +30 -0
- package/dist/types/react.d.ts +30 -0
- package/package.json +1 -1
- package/dist/RasterControl-BRFVTd2x.js.map +0 -1
package/README.md
CHANGED
|
@@ -114,6 +114,9 @@ The main control class implementing MapLibre's `IControl` interface.
|
|
|
114
114
|
| `interleaved` | `boolean` | `true` | Render the deck.gl overlay interleaved with the basemap layers |
|
|
115
115
|
| `defaultUrl` | `string` | `''` | Prefills the Add data URL input (not loaded until the user clicks Load) |
|
|
116
116
|
| `autoLoad` | `boolean` | `false` | Load `defaultUrl` automatically when the control is added to the map |
|
|
117
|
+
| `sampleData` | `RasterSampleDataset[]` | - | Sample COGs offered as a "Load sample data" dropdown above the URL input; picking one fills the input (hidden when empty) |
|
|
118
|
+
| `sampleDataLabel` | `string` | `'Load sample data...'` | Placeholder shown in the sample-data dropdown |
|
|
119
|
+
| `closeOnOutsideClick` | `boolean` | `true` | Collapse the panel when clicking outside it; set `false` to close only via the header button |
|
|
117
120
|
| `engine` | `RenderEngine` | `'maplibre-gl-raster'` | Initial rendering backend; switchable at runtime from the panel |
|
|
118
121
|
|
|
119
122
|
#### Raster Methods
|
|
@@ -2646,7 +2646,7 @@ var SourceMemory = class SourceMemory {
|
|
|
2646
2646
|
//#region node_modules/@developmentseed/geotiff/dist/crs.js
|
|
2647
2647
|
var PROJJSON_SCHEMA = "https://proj.org/schemas/v0.7/projjson.schema.json";
|
|
2648
2648
|
var MODEL_TYPE_PROJECTED$1 = 1;
|
|
2649
|
-
var MODEL_TYPE_GEOGRAPHIC = 2;
|
|
2649
|
+
var MODEL_TYPE_GEOGRAPHIC$1 = 2;
|
|
2650
2650
|
var USER_DEFINED$1 = 32767;
|
|
2651
2651
|
var CT_TRANSVERSE_MERCATOR = 1;
|
|
2652
2652
|
var CT_TRANSVERSE_MERCATOR_SOUTH = 2;
|
|
@@ -2701,7 +2701,7 @@ var LINEAR_UNIT = {
|
|
|
2701
2701
|
function crsFromGeoKeys(gkd) {
|
|
2702
2702
|
const modelType = gkd.modelType;
|
|
2703
2703
|
if (modelType === MODEL_TYPE_PROJECTED$1) return _projectedCrs(gkd);
|
|
2704
|
-
if (modelType === MODEL_TYPE_GEOGRAPHIC) return _geographicCrs(gkd);
|
|
2704
|
+
if (modelType === MODEL_TYPE_GEOGRAPHIC$1) return _geographicCrs(gkd);
|
|
2705
2705
|
throw new Error(`Unsupported GeoTIFF model type: ${modelType}`);
|
|
2706
2706
|
}
|
|
2707
2707
|
function _geographicCrs(gkd) {
|
|
@@ -4555,8 +4555,10 @@ var COLORMAP_OPTIONS = COLORMAP_NAMES.map((name) => ({
|
|
|
4555
4555
|
//#endregion
|
|
4556
4556
|
//#region src/lib/raster/repair-geokeys.ts
|
|
4557
4557
|
var MODEL_TYPE_PROJECTED = 1;
|
|
4558
|
+
var MODEL_TYPE_GEOGRAPHIC = 2;
|
|
4558
4559
|
var USER_DEFINED = 32767;
|
|
4559
4560
|
var EPSG_WEB_MERCATOR = 3857;
|
|
4561
|
+
var WKT_ROOT = /\b(?:PROJCS|PROJCRS|GEOGCS|GEOGCRS|GEOCCS|GEODCRS|BOUNDCRS|COMPD_CS|COMPOUNDCRS|VERT_CS|VERTCRS|LOCAL_CS|FITTED_CS)\s*\[/i;
|
|
4560
4562
|
var WEB_MERCATOR_ALIASES = new Set([
|
|
4561
4563
|
3785,
|
|
4562
4564
|
900913,
|
|
@@ -4572,6 +4574,26 @@ function citationText(gkd) {
|
|
|
4572
4574
|
].filter((value) => typeof value === "string").join(" ");
|
|
4573
4575
|
}
|
|
4574
4576
|
/**
|
|
4577
|
+
* Pull an embedded WKT (or ESRI PE string) definition out of a citation geo
|
|
4578
|
+
* key, if one is present. The projected citation is preferred because that is
|
|
4579
|
+
* where ArcGIS writes the full `PROJCS[...]` for an exotic projection; the
|
|
4580
|
+
* generic and geodetic citations are checked as fallbacks. Returns the WKT from
|
|
4581
|
+
* the first matching root keyword onward (dropping any `ESRI PE String = `
|
|
4582
|
+
* prefix), or `null` when no citation carries one.
|
|
4583
|
+
*/
|
|
4584
|
+
function wktFromCitation(gkd) {
|
|
4585
|
+
for (const citation of [
|
|
4586
|
+
gkd.projectedCitation,
|
|
4587
|
+
gkd.citation,
|
|
4588
|
+
gkd.geodeticCitation
|
|
4589
|
+
]) {
|
|
4590
|
+
if (typeof citation !== "string") continue;
|
|
4591
|
+
const match = WKT_ROOT.exec(citation);
|
|
4592
|
+
if (match) return citation.slice(match.index);
|
|
4593
|
+
}
|
|
4594
|
+
return null;
|
|
4595
|
+
}
|
|
4596
|
+
/**
|
|
4575
4597
|
* Repair GeoTIFF CRS geo keys so {@link import('@developmentseed/geotiff').Overview.crs}
|
|
4576
4598
|
* resolves them to the right projection, in place. Two problems are fixed:
|
|
4577
4599
|
*
|
|
@@ -4598,6 +4620,15 @@ function citationText(gkd) {
|
|
|
4598
4620
|
* untouched. Must run before any `Overview.crs` access (which caches its
|
|
4599
4621
|
* result), so callers invoke it immediately after opening the GeoTIFF.
|
|
4600
4622
|
*
|
|
4623
|
+
* 3. **A projection the geo keys cannot express.** Some projections have no
|
|
4624
|
+
* `ProjCoordTransGeoKey` (e.g. equal-area world CRSes such as ESRI:54009
|
|
4625
|
+
* World Mollweide), so ArcGIS/GDAL leave the model type user-defined and the
|
|
4626
|
+
* full definition only in the citation as an `ESRI PE String = PROJCS[...]`
|
|
4627
|
+
* WKT. `crsFromGeoKeys` then throws `Unsupported GeoTIFF model type: 32767`.
|
|
4628
|
+
* {@link recoverCrsFromWktCitation} seeds the cached CRS from that WKT so the
|
|
4629
|
+
* consuming layer (which calls `parseWkt`/proj4) builds the projection from
|
|
4630
|
+
* it. This is projection-agnostic: proj4 understands the ESRI/OGC names.
|
|
4631
|
+
*
|
|
4601
4632
|
* @param tiff - The opened GeoTIFF to repair in place.
|
|
4602
4633
|
*/
|
|
4603
4634
|
function repairUserDefinedProjectedCrs(tiff) {
|
|
@@ -4608,6 +4639,30 @@ function repairUserDefinedProjectedCrs(tiff) {
|
|
|
4608
4639
|
else if (projectedIsUserDefined && gkd.projMethod !== null && WEB_MERCATOR_CITATION.test(citationText(gkd))) gkd.projectedCRS = EPSG_WEB_MERCATOR;
|
|
4609
4640
|
if ((gkd.modelType === null || gkd.modelType === USER_DEFINED) && gkd.projMethod !== null) gkd.modelType = MODEL_TYPE_PROJECTED;
|
|
4610
4641
|
}
|
|
4642
|
+
recoverCrsFromWktCitation(tiff);
|
|
4643
|
+
}
|
|
4644
|
+
/**
|
|
4645
|
+
* Seed the GeoTIFF's cached CRS from an embedded WKT citation when the geo keys
|
|
4646
|
+
* still cannot describe the projection after {@link repairUserDefinedProjectedCrs}
|
|
4647
|
+
* has run. `crsFromGeoKeys` only accepts model type 1 (projected) or 2
|
|
4648
|
+
* (geographic) and throws otherwise; when the model type is still user-defined
|
|
4649
|
+
* (no `ProjMethodGeoKey` to promote it) the only definition is the WKT in the
|
|
4650
|
+
* citation. Setting the (lazily computed, single-shot) `_crs` cache to that WKT
|
|
4651
|
+
* string makes the getter return it instead of throwing, and the consuming layer
|
|
4652
|
+
* resolves it through `parseWkt` (wkt-parser + proj4).
|
|
4653
|
+
*
|
|
4654
|
+
* No-ops when the model type is resolvable, when the CRS is already cached, or
|
|
4655
|
+
* when no citation carries a WKT (so the original, descriptive error still
|
|
4656
|
+
* surfaces).
|
|
4657
|
+
*/
|
|
4658
|
+
function recoverCrsFromWktCitation(tiff) {
|
|
4659
|
+
const gkd = tiff.overviews[0]?.gkd;
|
|
4660
|
+
if (!gkd) return;
|
|
4661
|
+
if (gkd.modelType === MODEL_TYPE_PROJECTED || gkd.modelType === MODEL_TYPE_GEOGRAPHIC) return;
|
|
4662
|
+
const wkt = wktFromCitation(gkd);
|
|
4663
|
+
if (!wkt) return;
|
|
4664
|
+
const cache = tiff;
|
|
4665
|
+
if (cache._crs === void 0) cache._crs = wkt;
|
|
4611
4666
|
}
|
|
4612
4667
|
//#endregion
|
|
4613
4668
|
//#region src/lib/raster/load-geotiff.ts
|
|
@@ -19036,6 +19091,68 @@ var AddDataSection = class {
|
|
|
19036
19091
|
if (e.key === "Enter") submitUrl();
|
|
19037
19092
|
});
|
|
19038
19093
|
const urlRow = el("div", { className: "mlr-row" }, input, loadBtn);
|
|
19094
|
+
const samples = options.sampleData ?? [];
|
|
19095
|
+
let sampleRow;
|
|
19096
|
+
if (samples.length > 0) {
|
|
19097
|
+
const placeholder = options.sampleDataLabel ?? "Load sample data...";
|
|
19098
|
+
const triggerLabel = el("span", {
|
|
19099
|
+
className: "mlr-sample-trigger-label",
|
|
19100
|
+
text: placeholder
|
|
19101
|
+
});
|
|
19102
|
+
const trigger = el("button", {
|
|
19103
|
+
className: "mlr-sample-trigger",
|
|
19104
|
+
type: "button",
|
|
19105
|
+
ariaLabel: placeholder,
|
|
19106
|
+
attrs: {
|
|
19107
|
+
"aria-haspopup": "listbox",
|
|
19108
|
+
"aria-expanded": "false"
|
|
19109
|
+
}
|
|
19110
|
+
}, triggerLabel, el("span", {
|
|
19111
|
+
className: "mlr-sample-caret",
|
|
19112
|
+
text: "▾"
|
|
19113
|
+
}));
|
|
19114
|
+
const menu = el("div", {
|
|
19115
|
+
className: "mlr-sample-menu",
|
|
19116
|
+
attrs: { role: "listbox" }
|
|
19117
|
+
});
|
|
19118
|
+
menu.hidden = true;
|
|
19119
|
+
let menuOpen = false;
|
|
19120
|
+
const setMenuOpen = (open) => {
|
|
19121
|
+
menuOpen = open;
|
|
19122
|
+
menu.hidden = !open;
|
|
19123
|
+
trigger.setAttribute("aria-expanded", String(open));
|
|
19124
|
+
trigger.classList.toggle("open", open);
|
|
19125
|
+
if (open) menu.firstElementChild?.focus();
|
|
19126
|
+
};
|
|
19127
|
+
for (const sample of samples) {
|
|
19128
|
+
const option = el("button", {
|
|
19129
|
+
className: "mlr-sample-option",
|
|
19130
|
+
type: "button",
|
|
19131
|
+
text: sample.label,
|
|
19132
|
+
title: sample.url,
|
|
19133
|
+
attrs: { role: "option" }
|
|
19134
|
+
});
|
|
19135
|
+
option.addEventListener("click", () => {
|
|
19136
|
+
setMenuOpen(false);
|
|
19137
|
+
trigger.focus();
|
|
19138
|
+
input.value = sample.url;
|
|
19139
|
+
loadBtn.disabled = input.value.trim().length === 0;
|
|
19140
|
+
});
|
|
19141
|
+
menu.appendChild(option);
|
|
19142
|
+
}
|
|
19143
|
+
trigger.addEventListener("click", () => setMenuOpen(!menuOpen));
|
|
19144
|
+
sampleRow = el("div", { className: "mlr-sample-row" }, trigger, menu);
|
|
19145
|
+
sampleRow.addEventListener("keydown", (e) => {
|
|
19146
|
+
if (e.key === "Escape" && menuOpen) {
|
|
19147
|
+
setMenuOpen(false);
|
|
19148
|
+
trigger.focus();
|
|
19149
|
+
}
|
|
19150
|
+
});
|
|
19151
|
+
sampleRow.addEventListener("focusout", (e) => {
|
|
19152
|
+
const next = e.relatedTarget;
|
|
19153
|
+
if (!next || !sampleRow.contains(next)) setMenuOpen(false);
|
|
19154
|
+
});
|
|
19155
|
+
}
|
|
19039
19156
|
const fileInput = el("input", {
|
|
19040
19157
|
type: "file",
|
|
19041
19158
|
ariaLabel: "raster-file",
|
|
@@ -19078,7 +19195,7 @@ var AddDataSection = class {
|
|
|
19078
19195
|
this.el = el("div", { className: "mlr-section mlr-add-data" }, el("div", {
|
|
19079
19196
|
className: "mlr-section-title",
|
|
19080
19197
|
text: "Add data"
|
|
19081
|
-
}), urlRow, dropZone, beforeIdInput);
|
|
19198
|
+
}), ...sampleRow ? [sampleRow] : [], urlRow, dropZone, beforeIdInput);
|
|
19082
19199
|
}
|
|
19083
19200
|
};
|
|
19084
19201
|
//#endregion
|
|
@@ -20030,6 +20147,8 @@ var PanelUI = class {
|
|
|
20030
20147
|
this._engine = engine;
|
|
20031
20148
|
const addData = new AddDataSection({
|
|
20032
20149
|
initialUrl: options?.defaultUrl,
|
|
20150
|
+
sampleData: options?.sampleData,
|
|
20151
|
+
sampleDataLabel: options?.sampleDataLabel,
|
|
20033
20152
|
onAddUrl: (url, beforeId) => {
|
|
20034
20153
|
this._manager.addRaster(url, { beforeId }).catch(() => {});
|
|
20035
20154
|
},
|
|
@@ -20307,6 +20426,9 @@ var DEFAULT_OPTIONS = {
|
|
|
20307
20426
|
interleaved: true,
|
|
20308
20427
|
defaultUrl: "",
|
|
20309
20428
|
autoLoad: false,
|
|
20429
|
+
sampleData: [],
|
|
20430
|
+
sampleDataLabel: "Load sample data...",
|
|
20431
|
+
closeOnOutsideClick: true,
|
|
20310
20432
|
engine: "maplibre-gl-raster",
|
|
20311
20433
|
epsgResolver: createResilientEpsgResolver()
|
|
20312
20434
|
};
|
|
@@ -20394,6 +20516,8 @@ var RasterControl = class {
|
|
|
20394
20516
|
const autoLoading = this._options.autoLoad && !!this._options.defaultUrl;
|
|
20395
20517
|
if (content) this._panelUI = new PanelUI(content, this._layerManager, {
|
|
20396
20518
|
defaultUrl: autoLoading ? "" : this._options.defaultUrl,
|
|
20519
|
+
sampleData: this._options.sampleData,
|
|
20520
|
+
sampleDataLabel: this._options.sampleDataLabel,
|
|
20397
20521
|
inspect: {
|
|
20398
20522
|
onToggle: () => this._inspector?.toggle(),
|
|
20399
20523
|
isActive: () => this._inspector?.enabled ?? false
|
|
@@ -20912,13 +21036,15 @@ var RasterControl = class {
|
|
|
20912
21036
|
* Setup event listeners for panel positioning and click-outside behavior.
|
|
20913
21037
|
*/
|
|
20914
21038
|
_setupEventListeners() {
|
|
20915
|
-
this.
|
|
20916
|
-
|
|
20917
|
-
|
|
20918
|
-
|
|
20919
|
-
|
|
20920
|
-
|
|
20921
|
-
|
|
21039
|
+
if (this._options.closeOnOutsideClick !== false) {
|
|
21040
|
+
this._clickOutsideHandler = (e) => {
|
|
21041
|
+
const target = e.target;
|
|
21042
|
+
if (!target.isConnected) return;
|
|
21043
|
+
if (this._inspector?.enabled) return;
|
|
21044
|
+
if (this._container && this._panel && !this._container.contains(target) && !this._panel.contains(target)) this.collapse();
|
|
21045
|
+
};
|
|
21046
|
+
document.addEventListener("click", this._clickOutsideHandler);
|
|
21047
|
+
}
|
|
20922
21048
|
this._resizeHandler = () => {
|
|
20923
21049
|
if (!this._state.collapsed) this._updatePanelPosition();
|
|
20924
21050
|
};
|
|
@@ -20991,4 +21117,4 @@ var RasterControl = class {
|
|
|
20991
21117
|
//#endregion
|
|
20992
21118
|
export { MAX_SAMPLE_TILES as C, createResilientEpsgResolver as D, readBandNames as E, statsForBand as S, percentileFromHistogram as T, COLORMAP_OPTIONS as _, isKnownColormap as a, colormaps_default as b, clamp as c, formatNumericValue as d, generateId as f, COLORMAP_NAMES as g, COLORMAP_DISPLAY_NAMES as h, PALETTE_COLORMAP as i, classNames as l, loadGeoTIFF as m, Colorbar as n, loadColormapSprite as o, throttle as p, readPixelValues as r, sampleColormapStops as s, RasterControl as t, debounce as u, COLORMAP_ROW_COUNT as v, computeAutoStats as w, autoRangeFor as x, colormapDisplayName as y };
|
|
20993
21119
|
|
|
20994
|
-
//# sourceMappingURL=RasterControl-
|
|
21120
|
+
//# sourceMappingURL=RasterControl-CjnDWQDU.js.map
|