2026-03-04 12:59:40 +01:00

12058 lines
384 KiB
JavaScript

import {
ExtraSamplesValues,
arrayFields,
fieldTagNames,
fieldTypeNames,
fieldTypes,
geoKeyNames,
globals_exports,
photometricInterpretations
} from "./chunk-QTABLK4X.js";
import "./chunk-C5KGH6RQ.js";
import {
ImageCanvas_default,
fromResolutionLike
} from "./chunk-3TN6D4MD.js";
import {
ATTRIBUTION,
OSM_default
} from "./chunk-43GYE2V5.js";
import {
Vector_default,
loadFeaturesXhr
} from "./chunk-PD2E5XZ4.js";
import {
Image_default as Image_default2,
orthographic,
scale as scale3,
translate,
translation
} from "./chunk-E7S7Q7VV.js";
import "./chunk-V7WRBSQ6.js";
import "./chunk-W7BDJOQY.js";
import "./chunk-7JXPN73Q.js";
import {
Feature_default
} from "./chunk-E53S5GN6.js";
import {
DataTile_default,
LRUCache_default,
Tile_default as Tile_default2,
asArrayLike,
asImageLike,
toArray
} from "./chunk-UNDFRJ2M.js";
import "./chunk-JFXZSSOM.js";
import "./chunk-ZUI5NXIU.js";
import {
TileQueue_default
} from "./chunk-CAVOO5JW.js";
import "./chunk-M5TTSD4C.js";
import "./chunk-RW3V7S4F.js";
import "./chunk-I6K7MRGV.js";
import "./chunk-PGWX4545.js";
import "./chunk-AYBYZSAV.js";
import {
ViewHint_default
} from "./chunk-YLJGUH5Z.js";
import {
Point_default
} from "./chunk-AZGMK675.js";
import {
TileEventType_default,
TileGrid_default,
TileImage_default,
TileSourceEvent,
Tile_default as Tile_default3,
UrlTile_default,
XYZ_default,
appendParams,
createFromTemplates,
createFromTileUrlFunctions,
createXYZ,
expandUrl,
extentFromProjection,
getForProjection,
nullTileUrlFunction,
pickUrl,
renderXYZTemplate
} from "./chunk-3ZDRPUXW.js";
import {
Source_default
} from "./chunk-6Y7C6NBJ.js";
import {
ERROR_THRESHOLD,
ImageTile_default,
Tile_default,
Triangulation_default,
calculateSourceExtentResolution,
calculateSourceResolution,
createOrUpdate2 as createOrUpdate,
getCacheKey,
getKeyZXY,
hash,
render
} from "./chunk-7XMWB3J4.js";
import {
TileState_default
} from "./chunk-5D2XPBR2.js";
import {
ImageState_default,
Image_default,
decode,
scale as scale2,
toSize
} from "./chunk-SHUBVYN4.js";
import {
DEFAULT_MAX_ZOOM,
DEFAULT_TILE_SIZE
} from "./chunk-FM44FOIC.js";
import "./chunk-LMC3RO5P.js";
import {
apply,
create,
makeInverse,
multiply
} from "./chunk-X52LGBOS.js";
import {
assert
} from "./chunk-QFCIXVZ3.js";
import {
Projection_default,
add,
compareVersions,
createTransformFromCoordinateTransform,
equivalent,
error,
fromCode,
get,
getTransformFromProjections,
scale,
toLonLat,
toUserCoordinate,
toUserExtent,
transform,
transformExtent
} from "./chunk-A3RXLHYB.js";
import "./chunk-ZLPTRF2L.js";
import {
ceil,
clamp,
floor,
modulo,
round
} from "./chunk-54BTDBAD.js";
import {
createCanvasContext2D,
releaseCanvas
} from "./chunk-UPTVWZ45.js";
import {
WORKER_OFFSCREEN_CANVAS
} from "./chunk-5XHD7RSF.js";
import {
getUid
} from "./chunk-Q5ZULJHM.js";
import {
Disposable_default,
Event_default,
listen,
listenOnce,
unlistenByKey
} from "./chunk-NGFXCWUF.js";
import {
EventType_default,
linearFindNearest,
toPromise
} from "./chunk-K25ZO44T.js";
import {
applyTransform,
buffer,
containsExtent,
createEmpty,
createOrUpdateFromCoordinate,
equals,
extend,
getArea,
getBottomLeft,
getCenter,
getForViewAndSize,
getHeight,
getIntersection,
getTopLeft,
getTopRight,
getWidth,
intersects,
isEmpty as isEmpty2,
scaleFromCenter,
wrapAndSliceX
} from "./chunk-SRXHWJOY.js";
import {
isEmpty
} from "./chunk-5RHQVMYD.js";
import {
__commonJS,
__toESM
} from "./chunk-DC5AMYBS.js";
// node_modules/xml-utils/get-attribute.js
var require_get_attribute = __commonJS({
"node_modules/xml-utils/get-attribute.js"(exports, module) {
function getAttribute2(tag, attributeName, options) {
const debug = options && options.debug || false;
if (debug) console.log("[xml-utils] getting " + attributeName + " in " + tag);
const xml = typeof tag === "object" ? tag.outer : tag;
const opening = xml.slice(0, xml.indexOf(">") + 1);
const quotechars = ['"', "'"];
for (let i = 0; i < quotechars.length; i++) {
const char = quotechars[i];
const pattern = attributeName + "\\=" + char + "([^" + char + "]*)" + char;
if (debug) console.log("[xml-utils] pattern:", pattern);
const re = new RegExp(pattern);
const match = re.exec(opening);
if (debug) console.log("[xml-utils] match:", match);
if (match) return match[1];
}
}
module.exports = getAttribute2;
module.exports.default = getAttribute2;
}
});
// node_modules/xml-utils/index-of-match.js
var require_index_of_match = __commonJS({
"node_modules/xml-utils/index-of-match.js"(exports, module) {
function indexOfMatch(xml, pattern, startIndex) {
const re = new RegExp(pattern);
const match = re.exec(xml.slice(startIndex));
if (match) return startIndex + match.index;
else return -1;
}
module.exports = indexOfMatch;
module.exports.default = indexOfMatch;
}
});
// node_modules/xml-utils/index-of-match-end.js
var require_index_of_match_end = __commonJS({
"node_modules/xml-utils/index-of-match-end.js"(exports, module) {
function indexOfMatchEnd(xml, pattern, startIndex) {
const re = new RegExp(pattern);
const match = re.exec(xml.slice(startIndex));
if (match) return startIndex + match.index + match[0].length - 1;
else return -1;
}
module.exports = indexOfMatchEnd;
module.exports.default = indexOfMatchEnd;
}
});
// node_modules/xml-utils/count-substring.js
var require_count_substring = __commonJS({
"node_modules/xml-utils/count-substring.js"(exports, module) {
function countSubstring(string, substring) {
const pattern = new RegExp(substring, "g");
const match = string.match(pattern);
return match ? match.length : 0;
}
module.exports = countSubstring;
module.exports.default = countSubstring;
}
});
// node_modules/xml-utils/find-tag-by-name.js
var require_find_tag_by_name = __commonJS({
"node_modules/xml-utils/find-tag-by-name.js"(exports, module) {
var indexOfMatch = require_index_of_match();
var indexOfMatchEnd = require_index_of_match_end();
var countSubstring = require_count_substring();
function findTagByName(xml, tagName, options) {
const debug = options && options.debug || false;
const nested = !(options && typeof options.nested === false);
const startIndex = options && options.startIndex || 0;
if (debug) console.log("[xml-utils] starting findTagByName with", tagName, " and ", options);
const start = indexOfMatch(xml, `<${tagName}[
>/]`, startIndex);
if (debug) console.log("[xml-utils] start:", start);
if (start === -1) return void 0;
const afterStart = xml.slice(start + tagName.length);
let relativeEnd = indexOfMatchEnd(afterStart, "^[^<]*[ /]>", 0);
const selfClosing = relativeEnd !== -1 && afterStart[relativeEnd - 1] === "/";
if (debug) console.log("[xml-utils] selfClosing:", selfClosing);
if (selfClosing === false) {
if (nested) {
let startIndex2 = 0;
let openings = 1;
let closings = 0;
while ((relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", startIndex2)) !== -1) {
const clip = afterStart.substring(startIndex2, relativeEnd + 1);
openings += countSubstring(clip, "<" + tagName + "[ \n >]");
closings += countSubstring(clip, "</" + tagName + ">");
if (closings >= openings) break;
startIndex2 = relativeEnd;
}
} else {
relativeEnd = indexOfMatchEnd(afterStart, "[ /]" + tagName + ">", 0);
}
}
const end = start + tagName.length + relativeEnd + 1;
if (debug) console.log("[xml-utils] end:", end);
if (end === -1) return void 0;
const outer = xml.slice(start, end);
let inner;
if (selfClosing) {
inner = null;
} else {
inner = outer.slice(outer.indexOf(">") + 1, outer.lastIndexOf("<"));
}
return { inner, outer, start, end };
}
module.exports = findTagByName;
module.exports.default = findTagByName;
}
});
// node_modules/xml-utils/find-tags-by-name.js
var require_find_tags_by_name = __commonJS({
"node_modules/xml-utils/find-tags-by-name.js"(exports, module) {
var findTagByName = require_find_tag_by_name();
function findTagsByName2(xml, tagName, options) {
const tags = [];
const debug = options && options.debug || false;
const nested = options && typeof options.nested === "boolean" ? options.nested : true;
let startIndex = options && options.startIndex || 0;
let tag;
while (tag = findTagByName(xml, tagName, { debug, startIndex })) {
if (nested) {
startIndex = tag.start + 1 + tagName.length;
} else {
startIndex = tag.end;
}
tags.push(tag);
}
if (debug) console.log("findTagsByName found", tags.length, "tags");
return tags;
}
module.exports = findTagsByName2;
module.exports.default = findTagsByName2;
}
});
// browser-external:http
var require_http = __commonJS({
"browser-external:http"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "http" has been externalized for browser compatibility. Cannot access "http.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// browser-external:https
var require_https = __commonJS({
"browser-external:https"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "https" has been externalized for browser compatibility. Cannot access "https.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// browser-external:url
var require_url = __commonJS({
"browser-external:url"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "url" has been externalized for browser compatibility. Cannot access "url.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// browser-external:fs
var require_fs = __commonJS({
"browser-external:fs"(exports, module) {
module.exports = Object.create(new Proxy({}, {
get(_, key) {
if (key !== "__esModule" && key !== "__proto__" && key !== "constructor" && key !== "splice") {
console.warn(`Module "fs" has been externalized for browser compatibility. Cannot access "fs.${key}" in client code. See https://vite.dev/guide/troubleshooting.html#module-externalized-for-browser-compatibility for more details.`);
}
}
}));
}
});
// node_modules/ol/source/BingMaps.js
function quadKey(tileCoord) {
const z = tileCoord[0];
const digits = new Array(z);
let mask = 1 << z - 1;
let i, charCode;
for (i = 0; i < z; ++i) {
charCode = 48;
if (tileCoord[1] & mask) {
charCode += 1;
}
if (tileCoord[2] & mask) {
charCode += 2;
}
digits[i] = String.fromCharCode(charCode);
mask >>= 1;
}
return digits.join("");
}
var TOS_ATTRIBUTION = '<a class="ol-attribution-bing-tos" href="https://www.microsoft.com/maps/product/terms.html" target="_blank">Terms of Use</a>';
var BingMaps = class extends TileImage_default {
/**
* @param {Options} options Bing Maps options.
*/
constructor(options) {
const hidpi = options.hidpi !== void 0 ? options.hidpi : false;
super({
cacheSize: options.cacheSize,
crossOrigin: "anonymous",
interpolate: options.interpolate,
projection: get("EPSG:3857"),
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: "loading",
tileLoadFunction: options.tileLoadFunction,
tilePixelRatio: hidpi ? 2 : 1,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition,
zDirection: options.zDirection
});
this.hidpi_ = hidpi;
this.culture_ = options.culture !== void 0 ? options.culture : "en-us";
this.maxZoom_ = options.maxZoom !== void 0 ? options.maxZoom : -1;
this.apiKey_ = options.key;
this.imagerySet_ = options.imagerySet;
this.placeholderTiles_ = options.placeholderTiles;
const url = (options.url || "https://dev.virtualearth.net/REST/v1/Imagery/Metadata/") + this.imagerySet_ + "?uriScheme=https&include=ImageryProviders&key=" + this.apiKey_ + "&c=" + this.culture_;
fetch(url).then((response) => response.json()).then((json) => this.handleImageryMetadataResponse(json));
}
/**
* Get the api key used for this source.
*
* @return {string} The api key.
* @api
*/
getApiKey() {
return this.apiKey_;
}
/**
* Get the imagery set associated with this source.
*
* @return {string} The imagery set.
* @api
*/
getImagerySet() {
return this.imagerySet_;
}
/**
* @param {BingMapsImageryMetadataResponse} response Response.
*/
handleImageryMetadataResponse(response) {
if (response.statusCode != 200 || response.statusDescription != "OK" || response.authenticationResultCode != "ValidCredentials" || response.resourceSets.length != 1 || response.resourceSets[0].resources.length != 1) {
this.setState("error");
return;
}
const resource = response.resourceSets[0].resources[0];
const maxZoom2 = this.maxZoom_ == -1 ? resource.zoomMax : this.maxZoom_;
const sourceProjection = this.getProjection();
const extent = extentFromProjection(sourceProjection);
const scale4 = this.hidpi_ ? 2 : 1;
const tileSize = resource.imageWidth == resource.imageHeight ? resource.imageWidth / scale4 : [resource.imageWidth / scale4, resource.imageHeight / scale4];
const tileGrid = createXYZ({
extent,
minZoom: resource.zoomMin,
maxZoom: maxZoom2,
tileSize
});
this.tileGrid = tileGrid;
const culture = this.culture_;
const hidpi = this.hidpi_;
const placeholderTiles = this.placeholderTiles_;
this.tileUrlFunction = createFromTileUrlFunctions(
resource.imageUrlSubdomains.map(function(subdomain) {
const quadKeyTileCoord = [0, 0, 0];
const imageUrl = resource.imageUrl.replace("{subdomain}", subdomain).replace("{culture}", culture);
return (
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {string|undefined} Tile URL.
*/
(function(tileCoord, pixelRatio, projection) {
if (!tileCoord) {
return void 0;
}
createOrUpdate(
tileCoord[0],
tileCoord[1],
tileCoord[2],
quadKeyTileCoord
);
const url = new URL(
imageUrl.replace("{quadkey}", quadKey(quadKeyTileCoord))
);
const params = url.searchParams;
if (hidpi) {
params.set("dpi", "d1");
params.set("device", "mobile");
}
if (placeholderTiles === true) {
params.delete("n");
} else if (placeholderTiles === false) {
params.set("n", "z");
}
return url.toString();
})
);
})
);
if (resource.imageryProviders) {
const transform2 = getTransformFromProjections(
get("EPSG:4326"),
this.getProjection()
);
this.setAttributions((frameState) => {
const attributions = [];
const viewState = frameState.viewState;
const tileGrid2 = this.getTileGrid();
const z = tileGrid2.getZForResolution(
viewState.resolution,
this.zDirection
);
const tileCoord = tileGrid2.getTileCoordForCoordAndZ(
viewState.center,
z
);
const zoom = tileCoord[0];
resource.imageryProviders.map(function(imageryProvider) {
let intersecting = false;
const coverageAreas = imageryProvider.coverageAreas;
for (let i = 0, ii = coverageAreas.length; i < ii; ++i) {
const coverageArea = coverageAreas[i];
if (zoom >= coverageArea.zoomMin && zoom <= coverageArea.zoomMax) {
const bbox = coverageArea.bbox;
const epsg4326Extent = [bbox[1], bbox[0], bbox[3], bbox[2]];
const extent2 = applyTransform(epsg4326Extent, transform2);
if (intersects(extent2, frameState.extent)) {
intersecting = true;
break;
}
}
}
if (intersecting) {
attributions.push(imageryProvider.attribution);
}
});
attributions.push(TOS_ATTRIBUTION);
return attributions;
});
}
this.setState("ready");
}
};
var BingMaps_default = BingMaps;
// node_modules/ol/source/CartoDB.js
var CartoDB = class extends XYZ_default {
/**
* @param {Options} options CartoDB options.
*/
constructor(options) {
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
maxZoom: options.maxZoom !== void 0 ? options.maxZoom : 18,
minZoom: options.minZoom,
projection: options.projection,
transition: options.transition,
wrapX: options.wrapX,
zDirection: options.zDirection
});
this.account_ = options.account;
this.mapId_ = options.map || "";
this.config_ = options.config || {};
this.templateCache_ = {};
this.initializeMap_();
}
/**
* Returns the current config.
* @return {!Object} The current configuration.
* @api
*/
getConfig() {
return this.config_;
}
/**
* Updates the carto db config.
* @param {Object} config a key-value lookup. Values will replace current values
* in the config.
* @api
*/
updateConfig(config) {
Object.assign(this.config_, config);
this.initializeMap_();
}
/**
* Sets the CartoDB config
* @param {Object} config In the case of anonymous maps, a CartoDB configuration
* object.
* If using named maps, a key-value lookup with the template parameters.
* @api
*/
setConfig(config) {
this.config_ = config || {};
this.initializeMap_();
}
/**
* Issue a request to initialize the CartoDB map.
* @private
*/
initializeMap_() {
const paramHash = JSON.stringify(this.config_);
if (this.templateCache_[paramHash]) {
this.applyTemplate_(this.templateCache_[paramHash]);
return;
}
let mapUrl = "https://" + this.account_ + ".carto.com/api/v1/map";
if (this.mapId_) {
mapUrl += "/named/" + this.mapId_;
}
const client = new XMLHttpRequest();
client.addEventListener(
"load",
this.handleInitResponse_.bind(this, paramHash)
);
client.addEventListener("error", this.handleInitError_.bind(this));
client.open("POST", mapUrl);
client.setRequestHeader("Content-type", "application/json");
client.send(JSON.stringify(this.config_));
}
/**
* Handle map initialization response.
* @param {string} paramHash a hash representing the parameter set that was used
* for the request
* @param {Event} event Event.
* @private
*/
handleInitResponse_(paramHash, event) {
const client = (
/** @type {XMLHttpRequest} */
event.target
);
if (!client.status || client.status >= 200 && client.status < 300) {
let response;
try {
response = /** @type {CartoDBLayerInfo} */
JSON.parse(client.responseText);
} catch {
this.setState("error");
return;
}
this.applyTemplate_(response);
this.templateCache_[paramHash] = response;
this.setState("ready");
} else {
this.setState("error");
}
}
/**
* @private
* @param {Event} event Event.
*/
handleInitError_(event) {
this.setState("error");
}
/**
* Apply the new tile urls returned by carto db
* @param {CartoDBLayerInfo} data Result of carto db call.
* @private
*/
applyTemplate_(data) {
const tilesUrl = "https://" + data.cdn_url.https + "/" + this.account_ + "/api/v1/map/" + data.layergroupid + "/{z}/{x}/{y}.png";
this.setUrl(tilesUrl);
}
};
var CartoDB_default = CartoDB;
// node_modules/ol/source/Cluster.js
var Cluster = class extends Vector_default {
/**
* @param {Options<FeatureType>} [options] Cluster options.
*/
constructor(options) {
options = options || {};
super({
attributions: options.attributions,
wrapX: options.wrapX
});
this.resolution = void 0;
this.distance = options.distance !== void 0 ? options.distance : 20;
this.minDistance = options.minDistance || 0;
this.interpolationRatio = 0;
this.features = [];
this.geometryFunction = options.geometryFunction || function(feature) {
const geometry = (
/** @type {Point} */
feature.getGeometry()
);
assert(
!geometry || geometry.getType() === "Point",
"The default `geometryFunction` can only handle `Point` or null geometries"
);
return geometry;
};
this.createCustomCluster_ = options.createCluster;
this.source = null;
this.boundRefresh_ = this.refresh.bind(this);
this.updateDistance(this.distance, this.minDistance);
this.setSource(options.source || null);
}
/**
* Remove all features from the source.
* @param {boolean} [fast] Skip dispatching of {@link module:ol/source/VectorEventType~VectorEventType#removefeature} events.
* @api
* @override
*/
clear(fast) {
this.features.length = 0;
super.clear(fast);
}
/**
* Get the distance in pixels between clusters.
* @return {number} Distance.
* @api
*/
getDistance() {
return this.distance;
}
/**
* Get a reference to the wrapped source.
* @return {VectorSource<FeatureType>|null} Source.
* @api
*/
getSource() {
return this.source;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {import("../proj/Projection.js").default} projection Projection.
* @override
*/
loadFeatures(extent, resolution, projection) {
var _a;
(_a = this.source) == null ? void 0 : _a.loadFeatures(extent, resolution, projection);
if (resolution !== this.resolution) {
this.resolution = resolution;
this.refresh();
}
}
/**
* Set the distance within which features will be clusterd together.
* @param {number} distance The distance in pixels.
* @api
*/
setDistance(distance) {
this.updateDistance(distance, this.minDistance);
}
/**
* Set the minimum distance between clusters. Will be capped at the
* configured distance.
* @param {number} minDistance The minimum distance in pixels.
* @api
*/
setMinDistance(minDistance) {
this.updateDistance(this.distance, minDistance);
}
/**
* The configured minimum distance between clusters.
* @return {number} The minimum distance in pixels.
* @api
*/
getMinDistance() {
return this.minDistance;
}
/**
* Replace the wrapped source.
* @param {VectorSource<FeatureType>|null} source The new source for this instance.
* @api
*/
setSource(source) {
if (this.source) {
this.source.removeEventListener(EventType_default.CHANGE, this.boundRefresh_);
}
this.source = source;
if (source) {
source.addEventListener(EventType_default.CHANGE, this.boundRefresh_);
}
this.refresh();
}
/**
* Handle the source changing.
* @override
*/
refresh() {
this.clear();
this.cluster();
this.addFeatures(this.features);
}
/**
* Update the distances and refresh the source if necessary.
* @param {number} distance The new distance.
* @param {number} minDistance The new minimum distance.
*/
updateDistance(distance, minDistance) {
const ratio = distance === 0 ? 0 : Math.min(minDistance, distance) / distance;
const changed = distance !== this.distance || this.interpolationRatio !== ratio;
this.distance = distance;
this.minDistance = minDistance;
this.interpolationRatio = ratio;
if (changed) {
this.refresh();
}
}
/**
* @protected
*/
cluster() {
if (this.resolution === void 0 || !this.source) {
return;
}
const extent = createEmpty();
const mapDistance = this.distance * this.resolution;
const features = this.source.getFeatures();
const clustered = {};
for (let i = 0, ii = features.length; i < ii; i++) {
const feature = features[i];
if (!(getUid(feature) in clustered)) {
const geometry = this.geometryFunction(feature);
if (geometry) {
const coordinates = geometry.getCoordinates();
createOrUpdateFromCoordinate(coordinates, extent);
buffer(extent, mapDistance, extent);
const neighbors = this.source.getFeaturesInExtent(extent).filter(function(neighbor) {
const uid = getUid(neighbor);
if (uid in clustered) {
return false;
}
clustered[uid] = true;
return true;
});
this.features.push(this.createCluster(neighbors, extent));
}
}
}
}
/**
* @param {Array<FeatureType>} features Features
* @param {import("../extent.js").Extent} extent The searched extent for these features.
* @return {Feature} The cluster feature.
* @protected
*/
createCluster(features, extent) {
const centroid = [0, 0];
for (let i = features.length - 1; i >= 0; --i) {
const geometry2 = this.geometryFunction(features[i]);
if (geometry2) {
add(centroid, geometry2.getCoordinates());
} else {
features.splice(i, 1);
}
}
scale(centroid, 1 / features.length);
const searchCenter = getCenter(extent);
const ratio = this.interpolationRatio;
const geometry = new Point_default([
centroid[0] * (1 - ratio) + searchCenter[0] * ratio,
centroid[1] * (1 - ratio) + searchCenter[1] * ratio
]);
if (this.createCustomCluster_) {
return this.createCustomCluster_(geometry, features);
}
return new Feature_default({
geometry,
features
});
}
};
var Cluster_default = Cluster;
// node_modules/ol/webgl/Canvas.js
var VERTEX_SHADER = `
attribute vec4 a_position;
attribute vec4 a_texcoord;
uniform mat4 u_matrix;
uniform mat4 u_textureMatrix;
varying vec2 v_texcoord;
void main() {
gl_Position = u_matrix * a_position;
vec2 texcoord = (u_textureMatrix * a_texcoord).xy;
v_texcoord = texcoord;
}
`;
var FRAGMENT_SHADER = `
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
if (
v_texcoord.x < 0.0 ||
v_texcoord.y < 0.0 ||
v_texcoord.x > 1.0 ||
v_texcoord.y > 1.0
) {
discard;
}
gl_FragColor = texture2D(u_texture, v_texcoord);
}
`;
var Canvas = class {
/**
* @param {WebGLRenderingContext} gl Context to render in.
*/
constructor(gl) {
this.gl_ = gl;
this.program_ = createProgram(gl, FRAGMENT_SHADER, VERTEX_SHADER);
this.positionLocation = gl.getAttribLocation(this.program_, "a_position");
this.texcoordLocation = gl.getAttribLocation(this.program_, "a_texcoord");
this.matrixLocation = gl.getUniformLocation(this.program_, "u_matrix");
this.textureMatrixLocation = gl.getUniformLocation(
this.program_,
"u_textureMatrix"
);
this.textureLocation = gl.getUniformLocation(this.program_, "u_texture");
this.positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
this.positions = [0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1];
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(this.positions),
gl.STATIC_DRAW
);
this.texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
this.texcoords = [0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1];
gl.bufferData(
gl.ARRAY_BUFFER,
new Float32Array(this.texcoords),
gl.STATIC_DRAW
);
}
/**
* 2dContext drawImage call implemented in webgl.
* Unlike images, textures do not have a width and height associated
* with them so we'll pass in the width and height of the texture.
*
* @param {WebGLTexture} tex Image to draw.
* @param {number} texWidth Image width.
* @param {number} texHeight Image height.
* @param {number} srcX Top-left x-point to read src image.
* @param {number} srcY Top-left y-point to read src image.
* @param {number} [srcWidth] Width of source to read.
* @param {number} [srcHeight] Height of source to read.
* @param {number} [dstX] Top-left x-point of destination.
* @param {number} [dstY] Top-left y-point of destination.
* @param {number} [dstWidth] Width of written image in destination.
* @param {number} [dstHeight] Height of written image in destination.
* @param {number} [width] Width of canvas.
* @param {number} [height] Height of canvas.
*/
drawImage(tex, texWidth, texHeight, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight, width, height) {
const gl = this.gl_;
if (dstX === void 0) {
dstX = srcX;
}
if (dstY === void 0) {
dstY = srcY;
}
if (srcWidth === void 0) {
srcWidth = texWidth;
}
if (srcHeight === void 0) {
srcHeight = texHeight;
}
if (dstWidth === void 0) {
dstWidth = srcWidth;
}
if (dstHeight === void 0) {
dstHeight = srcHeight;
}
if (width === void 0) {
width = gl.canvas.width;
}
if (height === void 0) {
height = gl.canvas.height;
}
gl.bindTexture(gl.TEXTURE_2D, tex);
gl.useProgram(this.program_);
gl.bindBuffer(gl.ARRAY_BUFFER, this.positionBuffer);
gl.enableVertexAttribArray(this.positionLocation);
gl.vertexAttribPointer(this.positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.bindBuffer(gl.ARRAY_BUFFER, this.texcoordBuffer);
gl.enableVertexAttribArray(this.texcoordLocation);
gl.vertexAttribPointer(this.texcoordLocation, 2, gl.FLOAT, false, 0, 0);
let matrix = orthographic(0, width, 0, height, -1, 1);
matrix = translate(matrix, dstX, dstY, 0);
matrix = scale3(matrix, dstWidth, dstHeight, 1);
gl.uniformMatrix4fv(this.matrixLocation, false, matrix);
let texMatrix = translation(srcX / texWidth, srcY / texHeight, 0);
texMatrix = scale3(
texMatrix,
srcWidth / texWidth,
srcHeight / texHeight,
1
);
gl.uniformMatrix4fv(this.textureMatrixLocation, false, texMatrix);
gl.uniform1i(this.textureLocation, 0);
gl.drawArrays(gl.TRIANGLES, 0, this.positions.length / 2);
}
};
function createShader(gl, type, source) {
const shader = gl.createShader(type);
if (shader === null) {
throw new Error("Shader compilation failed");
}
gl.shaderSource(shader, source);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
const log = gl.getShaderInfoLog(shader);
if (log === null) {
throw new Error("Shader info log creation failed");
}
throw new Error(log);
}
return shader;
}
function createProgram(gl, fragmentSource, vertexSource) {
const program = gl.createProgram();
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentSource);
if (program === null) {
throw new Error("Program creation failed");
}
gl.attachShader(program, vertexShader);
gl.attachShader(program, fragmentShader);
gl.linkProgram(program);
if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
const log = gl.getProgramInfoLog(program);
if (log === null) {
throw new Error("Program info log creation failed");
}
throw new Error();
}
return program;
}
// node_modules/ol/reproj/glreproj.js
var EDGE_VERTEX_SHADER = `
attribute vec4 a_position;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * a_position;
}
`;
var EDGE_FRAGMENT_SHADER = `
precision mediump float;
uniform vec4 u_val;
void main() {
gl_FragColor = u_val;
}
`;
var TRIANGLE_VERTEX_SHADER = `
attribute vec4 a_position;
attribute vec2 a_texcoord;
varying vec2 v_texcoord;
uniform mat4 u_matrix;
void main() {
gl_Position = u_matrix * a_position;
v_texcoord = a_texcoord;
}
`;
var TRIANGLE_FRAGMENT_SHADER = `
precision mediump float;
varying vec2 v_texcoord;
uniform sampler2D u_texture;
void main() {
if (v_texcoord.x < 0.0 || v_texcoord.x > 1.0 || v_texcoord.y < 0.0 || v_texcoord.y > 1.0) {
discard;
}
gl_FragColor = texture2D(u_texture, v_texcoord);
}
`;
function createCanvasContextWebGL(width, height, canvasPool2, settings) {
let canvas;
if (canvasPool2 && canvasPool2.length) {
canvas = /** @type {HTMLCanvasElement} */
canvasPool2.shift();
} else if (WORKER_OFFSCREEN_CANVAS) {
canvas = new OffscreenCanvas(width || 300, height || 300);
} else {
canvas = document.createElement("canvas");
}
if (width) {
canvas.width = width;
}
if (height) {
canvas.height = height;
}
return (
/** @type {WebGLRenderingContext} */
canvas.getContext("webgl", settings)
);
}
function releaseGLCanvas(gl) {
const canvas = gl.canvas;
canvas.width = 1;
canvas.height = 1;
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
}
var canvasGLPool = [];
function render2(gl, width_, height_, pixelRatio, sourceResolution, targetResolution, targetExtent, triangulation, sources, gutter, dataType, renderEdges, interpolate, drawSingle) {
const width = Math.round(pixelRatio * width_);
const height = Math.round(pixelRatio * height_);
gl.canvas.width = width;
gl.canvas.height = height;
let resultFrameBuffer;
let resultTexture;
{
resultTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, resultTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
if (interpolate) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
width,
height,
0,
gl.RGBA,
dataType,
null
);
resultFrameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, resultFrameBuffer);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
resultTexture,
0
);
}
if (resultFrameBuffer === null) {
throw new Error("Could not create framebuffer");
}
if (resultTexture === null) {
throw new Error("Could not create texture");
}
if (sources.length === 0) {
return {
width,
height,
framebuffer: resultFrameBuffer,
texture: resultTexture
};
}
const sourceDataExtent = createEmpty();
sources.forEach(function(src, i, arr) {
extend(sourceDataExtent, src.extent);
});
let stitchTexture;
let stitchWidth;
let stitchHeight;
const stitchScale = 1 / sourceResolution;
if (!drawSingle || sources.length !== 1 || gutter !== 0) {
stitchTexture = gl.createTexture();
if (resultTexture === null) {
throw new Error("Could not create texture");
}
stitchWidth = Math.round(getWidth(sourceDataExtent) * stitchScale);
stitchHeight = Math.round(getHeight(sourceDataExtent) * stitchScale);
const maxTexSize = gl.getParameter(gl.MAX_TEXTURE_SIZE);
const largeSide = Math.max(stitchWidth, stitchHeight);
const scaleFactor = largeSide > maxTexSize ? maxTexSize / largeSide : 1;
const stitchWidthFixed = Math.round(stitchWidth * scaleFactor);
const stitchHeightFixed = Math.round(stitchHeight * scaleFactor);
gl.bindTexture(gl.TEXTURE_2D, stitchTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
if (interpolate) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
gl.texImage2D(
gl.TEXTURE_2D,
0,
gl.RGBA,
stitchWidthFixed,
stitchHeightFixed,
0,
gl.RGBA,
dataType,
null
);
const fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.framebufferTexture2D(
gl.FRAMEBUFFER,
gl.COLOR_ATTACHMENT0,
gl.TEXTURE_2D,
stitchTexture,
0
);
const webGLCanvas = new Canvas(gl);
sources.forEach(function(src, i, arr) {
const xPos = (src.extent[0] - sourceDataExtent[0]) * stitchScale * scaleFactor;
const yPos = -(src.extent[3] - sourceDataExtent[3]) * stitchScale * scaleFactor;
const srcWidth = getWidth(src.extent) * stitchScale * scaleFactor;
const srcHeight = getHeight(src.extent) * stitchScale * scaleFactor;
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
gl.viewport(0, 0, stitchWidthFixed, stitchHeightFixed);
if (src.clipExtent) {
const xPos2 = (src.clipExtent[0] - sourceDataExtent[0]) * stitchScale * scaleFactor;
const yPos2 = -(src.clipExtent[3] - sourceDataExtent[3]) * stitchScale * scaleFactor;
const width2 = getWidth(src.clipExtent) * stitchScale * scaleFactor;
const height2 = getHeight(src.clipExtent) * stitchScale * scaleFactor;
gl.enable(gl.SCISSOR_TEST);
gl.scissor(
interpolate ? xPos2 : Math.round(xPos2),
interpolate ? yPos2 : Math.round(yPos2),
interpolate ? width2 : Math.round(xPos2 + width2) - Math.round(xPos2),
interpolate ? height2 : Math.round(yPos2 + height2) - Math.round(yPos2)
);
}
webGLCanvas.drawImage(
src.texture,
src.width,
src.height,
gutter,
gutter,
src.width - 2 * gutter,
src.height - 2 * gutter,
interpolate ? xPos : Math.round(xPos),
interpolate ? yPos : Math.round(yPos),
interpolate ? srcWidth : Math.round(xPos + srcWidth) - Math.round(xPos),
interpolate ? srcHeight : Math.round(yPos + srcHeight) - Math.round(yPos),
stitchWidthFixed,
stitchHeightFixed
);
gl.disable(gl.SCISSOR_TEST);
});
gl.deleteFramebuffer(fb);
} else {
stitchTexture = sources[0].texture;
stitchWidth = sources[0].width;
stitchHeight = sources[0].width;
}
const targetTopLeft = getTopLeft(targetExtent);
const sourceTopLeft = getTopLeft(sourceDataExtent);
const getUVs = (target) => {
const u0 = (target[0][0] - targetTopLeft[0]) / targetResolution * pixelRatio;
const v0 = -(target[0][1] - targetTopLeft[1]) / targetResolution * pixelRatio;
const u1 = (target[1][0] - targetTopLeft[0]) / targetResolution * pixelRatio;
const v1 = -(target[1][1] - targetTopLeft[1]) / targetResolution * pixelRatio;
const u2 = (target[2][0] - targetTopLeft[0]) / targetResolution * pixelRatio;
const v2 = -(target[2][1] - targetTopLeft[1]) / targetResolution * pixelRatio;
return { u1, v1, u0, v0, u2, v2 };
};
gl.bindFramebuffer(gl.FRAMEBUFFER, resultFrameBuffer);
gl.viewport(0, 0, width, height);
{
const vertices = [];
const texcoords = [];
const triProgram = createProgram(
gl,
TRIANGLE_FRAGMENT_SHADER,
TRIANGLE_VERTEX_SHADER
);
gl.useProgram(triProgram);
const textureLocation = gl.getUniformLocation(triProgram, "u_texture");
gl.bindTexture(gl.TEXTURE_2D, stitchTexture);
gl.uniform1i(textureLocation, 0);
triangulation.getTriangles().forEach(function(triangle, i, arr) {
const source = triangle.source;
const target = triangle.target;
const { u1, v1, u0, v0, u2, v2 } = getUVs(target);
const su0 = (source[0][0] - sourceTopLeft[0]) / sourceResolution / stitchWidth;
const sv0 = -(source[0][1] - sourceTopLeft[1]) / sourceResolution / stitchHeight;
const su1 = (source[1][0] - sourceTopLeft[0]) / sourceResolution / stitchWidth;
const sv1 = -(source[1][1] - sourceTopLeft[1]) / sourceResolution / stitchHeight;
const su2 = (source[2][0] - sourceTopLeft[0]) / sourceResolution / stitchWidth;
const sv2 = -(source[2][1] - sourceTopLeft[1]) / sourceResolution / stitchHeight;
vertices.push(u1, v1, u0, v0, u2, v2);
texcoords.push(su1, sv1, su0, sv0, su2, sv2);
});
const matrix = orthographic(0, width, height, 0, -1, 1);
const matrixLocation = gl.getUniformLocation(triProgram, "u_matrix");
gl.uniformMatrix4fv(matrixLocation, false, matrix);
const positionLocation = gl.getAttribLocation(triProgram, "a_position");
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
const texcoordLocation = gl.getAttribLocation(triProgram, "a_texcoord");
const texcoordBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, texcoordBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(texcoords), gl.STATIC_DRAW);
gl.vertexAttribPointer(texcoordLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(texcoordLocation);
gl.drawArrays(gl.TRIANGLES, 0, vertices.length / 2);
}
if (renderEdges) {
const edgeProgram = createProgram(
gl,
EDGE_FRAGMENT_SHADER,
EDGE_VERTEX_SHADER
);
gl.useProgram(edgeProgram);
const matrix = orthographic(0, width, height, 0, -1, 1);
const matrixLocation = gl.getUniformLocation(edgeProgram, "u_matrix");
gl.uniformMatrix4fv(matrixLocation, false, matrix);
const burnval = Array.isArray(renderEdges) ? renderEdges : [0, 0, 0, 255];
const burnvalLocation = gl.getUniformLocation(edgeProgram, "u_val");
const isFloat = true;
if (isFloat) {
gl.uniform4fv(burnvalLocation, burnval);
} else {
gl.uniform4iv(burnvalLocation, burnval);
}
const positionLocation = gl.getAttribLocation(edgeProgram, "a_position");
const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);
gl.vertexAttribPointer(positionLocation, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(positionLocation);
const lines = triangulation.getTriangles().reduce(function(lines2, triangle) {
const target = triangle.target;
const { u1, v1, u0, v0, u2, v2 } = getUVs(target);
return lines2.concat([u1, v1, u0, v0, u0, v0, u2, v2, u2, v2, u1, v1]);
}, []);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(lines), gl.STATIC_DRAW);
gl.drawArrays(gl.LINES, 0, lines.length / 2);
}
return {
width,
height,
framebuffer: resultFrameBuffer,
texture: resultTexture
};
}
// node_modules/ol/reproj/DataTile.js
var ReprojDataTile = class extends DataTile_default {
/**
* @param {Options} options Tile options.
*/
constructor(options) {
super({
tileCoord: options.tileCoord,
loader: () => Promise.resolve(new Uint8ClampedArray(4)),
interpolate: options.interpolate,
transition: options.transition
});
this.renderEdges_ = options.renderEdges !== void 0 ? options.renderEdges : false;
this.pixelRatio_ = options.pixelRatio;
this.gutter_ = options.gutter;
this.reprojData_ = null;
this.reprojError_ = null;
this.reprojSize_ = void 0;
this.sourceTileGrid_ = options.sourceTileGrid;
this.targetTileGrid_ = options.targetTileGrid;
this.wrappedTileCoord_ = options.wrappedTileCoord || options.tileCoord;
this.sourceTiles_ = [];
this.sourcesListenerKeys_ = null;
this.sourceZ_ = 0;
const sourceProj = options.sourceProj;
const sourceProjExtent = sourceProj.getExtent();
const sourceTileGridExtent = options.sourceTileGrid.getExtent();
this.clipExtent_ = sourceProj.canWrapX() ? sourceTileGridExtent ? getIntersection(sourceProjExtent, sourceTileGridExtent) : sourceProjExtent : sourceTileGridExtent;
const targetExtent = this.targetTileGrid_.getTileCoordExtent(
this.wrappedTileCoord_
);
const maxTargetExtent = this.targetTileGrid_.getExtent();
let maxSourceExtent = this.sourceTileGrid_.getExtent();
const limitedTargetExtent = maxTargetExtent ? getIntersection(targetExtent, maxTargetExtent) : targetExtent;
if (getArea(limitedTargetExtent) === 0) {
this.state = TileState_default.EMPTY;
return;
}
if (sourceProjExtent) {
if (!maxSourceExtent) {
maxSourceExtent = sourceProjExtent;
} else {
maxSourceExtent = getIntersection(maxSourceExtent, sourceProjExtent);
}
}
const targetResolution = this.targetTileGrid_.getResolution(
this.wrappedTileCoord_[0]
);
const targetProj = options.targetProj;
const sourceResolution = calculateSourceExtentResolution(
sourceProj,
targetProj,
limitedTargetExtent,
targetResolution
);
if (!isFinite(sourceResolution) || sourceResolution <= 0) {
this.state = TileState_default.EMPTY;
return;
}
const errorThresholdInPixels = options.errorThreshold !== void 0 ? options.errorThreshold : ERROR_THRESHOLD;
this.triangulation_ = new Triangulation_default(
sourceProj,
targetProj,
limitedTargetExtent,
maxSourceExtent,
sourceResolution * errorThresholdInPixels,
targetResolution,
options.transformMatrix
);
if (this.triangulation_.getTriangles().length === 0) {
this.state = TileState_default.EMPTY;
return;
}
this.sourceZ_ = this.sourceTileGrid_.getZForResolution(sourceResolution);
let sourceExtent = this.triangulation_.calculateSourceExtent();
if (maxSourceExtent) {
if (sourceProj.canWrapX()) {
sourceExtent[1] = clamp(
sourceExtent[1],
maxSourceExtent[1],
maxSourceExtent[3]
);
sourceExtent[3] = clamp(
sourceExtent[3],
maxSourceExtent[1],
maxSourceExtent[3]
);
} else {
sourceExtent = getIntersection(sourceExtent, maxSourceExtent);
}
}
if (!getArea(sourceExtent)) {
this.state = TileState_default.EMPTY;
} else {
let worldWidth = 0;
let worldsAway = 0;
if (sourceProj.canWrapX()) {
worldWidth = getWidth(sourceProjExtent);
worldsAway = Math.floor(
(sourceExtent[0] - sourceProjExtent[0]) / worldWidth
);
}
const sourceExtents = wrapAndSliceX(
sourceExtent.slice(),
sourceProj,
true
);
sourceExtents.forEach((extent) => {
const sourceRange = this.sourceTileGrid_.getTileRangeForExtentAndZ(
extent,
this.sourceZ_
);
const getTile = options.getTileFunction;
for (let srcX = sourceRange.minX; srcX <= sourceRange.maxX; srcX++) {
for (let srcY = sourceRange.minY; srcY <= sourceRange.maxY; srcY++) {
const tile = getTile(this.sourceZ_, srcX, srcY, this.pixelRatio_);
if (tile) {
const offset = worldsAway * worldWidth;
this.sourceTiles_.push({ tile, offset });
}
}
}
++worldsAway;
});
if (this.sourceTiles_.length === 0) {
this.state = TileState_default.EMPTY;
}
}
}
/**
* Get the tile size.
* @return {import('../size.js').Size} Tile size.
* @override
*/
getSize() {
return this.reprojSize_;
}
/**
* Get the data for the tile.
* @return {import("../DataTile.js").Data} Tile data.
* @override
*/
getData() {
return this.reprojData_;
}
/**
* Get any loading error.
* @return {Error} Loading error.
* @override
*/
getError() {
return this.reprojError_;
}
/**
* @private
*/
reproject_() {
const dataSources = [];
let imageLike = false;
this.sourceTiles_.forEach((source) => {
var _a;
const tile = source.tile;
if (!tile || tile.getState() !== TileState_default.LOADED) {
return;
}
const size2 = tile.getSize();
const gutter = this.gutter_;
let tileData;
const arrayData = asArrayLike(tile.getData());
if (arrayData) {
tileData = arrayData;
} else {
imageLike = true;
tileData = toArray(asImageLike(tile.getData()));
}
const pixelSize = [size2[0] + 2 * gutter, size2[1] + 2 * gutter];
const isFloat = tileData instanceof Float32Array;
const pixelCount = pixelSize[0] * pixelSize[1];
const DataType = isFloat ? Float32Array : Uint8ClampedArray;
const tileDataR = new DataType(
/** @type {ArrayBuffer} */
tileData.buffer
);
const bytesPerElement = DataType.BYTES_PER_ELEMENT;
const bytesPerPixel = bytesPerElement * tileDataR.length / pixelCount;
const bytesPerRow = tileDataR.byteLength / pixelSize[1];
const bandCount2 = Math.floor(
bytesPerRow / bytesPerElement / pixelSize[0]
);
const extent = this.sourceTileGrid_.getTileCoordExtent(tile.tileCoord);
extent[0] += source.offset;
extent[2] += source.offset;
const clipExtent = (_a = this.clipExtent_) == null ? void 0 : _a.slice();
if (clipExtent) {
clipExtent[0] += source.offset;
clipExtent[2] += source.offset;
}
dataSources.push({
extent,
clipExtent,
data: tileDataR,
dataType: DataType,
bytesPerPixel,
pixelSize,
bandCount: bandCount2
});
});
this.sourceTiles_.length = 0;
if (dataSources.length === 0) {
this.state = TileState_default.ERROR;
this.changed();
return;
}
const z = this.wrappedTileCoord_[0];
const size = this.targetTileGrid_.getTileSize(z);
const targetWidth = typeof size === "number" ? size : size[0];
const targetHeight = typeof size === "number" ? size : size[1];
const outWidth = Math.round(targetWidth * this.pixelRatio_);
const outHeight = Math.round(targetHeight * this.pixelRatio_);
const targetResolution = this.targetTileGrid_.getResolution(z);
const sourceResolution = this.sourceTileGrid_.getResolution(this.sourceZ_);
const targetExtent = this.targetTileGrid_.getTileCoordExtent(
this.wrappedTileCoord_
);
const bandCount = dataSources[0].bandCount;
const dataR = new dataSources[0].dataType(bandCount * outWidth * outHeight);
const gl = createCanvasContextWebGL(outWidth, outHeight, canvasGLPool, {
premultipliedAlpha: false,
antialias: false
});
let willInterpolate;
const format = gl.RGBA;
let textureType;
if (dataSources[0].dataType == Float32Array) {
textureType = gl.FLOAT;
gl.getExtension("WEBGL_color_buffer_float");
gl.getExtension("OES_texture_float");
gl.getExtension("EXT_float_blend");
const extension = gl.getExtension("OES_texture_float_linear");
const canInterpolate = extension !== null;
willInterpolate = canInterpolate && this.interpolate;
} else {
textureType = gl.UNSIGNED_BYTE;
willInterpolate = this.interpolate;
}
const BANDS_PR_REPROJ = 4;
const reprojs = Math.ceil(bandCount / BANDS_PR_REPROJ);
for (let reproj = reprojs - 1; reproj >= 0; --reproj) {
const sources = [];
for (let i = 0, len = dataSources.length; i < len; ++i) {
const dataSource = dataSources[i];
const pixelSize = dataSource.pixelSize;
const width2 = pixelSize[0];
const height2 = pixelSize[1];
const data2 = new dataSource.dataType(BANDS_PR_REPROJ * width2 * height2);
const dataS = dataSource.data;
let offset2 = reproj * BANDS_PR_REPROJ;
for (let j = 0, len2 = data2.length; j < len2; j += BANDS_PR_REPROJ) {
data2[j] = dataS[offset2];
data2[j + 1] = dataS[offset2 + 1];
data2[j + 2] = dataS[offset2 + 2];
data2[j + 3] = dataS[offset2 + 3];
offset2 += bandCount;
}
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
if (willInterpolate) {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
} else {
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texImage2D(
gl.TEXTURE_2D,
0,
format,
width2,
height2,
0,
format,
textureType,
data2
);
sources.push({
extent: dataSource.extent,
clipExtent: dataSource.clipExtent,
texture,
width: width2,
height: height2
});
}
const { framebuffer, width, height } = render2(
gl,
targetWidth,
targetHeight,
this.pixelRatio_,
sourceResolution,
targetResolution,
targetExtent,
this.triangulation_,
sources,
this.gutter_,
textureType,
this.renderEdges_,
willInterpolate
);
const rows = width;
const cols = height * BANDS_PR_REPROJ;
const data = new dataSources[0].dataType(rows * cols);
gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
gl.readPixels(0, 0, width, height, gl.RGBA, textureType, data);
let offset = reproj * BANDS_PR_REPROJ;
for (let i = 0, len = data.length; i < len; i += BANDS_PR_REPROJ) {
const flipY = (rows - 1 - (i / cols | 0)) * cols + i % cols;
dataR[offset] = data[flipY];
dataR[offset + 1] = data[flipY + 1];
dataR[offset + 2] = data[flipY + 2];
dataR[offset + 3] = data[flipY + 3];
offset += bandCount;
}
}
releaseGLCanvas(gl);
canvasGLPool.push(gl.canvas);
if (imageLike) {
const context = createCanvasContext2D(targetWidth, targetHeight);
const imageData = new ImageData(dataR, targetWidth);
context.putImageData(imageData, 0, 0);
this.reprojData_ = context.canvas;
} else {
this.reprojData_ = dataR;
}
this.reprojSize_ = [outWidth, outHeight];
this.state = TileState_default.LOADED;
this.changed();
}
/**
* Load not yet loaded URI.
* @override
*/
load() {
if (this.state !== TileState_default.IDLE && this.state !== TileState_default.ERROR) {
return;
}
this.state = TileState_default.LOADING;
this.changed();
let leftToLoad = 0;
this.sourcesListenerKeys_ = [];
this.sourceTiles_.forEach(({ tile }) => {
const state = tile.getState();
if (state !== TileState_default.IDLE && state !== TileState_default.LOADING) {
return;
}
leftToLoad++;
const sourceListenKey = listen(tile, EventType_default.CHANGE, () => {
const state2 = tile.getState();
if (state2 == TileState_default.LOADED || state2 == TileState_default.ERROR || state2 == TileState_default.EMPTY) {
unlistenByKey(sourceListenKey);
leftToLoad--;
if (leftToLoad === 0) {
this.unlistenSources_();
this.reproject_();
}
}
});
this.sourcesListenerKeys_.push(sourceListenKey);
});
if (leftToLoad === 0) {
setTimeout(this.reproject_.bind(this), 0);
} else {
this.sourceTiles_.forEach(function({ tile }) {
const state = tile.getState();
if (state == TileState_default.IDLE) {
tile.load();
}
});
}
}
/**
* @private
*/
unlistenSources_() {
this.sourcesListenerKeys_.forEach(unlistenByKey);
this.sourcesListenerKeys_ = null;
}
};
var DataTile_default2 = ReprojDataTile;
// node_modules/ol/source/DataTile.js
var DataTileSource = class extends Tile_default3 {
/**
* @param {Options} options DataTile source options.
*/
constructor(options) {
const projection = options.projection === void 0 ? "EPSG:3857" : options.projection;
let tileGrid = options.tileGrid;
if (tileGrid === void 0 && projection) {
tileGrid = createXYZ({
extent: extentFromProjection(projection),
maxResolution: options.maxResolution,
maxZoom: options.maxZoom,
minZoom: options.minZoom,
tileSize: options.tileSize
});
}
super({
cacheSize: 0.1,
// don't cache on the source
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
projection,
tileGrid,
state: options.state,
wrapX: options.wrapX,
transition: options.transition,
interpolate: options.interpolate,
key: options.key,
zDirection: options.zDirection
});
this.gutter_ = options.gutter !== void 0 ? options.gutter : 0;
this.tileSize_ = options.tileSize ? toSize(options.tileSize) : null;
this.tileSizes_ = null;
this.tileLoadingKeys_ = {};
this.loader_ = options.loader;
this.handleTileChange_ = this.handleTileChange_.bind(this);
this.bandCount = options.bandCount === void 0 ? 4 : options.bandCount;
this.tileGridForProjection_ = {};
this.crossOrigin_ = options.crossOrigin || "anonymous";
this.transformMatrix = null;
}
/**
* Set the source tile sizes. The length of the array is expected to match the number of
* levels in the tile grid.
* @protected
* @param {Array<import('../size.js').Size>} tileSizes An array of tile sizes.
*/
setTileSizes(tileSizes) {
this.tileSizes_ = tileSizes;
}
/**
* Get the source tile size at the given zoom level. This may be different than the rendered tile
* size.
* @protected
* @param {number} z Tile zoom level.
* @return {import('../size.js').Size} The source tile size.
*/
getTileSize(z) {
if (this.tileSizes_) {
return this.tileSizes_[z];
}
if (this.tileSize_) {
return this.tileSize_;
}
const tileGrid = this.getTileGrid();
return tileGrid ? toSize(tileGrid.getTileSize(z)) : [256, 256];
}
/**
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {number} Gutter.
* @override
*/
getGutterForProjection(projection) {
const thisProj = this.getProjection();
if ((!thisProj || equivalent(thisProj, projection)) && !this.transformMatrix) {
return this.gutter_;
}
return 0;
}
/**
* @param {Loader} loader The data loader.
* @protected
*/
setLoader(loader) {
this.loader_ = loader;
}
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {import("../proj/Projection.js").default} targetProj The output projection.
* @param {import("../proj/Projection.js").default} sourceProj The input projection.
* @param {import("../structs/LRUCache.js").default<import("../Tile.js").default>} [tileCache] Tile cache.
* @return {!TileType} Tile.
*/
getReprojTile_(z, x, y, targetProj, sourceProj, tileCache) {
const sourceTileGrid = this.tileGrid || this.getTileGridForProjection(sourceProj || targetProj);
const reprojTilePixelRatio = Math.max.apply(
null,
sourceTileGrid.getResolutions().map((r, z2) => {
const tileSize = toSize(sourceTileGrid.getTileSize(z2));
const textureSize = this.getTileSize(z2);
return Math.max(
textureSize[0] / tileSize[0],
textureSize[1] / tileSize[1]
);
})
);
const targetTileGrid = this.getTileGridForProjection(targetProj);
const tileCoord = [z, x, y];
const wrappedTileCoord = this.getTileCoordForTileUrlFunction(
tileCoord,
targetProj
);
const options = Object.assign(
{
sourceProj: sourceProj || targetProj,
sourceTileGrid,
targetProj,
targetTileGrid,
tileCoord,
wrappedTileCoord,
pixelRatio: reprojTilePixelRatio,
gutter: this.gutter_,
getTileFunction: (z2, x2, y2, pixelRatio) => this.getTile(z2, x2, y2, pixelRatio, void 0, tileCache),
transformMatrix: this.transformMatrix
},
/** @type {import("../reproj/DataTile.js").Options} */
this.tileOptions
);
const tile = (
/** @type {TileType} */
/** @type {*} */
new DataTile_default2(options)
);
tile.key = this.getKey();
return tile;
}
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} [projection] Projection.
* @param {import("../structs/LRUCache.js").default<import("../Tile.js").default>} [tileCache] Tile cache.
* @return {TileType|null} Tile (or null if outside source extent).
* @override
*/
getTile(z, x, y, pixelRatio, projection, tileCache) {
var _a;
const sourceProjection = this.getProjection();
if (projection && (sourceProjection && !equivalent(sourceProjection, projection) || this.transformMatrix)) {
return this.getReprojTile_(
z,
x,
y,
projection,
sourceProjection,
tileCache
);
}
const size = this.getTileSize(z);
const sourceLoader = this.loader_;
const controller = new AbortController();
const loaderOptions = {
signal: controller.signal,
crossOrigin: this.crossOrigin_
};
const tileCoord = this.getTileCoordForTileUrlFunction([z, x, y]);
if (!tileCoord) {
return null;
}
const key = this.getKey();
const cacheKey = getCacheKey(this, key, z, x, y);
if (tileCache && tileCache.containsKey(cacheKey)) {
return (
/** @type {TileType} */
tileCache.get(cacheKey)
);
}
const requestZ = tileCoord[0];
const requestX = tileCoord[1];
const requestY = tileCoord[2];
const range = (_a = this.getTileGrid()) == null ? void 0 : _a.getFullTileRange(requestZ);
if (range) {
loaderOptions.maxY = range.getHeight() - 1;
}
function loader() {
return toPromise(function() {
return sourceLoader(requestZ, requestX, requestY, loaderOptions);
});
}
const options = Object.assign(
{
tileCoord: [z, x, y],
loader,
size,
controller
},
this.tileOptions
);
const tile = (
/** @type {TileType} */
/** @type {*} */
new DataTile_default(options)
);
tile.key = this.getKey();
tile.addEventListener(EventType_default.CHANGE, this.handleTileChange_);
tileCache == null ? void 0 : tileCache.set(cacheKey, tile);
return tile;
}
/**
* Handle tile change events.
* @param {import("../events/Event.js").default} event Event.
*/
handleTileChange_(event) {
const tile = (
/** @type {import("../Tile.js").default} */
event.target
);
const uid = getUid(tile);
const tileState = tile.getState();
let type;
if (tileState == TileState_default.LOADING) {
this.tileLoadingKeys_[uid] = true;
type = TileEventType_default.TILELOADSTART;
} else if (uid in this.tileLoadingKeys_) {
delete this.tileLoadingKeys_[uid];
type = tileState == TileState_default.ERROR ? TileEventType_default.TILELOADERROR : tileState == TileState_default.LOADED ? TileEventType_default.TILELOADEND : void 0;
}
if (type) {
this.dispatchEvent(new TileSourceEvent(type, tile));
}
}
/**
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {!import("../tilegrid/TileGrid.js").default} Tile grid.
* @override
*/
getTileGridForProjection(projection) {
const thisProj = this.getProjection();
if (this.tileGrid && (!thisProj || equivalent(thisProj, projection)) && !this.transformMatrix) {
return this.tileGrid;
}
const projKey = getUid(projection);
if (!(projKey in this.tileGridForProjection_)) {
this.tileGridForProjection_[projKey] = getForProjection(projection);
}
return this.tileGridForProjection_[projKey];
}
/**
* Sets the tile grid to use when reprojecting the tiles to the given
* projection instead of the default tile grid for the projection.
*
* This can be useful when the default tile grid cannot be created
* (e.g. projection has no extent defined) or
* for optimization reasons (custom tile size, resolutions, ...).
*
* @param {import("../proj.js").ProjectionLike} projection Projection.
* @param {import("../tilegrid/TileGrid.js").default} tilegrid Tile grid to use for the projection.
* @api
*/
setTileGridForProjection(projection, tilegrid) {
const proj = get(projection);
if (proj) {
const projKey = getUid(proj);
if (!(projKey in this.tileGridForProjection_)) {
this.tileGridForProjection_[projKey] = tilegrid;
}
}
}
};
var DataTile_default3 = DataTileSource;
// node_modules/@petamoriken/float16/src/_util/messages.mjs
var THIS_IS_NOT_AN_OBJECT = "This is not an object";
var THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT = "This is not a Float16Array object";
var THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY = "This constructor is not a subclass of Float16Array";
var THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT = "The constructor property value is not an object";
var SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT = "Species constructor didn't return TypedArray object";
var DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH = "Derived constructor created TypedArray object which was too small length";
var ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER = "Attempting to access detached ArrayBuffer";
var CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT = "Cannot convert undefined or null to object";
var CANNOT_MIX_BIGINT_AND_OTHER_TYPES = "Cannot mix BigInt and other types, use explicit conversions";
var ITERATOR_PROPERTY_IS_NOT_CALLABLE = "@@iterator property is not callable";
var REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE = "Reduce of empty array with no initial value";
var THE_COMPARISON_FUNCTION_MUST_BE_EITHER_A_FUNCTION_OR_UNDEFINED = "The comparison function must be either a function or undefined";
var OFFSET_IS_OUT_OF_BOUNDS = "Offset is out of bounds";
// node_modules/@petamoriken/float16/src/_util/primordials.mjs
function uncurryThis(target) {
return (thisArg, ...args) => {
return ReflectApply(target, thisArg, args);
};
}
function uncurryThisGetter(target, key) {
return uncurryThis(
ReflectGetOwnPropertyDescriptor(
target,
key
).get
);
}
var {
apply: ReflectApply,
construct: ReflectConstruct,
defineProperty: ReflectDefineProperty,
get: ReflectGet,
getOwnPropertyDescriptor: ReflectGetOwnPropertyDescriptor,
getPrototypeOf: ReflectGetPrototypeOf,
has: ReflectHas,
ownKeys: ReflectOwnKeys,
set: ReflectSet,
setPrototypeOf: ReflectSetPrototypeOf
} = Reflect;
var NativeProxy = Proxy;
var {
EPSILON,
MAX_SAFE_INTEGER,
isFinite: NumberIsFinite,
isNaN: NumberIsNaN
} = Number;
var {
iterator: SymbolIterator,
species: SymbolSpecies,
toStringTag: SymbolToStringTag,
for: SymbolFor
} = Symbol;
var NativeObject = Object;
var {
create: ObjectCreate,
defineProperty: ObjectDefineProperty,
freeze: ObjectFreeze,
is: ObjectIs
} = NativeObject;
var ObjectPrototype = NativeObject.prototype;
var ObjectPrototype__lookupGetter__ = (
/** @type {any} */
ObjectPrototype.__lookupGetter__ ? uncurryThis(
/** @type {any} */
ObjectPrototype.__lookupGetter__
) : (object, key) => {
if (object == null) {
throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
let target = NativeObject(object);
do {
const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
if (descriptor !== void 0) {
if (ObjectHasOwn(descriptor, "get")) {
return descriptor.get;
}
return;
}
} while ((target = ReflectGetPrototypeOf(target)) !== null);
}
);
var ObjectHasOwn = (
/** @type {any} */
NativeObject.hasOwn || uncurryThis(ObjectPrototype.hasOwnProperty)
);
var NativeArray = Array;
var ArrayIsArray = NativeArray.isArray;
var ArrayPrototype = NativeArray.prototype;
var ArrayPrototypeJoin = uncurryThis(ArrayPrototype.join);
var ArrayPrototypePush = uncurryThis(ArrayPrototype.push);
var ArrayPrototypeToLocaleString = uncurryThis(
ArrayPrototype.toLocaleString
);
var NativeArrayPrototypeSymbolIterator = ArrayPrototype[SymbolIterator];
var ArrayPrototypeSymbolIterator = uncurryThis(NativeArrayPrototypeSymbolIterator);
var {
abs: MathAbs,
trunc: MathTrunc
} = Math;
var NativeArrayBuffer = ArrayBuffer;
var ArrayBufferIsView = NativeArrayBuffer.isView;
var ArrayBufferPrototype = NativeArrayBuffer.prototype;
var ArrayBufferPrototypeSlice = uncurryThis(ArrayBufferPrototype.slice);
var ArrayBufferPrototypeGetByteLength = uncurryThisGetter(ArrayBufferPrototype, "byteLength");
var NativeSharedArrayBuffer = typeof SharedArrayBuffer !== "undefined" ? SharedArrayBuffer : null;
var SharedArrayBufferPrototypeGetByteLength = NativeSharedArrayBuffer && uncurryThisGetter(NativeSharedArrayBuffer.prototype, "byteLength");
var TypedArray = ReflectGetPrototypeOf(Uint8Array);
var TypedArrayFrom = TypedArray.from;
var TypedArrayPrototype = TypedArray.prototype;
var NativeTypedArrayPrototypeSymbolIterator = TypedArrayPrototype[SymbolIterator];
var TypedArrayPrototypeKeys = uncurryThis(TypedArrayPrototype.keys);
var TypedArrayPrototypeValues = uncurryThis(
TypedArrayPrototype.values
);
var TypedArrayPrototypeEntries = uncurryThis(
TypedArrayPrototype.entries
);
var TypedArrayPrototypeSet = uncurryThis(TypedArrayPrototype.set);
var TypedArrayPrototypeReverse = uncurryThis(
TypedArrayPrototype.reverse
);
var TypedArrayPrototypeFill = uncurryThis(TypedArrayPrototype.fill);
var TypedArrayPrototypeCopyWithin = uncurryThis(
TypedArrayPrototype.copyWithin
);
var TypedArrayPrototypeSort = uncurryThis(TypedArrayPrototype.sort);
var TypedArrayPrototypeSlice = uncurryThis(TypedArrayPrototype.slice);
var TypedArrayPrototypeSubarray = uncurryThis(
TypedArrayPrototype.subarray
);
var TypedArrayPrototypeGetBuffer = uncurryThisGetter(
TypedArrayPrototype,
"buffer"
);
var TypedArrayPrototypeGetByteOffset = uncurryThisGetter(
TypedArrayPrototype,
"byteOffset"
);
var TypedArrayPrototypeGetLength = uncurryThisGetter(
TypedArrayPrototype,
"length"
);
var TypedArrayPrototypeGetSymbolToStringTag = uncurryThisGetter(
TypedArrayPrototype,
SymbolToStringTag
);
var NativeUint8Array = Uint8Array;
var NativeUint16Array = Uint16Array;
var Uint16ArrayFrom = (...args) => {
return ReflectApply(TypedArrayFrom, NativeUint16Array, args);
};
var NativeUint32Array = Uint32Array;
var NativeFloat32Array = Float32Array;
var ArrayIteratorPrototype = ReflectGetPrototypeOf([][SymbolIterator]());
var ArrayIteratorPrototypeNext = uncurryThis(ArrayIteratorPrototype.next);
var GeneratorPrototypeNext = uncurryThis((function* () {
})().next);
var IteratorPrototype = ReflectGetPrototypeOf(ArrayIteratorPrototype);
var DataViewPrototype = DataView.prototype;
var DataViewPrototypeGetUint16 = uncurryThis(
DataViewPrototype.getUint16
);
var DataViewPrototypeSetUint16 = uncurryThis(
DataViewPrototype.setUint16
);
var NativeTypeError = TypeError;
var NativeRangeError = RangeError;
var NativeWeakSet = WeakSet;
var WeakSetPrototype = NativeWeakSet.prototype;
var WeakSetPrototypeAdd = uncurryThis(WeakSetPrototype.add);
var WeakSetPrototypeHas = uncurryThis(WeakSetPrototype.has);
var NativeWeakMap = WeakMap;
var WeakMapPrototype = NativeWeakMap.prototype;
var WeakMapPrototypeGet = uncurryThis(WeakMapPrototype.get);
var WeakMapPrototypeHas = uncurryThis(WeakMapPrototype.has);
var WeakMapPrototypeSet = uncurryThis(WeakMapPrototype.set);
// node_modules/@petamoriken/float16/src/_util/arrayIterator.mjs
var arrayIterators = new NativeWeakMap();
var SafeIteratorPrototype = ObjectCreate(null, {
next: {
value: function next() {
const arrayIterator = WeakMapPrototypeGet(arrayIterators, this);
return ArrayIteratorPrototypeNext(arrayIterator);
}
},
[SymbolIterator]: {
value: function values() {
return this;
}
}
});
function safeIfNeeded(array) {
if (array[SymbolIterator] === NativeArrayPrototypeSymbolIterator && ArrayIteratorPrototype.next === ArrayIteratorPrototypeNext) {
return array;
}
const safe = ObjectCreate(SafeIteratorPrototype);
WeakMapPrototypeSet(arrayIterators, safe, ArrayPrototypeSymbolIterator(array));
return safe;
}
var generators = new NativeWeakMap();
var DummyArrayIteratorPrototype = ObjectCreate(IteratorPrototype, {
next: {
value: function next2() {
const generator = WeakMapPrototypeGet(generators, this);
return GeneratorPrototypeNext(generator);
},
writable: true,
configurable: true
}
});
for (const key of ReflectOwnKeys(ArrayIteratorPrototype)) {
if (key === "next") {
continue;
}
ObjectDefineProperty(DummyArrayIteratorPrototype, key, ReflectGetOwnPropertyDescriptor(ArrayIteratorPrototype, key));
}
function wrap(generator) {
const dummy = ObjectCreate(DummyArrayIteratorPrototype);
WeakMapPrototypeSet(generators, dummy, generator);
return dummy;
}
// node_modules/@petamoriken/float16/src/_util/is.mjs
function isObject(value) {
return value !== null && typeof value === "object" || typeof value === "function";
}
function isObjectLike(value) {
return value !== null && typeof value === "object";
}
function isNativeTypedArray(value) {
return TypedArrayPrototypeGetSymbolToStringTag(value) !== void 0;
}
function isNativeBigIntTypedArray(value) {
const typedArrayName = TypedArrayPrototypeGetSymbolToStringTag(value);
return typedArrayName === "BigInt64Array" || typedArrayName === "BigUint64Array";
}
function isArrayBuffer(value) {
try {
if (ArrayIsArray(value)) {
return false;
}
ArrayBufferPrototypeGetByteLength(
/** @type {any} */
value
);
return true;
} catch (e) {
return false;
}
}
function isSharedArrayBuffer(value) {
if (NativeSharedArrayBuffer === null) {
return false;
}
try {
SharedArrayBufferPrototypeGetByteLength(
/** @type {any} */
value
);
return true;
} catch (e) {
return false;
}
}
function isAnyArrayBuffer(value) {
return isArrayBuffer(value) || isSharedArrayBuffer(value);
}
function isOrdinaryArray(value) {
if (!ArrayIsArray(value)) {
return false;
}
return value[SymbolIterator] === NativeArrayPrototypeSymbolIterator && ArrayIteratorPrototype.next === ArrayIteratorPrototypeNext;
}
function isOrdinaryNativeTypedArray(value) {
if (!isNativeTypedArray(value)) {
return false;
}
return value[SymbolIterator] === NativeTypedArrayPrototypeSymbolIterator && ArrayIteratorPrototype.next === ArrayIteratorPrototypeNext;
}
function isCanonicalIntegerIndexString(value) {
if (typeof value !== "string") {
return false;
}
const number = +value;
if (value !== number + "") {
return false;
}
if (!NumberIsFinite(number)) {
return false;
}
return number === MathTrunc(number);
}
// node_modules/@petamoriken/float16/src/_util/brand.mjs
var brand = SymbolFor("__Float16Array__");
function hasFloat16ArrayBrand(target) {
if (!isObjectLike(target)) {
return false;
}
const prototype = ReflectGetPrototypeOf(target);
if (!isObjectLike(prototype)) {
return false;
}
const constructor = prototype.constructor;
if (constructor === void 0) {
return false;
}
if (!isObject(constructor)) {
throw NativeTypeError(THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT);
}
return ReflectHas(constructor, brand);
}
// node_modules/@petamoriken/float16/src/_util/converter.mjs
var INVERSE_OF_EPSILON = 1 / EPSILON;
function roundTiesToEven(num) {
return num + INVERSE_OF_EPSILON - INVERSE_OF_EPSILON;
}
var FLOAT16_MIN_VALUE = 6103515625e-14;
var FLOAT16_MAX_VALUE = 65504;
var FLOAT16_EPSILON = 9765625e-10;
var FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE = FLOAT16_EPSILON * FLOAT16_MIN_VALUE;
var FLOAT16_EPSILON_DEVIDED_BY_EPSILON = FLOAT16_EPSILON * INVERSE_OF_EPSILON;
function roundToFloat16(num) {
const number = +num;
if (!NumberIsFinite(number) || number === 0) {
return number;
}
const sign = number > 0 ? 1 : -1;
const absolute = MathAbs(number);
if (absolute < FLOAT16_MIN_VALUE) {
return sign * roundTiesToEven(absolute / FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE) * FLOAT16_EPSILON_MULTIPLIED_BY_FLOAT16_MIN_VALUE;
}
const temp = (1 + FLOAT16_EPSILON_DEVIDED_BY_EPSILON) * absolute;
const result = temp - (temp - absolute);
if (result > FLOAT16_MAX_VALUE || NumberIsNaN(result)) {
return sign * Infinity;
}
return sign * result;
}
var buffer2 = new NativeArrayBuffer(4);
var floatView = new NativeFloat32Array(buffer2);
var uint32View = new NativeUint32Array(buffer2);
var baseTable = new NativeUint16Array(512);
var shiftTable = new NativeUint8Array(512);
for (let i = 0; i < 256; ++i) {
const e = i - 127;
if (e < -24) {
baseTable[i] = 0;
baseTable[i | 256] = 32768;
shiftTable[i] = 24;
shiftTable[i | 256] = 24;
} else if (e < -14) {
baseTable[i] = 1024 >> -e - 14;
baseTable[i | 256] = 1024 >> -e - 14 | 32768;
shiftTable[i] = -e - 1;
shiftTable[i | 256] = -e - 1;
} else if (e <= 15) {
baseTable[i] = e + 15 << 10;
baseTable[i | 256] = e + 15 << 10 | 32768;
shiftTable[i] = 13;
shiftTable[i | 256] = 13;
} else if (e < 128) {
baseTable[i] = 31744;
baseTable[i | 256] = 64512;
shiftTable[i] = 24;
shiftTable[i | 256] = 24;
} else {
baseTable[i] = 31744;
baseTable[i | 256] = 64512;
shiftTable[i] = 13;
shiftTable[i | 256] = 13;
}
}
function roundToFloat16Bits(num) {
floatView[0] = roundToFloat16(num);
const f = uint32View[0];
const e = f >> 23 & 511;
return baseTable[e] + ((f & 8388607) >> shiftTable[e]);
}
var mantissaTable = new NativeUint32Array(2048);
for (let i = 1; i < 1024; ++i) {
let m = i << 13;
let e = 0;
while ((m & 8388608) === 0) {
m <<= 1;
e -= 8388608;
}
m &= ~8388608;
e += 947912704;
mantissaTable[i] = m | e;
}
for (let i = 1024; i < 2048; ++i) {
mantissaTable[i] = 939524096 + (i - 1024 << 13);
}
var exponentTable = new NativeUint32Array(64);
for (let i = 1; i < 31; ++i) {
exponentTable[i] = i << 23;
}
exponentTable[31] = 1199570944;
exponentTable[32] = 2147483648;
for (let i = 33; i < 63; ++i) {
exponentTable[i] = 2147483648 + (i - 32 << 23);
}
exponentTable[63] = 3347054592;
var offsetTable = new NativeUint16Array(64);
for (let i = 1; i < 64; ++i) {
if (i !== 32) {
offsetTable[i] = 1024;
}
}
function convertToNumber(float16bits) {
const i = float16bits >> 10;
uint32View[0] = mantissaTable[offsetTable[i] + (float16bits & 1023)] + exponentTable[i];
return floatView[0];
}
// node_modules/@petamoriken/float16/src/_util/spec.mjs
function ToIntegerOrInfinity(target) {
const number = +target;
if (NumberIsNaN(number) || number === 0) {
return 0;
}
return MathTrunc(number);
}
function ToLength(target) {
const length = ToIntegerOrInfinity(target);
if (length < 0) {
return 0;
}
return length < MAX_SAFE_INTEGER ? length : MAX_SAFE_INTEGER;
}
function SpeciesConstructor(target, defaultConstructor) {
if (!isObject(target)) {
throw NativeTypeError(THIS_IS_NOT_AN_OBJECT);
}
const constructor = target.constructor;
if (constructor === void 0) {
return defaultConstructor;
}
if (!isObject(constructor)) {
throw NativeTypeError(THE_CONSTRUCTOR_PROPERTY_VALUE_IS_NOT_AN_OBJECT);
}
const species = constructor[SymbolSpecies];
if (species == null) {
return defaultConstructor;
}
return species;
}
function IsDetachedBuffer(buffer3) {
if (isSharedArrayBuffer(buffer3)) {
return false;
}
try {
ArrayBufferPrototypeSlice(buffer3, 0, 0);
return false;
} catch (e) {
}
return true;
}
function defaultCompare(x, y) {
const isXNaN = NumberIsNaN(x);
const isYNaN = NumberIsNaN(y);
if (isXNaN && isYNaN) {
return 0;
}
if (isXNaN) {
return 1;
}
if (isYNaN) {
return -1;
}
if (x < y) {
return -1;
}
if (x > y) {
return 1;
}
if (x === 0 && y === 0) {
const isXPlusZero = ObjectIs(x, 0);
const isYPlusZero = ObjectIs(y, 0);
if (!isXPlusZero && isYPlusZero) {
return -1;
}
if (isXPlusZero && !isYPlusZero) {
return 1;
}
}
return 0;
}
// node_modules/@petamoriken/float16/src/Float16Array.mjs
var BYTES_PER_ELEMENT = 2;
var float16bitsArrays = new NativeWeakMap();
function isFloat16Array(target) {
return WeakMapPrototypeHas(float16bitsArrays, target) || !ArrayBufferIsView(target) && hasFloat16ArrayBrand(target);
}
function assertFloat16Array(target) {
if (!isFloat16Array(target)) {
throw NativeTypeError(THIS_IS_NOT_A_FLOAT16ARRAY_OBJECT);
}
}
function assertSpeciesTypedArray(target, count) {
const isTargetFloat16Array = isFloat16Array(target);
const isTargetTypedArray = isNativeTypedArray(target);
if (!isTargetFloat16Array && !isTargetTypedArray) {
throw NativeTypeError(SPECIES_CONSTRUCTOR_DIDNT_RETURN_TYPEDARRAY_OBJECT);
}
if (typeof count === "number") {
let length;
if (isTargetFloat16Array) {
const float16bitsArray = getFloat16BitsArray(target);
length = TypedArrayPrototypeGetLength(float16bitsArray);
} else {
length = TypedArrayPrototypeGetLength(target);
}
if (length < count) {
throw NativeTypeError(
DERIVED_CONSTRUCTOR_CREATED_TYPEDARRAY_OBJECT_WHICH_WAS_TOO_SMALL_LENGTH
);
}
}
if (isNativeBigIntTypedArray(target)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
}
}
function getFloat16BitsArray(float16) {
const float16bitsArray = WeakMapPrototypeGet(float16bitsArrays, float16);
if (float16bitsArray !== void 0) {
const buffer4 = TypedArrayPrototypeGetBuffer(float16bitsArray);
if (IsDetachedBuffer(buffer4)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
return float16bitsArray;
}
const buffer3 = (
/** @type {any} */
float16.buffer
);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
const cloned = ReflectConstruct(Float16Array, [
buffer3,
/** @type {any} */
float16.byteOffset,
/** @type {any} */
float16.length
], float16.constructor);
return WeakMapPrototypeGet(float16bitsArrays, cloned);
}
function copyToArray(float16bitsArray) {
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const array = [];
for (let i = 0; i < length; ++i) {
array[i] = convertToNumber(float16bitsArray[i]);
}
return array;
}
var TypedArrayPrototypeGetters = new NativeWeakSet();
for (const key of ReflectOwnKeys(TypedArrayPrototype)) {
if (key === SymbolToStringTag) {
continue;
}
const descriptor = ReflectGetOwnPropertyDescriptor(TypedArrayPrototype, key);
if (ObjectHasOwn(descriptor, "get") && typeof descriptor.get === "function") {
WeakSetPrototypeAdd(TypedArrayPrototypeGetters, descriptor.get);
}
}
var handler = ObjectFreeze(
/** @type {ProxyHandler<Float16BitsArray>} */
{
get(target, key, receiver) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
return convertToNumber(ReflectGet(target, key));
}
if (WeakSetPrototypeHas(TypedArrayPrototypeGetters, ObjectPrototype__lookupGetter__(target, key))) {
return ReflectGet(target, key);
}
return ReflectGet(target, key, receiver);
},
set(target, key, value, receiver) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
return ReflectSet(target, key, roundToFloat16Bits(value));
}
return ReflectSet(target, key, value, receiver);
},
getOwnPropertyDescriptor(target, key) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key)) {
const descriptor = ReflectGetOwnPropertyDescriptor(target, key);
descriptor.value = convertToNumber(descriptor.value);
return descriptor;
}
return ReflectGetOwnPropertyDescriptor(target, key);
},
defineProperty(target, key, descriptor) {
if (isCanonicalIntegerIndexString(key) && ObjectHasOwn(target, key) && ObjectHasOwn(descriptor, "value")) {
descriptor.value = roundToFloat16Bits(descriptor.value);
return ReflectDefineProperty(target, key, descriptor);
}
return ReflectDefineProperty(target, key, descriptor);
}
}
);
var Float16Array = class _Float16Array {
/** @see https://tc39.es/ecma262/#sec-typedarray */
constructor(input, _byteOffset, _length) {
let float16bitsArray;
if (isFloat16Array(input)) {
float16bitsArray = ReflectConstruct(NativeUint16Array, [getFloat16BitsArray(input)], new.target);
} else if (isObject(input) && !isAnyArrayBuffer(input)) {
let list;
let length;
if (isNativeTypedArray(input)) {
list = input;
length = TypedArrayPrototypeGetLength(input);
const buffer3 = TypedArrayPrototypeGetBuffer(input);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(CANNOT_MIX_BIGINT_AND_OTHER_TYPES);
}
const data = new NativeArrayBuffer(
length * BYTES_PER_ELEMENT
);
float16bitsArray = ReflectConstruct(NativeUint16Array, [data], new.target);
} else {
const iterator = input[SymbolIterator];
if (iterator != null && typeof iterator !== "function") {
throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
}
if (iterator != null) {
if (isOrdinaryArray(input)) {
list = input;
length = input.length;
} else {
list = [.../** @type {Iterable<unknown>} */
input];
length = list.length;
}
} else {
list = /** @type {ArrayLike<unknown>} */
input;
length = ToLength(list.length);
}
float16bitsArray = ReflectConstruct(NativeUint16Array, [length], new.target);
}
for (let i = 0; i < length; ++i) {
float16bitsArray[i] = roundToFloat16Bits(list[i]);
}
} else {
float16bitsArray = ReflectConstruct(NativeUint16Array, arguments, new.target);
}
const proxy = (
/** @type {any} */
new NativeProxy(float16bitsArray, handler)
);
WeakMapPrototypeSet(float16bitsArrays, proxy, float16bitsArray);
return proxy;
}
/**
* limitation: `Object.getOwnPropertyNames(Float16Array)` or `Reflect.ownKeys(Float16Array)` include this key
* @see https://tc39.es/ecma262/#sec-%typedarray%.from
*/
static from(src, ...opts) {
const Constructor = this;
if (!ReflectHas(Constructor, brand)) {
throw NativeTypeError(
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
);
}
if (Constructor === _Float16Array) {
if (isFloat16Array(src) && opts.length === 0) {
const float16bitsArray = getFloat16BitsArray(src);
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
return new _Float16Array(
TypedArrayPrototypeGetBuffer(TypedArrayPrototypeSlice(uint16))
);
}
if (opts.length === 0) {
return new _Float16Array(
TypedArrayPrototypeGetBuffer(
Uint16ArrayFrom(src, roundToFloat16Bits)
)
);
}
const mapFunc = opts[0];
const thisArg = opts[1];
return new _Float16Array(
TypedArrayPrototypeGetBuffer(
Uint16ArrayFrom(src, function(val, ...args) {
return roundToFloat16Bits(
ReflectApply(mapFunc, this, [val, ...safeIfNeeded(args)])
);
}, thisArg)
)
);
}
let list;
let length;
const iterator = src[SymbolIterator];
if (iterator != null && typeof iterator !== "function") {
throw NativeTypeError(ITERATOR_PROPERTY_IS_NOT_CALLABLE);
}
if (iterator != null) {
if (isOrdinaryArray(src)) {
list = src;
length = src.length;
} else if (isOrdinaryNativeTypedArray(src)) {
list = src;
length = TypedArrayPrototypeGetLength(src);
} else {
list = [...src];
length = list.length;
}
} else {
if (src == null) {
throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
list = NativeObject(src);
length = ToLength(list.length);
}
const array = new Constructor(length);
if (opts.length === 0) {
for (let i = 0; i < length; ++i) {
array[i] = /** @type {number} */
list[i];
}
} else {
const mapFunc = opts[0];
const thisArg = opts[1];
for (let i = 0; i < length; ++i) {
array[i] = ReflectApply(mapFunc, thisArg, [list[i], i]);
}
}
return array;
}
/**
* limitation: `Object.getOwnPropertyNames(Float16Array)` or `Reflect.ownKeys(Float16Array)` include this key
* @see https://tc39.es/ecma262/#sec-%typedarray%.of
*/
static of(...items) {
const Constructor = this;
if (!ReflectHas(Constructor, brand)) {
throw NativeTypeError(
THIS_CONSTRUCTOR_IS_NOT_A_SUBCLASS_OF_FLOAT16ARRAY
);
}
const length = items.length;
if (Constructor === _Float16Array) {
const proxy = new _Float16Array(length);
const float16bitsArray = getFloat16BitsArray(proxy);
for (let i = 0; i < length; ++i) {
float16bitsArray[i] = roundToFloat16Bits(items[i]);
}
return proxy;
}
const array = new Constructor(length);
for (let i = 0; i < length; ++i) {
array[i] = items[i];
}
return array;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.keys */
keys() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
return TypedArrayPrototypeKeys(float16bitsArray);
}
/**
* limitation: returns a object whose prototype is not `%ArrayIteratorPrototype%`
* @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.values
*/
values() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
return wrap((function* () {
for (const val of TypedArrayPrototypeValues(float16bitsArray)) {
yield convertToNumber(val);
}
})());
}
/**
* limitation: returns a object whose prototype is not `%ArrayIteratorPrototype%`
* @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.entries
*/
entries() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
return wrap((function* () {
for (const [i, val] of TypedArrayPrototypeEntries(float16bitsArray)) {
yield (
/** @type {[number, number]} */
[i, convertToNumber(val)]
);
}
})());
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.at */
at(index) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const relativeIndex = ToIntegerOrInfinity(index);
const k = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
if (k < 0 || k >= length) {
return;
}
return convertToNumber(float16bitsArray[k]);
}
/** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with */
with(index, value) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const relativeIndex = ToIntegerOrInfinity(index);
const k = relativeIndex >= 0 ? relativeIndex : length + relativeIndex;
const number = +value;
if (k < 0 || k >= length) {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
}
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const cloned = new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16)
)
);
const array = getFloat16BitsArray(cloned);
array[k] = roundToFloat16Bits(number);
return cloned;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.map */
map(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
if (Constructor === _Float16Array) {
const proxy = new _Float16Array(length);
const array2 = getFloat16BitsArray(proxy);
for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]);
array2[i] = roundToFloat16Bits(
ReflectApply(callback, thisArg, [val, i, this])
);
}
return proxy;
}
const array = new Constructor(length);
assertSpeciesTypedArray(array, length);
for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]);
array[i] = ReflectApply(callback, thisArg, [val, i, this]);
}
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.filter */
filter(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
const kept = [];
for (let i = 0; i < length; ++i) {
const val = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [val, i, this])) {
ArrayPrototypePush(kept, val);
}
}
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
const array = new Constructor(kept);
assertSpeciesTypedArray(array);
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduce */
reduce(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
if (length === 0 && opts.length === 0) {
throw NativeTypeError(REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE);
}
let accumulator, start;
if (opts.length === 0) {
accumulator = convertToNumber(float16bitsArray[0]);
start = 1;
} else {
accumulator = opts[0];
start = 0;
}
for (let i = start; i < length; ++i) {
accumulator = callback(
accumulator,
convertToNumber(float16bitsArray[i]),
i,
this
);
}
return accumulator;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reduceright */
reduceRight(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
if (length === 0 && opts.length === 0) {
throw NativeTypeError(REDUCE_OF_EMPTY_ARRAY_WITH_NO_INITIAL_VALUE);
}
let accumulator, start;
if (opts.length === 0) {
accumulator = convertToNumber(float16bitsArray[length - 1]);
start = length - 2;
} else {
accumulator = opts[0];
start = length - 1;
}
for (let i = start; i >= 0; --i) {
accumulator = callback(
accumulator,
convertToNumber(float16bitsArray[i]),
i,
this
);
}
return accumulator;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.foreach */
forEach(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this
]);
}
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.find */
find(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return value;
}
}
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.findindex */
findIndex(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlast */
findLast(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = length - 1; i >= 0; --i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return value;
}
}
}
/** @see https://tc39.es/proposal-array-find-from-last/index.html#sec-%typedarray%.prototype.findlastindex */
findLastIndex(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = length - 1; i >= 0; --i) {
const value = convertToNumber(float16bitsArray[i]);
if (ReflectApply(callback, thisArg, [value, i, this])) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.every */
every(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
if (!ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this
])) {
return false;
}
}
return true;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.some */
some(callback, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const thisArg = opts[0];
for (let i = 0; i < length; ++i) {
if (ReflectApply(callback, thisArg, [
convertToNumber(float16bitsArray[i]),
i,
this
])) {
return true;
}
}
return false;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.set */
set(input, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const targetOffset = ToIntegerOrInfinity(opts[0]);
if (targetOffset < 0) {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
}
if (input == null) {
throw NativeTypeError(
CANNOT_CONVERT_UNDEFINED_OR_NULL_TO_OBJECT
);
}
if (isNativeBigIntTypedArray(input)) {
throw NativeTypeError(
CANNOT_MIX_BIGINT_AND_OTHER_TYPES
);
}
if (isFloat16Array(input)) {
return TypedArrayPrototypeSet(
getFloat16BitsArray(this),
getFloat16BitsArray(input),
targetOffset
);
}
if (isNativeTypedArray(input)) {
const buffer3 = TypedArrayPrototypeGetBuffer(input);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
}
const targetLength = TypedArrayPrototypeGetLength(float16bitsArray);
const src = NativeObject(input);
const srcLength = ToLength(src.length);
if (targetOffset === Infinity || srcLength + targetOffset > targetLength) {
throw NativeRangeError(OFFSET_IS_OUT_OF_BOUNDS);
}
for (let i = 0; i < srcLength; ++i) {
float16bitsArray[i + targetOffset] = roundToFloat16Bits(src[i]);
}
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.reverse */
reverse() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeReverse(float16bitsArray);
return this;
}
/** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toReversed */
toReversed() {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const cloned = new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16)
)
);
const clonedFloat16bitsArray = getFloat16BitsArray(cloned);
TypedArrayPrototypeReverse(clonedFloat16bitsArray);
return cloned;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.fill */
fill(value, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeFill(
float16bitsArray,
roundToFloat16Bits(value),
...safeIfNeeded(opts)
);
return this;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.copywithin */
copyWithin(target, start, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
TypedArrayPrototypeCopyWithin(float16bitsArray, target, start, ...safeIfNeeded(opts));
return this;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.sort */
sort(compareFn) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const sortCompare = compareFn !== void 0 ? compareFn : defaultCompare;
TypedArrayPrototypeSort(float16bitsArray, (x, y) => {
return sortCompare(convertToNumber(x), convertToNumber(y));
});
return this;
}
/** @see https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.toSorted */
toSorted(compareFn) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
if (compareFn !== void 0 && typeof compareFn !== "function") {
throw new NativeTypeError(THE_COMPARISON_FUNCTION_MUST_BE_EITHER_A_FUNCTION_OR_UNDEFINED);
}
const sortCompare = compareFn !== void 0 ? compareFn : defaultCompare;
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const cloned = new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16)
)
);
const clonedFloat16bitsArray = getFloat16BitsArray(cloned);
TypedArrayPrototypeSort(clonedFloat16bitsArray, (x, y) => {
return sortCompare(convertToNumber(x), convertToNumber(y));
});
return cloned;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.slice */
slice(start, end) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
if (Constructor === _Float16Array) {
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
return new _Float16Array(
TypedArrayPrototypeGetBuffer(
TypedArrayPrototypeSlice(uint16, start, end)
)
);
}
const length = TypedArrayPrototypeGetLength(float16bitsArray);
const relativeStart = ToIntegerOrInfinity(start);
const relativeEnd = end === void 0 ? length : ToIntegerOrInfinity(end);
let k;
if (relativeStart === -Infinity) {
k = 0;
} else if (relativeStart < 0) {
k = length + relativeStart > 0 ? length + relativeStart : 0;
} else {
k = length < relativeStart ? length : relativeStart;
}
let final;
if (relativeEnd === -Infinity) {
final = 0;
} else if (relativeEnd < 0) {
final = length + relativeEnd > 0 ? length + relativeEnd : 0;
} else {
final = length < relativeEnd ? length : relativeEnd;
}
const count = final - k > 0 ? final - k : 0;
const array = new Constructor(count);
assertSpeciesTypedArray(array, count);
if (count === 0) {
return array;
}
const buffer3 = TypedArrayPrototypeGetBuffer(float16bitsArray);
if (IsDetachedBuffer(buffer3)) {
throw NativeTypeError(ATTEMPTING_TO_ACCESS_DETACHED_ARRAYBUFFER);
}
let n = 0;
while (k < final) {
array[n] = convertToNumber(float16bitsArray[k]);
++k;
++n;
}
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.subarray */
subarray(begin, end) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const Constructor = SpeciesConstructor(float16bitsArray, _Float16Array);
const uint16 = new NativeUint16Array(
TypedArrayPrototypeGetBuffer(float16bitsArray),
TypedArrayPrototypeGetByteOffset(float16bitsArray),
TypedArrayPrototypeGetLength(float16bitsArray)
);
const uint16Subarray = TypedArrayPrototypeSubarray(uint16, begin, end);
const array = new Constructor(
TypedArrayPrototypeGetBuffer(uint16Subarray),
TypedArrayPrototypeGetByteOffset(uint16Subarray),
TypedArrayPrototypeGetLength(uint16Subarray)
);
assertSpeciesTypedArray(array);
return (
/** @type {any} */
array
);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.indexof */
indexOf(element, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
let from = ToIntegerOrInfinity(opts[0]);
if (from === Infinity) {
return -1;
}
if (from < 0) {
from += length;
if (from < 0) {
from = 0;
}
}
for (let i = from; i < length; ++i) {
if (ObjectHasOwn(float16bitsArray, i) && convertToNumber(float16bitsArray[i]) === element) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.lastindexof */
lastIndexOf(element, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
let from = opts.length >= 1 ? ToIntegerOrInfinity(opts[0]) : length - 1;
if (from === -Infinity) {
return -1;
}
if (from >= 0) {
from = from < length - 1 ? from : length - 1;
} else {
from += length;
}
for (let i = from; i >= 0; --i) {
if (ObjectHasOwn(float16bitsArray, i) && convertToNumber(float16bitsArray[i]) === element) {
return i;
}
}
return -1;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.includes */
includes(element, ...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const length = TypedArrayPrototypeGetLength(float16bitsArray);
let from = ToIntegerOrInfinity(opts[0]);
if (from === Infinity) {
return false;
}
if (from < 0) {
from += length;
if (from < 0) {
from = 0;
}
}
const isNaN2 = NumberIsNaN(element);
for (let i = from; i < length; ++i) {
const value = convertToNumber(float16bitsArray[i]);
if (isNaN2 && NumberIsNaN(value)) {
return true;
}
if (value === element) {
return true;
}
}
return false;
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.join */
join(separator) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const array = copyToArray(float16bitsArray);
return ArrayPrototypeJoin(array, separator);
}
/** @see https://tc39.es/ecma262/#sec-%typedarray%.prototype.tolocalestring */
toLocaleString(...opts) {
assertFloat16Array(this);
const float16bitsArray = getFloat16BitsArray(this);
const array = copyToArray(float16bitsArray);
return ArrayPrototypeToLocaleString(array, ...safeIfNeeded(opts));
}
/** @see https://tc39.es/ecma262/#sec-get-%typedarray%.prototype-@@tostringtag */
get [SymbolToStringTag]() {
if (isFloat16Array(this)) {
return (
/** @type {any} */
"Float16Array"
);
}
}
};
ObjectDefineProperty(Float16Array, "BYTES_PER_ELEMENT", {
value: BYTES_PER_ELEMENT
});
ObjectDefineProperty(Float16Array, brand, {});
ReflectSetPrototypeOf(Float16Array, TypedArray);
var Float16ArrayPrototype = Float16Array.prototype;
ObjectDefineProperty(Float16ArrayPrototype, "BYTES_PER_ELEMENT", {
value: BYTES_PER_ELEMENT
});
ObjectDefineProperty(Float16ArrayPrototype, SymbolIterator, {
value: Float16ArrayPrototype.values,
writable: true,
configurable: true
});
ReflectSetPrototypeOf(Float16ArrayPrototype, TypedArrayPrototype);
// node_modules/@petamoriken/float16/src/DataView.mjs
function getFloat16(dataView, byteOffset, ...opts) {
return convertToNumber(
DataViewPrototypeGetUint16(dataView, byteOffset, ...safeIfNeeded(opts))
);
}
// node_modules/geotiff/dist-module/geotiffimage.js
var import_get_attribute = __toESM(require_get_attribute(), 1);
var import_find_tags_by_name = __toESM(require_find_tags_by_name(), 1);
// node_modules/geotiff/dist-module/rgb.js
function fromWhiteIsZero(raster, max) {
const { width, height } = raster;
const rgbRaster = new Uint8Array(width * height * 3);
let value;
for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {
value = 256 - raster[i] / max * 256;
rgbRaster[j] = value;
rgbRaster[j + 1] = value;
rgbRaster[j + 2] = value;
}
return rgbRaster;
}
function fromBlackIsZero(raster, max) {
const { width, height } = raster;
const rgbRaster = new Uint8Array(width * height * 3);
let value;
for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {
value = raster[i] / max * 256;
rgbRaster[j] = value;
rgbRaster[j + 1] = value;
rgbRaster[j + 2] = value;
}
return rgbRaster;
}
function fromPalette(raster, colorMap) {
const { width, height } = raster;
const rgbRaster = new Uint8Array(width * height * 3);
const greenOffset = colorMap.length / 3;
const blueOffset = colorMap.length / 3 * 2;
for (let i = 0, j = 0; i < raster.length; ++i, j += 3) {
const mapIndex = raster[i];
rgbRaster[j] = colorMap[mapIndex] / 65536 * 256;
rgbRaster[j + 1] = colorMap[mapIndex + greenOffset] / 65536 * 256;
rgbRaster[j + 2] = colorMap[mapIndex + blueOffset] / 65536 * 256;
}
return rgbRaster;
}
function fromCMYK(cmykRaster) {
const { width, height } = cmykRaster;
const rgbRaster = new Uint8Array(width * height * 3);
for (let i = 0, j = 0; i < cmykRaster.length; i += 4, j += 3) {
const c = cmykRaster[i];
const m = cmykRaster[i + 1];
const y = cmykRaster[i + 2];
const k = cmykRaster[i + 3];
rgbRaster[j] = 255 * ((255 - c) / 256) * ((255 - k) / 256);
rgbRaster[j + 1] = 255 * ((255 - m) / 256) * ((255 - k) / 256);
rgbRaster[j + 2] = 255 * ((255 - y) / 256) * ((255 - k) / 256);
}
return rgbRaster;
}
function fromYCbCr(yCbCrRaster) {
const { width, height } = yCbCrRaster;
const rgbRaster = new Uint8ClampedArray(width * height * 3);
for (let i = 0, j = 0; i < yCbCrRaster.length; i += 3, j += 3) {
const y = yCbCrRaster[i];
const cb = yCbCrRaster[i + 1];
const cr = yCbCrRaster[i + 2];
rgbRaster[j] = y + 1.402 * (cr - 128);
rgbRaster[j + 1] = y - 0.34414 * (cb - 128) - 0.71414 * (cr - 128);
rgbRaster[j + 2] = y + 1.772 * (cb - 128);
}
return rgbRaster;
}
var Xn = 0.95047;
var Yn = 1;
var Zn = 1.08883;
function fromCIELab(cieLabRaster) {
const { width, height } = cieLabRaster;
const rgbRaster = new Uint8Array(width * height * 3);
for (let i = 0, j = 0; i < cieLabRaster.length; i += 3, j += 3) {
const L = cieLabRaster[i + 0];
const a_ = cieLabRaster[i + 1] << 24 >> 24;
const b_ = cieLabRaster[i + 2] << 24 >> 24;
let y = (L + 16) / 116;
let x = a_ / 500 + y;
let z = y - b_ / 200;
let r;
let g;
let b;
x = Xn * (x * x * x > 8856e-6 ? x * x * x : (x - 16 / 116) / 7.787);
y = Yn * (y * y * y > 8856e-6 ? y * y * y : (y - 16 / 116) / 7.787);
z = Zn * (z * z * z > 8856e-6 ? z * z * z : (z - 16 / 116) / 7.787);
r = x * 3.2406 + y * -1.5372 + z * -0.4986;
g = x * -0.9689 + y * 1.8758 + z * 0.0415;
b = x * 0.0557 + y * -0.204 + z * 1.057;
r = r > 31308e-7 ? 1.055 * r ** (1 / 2.4) - 0.055 : 12.92 * r;
g = g > 31308e-7 ? 1.055 * g ** (1 / 2.4) - 0.055 : 12.92 * g;
b = b > 31308e-7 ? 1.055 * b ** (1 / 2.4) - 0.055 : 12.92 * b;
rgbRaster[j] = Math.max(0, Math.min(1, r)) * 255;
rgbRaster[j + 1] = Math.max(0, Math.min(1, g)) * 255;
rgbRaster[j + 2] = Math.max(0, Math.min(1, b)) * 255;
}
return rgbRaster;
}
// node_modules/geotiff/dist-module/compression/index.js
var registry = /* @__PURE__ */ new Map();
function addDecoder(cases, importFn) {
if (!Array.isArray(cases)) {
cases = [cases];
}
cases.forEach((c) => registry.set(c, importFn));
}
async function getDecoder(fileDirectory) {
const importFn = registry.get(fileDirectory.Compression);
if (!importFn) {
throw new Error(`Unknown compression method identifier: ${fileDirectory.Compression}`);
}
const Decoder = await importFn();
return new Decoder(fileDirectory);
}
addDecoder([void 0, 1], () => import("./raw-UKC26CDE.js").then((m) => m.default));
addDecoder(5, () => import("./lzw-7DRJSDK5.js").then((m) => m.default));
addDecoder(6, () => {
throw new Error("old style JPEG compression is not supported.");
});
addDecoder(7, () => import("./jpeg-HGEGG7HT.js").then((m) => m.default));
addDecoder([8, 32946], () => import("./deflate-IME5YE3D.js").then((m) => m.default));
addDecoder(32773, () => import("./packbits-F6QMWCFA.js").then((m) => m.default));
addDecoder(
34887,
() => import("./lerc-YJMC4I3X.js").then(async (m) => {
await m.zstd.init();
return m;
}).then((m) => m.default)
);
addDecoder(50001, () => import("./webimage-T4PTOJUP.js").then((m) => m.default));
// node_modules/geotiff/dist-module/resample.js
function copyNewSize(array, width, height, samplesPerPixel = 1) {
return new (Object.getPrototypeOf(array)).constructor(width * height * samplesPerPixel);
}
function resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
return valueArrays.map((array) => {
const newArray = copyNewSize(array, outWidth, outHeight);
for (let y = 0; y < outHeight; ++y) {
const cy = Math.min(Math.round(relY * y), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const cx = Math.min(Math.round(relX * x), inWidth - 1);
const value = array[cy * inWidth + cx];
newArray[y * outWidth + x] = value;
}
}
return newArray;
});
}
function lerp(v0, v1, t) {
return (1 - t) * v0 + t * v1;
}
function resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
return valueArrays.map((array) => {
const newArray = copyNewSize(array, outWidth, outHeight);
for (let y = 0; y < outHeight; ++y) {
const rawY = relY * y;
const yl = Math.floor(rawY);
const yh = Math.min(Math.ceil(rawY), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const rawX = relX * x;
const tx = rawX % 1;
const xl = Math.floor(rawX);
const xh = Math.min(Math.ceil(rawX), inWidth - 1);
const ll = array[yl * inWidth + xl];
const hl = array[yl * inWidth + xh];
const lh = array[yh * inWidth + xl];
const hh = array[yh * inWidth + xh];
const value = lerp(
lerp(ll, hl, tx),
lerp(lh, hh, tx),
rawY % 1
);
newArray[y * outWidth + x] = value;
}
}
return newArray;
});
}
function resample(valueArrays, inWidth, inHeight, outWidth, outHeight, method = "nearest") {
switch (method.toLowerCase()) {
case "nearest":
return resampleNearest(valueArrays, inWidth, inHeight, outWidth, outHeight);
case "bilinear":
case "linear":
return resampleBilinear(valueArrays, inWidth, inHeight, outWidth, outHeight);
default:
throw new Error(`Unsupported resampling method: '${method}'`);
}
}
function resampleNearestInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
const newArray = copyNewSize(valueArray, outWidth, outHeight, samples);
for (let y = 0; y < outHeight; ++y) {
const cy = Math.min(Math.round(relY * y), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const cx = Math.min(Math.round(relX * x), inWidth - 1);
for (let i = 0; i < samples; ++i) {
const value = valueArray[cy * inWidth * samples + cx * samples + i];
newArray[y * outWidth * samples + x * samples + i] = value;
}
}
}
return newArray;
}
function resampleBilinearInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples) {
const relX = inWidth / outWidth;
const relY = inHeight / outHeight;
const newArray = copyNewSize(valueArray, outWidth, outHeight, samples);
for (let y = 0; y < outHeight; ++y) {
const rawY = relY * y;
const yl = Math.floor(rawY);
const yh = Math.min(Math.ceil(rawY), inHeight - 1);
for (let x = 0; x < outWidth; ++x) {
const rawX = relX * x;
const tx = rawX % 1;
const xl = Math.floor(rawX);
const xh = Math.min(Math.ceil(rawX), inWidth - 1);
for (let i = 0; i < samples; ++i) {
const ll = valueArray[yl * inWidth * samples + xl * samples + i];
const hl = valueArray[yl * inWidth * samples + xh * samples + i];
const lh = valueArray[yh * inWidth * samples + xl * samples + i];
const hh = valueArray[yh * inWidth * samples + xh * samples + i];
const value = lerp(
lerp(ll, hl, tx),
lerp(lh, hh, tx),
rawY % 1
);
newArray[y * outWidth * samples + x * samples + i] = value;
}
}
}
return newArray;
}
function resampleInterleaved(valueArray, inWidth, inHeight, outWidth, outHeight, samples, method = "nearest") {
switch (method.toLowerCase()) {
case "nearest":
return resampleNearestInterleaved(
valueArray,
inWidth,
inHeight,
outWidth,
outHeight,
samples
);
case "bilinear":
case "linear":
return resampleBilinearInterleaved(
valueArray,
inWidth,
inHeight,
outWidth,
outHeight,
samples
);
default:
throw new Error(`Unsupported resampling method: '${method}'`);
}
}
// node_modules/geotiff/dist-module/geotiffimage.js
function sum(array, start, end) {
let s = 0;
for (let i = start; i < end; ++i) {
s += array[i];
}
return s;
}
function arrayForType(format, bitsPerSample, size) {
switch (format) {
case 1:
if (bitsPerSample <= 8) {
return new Uint8Array(size);
} else if (bitsPerSample <= 16) {
return new Uint16Array(size);
} else if (bitsPerSample <= 32) {
return new Uint32Array(size);
}
break;
case 2:
if (bitsPerSample === 8) {
return new Int8Array(size);
} else if (bitsPerSample === 16) {
return new Int16Array(size);
} else if (bitsPerSample === 32) {
return new Int32Array(size);
}
break;
case 3:
switch (bitsPerSample) {
case 16:
case 32:
return new Float32Array(size);
case 64:
return new Float64Array(size);
default:
break;
}
break;
default:
break;
}
throw Error("Unsupported data format/bitsPerSample");
}
function needsNormalization(format, bitsPerSample) {
if ((format === 1 || format === 2) && bitsPerSample <= 32 && bitsPerSample % 8 === 0) {
return false;
} else if (format === 3 && (bitsPerSample === 16 || bitsPerSample === 32 || bitsPerSample === 64)) {
return false;
}
return true;
}
function normalizeArray(inBuffer, format, planarConfiguration, samplesPerPixel, bitsPerSample, tileWidth, tileHeight) {
const view = new DataView(inBuffer);
const outSize = planarConfiguration === 2 ? tileHeight * tileWidth : tileHeight * tileWidth * samplesPerPixel;
const samplesToTransfer = planarConfiguration === 2 ? 1 : samplesPerPixel;
const outArray = arrayForType(format, bitsPerSample, outSize);
const bitMask = parseInt("1".repeat(bitsPerSample), 2);
if (format === 1) {
let pixelBitSkip;
if (planarConfiguration === 1) {
pixelBitSkip = samplesPerPixel * bitsPerSample;
} else {
pixelBitSkip = bitsPerSample;
}
let bitsPerLine = tileWidth * pixelBitSkip;
if ((bitsPerLine & 7) !== 0) {
bitsPerLine = bitsPerLine + 7 & ~7;
}
for (let y = 0; y < tileHeight; ++y) {
const lineBitOffset = y * bitsPerLine;
for (let x = 0; x < tileWidth; ++x) {
const pixelBitOffset = lineBitOffset + x * samplesToTransfer * bitsPerSample;
for (let i = 0; i < samplesToTransfer; ++i) {
const bitOffset = pixelBitOffset + i * bitsPerSample;
const outIndex = (y * tileWidth + x) * samplesToTransfer + i;
const byteOffset = Math.floor(bitOffset / 8);
const innerBitOffset = bitOffset % 8;
if (innerBitOffset + bitsPerSample <= 8) {
outArray[outIndex] = view.getUint8(byteOffset) >> 8 - bitsPerSample - innerBitOffset & bitMask;
} else if (innerBitOffset + bitsPerSample <= 16) {
outArray[outIndex] = view.getUint16(byteOffset) >> 16 - bitsPerSample - innerBitOffset & bitMask;
} else if (innerBitOffset + bitsPerSample <= 24) {
const raw = view.getUint16(byteOffset) << 8 | view.getUint8(byteOffset + 2);
outArray[outIndex] = raw >> 24 - bitsPerSample - innerBitOffset & bitMask;
} else {
outArray[outIndex] = view.getUint32(byteOffset) >> 32 - bitsPerSample - innerBitOffset & bitMask;
}
}
}
}
} else if (format === 3) {
}
return outArray.buffer;
}
var GeoTIFFImage = class {
/**
* @constructor
* @param {Object} fileDirectory The parsed file directory
* @param {Object} geoKeys The parsed geo-keys
* @param {DataView} dataView The DataView for the underlying file.
* @param {Boolean} littleEndian Whether the file is encoded in little or big endian
* @param {Boolean} cache Whether or not decoded tiles shall be cached
* @param {import('./source/basesource').BaseSource} source The datasource to read from
*/
constructor(fileDirectory, geoKeys, dataView, littleEndian, cache, source) {
this.fileDirectory = fileDirectory;
this.geoKeys = geoKeys;
this.dataView = dataView;
this.littleEndian = littleEndian;
this.tiles = cache ? {} : null;
this.isTiled = !fileDirectory.StripOffsets;
const planarConfiguration = fileDirectory.PlanarConfiguration;
this.planarConfiguration = typeof planarConfiguration === "undefined" ? 1 : planarConfiguration;
if (this.planarConfiguration !== 1 && this.planarConfiguration !== 2) {
throw new Error("Invalid planar configuration.");
}
this.source = source;
}
/**
* Returns the associated parsed file directory.
* @returns {Object} the parsed file directory
*/
getFileDirectory() {
return this.fileDirectory;
}
/**
* Returns the associated parsed geo keys.
* @returns {Object} the parsed geo keys
*/
getGeoKeys() {
return this.geoKeys;
}
/**
* Returns the width of the image.
* @returns {Number} the width of the image
*/
getWidth() {
return this.fileDirectory.ImageWidth;
}
/**
* Returns the height of the image.
* @returns {Number} the height of the image
*/
getHeight() {
return this.fileDirectory.ImageLength;
}
/**
* Returns the number of samples per pixel.
* @returns {Number} the number of samples per pixel
*/
getSamplesPerPixel() {
return typeof this.fileDirectory.SamplesPerPixel !== "undefined" ? this.fileDirectory.SamplesPerPixel : 1;
}
/**
* Returns the width of each tile.
* @returns {Number} the width of each tile
*/
getTileWidth() {
return this.isTiled ? this.fileDirectory.TileWidth : this.getWidth();
}
/**
* Returns the height of each tile.
* @returns {Number} the height of each tile
*/
getTileHeight() {
if (this.isTiled) {
return this.fileDirectory.TileLength;
}
if (typeof this.fileDirectory.RowsPerStrip !== "undefined") {
return Math.min(this.fileDirectory.RowsPerStrip, this.getHeight());
}
return this.getHeight();
}
getBlockWidth() {
return this.getTileWidth();
}
getBlockHeight(y) {
if (this.isTiled || (y + 1) * this.getTileHeight() <= this.getHeight()) {
return this.getTileHeight();
} else {
return this.getHeight() - y * this.getTileHeight();
}
}
/**
* Calculates the number of bytes for each pixel across all samples. Only full
* bytes are supported, an exception is thrown when this is not the case.
* @returns {Number} the bytes per pixel
*/
getBytesPerPixel() {
let bytes = 0;
for (let i = 0; i < this.fileDirectory.BitsPerSample.length; ++i) {
bytes += this.getSampleByteSize(i);
}
return bytes;
}
getSampleByteSize(i) {
if (i >= this.fileDirectory.BitsPerSample.length) {
throw new RangeError(`Sample index ${i} is out of range.`);
}
return Math.ceil(this.fileDirectory.BitsPerSample[i] / 8);
}
getReaderForSample(sampleIndex) {
const format = this.fileDirectory.SampleFormat ? this.fileDirectory.SampleFormat[sampleIndex] : 1;
const bitsPerSample = this.fileDirectory.BitsPerSample[sampleIndex];
switch (format) {
case 1:
if (bitsPerSample <= 8) {
return DataView.prototype.getUint8;
} else if (bitsPerSample <= 16) {
return DataView.prototype.getUint16;
} else if (bitsPerSample <= 32) {
return DataView.prototype.getUint32;
}
break;
case 2:
if (bitsPerSample <= 8) {
return DataView.prototype.getInt8;
} else if (bitsPerSample <= 16) {
return DataView.prototype.getInt16;
} else if (bitsPerSample <= 32) {
return DataView.prototype.getInt32;
}
break;
case 3:
switch (bitsPerSample) {
case 16:
return function(offset, littleEndian) {
return getFloat16(this, offset, littleEndian);
};
case 32:
return DataView.prototype.getFloat32;
case 64:
return DataView.prototype.getFloat64;
default:
break;
}
break;
default:
break;
}
throw Error("Unsupported data format/bitsPerSample");
}
getSampleFormat(sampleIndex = 0) {
return this.fileDirectory.SampleFormat ? this.fileDirectory.SampleFormat[sampleIndex] : 1;
}
getBitsPerSample(sampleIndex = 0) {
return this.fileDirectory.BitsPerSample[sampleIndex];
}
getArrayForSample(sampleIndex, size) {
const format = this.getSampleFormat(sampleIndex);
const bitsPerSample = this.getBitsPerSample(sampleIndex);
return arrayForType(format, bitsPerSample, size);
}
/**
* Returns the decoded strip or tile.
* @param {Number} x the strip or tile x-offset
* @param {Number} y the tile y-offset (0 for stripped images)
* @param {Number} sample the sample to get for separated samples
* @param {import("./geotiff").Pool|import("./geotiff").BaseDecoder} poolOrDecoder the decoder or decoder pool
* @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
* to be aborted
* @returns {Promise.<ArrayBuffer>}
*/
async getTileOrStrip(x, y, sample, poolOrDecoder, signal) {
const numTilesPerRow = Math.ceil(this.getWidth() / this.getTileWidth());
const numTilesPerCol = Math.ceil(this.getHeight() / this.getTileHeight());
let index;
const { tiles } = this;
if (this.planarConfiguration === 1) {
index = y * numTilesPerRow + x;
} else if (this.planarConfiguration === 2) {
index = sample * numTilesPerRow * numTilesPerCol + y * numTilesPerRow + x;
}
let offset;
let byteCount;
if (this.isTiled) {
offset = this.fileDirectory.TileOffsets[index];
byteCount = this.fileDirectory.TileByteCounts[index];
} else {
offset = this.fileDirectory.StripOffsets[index];
byteCount = this.fileDirectory.StripByteCounts[index];
}
const slice = (await this.source.fetch([{ offset, length: byteCount }], signal))[0];
let request;
if (tiles === null || !tiles[index]) {
request = (async () => {
let data = await poolOrDecoder.decode(this.fileDirectory, slice);
const sampleFormat = this.getSampleFormat();
const bitsPerSample = this.getBitsPerSample();
if (needsNormalization(sampleFormat, bitsPerSample)) {
data = normalizeArray(
data,
sampleFormat,
this.planarConfiguration,
this.getSamplesPerPixel(),
bitsPerSample,
this.getTileWidth(),
this.getBlockHeight(y)
);
}
return data;
})();
if (tiles !== null) {
tiles[index] = request;
}
} else {
request = tiles[index];
}
return { x, y, sample, data: await request };
}
/**
* Internal read function.
* @private
* @param {Array} imageWindow The image window in pixel coordinates
* @param {Array} samples The selected samples (0-based indices)
* @param {TypedArray|TypedArray[]} valueArrays The array(s) to write into
* @param {Boolean} interleave Whether or not to write in an interleaved manner
* @param {import("./geotiff").Pool|AbstractDecoder} poolOrDecoder the decoder or decoder pool
* @param {number} width the width of window to be read into
* @param {number} height the height of window to be read into
* @param {number} resampleMethod the resampling method to be used when interpolating
* @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
* to be aborted
* @returns {Promise<ReadRasterResult>}
*/
async _readRaster(imageWindow, samples, valueArrays, interleave, poolOrDecoder, width, height, resampleMethod, signal) {
const tileWidth = this.getTileWidth();
const tileHeight = this.getTileHeight();
const imageWidth = this.getWidth();
const imageHeight = this.getHeight();
const minXTile = Math.max(Math.floor(imageWindow[0] / tileWidth), 0);
const maxXTile = Math.min(
Math.ceil(imageWindow[2] / tileWidth),
Math.ceil(imageWidth / tileWidth)
);
const minYTile = Math.max(Math.floor(imageWindow[1] / tileHeight), 0);
const maxYTile = Math.min(
Math.ceil(imageWindow[3] / tileHeight),
Math.ceil(imageHeight / tileHeight)
);
const windowWidth = imageWindow[2] - imageWindow[0];
let bytesPerPixel = this.getBytesPerPixel();
const srcSampleOffsets = [];
const sampleReaders = [];
for (let i = 0; i < samples.length; ++i) {
if (this.planarConfiguration === 1) {
srcSampleOffsets.push(sum(this.fileDirectory.BitsPerSample, 0, samples[i]) / 8);
} else {
srcSampleOffsets.push(0);
}
sampleReaders.push(this.getReaderForSample(samples[i]));
}
const promises = [];
const { littleEndian } = this;
for (let yTile = minYTile; yTile < maxYTile; ++yTile) {
for (let xTile = minXTile; xTile < maxXTile; ++xTile) {
let getPromise;
if (this.planarConfiguration === 1) {
getPromise = this.getTileOrStrip(xTile, yTile, 0, poolOrDecoder, signal);
}
for (let sampleIndex = 0; sampleIndex < samples.length; ++sampleIndex) {
const si = sampleIndex;
const sample = samples[sampleIndex];
if (this.planarConfiguration === 2) {
bytesPerPixel = this.getSampleByteSize(sample);
getPromise = this.getTileOrStrip(xTile, yTile, sample, poolOrDecoder, signal);
}
const promise = getPromise.then((tile) => {
const buffer3 = tile.data;
const dataView = new DataView(buffer3);
const blockHeight = this.getBlockHeight(tile.y);
const firstLine = tile.y * tileHeight;
const firstCol = tile.x * tileWidth;
const lastLine = firstLine + blockHeight;
const lastCol = (tile.x + 1) * tileWidth;
const reader = sampleReaders[si];
const ymax = Math.min(blockHeight, blockHeight - (lastLine - imageWindow[3]), imageHeight - firstLine);
const xmax = Math.min(tileWidth, tileWidth - (lastCol - imageWindow[2]), imageWidth - firstCol);
for (let y = Math.max(0, imageWindow[1] - firstLine); y < ymax; ++y) {
for (let x = Math.max(0, imageWindow[0] - firstCol); x < xmax; ++x) {
const pixelOffset = (y * tileWidth + x) * bytesPerPixel;
const value = reader.call(
dataView,
pixelOffset + srcSampleOffsets[si],
littleEndian
);
let windowCoordinate;
if (interleave) {
windowCoordinate = (y + firstLine - imageWindow[1]) * windowWidth * samples.length + (x + firstCol - imageWindow[0]) * samples.length + si;
valueArrays[windowCoordinate] = value;
} else {
windowCoordinate = (y + firstLine - imageWindow[1]) * windowWidth + x + firstCol - imageWindow[0];
valueArrays[si][windowCoordinate] = value;
}
}
}
});
promises.push(promise);
}
}
}
await Promise.all(promises);
if (width && imageWindow[2] - imageWindow[0] !== width || height && imageWindow[3] - imageWindow[1] !== height) {
let resampled;
if (interleave) {
resampled = resampleInterleaved(
valueArrays,
imageWindow[2] - imageWindow[0],
imageWindow[3] - imageWindow[1],
width,
height,
samples.length,
resampleMethod
);
} else {
resampled = resample(
valueArrays,
imageWindow[2] - imageWindow[0],
imageWindow[3] - imageWindow[1],
width,
height,
resampleMethod
);
}
resampled.width = width;
resampled.height = height;
return resampled;
}
valueArrays.width = width || imageWindow[2] - imageWindow[0];
valueArrays.height = height || imageWindow[3] - imageWindow[1];
return valueArrays;
}
/**
* Reads raster data from the image. This function reads all selected samples
* into separate arrays of the correct type for that sample or into a single
* combined array when `interleave` is set. When provided, only a subset
* of the raster is read for each sample.
*
* @param {ReadRasterOptions} [options={}] optional parameters
* @returns {Promise<ReadRasterResult>} the decoded arrays as a promise
*/
async readRasters({
window: wnd,
samples = [],
interleave,
pool = null,
width,
height,
resampleMethod,
fillValue,
signal
} = {}) {
const imageWindow = wnd || [0, 0, this.getWidth(), this.getHeight()];
if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
throw new Error("Invalid subsets");
}
const imageWindowWidth = imageWindow[2] - imageWindow[0];
const imageWindowHeight = imageWindow[3] - imageWindow[1];
const numPixels = imageWindowWidth * imageWindowHeight;
const samplesPerPixel = this.getSamplesPerPixel();
if (!samples || !samples.length) {
for (let i = 0; i < samplesPerPixel; ++i) {
samples.push(i);
}
} else {
for (let i = 0; i < samples.length; ++i) {
if (samples[i] >= samplesPerPixel) {
return Promise.reject(new RangeError(`Invalid sample index '${samples[i]}'.`));
}
}
}
let valueArrays;
if (interleave) {
const format = this.fileDirectory.SampleFormat ? Math.max.apply(null, this.fileDirectory.SampleFormat) : 1;
const bitsPerSample = Math.max.apply(null, this.fileDirectory.BitsPerSample);
valueArrays = arrayForType(format, bitsPerSample, numPixels * samples.length);
if (fillValue) {
valueArrays.fill(fillValue);
}
} else {
valueArrays = [];
for (let i = 0; i < samples.length; ++i) {
const valueArray = this.getArrayForSample(samples[i], numPixels);
if (Array.isArray(fillValue) && i < fillValue.length) {
valueArray.fill(fillValue[i]);
} else if (fillValue && !Array.isArray(fillValue)) {
valueArray.fill(fillValue);
}
valueArrays.push(valueArray);
}
}
const poolOrDecoder = pool || await getDecoder(this.fileDirectory);
const result = await this._readRaster(
imageWindow,
samples,
valueArrays,
interleave,
poolOrDecoder,
width,
height,
resampleMethod,
signal
);
return result;
}
/**
* Reads raster data from the image as RGB. The result is always an
* interleaved typed array.
* Colorspaces other than RGB will be transformed to RGB, color maps expanded.
* When no other method is applicable, the first sample is used to produce a
* grayscale image.
* When provided, only a subset of the raster is read for each sample.
*
* @param {Object} [options] optional parameters
* @param {Array<number>} [options.window] the subset to read data from in pixels.
* @param {boolean} [options.interleave=true] whether the data shall be read
* in one single array or separate
* arrays.
* @param {import("./geotiff").Pool} [options.pool=null] The optional decoder pool to use.
* @param {number} [options.width] The desired width of the output. When the width is no the
* same as the images, resampling will be performed.
* @param {number} [options.height] The desired height of the output. When the width is no the
* same as the images, resampling will be performed.
* @param {string} [options.resampleMethod='nearest'] The desired resampling method.
* @param {boolean} [options.enableAlpha=false] Enable reading alpha channel if present.
* @param {AbortSignal} [options.signal] An AbortSignal that may be signalled if the request is
* to be aborted
* @returns {Promise<ReadRasterResult>} the RGB array as a Promise
*/
async readRGB({
window: window2,
interleave = true,
pool = null,
width,
height,
resampleMethod,
enableAlpha = false,
signal
} = {}) {
const imageWindow = window2 || [0, 0, this.getWidth(), this.getHeight()];
if (imageWindow[0] > imageWindow[2] || imageWindow[1] > imageWindow[3]) {
throw new Error("Invalid subsets");
}
const pi = this.fileDirectory.PhotometricInterpretation;
if (pi === photometricInterpretations.RGB) {
let s = [0, 1, 2];
if (!(this.fileDirectory.ExtraSamples === ExtraSamplesValues.Unspecified) && enableAlpha) {
s = [];
for (let i = 0; i < this.fileDirectory.BitsPerSample.length; i += 1) {
s.push(i);
}
}
return this.readRasters({
window: window2,
interleave,
samples: s,
pool,
width,
height,
resampleMethod,
signal
});
}
let samples;
switch (pi) {
case photometricInterpretations.WhiteIsZero:
case photometricInterpretations.BlackIsZero:
case photometricInterpretations.Palette:
samples = [0];
break;
case photometricInterpretations.CMYK:
samples = [0, 1, 2, 3];
break;
case photometricInterpretations.YCbCr:
case photometricInterpretations.CIELab:
samples = [0, 1, 2];
break;
default:
throw new Error("Invalid or unsupported photometric interpretation.");
}
const subOptions = {
window: imageWindow,
interleave: true,
samples,
pool,
width,
height,
resampleMethod,
signal
};
const { fileDirectory } = this;
const raster = await this.readRasters(subOptions);
const max = 2 ** this.fileDirectory.BitsPerSample[0];
let data;
switch (pi) {
case photometricInterpretations.WhiteIsZero:
data = fromWhiteIsZero(raster, max);
break;
case photometricInterpretations.BlackIsZero:
data = fromBlackIsZero(raster, max);
break;
case photometricInterpretations.Palette:
data = fromPalette(raster, fileDirectory.ColorMap);
break;
case photometricInterpretations.CMYK:
data = fromCMYK(raster);
break;
case photometricInterpretations.YCbCr:
data = fromYCbCr(raster);
break;
case photometricInterpretations.CIELab:
data = fromCIELab(raster);
break;
default:
throw new Error("Unsupported photometric interpretation.");
}
if (!interleave) {
const red = new Uint8Array(data.length / 3);
const green = new Uint8Array(data.length / 3);
const blue = new Uint8Array(data.length / 3);
for (let i = 0, j = 0; i < data.length; i += 3, ++j) {
red[j] = data[i];
green[j] = data[i + 1];
blue[j] = data[i + 2];
}
data = [red, green, blue];
}
data.width = raster.width;
data.height = raster.height;
return data;
}
/**
* Returns an array of tiepoints.
* @returns {Object[]}
*/
getTiePoints() {
if (!this.fileDirectory.ModelTiepoint) {
return [];
}
const tiePoints = [];
for (let i = 0; i < this.fileDirectory.ModelTiepoint.length; i += 6) {
tiePoints.push({
i: this.fileDirectory.ModelTiepoint[i],
j: this.fileDirectory.ModelTiepoint[i + 1],
k: this.fileDirectory.ModelTiepoint[i + 2],
x: this.fileDirectory.ModelTiepoint[i + 3],
y: this.fileDirectory.ModelTiepoint[i + 4],
z: this.fileDirectory.ModelTiepoint[i + 5]
});
}
return tiePoints;
}
/**
* Returns the parsed GDAL metadata items.
*
* If sample is passed to null, dataset-level metadata will be returned.
* Otherwise only metadata specific to the provided sample will be returned.
*
* @param {number} [sample=null] The sample index.
* @returns {Object}
*/
getGDALMetadata(sample = null) {
const metadata = {};
if (!this.fileDirectory.GDAL_METADATA) {
return null;
}
const string = this.fileDirectory.GDAL_METADATA;
let items = (0, import_find_tags_by_name.default)(string, "Item");
if (sample === null) {
items = items.filter((item) => (0, import_get_attribute.default)(item, "sample") === void 0);
} else {
items = items.filter((item) => Number((0, import_get_attribute.default)(item, "sample")) === sample);
}
for (let i = 0; i < items.length; ++i) {
const item = items[i];
metadata[(0, import_get_attribute.default)(item, "name")] = item.inner;
}
return metadata;
}
/**
* Returns the GDAL nodata value
* @returns {number|null}
*/
getGDALNoData() {
if (!this.fileDirectory.GDAL_NODATA) {
return null;
}
const string = this.fileDirectory.GDAL_NODATA;
return Number(string.substring(0, string.length - 1));
}
/**
* Returns the image origin as a XYZ-vector. When the image has no affine
* transformation, then an exception is thrown.
* @returns {Array<number>} The origin as a vector
*/
getOrigin() {
const tiePoints = this.fileDirectory.ModelTiepoint;
const modelTransformation = this.fileDirectory.ModelTransformation;
if (tiePoints && tiePoints.length === 6) {
return [
tiePoints[3],
tiePoints[4],
tiePoints[5]
];
}
if (modelTransformation) {
return [
modelTransformation[3],
modelTransformation[7],
modelTransformation[11]
];
}
throw new Error("The image does not have an affine transformation.");
}
/**
* Returns the image resolution as a XYZ-vector. When the image has no affine
* transformation, then an exception is thrown.
* @param {GeoTIFFImage} [referenceImage=null] A reference image to calculate the resolution from
* in cases when the current image does not have the
* required tags on its own.
* @returns {Array<number>} The resolution as a vector
*/
getResolution(referenceImage = null) {
const modelPixelScale = this.fileDirectory.ModelPixelScale;
const modelTransformation = this.fileDirectory.ModelTransformation;
if (modelPixelScale) {
return [
modelPixelScale[0],
-modelPixelScale[1],
modelPixelScale[2]
];
}
if (modelTransformation) {
if (modelTransformation[1] === 0 && modelTransformation[4] === 0) {
return [
modelTransformation[0],
-modelTransformation[5],
modelTransformation[10]
];
}
return [
Math.sqrt(modelTransformation[0] * modelTransformation[0] + modelTransformation[4] * modelTransformation[4]),
-Math.sqrt(modelTransformation[1] * modelTransformation[1] + modelTransformation[5] * modelTransformation[5]),
modelTransformation[10]
];
}
if (referenceImage) {
const [refResX, refResY, refResZ] = referenceImage.getResolution();
return [
refResX * referenceImage.getWidth() / this.getWidth(),
refResY * referenceImage.getHeight() / this.getHeight(),
refResZ * referenceImage.getWidth() / this.getWidth()
];
}
throw new Error("The image does not have an affine transformation.");
}
/**
* Returns whether or not the pixels of the image depict an area (or point).
* @returns {Boolean} Whether the pixels are a point
*/
pixelIsArea() {
return this.geoKeys.GTRasterTypeGeoKey === 1;
}
/**
* Returns the image bounding box as an array of 4 values: min-x, min-y,
* max-x and max-y. When the image has no affine transformation, then an
* exception is thrown.
* @param {boolean} [tilegrid=false] If true return extent for a tilegrid
* without adjustment for ModelTransformation.
* @returns {Array<number>} The bounding box
*/
getBoundingBox(tilegrid = false) {
const height = this.getHeight();
const width = this.getWidth();
if (this.fileDirectory.ModelTransformation && !tilegrid) {
const [a, b, c, d, e, f, g, h] = this.fileDirectory.ModelTransformation;
const corners = [
[0, 0],
[0, height],
[width, 0],
[width, height]
];
const projected = corners.map(([I, J]) => [
d + a * I + b * J,
h + e * I + f * J
]);
const xs = projected.map((pt) => pt[0]);
const ys = projected.map((pt) => pt[1]);
return [
Math.min(...xs),
Math.min(...ys),
Math.max(...xs),
Math.max(...ys)
];
} else {
const origin = this.getOrigin();
const resolution = this.getResolution();
const x1 = origin[0];
const y1 = origin[1];
const x2 = x1 + resolution[0] * width;
const y2 = y1 + resolution[1] * height;
return [
Math.min(x1, x2),
Math.min(y1, y2),
Math.max(x1, x2),
Math.max(y1, y2)
];
}
}
};
var geotiffimage_default = GeoTIFFImage;
// node_modules/geotiff/dist-module/dataview64.js
var DataView64 = class {
constructor(arrayBuffer) {
this._dataView = new DataView(arrayBuffer);
}
get buffer() {
return this._dataView.buffer;
}
getUint64(offset, littleEndian) {
const left = this.getUint32(offset, littleEndian);
const right = this.getUint32(offset + 4, littleEndian);
let combined;
if (littleEndian) {
combined = left + 2 ** 32 * right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
combined = 2 ** 32 * left + right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
// adapted from https://stackoverflow.com/a/55338384/8060591
getInt64(offset, littleEndian) {
let value = 0;
const isNegative = (this._dataView.getUint8(offset + (littleEndian ? 7 : 0)) & 128) > 0;
let carrying = true;
for (let i = 0; i < 8; i++) {
let byte = this._dataView.getUint8(offset + (littleEndian ? i : 7 - i));
if (isNegative) {
if (carrying) {
if (byte !== 0) {
byte = ~(byte - 1) & 255;
carrying = false;
}
} else {
byte = ~byte & 255;
}
}
value += byte * 256 ** i;
}
if (isNegative) {
value = -value;
}
return value;
}
getUint8(offset, littleEndian) {
return this._dataView.getUint8(offset, littleEndian);
}
getInt8(offset, littleEndian) {
return this._dataView.getInt8(offset, littleEndian);
}
getUint16(offset, littleEndian) {
return this._dataView.getUint16(offset, littleEndian);
}
getInt16(offset, littleEndian) {
return this._dataView.getInt16(offset, littleEndian);
}
getUint32(offset, littleEndian) {
return this._dataView.getUint32(offset, littleEndian);
}
getInt32(offset, littleEndian) {
return this._dataView.getInt32(offset, littleEndian);
}
getFloat16(offset, littleEndian) {
return getFloat16(this._dataView, offset, littleEndian);
}
getFloat32(offset, littleEndian) {
return this._dataView.getFloat32(offset, littleEndian);
}
getFloat64(offset, littleEndian) {
return this._dataView.getFloat64(offset, littleEndian);
}
};
// node_modules/geotiff/dist-module/dataslice.js
var DataSlice = class {
constructor(arrayBuffer, sliceOffset, littleEndian, bigTiff) {
this._dataView = new DataView(arrayBuffer);
this._sliceOffset = sliceOffset;
this._littleEndian = littleEndian;
this._bigTiff = bigTiff;
}
get sliceOffset() {
return this._sliceOffset;
}
get sliceTop() {
return this._sliceOffset + this.buffer.byteLength;
}
get littleEndian() {
return this._littleEndian;
}
get bigTiff() {
return this._bigTiff;
}
get buffer() {
return this._dataView.buffer;
}
covers(offset, length) {
return this.sliceOffset <= offset && this.sliceTop >= offset + length;
}
readUint8(offset) {
return this._dataView.getUint8(
offset - this._sliceOffset,
this._littleEndian
);
}
readInt8(offset) {
return this._dataView.getInt8(
offset - this._sliceOffset,
this._littleEndian
);
}
readUint16(offset) {
return this._dataView.getUint16(
offset - this._sliceOffset,
this._littleEndian
);
}
readInt16(offset) {
return this._dataView.getInt16(
offset - this._sliceOffset,
this._littleEndian
);
}
readUint32(offset) {
return this._dataView.getUint32(
offset - this._sliceOffset,
this._littleEndian
);
}
readInt32(offset) {
return this._dataView.getInt32(
offset - this._sliceOffset,
this._littleEndian
);
}
readFloat32(offset) {
return this._dataView.getFloat32(
offset - this._sliceOffset,
this._littleEndian
);
}
readFloat64(offset) {
return this._dataView.getFloat64(
offset - this._sliceOffset,
this._littleEndian
);
}
readUint64(offset) {
const left = this.readUint32(offset);
const right = this.readUint32(offset + 4);
let combined;
if (this._littleEndian) {
combined = left + 2 ** 32 * right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
combined = 2 ** 32 * left + right;
if (!Number.isSafeInteger(combined)) {
throw new Error(
`${combined} exceeds MAX_SAFE_INTEGER. Precision may be lost. Please report if you get this message to https://github.com/geotiffjs/geotiff.js/issues`
);
}
return combined;
}
// adapted from https://stackoverflow.com/a/55338384/8060591
readInt64(offset) {
let value = 0;
const isNegative = (this._dataView.getUint8(offset + (this._littleEndian ? 7 : 0)) & 128) > 0;
let carrying = true;
for (let i = 0; i < 8; i++) {
let byte = this._dataView.getUint8(
offset + (this._littleEndian ? i : 7 - i)
);
if (isNegative) {
if (carrying) {
if (byte !== 0) {
byte = ~(byte - 1) & 255;
carrying = false;
}
} else {
byte = ~byte & 255;
}
}
value += byte * 256 ** i;
}
if (isNegative) {
value = -value;
}
return value;
}
readOffset(offset) {
if (this._bigTiff) {
return this.readUint64(offset);
}
return this.readUint32(offset);
}
};
// node_modules/geotiff/dist-module/pool.js
var defaultPoolSize = typeof navigator !== "undefined" ? navigator.hardwareConcurrency || 2 : 2;
var Pool = class {
/**
* @constructor
* @param {Number} [size] The size of the pool. Defaults to the number of CPUs
* available. When this parameter is `null` or 0, then the
* decoding will be done in the main thread.
* @param {function(): Worker} [createWorker] A function that creates the decoder worker.
* Defaults to a worker with all decoders that ship with geotiff.js. The `createWorker()`
* function is expected to return a `Worker` compatible with Web Workers. For code that
* runs in Node, [web-worker](https://www.npmjs.com/package/web-worker) is a good choice.
*
* A worker that uses a custom lzw decoder would look like this `my-custom-worker.js` file:
* ```js
* import { addDecoder, getDecoder } from 'geotiff';
* addDecoder(5, () => import ('./my-custom-lzw').then((m) => m.default));
* self.addEventListener('message', async (e) => {
* const { id, fileDirectory, buffer } = e.data;
* const decoder = await getDecoder(fileDirectory);
* const decoded = await decoder.decode(fileDirectory, buffer);
* self.postMessage({ decoded, id }, [decoded]);
* });
* ```
* The way the above code is built into a worker by the `createWorker()` function
* depends on the used bundler. For most bundlers, something like this will work:
* ```js
* function createWorker() {
* return new Worker(new URL('./my-custom-worker.js', import.meta.url));
* }
* ```
*/
constructor(size = defaultPoolSize, createWorker2) {
this.workers = null;
this._awaitingDecoder = null;
this.size = size;
this.messageId = 0;
if (size) {
this._awaitingDecoder = createWorker2 ? Promise.resolve(createWorker2) : new Promise((resolve) => {
import("./decoder-FUDNTCPN.js").then((module) => {
resolve(module.create);
});
});
this._awaitingDecoder.then((create2) => {
this._awaitingDecoder = null;
this.workers = [];
for (let i = 0; i < size; i++) {
this.workers.push({ worker: create2(), idle: true });
}
});
}
}
/**
* Decode the given block of bytes with the set compression method.
* @param {ArrayBuffer} buffer the array buffer of bytes to decode.
* @returns {Promise<ArrayBuffer>} the decoded result as a `Promise`
*/
async decode(fileDirectory, buffer3) {
if (this._awaitingDecoder) {
await this._awaitingDecoder;
}
return this.size === 0 ? getDecoder(fileDirectory).then((decoder) => decoder.decode(fileDirectory, buffer3)) : new Promise((resolve) => {
const worker = this.workers.find((candidate) => candidate.idle) || this.workers[Math.floor(Math.random() * this.size)];
worker.idle = false;
const id = this.messageId++;
const onMessage = (e) => {
if (e.data.id === id) {
worker.idle = true;
resolve(e.data.decoded);
worker.worker.removeEventListener("message", onMessage);
}
};
worker.worker.addEventListener("message", onMessage);
worker.worker.postMessage({ fileDirectory, buffer: buffer3, id }, [buffer3]);
});
}
destroy() {
if (this.workers) {
this.workers.forEach((worker) => {
worker.worker.terminate();
});
this.workers = null;
}
}
};
var pool_default = Pool;
// node_modules/geotiff/dist-module/source/httputils.js
var CRLFCRLF = "\r\n\r\n";
function itemsToObject(items) {
if (typeof Object.fromEntries !== "undefined") {
return Object.fromEntries(items);
}
const obj = {};
for (const [key, value] of items) {
obj[key.toLowerCase()] = value;
}
return obj;
}
function parseHeaders(text) {
const items = text.split("\r\n").map((line) => {
const kv = line.split(":").map((str) => str.trim());
kv[0] = kv[0].toLowerCase();
return kv;
});
return itemsToObject(items);
}
function parseContentType(rawContentType) {
const [type, ...rawParams] = rawContentType.split(";").map((s) => s.trim());
const paramsItems = rawParams.map((param) => param.split("="));
return { type, params: itemsToObject(paramsItems) };
}
function parseContentRange(rawContentRange) {
let start;
let end;
let total;
if (rawContentRange) {
[, start, end, total] = rawContentRange.match(/bytes (\d+)-(\d+)\/(\d+)/);
start = parseInt(start, 10);
end = parseInt(end, 10);
total = parseInt(total, 10);
}
return { start, end, total };
}
function parseByteRanges(responseArrayBuffer, boundary) {
let offset = null;
const decoder = new TextDecoder("ascii");
const out = [];
const startBoundary = `--${boundary}`;
const endBoundary = `${startBoundary}--`;
for (let i = 0; i < 10; ++i) {
const text = decoder.decode(
new Uint8Array(responseArrayBuffer, i, startBoundary.length)
);
if (text === startBoundary) {
offset = i;
}
}
if (offset === null) {
throw new Error("Could not find initial boundary");
}
while (offset < responseArrayBuffer.byteLength) {
const text = decoder.decode(
new Uint8Array(
responseArrayBuffer,
offset,
Math.min(startBoundary.length + 1024, responseArrayBuffer.byteLength - offset)
)
);
if (text.length === 0 || text.startsWith(endBoundary)) {
break;
}
if (!text.startsWith(startBoundary)) {
throw new Error("Part does not start with boundary");
}
const innerText = text.substr(startBoundary.length + 2);
if (innerText.length === 0) {
break;
}
const endOfHeaders = innerText.indexOf(CRLFCRLF);
const headers = parseHeaders(innerText.substr(0, endOfHeaders));
const { start, end, total } = parseContentRange(headers["content-range"]);
const startOfData = offset + startBoundary.length + endOfHeaders + CRLFCRLF.length;
const length = parseInt(end, 10) + 1 - parseInt(start, 10);
out.push({
headers,
data: responseArrayBuffer.slice(startOfData, startOfData + length),
offset: start,
length,
fileSize: total
});
offset = startOfData + length + 4;
}
return out;
}
// node_modules/geotiff/dist-module/source/basesource.js
var BaseSource = class {
/**
*
* @param {Slice[]} slices
* @returns {ArrayBuffer[]}
*/
async fetch(slices, signal = void 0) {
return Promise.all(
slices.map((slice) => this.fetchSlice(slice, signal))
);
}
/**
*
* @param {Slice} slice
* @returns {ArrayBuffer}
*/
async fetchSlice(slice) {
throw new Error(`fetching of slice ${slice} not possible, not implemented`);
}
/**
* Returns the filesize if already determined and null otherwise
*/
get fileSize() {
return null;
}
async close() {
}
};
// node_modules/quick-lru/index.js
var QuickLRU = class extends Map {
constructor(options = {}) {
super();
if (!(options.maxSize && options.maxSize > 0)) {
throw new TypeError("`maxSize` must be a number greater than 0");
}
if (typeof options.maxAge === "number" && options.maxAge === 0) {
throw new TypeError("`maxAge` must be a number greater than 0");
}
this.maxSize = options.maxSize;
this.maxAge = options.maxAge || Number.POSITIVE_INFINITY;
this.onEviction = options.onEviction;
this.cache = /* @__PURE__ */ new Map();
this.oldCache = /* @__PURE__ */ new Map();
this._size = 0;
}
// TODO: Use private class methods when targeting Node.js 16.
_emitEvictions(cache) {
if (typeof this.onEviction !== "function") {
return;
}
for (const [key, item] of cache) {
this.onEviction(key, item.value);
}
}
_deleteIfExpired(key, item) {
if (typeof item.expiry === "number" && item.expiry <= Date.now()) {
if (typeof this.onEviction === "function") {
this.onEviction(key, item.value);
}
return this.delete(key);
}
return false;
}
_getOrDeleteIfExpired(key, item) {
const deleted = this._deleteIfExpired(key, item);
if (deleted === false) {
return item.value;
}
}
_getItemValue(key, item) {
return item.expiry ? this._getOrDeleteIfExpired(key, item) : item.value;
}
_peek(key, cache) {
const item = cache.get(key);
return this._getItemValue(key, item);
}
_set(key, value) {
this.cache.set(key, value);
this._size++;
if (this._size >= this.maxSize) {
this._size = 0;
this._emitEvictions(this.oldCache);
this.oldCache = this.cache;
this.cache = /* @__PURE__ */ new Map();
}
}
_moveToRecent(key, item) {
this.oldCache.delete(key);
this._set(key, item);
}
*_entriesAscending() {
for (const item of this.oldCache) {
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield item;
}
}
}
for (const item of this.cache) {
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield item;
}
}
}
get(key) {
if (this.cache.has(key)) {
const item = this.cache.get(key);
return this._getItemValue(key, item);
}
if (this.oldCache.has(key)) {
const item = this.oldCache.get(key);
if (this._deleteIfExpired(key, item) === false) {
this._moveToRecent(key, item);
return item.value;
}
}
}
set(key, value, { maxAge = this.maxAge } = {}) {
const expiry = typeof maxAge === "number" && maxAge !== Number.POSITIVE_INFINITY ? Date.now() + maxAge : void 0;
if (this.cache.has(key)) {
this.cache.set(key, {
value,
expiry
});
} else {
this._set(key, { value, expiry });
}
return this;
}
has(key) {
if (this.cache.has(key)) {
return !this._deleteIfExpired(key, this.cache.get(key));
}
if (this.oldCache.has(key)) {
return !this._deleteIfExpired(key, this.oldCache.get(key));
}
return false;
}
peek(key) {
if (this.cache.has(key)) {
return this._peek(key, this.cache);
}
if (this.oldCache.has(key)) {
return this._peek(key, this.oldCache);
}
}
delete(key) {
const deleted = this.cache.delete(key);
if (deleted) {
this._size--;
}
return this.oldCache.delete(key) || deleted;
}
clear() {
this.cache.clear();
this.oldCache.clear();
this._size = 0;
}
resize(newSize) {
if (!(newSize && newSize > 0)) {
throw new TypeError("`maxSize` must be a number greater than 0");
}
const items = [...this._entriesAscending()];
const removeCount = items.length - newSize;
if (removeCount < 0) {
this.cache = new Map(items);
this.oldCache = /* @__PURE__ */ new Map();
this._size = items.length;
} else {
if (removeCount > 0) {
this._emitEvictions(items.slice(0, removeCount));
}
this.oldCache = new Map(items.slice(removeCount));
this.cache = /* @__PURE__ */ new Map();
this._size = 0;
}
this.maxSize = newSize;
}
*keys() {
for (const [key] of this) {
yield key;
}
}
*values() {
for (const [, value] of this) {
yield value;
}
}
*[Symbol.iterator]() {
for (const item of this.cache) {
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
for (const item of this.oldCache) {
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
}
}
*entriesDescending() {
let items = [...this.cache];
for (let i = items.length - 1; i >= 0; --i) {
const item = items[i];
const [key, value] = item;
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
items = [...this.oldCache];
for (let i = items.length - 1; i >= 0; --i) {
const item = items[i];
const [key, value] = item;
if (!this.cache.has(key)) {
const deleted = this._deleteIfExpired(key, value);
if (deleted === false) {
yield [key, value.value];
}
}
}
}
*entriesAscending() {
for (const [key, value] of this._entriesAscending()) {
yield [key, value.value];
}
}
get size() {
if (!this._size) {
return this.oldCache.size;
}
let oldCacheSize = 0;
for (const key of this.oldCache.keys()) {
if (!this.cache.has(key)) {
oldCacheSize++;
}
}
return Math.min(this._size + oldCacheSize, this.maxSize);
}
entries() {
return this.entriesAscending();
}
forEach(callbackFunction, thisArgument = this) {
for (const [key, value] of this.entriesAscending()) {
callbackFunction.call(thisArgument, value, key, this);
}
}
get [Symbol.toStringTag]() {
return JSON.stringify([...this.entriesAscending()]);
}
};
// node_modules/geotiff/dist-module/utils.js
function assign(target, source) {
for (const key in source) {
if (source.hasOwnProperty(key)) {
target[key] = source[key];
}
}
}
function invert(oldObj) {
const newObj = {};
for (const key in oldObj) {
if (oldObj.hasOwnProperty(key)) {
const value = oldObj[key];
newObj[value] = key;
}
}
return newObj;
}
function times(numTimes, func) {
const results = [];
for (let i = 0; i < numTimes; i++) {
results.push(func(i));
}
return results;
}
async function wait(milliseconds) {
return new Promise((resolve) => setTimeout(resolve, milliseconds));
}
function zip(a, b) {
const A = Array.isArray(a) ? a : Array.from(a);
const B = Array.isArray(b) ? b : Array.from(b);
return A.map((k, i) => [k, B[i]]);
}
var AbortError = class _AbortError extends Error {
constructor(params) {
super(params);
if (Error.captureStackTrace) {
Error.captureStackTrace(this, _AbortError);
}
this.name = "AbortError";
}
};
var CustomAggregateError = class extends Error {
constructor(errors, message) {
super(message);
this.errors = errors;
this.message = message;
this.name = "AggregateError";
}
};
var AggregateError = CustomAggregateError;
// node_modules/geotiff/dist-module/source/blockedsource.js
var Block = class {
/**
*
* @param {number} offset
* @param {number} length
* @param {ArrayBuffer} [data]
*/
constructor(offset, length, data = null) {
this.offset = offset;
this.length = length;
this.data = data;
}
/**
* @returns {number} the top byte border
*/
get top() {
return this.offset + this.length;
}
};
var BlockGroup = class {
/**
*
* @param {number} offset
* @param {number} length
* @param {number[]} blockIds
*/
constructor(offset, length, blockIds) {
this.offset = offset;
this.length = length;
this.blockIds = blockIds;
}
};
var BlockedSource = class extends BaseSource {
/**
*
* @param {BaseSource} source The underlying source that shall be blocked and cached
* @param {object} options
* @param {number} [options.blockSize]
* @param {number} [options.cacheSize]
*/
constructor(source, { blockSize = 65536, cacheSize = 100 } = {}) {
super();
this.source = source;
this.blockSize = blockSize;
this.blockCache = new QuickLRU({
maxSize: cacheSize,
onEviction: (blockId, block) => {
this.evictedBlocks.set(blockId, block);
}
});
this.evictedBlocks = /* @__PURE__ */ new Map();
this.blockRequests = /* @__PURE__ */ new Map();
this.blockIdsToFetch = /* @__PURE__ */ new Set();
this.abortedBlockIds = /* @__PURE__ */ new Set();
}
get fileSize() {
return this.source.fileSize;
}
/**
*
* @param {import("./basesource").Slice[]} slices
*/
async fetch(slices, signal) {
const blockRequests = [];
const missingBlockIds = [];
const allBlockIds = [];
this.evictedBlocks.clear();
for (const { offset, length } of slices) {
let top = offset + length;
const { fileSize } = this;
if (fileSize !== null) {
top = Math.min(top, fileSize);
}
const firstBlockOffset = Math.floor(offset / this.blockSize) * this.blockSize;
for (let current = firstBlockOffset; current < top; current += this.blockSize) {
const blockId = Math.floor(current / this.blockSize);
if (!this.blockCache.has(blockId) && !this.blockRequests.has(blockId)) {
this.blockIdsToFetch.add(blockId);
missingBlockIds.push(blockId);
}
if (this.blockRequests.has(blockId)) {
blockRequests.push(this.blockRequests.get(blockId));
}
allBlockIds.push(blockId);
}
}
await wait();
this.fetchBlocks(signal);
const missingRequests = [];
for (const blockId of missingBlockIds) {
if (this.blockRequests.has(blockId)) {
missingRequests.push(this.blockRequests.get(blockId));
}
}
await Promise.allSettled(blockRequests);
await Promise.allSettled(missingRequests);
const abortedBlockRequests = [];
const abortedBlockIds = allBlockIds.filter((id) => this.abortedBlockIds.has(id) || !this.blockCache.has(id));
abortedBlockIds.forEach((id) => this.blockIdsToFetch.add(id));
if (abortedBlockIds.length > 0 && signal && !signal.aborted) {
this.fetchBlocks(null);
for (const blockId of abortedBlockIds) {
const block = this.blockRequests.get(blockId);
if (!block) {
throw new Error(`Block ${blockId} is not in the block requests`);
}
abortedBlockRequests.push(block);
}
await Promise.allSettled(abortedBlockRequests);
}
if (signal && signal.aborted) {
throw new AbortError("Request was aborted");
}
const blocks = allBlockIds.map((id) => this.blockCache.get(id) || this.evictedBlocks.get(id));
const failedBlocks = blocks.filter((i) => !i);
if (failedBlocks.length) {
throw new AggregateError(failedBlocks, "Request failed");
}
const requiredBlocks = new Map(zip(allBlockIds, blocks));
return this.readSliceData(slices, requiredBlocks);
}
/**
*
* @param {AbortSignal} signal
*/
fetchBlocks(signal) {
if (this.blockIdsToFetch.size > 0) {
const groups = this.groupBlocks(this.blockIdsToFetch);
const groupRequests = this.source.fetch(groups, signal);
for (let groupIndex = 0; groupIndex < groups.length; ++groupIndex) {
const group = groups[groupIndex];
for (const blockId of group.blockIds) {
this.blockRequests.set(blockId, (async () => {
try {
const response = (await groupRequests)[groupIndex];
const blockOffset = blockId * this.blockSize;
const o = blockOffset - response.offset;
const t = Math.min(o + this.blockSize, response.data.byteLength);
const data = response.data.slice(o, t);
const block = new Block(
blockOffset,
data.byteLength,
data,
blockId
);
this.blockCache.set(blockId, block);
this.abortedBlockIds.delete(blockId);
} catch (err) {
if (err.name === "AbortError") {
err.signal = signal;
this.blockCache.delete(blockId);
this.abortedBlockIds.add(blockId);
} else {
throw err;
}
} finally {
this.blockRequests.delete(blockId);
}
})());
}
}
this.blockIdsToFetch.clear();
}
}
/**
*
* @param {Set} blockIds
* @returns {BlockGroup[]}
*/
groupBlocks(blockIds) {
const sortedBlockIds = Array.from(blockIds).sort((a, b) => a - b);
if (sortedBlockIds.length === 0) {
return [];
}
let current = [];
let lastBlockId = null;
const groups = [];
for (const blockId of sortedBlockIds) {
if (lastBlockId === null || lastBlockId + 1 === blockId) {
current.push(blockId);
lastBlockId = blockId;
} else {
groups.push(new BlockGroup(
current[0] * this.blockSize,
current.length * this.blockSize,
current
));
current = [blockId];
lastBlockId = blockId;
}
}
groups.push(new BlockGroup(
current[0] * this.blockSize,
current.length * this.blockSize,
current
));
return groups;
}
/**
*
* @param {import("./basesource").Slice[]} slices
* @param {Map} blocks
*/
readSliceData(slices, blocks) {
return slices.map((slice) => {
let top = slice.offset + slice.length;
if (this.fileSize !== null) {
top = Math.min(this.fileSize, top);
}
const blockIdLow = Math.floor(slice.offset / this.blockSize);
const blockIdHigh = Math.floor(top / this.blockSize);
const sliceData = new ArrayBuffer(slice.length);
const sliceView = new Uint8Array(sliceData);
for (let blockId = blockIdLow; blockId <= blockIdHigh; ++blockId) {
const block = blocks.get(blockId);
const delta = block.offset - slice.offset;
const topDelta = block.top - top;
let blockInnerOffset = 0;
let rangeInnerOffset = 0;
let usedBlockLength;
if (delta < 0) {
blockInnerOffset = -delta;
} else if (delta > 0) {
rangeInnerOffset = delta;
}
if (topDelta < 0) {
usedBlockLength = block.length - blockInnerOffset;
} else {
usedBlockLength = top - block.offset - blockInnerOffset;
}
const blockView = new Uint8Array(block.data, blockInnerOffset, usedBlockLength);
sliceView.set(blockView, rangeInnerOffset);
}
return sliceData;
});
}
};
// node_modules/geotiff/dist-module/source/client/base.js
var BaseResponse = class {
/**
* Returns whether the response has an ok'ish status code
*/
get ok() {
return this.status >= 200 && this.status <= 299;
}
/**
* Returns the status code of the response
*/
get status() {
throw new Error("not implemented");
}
/**
* Returns the value of the specified header
* @param {string} headerName the header name
* @returns {string} the header value
*/
getHeader(headerName) {
throw new Error("not implemented");
}
/**
* @returns {ArrayBuffer} the response data of the request
*/
async getData() {
throw new Error("not implemented");
}
};
var BaseClient = class {
constructor(url) {
this.url = url;
}
/**
* Send a request with the options
* @param {{headers: HeadersInit, signal: AbortSignal}} [options={}]
* @returns {Promise<BaseResponse>}
*/
async request({ headers, signal } = {}) {
throw new Error("request is not implemented");
}
};
// node_modules/geotiff/dist-module/source/client/fetch.js
var FetchResponse = class extends BaseResponse {
/**
* BaseResponse facade for fetch API Response
* @param {Response} response
*/
constructor(response) {
super();
this.response = response;
}
get status() {
return this.response.status;
}
getHeader(name) {
return this.response.headers.get(name);
}
async getData() {
const data = this.response.arrayBuffer ? await this.response.arrayBuffer() : (await this.response.buffer()).buffer;
return data;
}
};
var FetchClient = class extends BaseClient {
constructor(url, credentials) {
super(url);
this.credentials = credentials;
}
/**
* @param {{headers: HeadersInit, signal: AbortSignal}} [options={}]
* @returns {Promise<FetchResponse>}
*/
async request({ headers, signal } = {}) {
const response = await fetch(this.url, {
headers,
credentials: this.credentials,
signal
});
return new FetchResponse(response);
}
};
// node_modules/geotiff/dist-module/source/client/xhr.js
var XHRResponse = class extends BaseResponse {
/**
* BaseResponse facade for XMLHttpRequest
* @param {XMLHttpRequest} xhr
* @param {ArrayBuffer} data
*/
constructor(xhr, data) {
super();
this.xhr = xhr;
this.data = data;
}
get status() {
return this.xhr.status;
}
getHeader(name) {
return this.xhr.getResponseHeader(name);
}
async getData() {
return this.data;
}
};
var XHRClient = class extends BaseClient {
constructRequest(headers, signal) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", this.url);
xhr.responseType = "arraybuffer";
for (const [key, value] of Object.entries(headers)) {
xhr.setRequestHeader(key, value);
}
xhr.onload = () => {
const data = xhr.response;
resolve(new XHRResponse(xhr, data));
};
xhr.onerror = reject;
xhr.onabort = () => reject(new AbortError("Request aborted"));
xhr.send();
if (signal) {
if (signal.aborted) {
xhr.abort();
}
signal.addEventListener("abort", () => xhr.abort());
}
});
}
async request({ headers, signal } = {}) {
const response = await this.constructRequest(headers, signal);
return response;
}
};
// node_modules/geotiff/dist-module/source/client/http.js
var import_http = __toESM(require_http(), 1);
var import_https = __toESM(require_https(), 1);
var import_url = __toESM(require_url(), 1);
var HttpResponse = class extends BaseResponse {
/**
* BaseResponse facade for node HTTP/HTTPS API Response
* @param {http.ServerResponse} response
*/
constructor(response, dataPromise) {
super();
this.response = response;
this.dataPromise = dataPromise;
}
get status() {
return this.response.statusCode;
}
getHeader(name) {
return this.response.headers[name];
}
async getData() {
const data = await this.dataPromise;
return data;
}
};
var HttpClient = class extends BaseClient {
constructor(url) {
super(url);
this.parsedUrl = import_url.default.parse(this.url);
this.httpApi = this.parsedUrl.protocol === "http:" ? import_http.default : import_https.default;
}
constructRequest(headers, signal) {
return new Promise((resolve, reject) => {
const request = this.httpApi.get(
{
...this.parsedUrl,
headers
},
(response) => {
const dataPromise = new Promise((resolveData) => {
const chunks = [];
response.on("data", (chunk) => {
chunks.push(chunk);
});
response.on("end", () => {
const data = Buffer.concat(chunks).buffer;
resolveData(data);
});
response.on("error", reject);
});
resolve(new HttpResponse(response, dataPromise));
}
);
request.on("error", reject);
if (signal) {
if (signal.aborted) {
request.destroy(new AbortError("Request aborted"));
}
signal.addEventListener("abort", () => request.destroy(new AbortError("Request aborted")));
}
});
}
async request({ headers, signal } = {}) {
const response = await this.constructRequest(headers, signal);
return response;
}
};
// node_modules/geotiff/dist-module/source/remote.js
var RemoteSource = class extends BaseSource {
/**
*
* @param {BaseClient} client
* @param {object} headers
* @param {numbers} maxRanges
* @param {boolean} allowFullFile
*/
constructor(client, headers, maxRanges, allowFullFile) {
super();
this.client = client;
this.headers = headers;
this.maxRanges = maxRanges;
this.allowFullFile = allowFullFile;
this._fileSize = null;
}
/**
*
* @param {Slice[]} slices
*/
async fetch(slices, signal) {
if (this.maxRanges >= slices.length) {
return this.fetchSlices(slices, signal);
} else if (this.maxRanges > 0 && slices.length > 1) {
}
return Promise.all(
slices.map((slice) => this.fetchSlice(slice, signal))
);
}
async fetchSlices(slices, signal) {
const response = await this.client.request({
headers: {
...this.headers,
Range: `bytes=${slices.map(({ offset, length }) => `${offset}-${offset + length}`).join(",")}`
},
signal
});
if (!response.ok) {
throw new Error("Error fetching data.");
} else if (response.status === 206) {
const { type, params } = parseContentType(response.getHeader("content-type"));
if (type === "multipart/byteranges") {
const byteRanges = parseByteRanges(await response.getData(), params.boundary);
this._fileSize = byteRanges[0].fileSize || null;
return byteRanges;
}
const data = await response.getData();
const { start, end, total } = parseContentRange(response.getHeader("content-range"));
this._fileSize = total || null;
const first = [{
data,
offset: start,
length: end - start
}];
if (slices.length > 1) {
const others = await Promise.all(slices.slice(1).map((slice) => this.fetchSlice(slice, signal)));
return first.concat(others);
}
return first;
} else {
if (!this.allowFullFile) {
throw new Error("Server responded with full file");
}
const data = await response.getData();
this._fileSize = data.byteLength;
return [{
data,
offset: 0,
length: data.byteLength
}];
}
}
async fetchSlice(slice, signal) {
const { offset, length } = slice;
const response = await this.client.request({
headers: {
...this.headers,
Range: `bytes=${offset}-${offset + length}`
},
signal
});
if (!response.ok) {
throw new Error("Error fetching data.");
} else if (response.status === 206) {
const data = await response.getData();
const { total } = parseContentRange(response.getHeader("content-range"));
this._fileSize = total || null;
return {
data,
offset,
length
};
} else {
if (!this.allowFullFile) {
throw new Error("Server responded with full file");
}
const data = await response.getData();
this._fileSize = data.byteLength;
return {
data,
offset: 0,
length: data.byteLength
};
}
}
get fileSize() {
return this._fileSize;
}
};
function maybeWrapInBlockedSource(source, { blockSize, cacheSize }) {
if (blockSize === null) {
return source;
}
return new BlockedSource(source, { blockSize, cacheSize });
}
function makeFetchSource(url, { headers = {}, credentials, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {
const client = new FetchClient(url, credentials);
const source = new RemoteSource(client, headers, maxRanges, allowFullFile);
return maybeWrapInBlockedSource(source, blockOptions);
}
function makeXHRSource(url, { headers = {}, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {
const client = new XHRClient(url);
const source = new RemoteSource(client, headers, maxRanges, allowFullFile);
return maybeWrapInBlockedSource(source, blockOptions);
}
function makeHttpSource(url, { headers = {}, maxRanges = 0, allowFullFile = false, ...blockOptions } = {}) {
const client = new HttpClient(url);
const source = new RemoteSource(client, headers, maxRanges, allowFullFile);
return maybeWrapInBlockedSource(source, blockOptions);
}
function makeRemoteSource(url, { forceXHR = false, ...clientOptions } = {}) {
if (typeof fetch === "function" && !forceXHR) {
return makeFetchSource(url, clientOptions);
}
if (typeof XMLHttpRequest !== "undefined") {
return makeXHRSource(url, clientOptions);
}
return makeHttpSource(url, clientOptions);
}
// node_modules/geotiff/dist-module/source/filereader.js
var FileReaderSource = class extends BaseSource {
constructor(file) {
super();
this.file = file;
}
async fetchSlice(slice, signal) {
return new Promise((resolve, reject) => {
const blob = this.file.slice(slice.offset, slice.offset + slice.length);
const reader = new FileReader();
reader.onload = (event) => resolve(event.target.result);
reader.onerror = reject;
reader.onabort = reject;
reader.readAsArrayBuffer(blob);
if (signal) {
signal.addEventListener("abort", () => reader.abort());
}
});
}
};
function makeFileReaderSource(file) {
return new FileReaderSource(file);
}
// node_modules/geotiff/dist-module/source/file.js
var import_fs = __toESM(require_fs(), 1);
// node_modules/geotiff/dist-module/geotiffwriter.js
var tagName2Code = invert(fieldTagNames);
var geoKeyName2Code = invert(geoKeyNames);
var name2code = {};
assign(name2code, tagName2Code);
assign(name2code, geoKeyName2Code);
var typeName2byte = invert(fieldTypeNames);
var _binBE = {
nextZero: (data, o) => {
let oincr = o;
while (data[oincr] !== 0) {
oincr++;
}
return oincr;
},
readUshort: (buff, p) => {
return buff[p] << 8 | buff[p + 1];
},
readShort: (buff, p) => {
const a = _binBE.ui8;
a[0] = buff[p + 1];
a[1] = buff[p + 0];
return _binBE.i16[0];
},
readInt: (buff, p) => {
const a = _binBE.ui8;
a[0] = buff[p + 3];
a[1] = buff[p + 2];
a[2] = buff[p + 1];
a[3] = buff[p + 0];
return _binBE.i32[0];
},
readUint: (buff, p) => {
const a = _binBE.ui8;
a[0] = buff[p + 3];
a[1] = buff[p + 2];
a[2] = buff[p + 1];
a[3] = buff[p + 0];
return _binBE.ui32[0];
},
readASCII: (buff, p, l) => {
return l.map((i) => String.fromCharCode(buff[p + i])).join("");
},
readFloat: (buff, p) => {
const a = _binBE.ui8;
times(4, (i) => {
a[i] = buff[p + 3 - i];
});
return _binBE.fl32[0];
},
readDouble: (buff, p) => {
const a = _binBE.ui8;
times(8, (i) => {
a[i] = buff[p + 7 - i];
});
return _binBE.fl64[0];
},
writeUshort: (buff, p, n) => {
buff[p] = n >> 8 & 255;
buff[p + 1] = n & 255;
},
writeUint: (buff, p, n) => {
buff[p] = n >> 24 & 255;
buff[p + 1] = n >> 16 & 255;
buff[p + 2] = n >> 8 & 255;
buff[p + 3] = n >> 0 & 255;
},
writeASCII: (buff, p, s) => {
times(s.length, (i) => {
buff[p + i] = s.charCodeAt(i);
});
},
ui8: new Uint8Array(8)
};
_binBE.fl64 = new Float64Array(_binBE.ui8.buffer);
_binBE.writeDouble = (buff, p, n) => {
_binBE.fl64[0] = n;
times(8, (i) => {
buff[p + i] = _binBE.ui8[7 - i];
});
};
// node_modules/geotiff/dist-module/logging.js
var DummyLogger = class {
log() {
}
debug() {
}
info() {
}
warn() {
}
error() {
}
time() {
}
timeEnd() {
}
};
var LOGGER = new DummyLogger();
// node_modules/geotiff/dist-module/geotiff.js
function getFieldTypeLength(fieldType) {
switch (fieldType) {
case fieldTypes.BYTE:
case fieldTypes.ASCII:
case fieldTypes.SBYTE:
case fieldTypes.UNDEFINED:
return 1;
case fieldTypes.SHORT:
case fieldTypes.SSHORT:
return 2;
case fieldTypes.LONG:
case fieldTypes.SLONG:
case fieldTypes.FLOAT:
case fieldTypes.IFD:
return 4;
case fieldTypes.RATIONAL:
case fieldTypes.SRATIONAL:
case fieldTypes.DOUBLE:
case fieldTypes.LONG8:
case fieldTypes.SLONG8:
case fieldTypes.IFD8:
return 8;
default:
throw new RangeError(`Invalid field type: ${fieldType}`);
}
}
function parseGeoKeyDirectory(fileDirectory) {
const rawGeoKeyDirectory = fileDirectory.GeoKeyDirectory;
if (!rawGeoKeyDirectory) {
return null;
}
const geoKeyDirectory = {};
for (let i = 4; i <= rawGeoKeyDirectory[3] * 4; i += 4) {
const key = geoKeyNames[rawGeoKeyDirectory[i]];
const location = rawGeoKeyDirectory[i + 1] ? fieldTagNames[rawGeoKeyDirectory[i + 1]] : null;
const count = rawGeoKeyDirectory[i + 2];
const offset = rawGeoKeyDirectory[i + 3];
let value = null;
if (!location) {
value = offset;
} else {
value = fileDirectory[location];
if (typeof value === "undefined" || value === null) {
throw new Error(`Could not get value of geoKey '${key}'.`);
} else if (typeof value === "string") {
value = value.substring(offset, offset + count - 1);
} else if (value.subarray) {
value = value.subarray(offset, offset + count);
if (count === 1) {
value = value[0];
}
}
}
geoKeyDirectory[key] = value;
}
return geoKeyDirectory;
}
function getValues(dataSlice, fieldType, count, offset) {
let values2 = null;
let readMethod = null;
const fieldTypeLength = getFieldTypeLength(fieldType);
switch (fieldType) {
case fieldTypes.BYTE:
case fieldTypes.ASCII:
case fieldTypes.UNDEFINED:
values2 = new Uint8Array(count);
readMethod = dataSlice.readUint8;
break;
case fieldTypes.SBYTE:
values2 = new Int8Array(count);
readMethod = dataSlice.readInt8;
break;
case fieldTypes.SHORT:
values2 = new Uint16Array(count);
readMethod = dataSlice.readUint16;
break;
case fieldTypes.SSHORT:
values2 = new Int16Array(count);
readMethod = dataSlice.readInt16;
break;
case fieldTypes.LONG:
case fieldTypes.IFD:
values2 = new Uint32Array(count);
readMethod = dataSlice.readUint32;
break;
case fieldTypes.SLONG:
values2 = new Int32Array(count);
readMethod = dataSlice.readInt32;
break;
case fieldTypes.LONG8:
case fieldTypes.IFD8:
values2 = new Array(count);
readMethod = dataSlice.readUint64;
break;
case fieldTypes.SLONG8:
values2 = new Array(count);
readMethod = dataSlice.readInt64;
break;
case fieldTypes.RATIONAL:
values2 = new Uint32Array(count * 2);
readMethod = dataSlice.readUint32;
break;
case fieldTypes.SRATIONAL:
values2 = new Int32Array(count * 2);
readMethod = dataSlice.readInt32;
break;
case fieldTypes.FLOAT:
values2 = new Float32Array(count);
readMethod = dataSlice.readFloat32;
break;
case fieldTypes.DOUBLE:
values2 = new Float64Array(count);
readMethod = dataSlice.readFloat64;
break;
default:
throw new RangeError(`Invalid field type: ${fieldType}`);
}
if (!(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
for (let i = 0; i < count; ++i) {
values2[i] = readMethod.call(
dataSlice,
offset + i * fieldTypeLength
);
}
} else {
for (let i = 0; i < count; i += 2) {
values2[i] = readMethod.call(
dataSlice,
offset + i * fieldTypeLength
);
values2[i + 1] = readMethod.call(
dataSlice,
offset + (i * fieldTypeLength + 4)
);
}
}
if (fieldType === fieldTypes.ASCII) {
return new TextDecoder("utf-8").decode(values2);
}
return values2;
}
var ImageFileDirectory = class {
constructor(fileDirectory, geoKeyDirectory, nextIFDByteOffset) {
this.fileDirectory = fileDirectory;
this.geoKeyDirectory = geoKeyDirectory;
this.nextIFDByteOffset = nextIFDByteOffset;
}
};
var GeoTIFFImageIndexError = class extends Error {
constructor(index) {
super(`No image at index ${index}`);
this.index = index;
}
};
var GeoTIFFBase = class {
/**
* (experimental) Reads raster data from the best fitting image. This function uses
* the image with the lowest resolution that is still a higher resolution than the
* requested resolution.
* When specified, the `bbox` option is translated to the `window` option and the
* `resX` and `resY` to `width` and `height` respectively.
* Then, the [readRasters]{@link GeoTIFFImage#readRasters} method of the selected
* image is called and the result returned.
* @see GeoTIFFImage.readRasters
* @param {import('./geotiffimage').ReadRasterOptions} [options={}] optional parameters
* @returns {Promise<ReadRasterResult>} the decoded array(s), with `height` and `width`, as a promise
*/
async readRasters(options = {}) {
const { window: imageWindow, width, height } = options;
let { resX, resY, bbox } = options;
const firstImage = await this.getImage();
let usedImage = firstImage;
const imageCount = await this.getImageCount();
const imgBBox = firstImage.getBoundingBox();
if (imageWindow && bbox) {
throw new Error('Both "bbox" and "window" passed.');
}
if (width || height) {
if (imageWindow) {
const [oX, oY] = firstImage.getOrigin();
const [rX, rY] = firstImage.getResolution();
bbox = [
oX + imageWindow[0] * rX,
oY + imageWindow[1] * rY,
oX + imageWindow[2] * rX,
oY + imageWindow[3] * rY
];
}
const usedBBox = bbox || imgBBox;
if (width) {
if (resX) {
throw new Error("Both width and resX passed");
}
resX = (usedBBox[2] - usedBBox[0]) / width;
}
if (height) {
if (resY) {
throw new Error("Both width and resY passed");
}
resY = (usedBBox[3] - usedBBox[1]) / height;
}
}
if (resX || resY) {
const allImages = [];
for (let i = 0; i < imageCount; ++i) {
const image = await this.getImage(i);
const { SubfileType: subfileType, NewSubfileType: newSubfileType } = image.fileDirectory;
if (i === 0 || subfileType === 2 || newSubfileType & 1) {
allImages.push(image);
}
}
allImages.sort((a, b) => a.getWidth() - b.getWidth());
for (let i = 0; i < allImages.length; ++i) {
const image = allImages[i];
const imgResX = (imgBBox[2] - imgBBox[0]) / image.getWidth();
const imgResY = (imgBBox[3] - imgBBox[1]) / image.getHeight();
usedImage = image;
if (resX && resX > imgResX || resY && resY > imgResY) {
break;
}
}
}
let wnd = imageWindow;
if (bbox) {
const [oX, oY] = firstImage.getOrigin();
const [imageResX, imageResY] = usedImage.getResolution(firstImage);
wnd = [
Math.round((bbox[0] - oX) / imageResX),
Math.round((bbox[1] - oY) / imageResY),
Math.round((bbox[2] - oX) / imageResX),
Math.round((bbox[3] - oY) / imageResY)
];
wnd = [
Math.min(wnd[0], wnd[2]),
Math.min(wnd[1], wnd[3]),
Math.max(wnd[0], wnd[2]),
Math.max(wnd[1], wnd[3])
];
}
return usedImage.readRasters({ ...options, window: wnd });
}
};
var GeoTIFF = class _GeoTIFF extends GeoTIFFBase {
/**
* @constructor
* @param {*} source The datasource to read from.
* @param {boolean} littleEndian Whether the image uses little endian.
* @param {boolean} bigTiff Whether the image uses bigTIFF conventions.
* @param {number} firstIFDOffset The numeric byte-offset from the start of the image
* to the first IFD.
* @param {GeoTIFFOptions} [options] further options.
*/
constructor(source, littleEndian, bigTiff, firstIFDOffset, options = {}) {
super();
this.source = source;
this.littleEndian = littleEndian;
this.bigTiff = bigTiff;
this.firstIFDOffset = firstIFDOffset;
this.cache = options.cache || false;
this.ifdRequests = [];
this.ghostValues = null;
}
async getSlice(offset, size) {
const fallbackSize = this.bigTiff ? 4048 : 1024;
return new DataSlice(
(await this.source.fetch([{
offset,
length: typeof size !== "undefined" ? size : fallbackSize
}]))[0],
offset,
this.littleEndian,
this.bigTiff
);
}
/**
* Instructs to parse an image file directory at the given file offset.
* As there is no way to ensure that a location is indeed the start of an IFD,
* this function must be called with caution (e.g only using the IFD offsets from
* the headers or other IFDs).
* @param {number} offset the offset to parse the IFD at
* @returns {Promise<ImageFileDirectory>} the parsed IFD
*/
async parseFileDirectoryAt(offset) {
const entrySize = this.bigTiff ? 20 : 12;
const offsetSize = this.bigTiff ? 8 : 2;
let dataSlice = await this.getSlice(offset);
const numDirEntries = this.bigTiff ? dataSlice.readUint64(offset) : dataSlice.readUint16(offset);
const byteSize = numDirEntries * entrySize + (this.bigTiff ? 16 : 6);
if (!dataSlice.covers(offset, byteSize)) {
dataSlice = await this.getSlice(offset, byteSize);
}
const fileDirectory = {};
let i = offset + (this.bigTiff ? 8 : 2);
for (let entryCount = 0; entryCount < numDirEntries; i += entrySize, ++entryCount) {
const fieldTag = dataSlice.readUint16(i);
const fieldType = dataSlice.readUint16(i + 2);
const typeCount = this.bigTiff ? dataSlice.readUint64(i + 4) : dataSlice.readUint32(i + 4);
let fieldValues;
let value;
const fieldTypeLength = getFieldTypeLength(fieldType);
const valueOffset = i + (this.bigTiff ? 12 : 8);
if (fieldTypeLength * typeCount <= (this.bigTiff ? 8 : 4)) {
fieldValues = getValues(dataSlice, fieldType, typeCount, valueOffset);
} else {
const actualOffset = dataSlice.readOffset(valueOffset);
const length = getFieldTypeLength(fieldType) * typeCount;
if (dataSlice.covers(actualOffset, length)) {
fieldValues = getValues(dataSlice, fieldType, typeCount, actualOffset);
} else {
const fieldDataSlice = await this.getSlice(actualOffset, length);
fieldValues = getValues(fieldDataSlice, fieldType, typeCount, actualOffset);
}
}
if (typeCount === 1 && arrayFields.indexOf(fieldTag) === -1 && !(fieldType === fieldTypes.RATIONAL || fieldType === fieldTypes.SRATIONAL)) {
value = fieldValues[0];
} else {
value = fieldValues;
}
fileDirectory[fieldTagNames[fieldTag]] = value;
}
const geoKeyDirectory = parseGeoKeyDirectory(fileDirectory);
const nextIFDByteOffset = dataSlice.readOffset(
offset + offsetSize + entrySize * numDirEntries
);
return new ImageFileDirectory(
fileDirectory,
geoKeyDirectory,
nextIFDByteOffset
);
}
async requestIFD(index) {
if (this.ifdRequests[index]) {
return this.ifdRequests[index];
} else if (index === 0) {
this.ifdRequests[index] = this.parseFileDirectoryAt(this.firstIFDOffset);
return this.ifdRequests[index];
} else if (!this.ifdRequests[index - 1]) {
try {
this.ifdRequests[index - 1] = this.requestIFD(index - 1);
} catch (e) {
if (e instanceof GeoTIFFImageIndexError) {
throw new GeoTIFFImageIndexError(index);
}
throw e;
}
}
this.ifdRequests[index] = (async () => {
const previousIfd = await this.ifdRequests[index - 1];
if (previousIfd.nextIFDByteOffset === 0) {
throw new GeoTIFFImageIndexError(index);
}
return this.parseFileDirectoryAt(previousIfd.nextIFDByteOffset);
})();
return this.ifdRequests[index];
}
/**
* Get the n-th internal subfile of an image. By default, the first is returned.
*
* @param {number} [index=0] the index of the image to return.
* @returns {Promise<GeoTIFFImage>} the image at the given index
*/
async getImage(index = 0) {
const ifd = await this.requestIFD(index);
return new geotiffimage_default(
ifd.fileDirectory,
ifd.geoKeyDirectory,
this.dataView,
this.littleEndian,
this.cache,
this.source
);
}
/**
* Returns the count of the internal subfiles.
*
* @returns {Promise<number>} the number of internal subfile images
*/
async getImageCount() {
let index = 0;
let hasNext = true;
while (hasNext) {
try {
await this.requestIFD(index);
++index;
} catch (e) {
if (e instanceof GeoTIFFImageIndexError) {
hasNext = false;
} else {
throw e;
}
}
}
return index;
}
/**
* Get the values of the COG ghost area as a parsed map.
* See https://gdal.org/drivers/raster/cog.html#header-ghost-area for reference
* @returns {Promise<Object>} the parsed ghost area or null, if no such area was found
*/
async getGhostValues() {
const offset = this.bigTiff ? 16 : 8;
if (this.ghostValues) {
return this.ghostValues;
}
const detectionString = "GDAL_STRUCTURAL_METADATA_SIZE=";
const heuristicAreaSize = detectionString.length + 100;
let slice = await this.getSlice(offset, heuristicAreaSize);
if (detectionString === getValues(slice, fieldTypes.ASCII, detectionString.length, offset)) {
const valuesString = getValues(slice, fieldTypes.ASCII, heuristicAreaSize, offset);
const firstLine = valuesString.split("\n")[0];
const metadataSize = Number(firstLine.split("=")[1].split(" ")[0]) + firstLine.length;
if (metadataSize > heuristicAreaSize) {
slice = await this.getSlice(offset, metadataSize);
}
const fullString = getValues(slice, fieldTypes.ASCII, metadataSize, offset);
this.ghostValues = {};
fullString.split("\n").filter((line) => line.length > 0).map((line) => line.split("=")).forEach(([key, value]) => {
this.ghostValues[key] = value;
});
}
return this.ghostValues;
}
/**
* Parse a (Geo)TIFF file from the given source.
*
* @param {*} source The source of data to parse from.
* @param {GeoTIFFOptions} [options] Additional options.
* @param {AbortSignal} [signal] An AbortSignal that may be signalled if the request is
* to be aborted
*/
static async fromSource(source, options, signal) {
const headerData = (await source.fetch([{ offset: 0, length: 1024 }], signal))[0];
const dataView = new DataView64(headerData);
const BOM = dataView.getUint16(0, 0);
let littleEndian;
if (BOM === 18761) {
littleEndian = true;
} else if (BOM === 19789) {
littleEndian = false;
} else {
throw new TypeError("Invalid byte order value.");
}
const magicNumber = dataView.getUint16(2, littleEndian);
let bigTiff;
if (magicNumber === 42) {
bigTiff = false;
} else if (magicNumber === 43) {
bigTiff = true;
const offsetByteSize = dataView.getUint16(4, littleEndian);
if (offsetByteSize !== 8) {
throw new Error("Unsupported offset byte-size.");
}
} else {
throw new TypeError("Invalid magic number.");
}
const firstIFDOffset = bigTiff ? dataView.getUint64(8, littleEndian) : dataView.getUint32(4, littleEndian);
return new _GeoTIFF(source, littleEndian, bigTiff, firstIFDOffset, options);
}
/**
* Closes the underlying file buffer
* N.B. After the GeoTIFF has been completely processed it needs
* to be closed but only if it has been constructed from a file.
*/
close() {
if (typeof this.source.close === "function") {
return this.source.close();
}
return false;
}
};
var MultiGeoTIFF = class extends GeoTIFFBase {
/**
* Construct a new MultiGeoTIFF from a main and several overview files.
* @param {GeoTIFF} mainFile The main GeoTIFF file.
* @param {GeoTIFF[]} overviewFiles An array of overview files.
*/
constructor(mainFile, overviewFiles) {
super();
this.mainFile = mainFile;
this.overviewFiles = overviewFiles;
this.imageFiles = [mainFile].concat(overviewFiles);
this.fileDirectoriesPerFile = null;
this.fileDirectoriesPerFileParsing = null;
this.imageCount = null;
}
async parseFileDirectoriesPerFile() {
const requests = [this.mainFile.parseFileDirectoryAt(this.mainFile.firstIFDOffset)].concat(this.overviewFiles.map((file) => file.parseFileDirectoryAt(file.firstIFDOffset)));
this.fileDirectoriesPerFile = await Promise.all(requests);
return this.fileDirectoriesPerFile;
}
/**
* Get the n-th internal subfile of an image. By default, the first is returned.
*
* @param {number} [index=0] the index of the image to return.
* @returns {Promise<GeoTIFFImage>} the image at the given index
*/
async getImage(index = 0) {
await this.getImageCount();
await this.parseFileDirectoriesPerFile();
let visited = 0;
let relativeIndex = 0;
for (let i = 0; i < this.imageFiles.length; i++) {
const imageFile = this.imageFiles[i];
for (let ii = 0; ii < this.imageCounts[i]; ii++) {
if (index === visited) {
const ifd = await imageFile.requestIFD(relativeIndex);
return new geotiffimage_default(
ifd.fileDirectory,
ifd.geoKeyDirectory,
imageFile.dataView,
imageFile.littleEndian,
imageFile.cache,
imageFile.source
);
}
visited++;
relativeIndex++;
}
relativeIndex = 0;
}
throw new RangeError("Invalid image index");
}
/**
* Returns the count of the internal subfiles.
*
* @returns {Promise<number>} the number of internal subfile images
*/
async getImageCount() {
if (this.imageCount !== null) {
return this.imageCount;
}
const requests = [this.mainFile.getImageCount()].concat(this.overviewFiles.map((file) => file.getImageCount()));
this.imageCounts = await Promise.all(requests);
this.imageCount = this.imageCounts.reduce((count, ifds) => count + ifds, 0);
return this.imageCount;
}
};
async function fromUrl(url, options = {}, signal) {
return GeoTIFF.fromSource(makeRemoteSource(url, options), signal);
}
async function fromBlob(blob, signal) {
return GeoTIFF.fromSource(makeFileReaderSource(blob), signal);
}
async function fromUrls(mainUrl, overviewUrls = [], options = {}, signal) {
const mainFile = await GeoTIFF.fromSource(makeRemoteSource(mainUrl, options), signal);
const overviewFiles = await Promise.all(
overviewUrls.map((url) => GeoTIFF.fromSource(makeRemoteSource(url, options)))
);
return new MultiGeoTIFF(mainFile, overviewFiles);
}
// node_modules/ol/source/GeoTIFF.js
function isMask(image) {
const fileDirectory = image.fileDirectory;
const type = fileDirectory.NewSubfileType || 0;
return (type & 4) === 4;
}
function readRGB(preference, image) {
if (!preference) {
return false;
}
if (preference === true) {
return true;
}
if (image.getSamplesPerPixel() !== 3) {
return false;
}
const interpretation = image.fileDirectory.PhotometricInterpretation;
const interpretations = globals_exports.photometricInterpretations;
return interpretation === interpretations.CMYK || interpretation === interpretations.YCbCr || interpretation === interpretations.CIELab || interpretation === interpretations.ICCLab;
}
var STATISTICS_MAXIMUM = "STATISTICS_MAXIMUM";
var STATISTICS_MINIMUM = "STATISTICS_MINIMUM";
var defaultTileSize = 256;
var workerPool;
function getWorkerPool() {
if (!workerPool) {
workerPool = new pool_default();
}
return workerPool;
}
function getBoundingBox(image) {
try {
return image.getBoundingBox(true);
} catch {
return [0, 0, image.getWidth(), image.getHeight()];
}
}
function getOrigin(image) {
try {
return image.getOrigin().slice(0, 2);
} catch {
return [0, image.getHeight()];
}
}
function getResolutions(image, referenceImage) {
try {
return image.getResolution(referenceImage);
} catch {
return [
referenceImage.getWidth() / image.getWidth(),
referenceImage.getHeight() / image.getHeight()
];
}
}
function getProjection(image) {
const geoKeys = image.geoKeys;
if (!geoKeys) {
return null;
}
if (geoKeys.ProjectedCSTypeGeoKey && geoKeys.ProjectedCSTypeGeoKey !== 32767) {
const code = "EPSG:" + geoKeys.ProjectedCSTypeGeoKey;
let projection = get(code);
if (!projection) {
const units = fromCode(geoKeys.ProjLinearUnitsGeoKey);
if (units) {
projection = new Projection_default({
code,
units
});
}
}
return projection;
}
if (geoKeys.GeographicTypeGeoKey && geoKeys.GeographicTypeGeoKey !== 32767) {
const code = "EPSG:" + geoKeys.GeographicTypeGeoKey;
let projection = get(code);
if (!projection) {
const units = fromCode(geoKeys.GeogAngularUnitsGeoKey);
if (units) {
projection = new Projection_default({
code,
units
});
}
}
return projection;
}
return null;
}
function getImagesForTIFF(tiff) {
return tiff.getImageCount().then(function(count) {
const requests = new Array(count);
for (let i = 0; i < count; ++i) {
requests[i] = tiff.getImage(i);
}
return Promise.all(requests);
});
}
function getImagesForSource(source, options) {
let request;
if (source.blob) {
request = fromBlob(source.blob);
} else if (source.overviews) {
request = fromUrls(source.url, source.overviews, options);
} else {
request = fromUrl(source.url, options);
}
return request.then(getImagesForTIFF);
}
function assertEqual(expected, got, tolerance, message, rejector) {
if (Array.isArray(expected)) {
const length = expected.length;
if (!Array.isArray(got) || length != got.length) {
const error2 = new Error(message);
rejector(error2);
throw error2;
}
for (let i = 0; i < length; ++i) {
assertEqual(expected[i], got[i], tolerance, message, rejector);
}
return;
}
got = /** @type {number} */
got;
if (Math.abs(expected - got) > tolerance * expected) {
throw new Error(message);
}
}
function getMinForDataType(array) {
if (array instanceof Int8Array) {
return -128;
}
if (array instanceof Int16Array) {
return -32768;
}
if (array instanceof Int32Array) {
return -2147483648;
}
if (array instanceof Float32Array) {
return 12e-39;
}
return 0;
}
function getMaxForDataType(array) {
if (array instanceof Int8Array) {
return 127;
}
if (array instanceof Uint8Array) {
return 255;
}
if (array instanceof Uint8ClampedArray) {
return 255;
}
if (array instanceof Int16Array) {
return 32767;
}
if (array instanceof Uint16Array) {
return 65535;
}
if (array instanceof Int32Array) {
return 2147483647;
}
if (array instanceof Uint32Array) {
return 4294967295;
}
if (array instanceof Float32Array) {
return 34e37;
}
return 255;
}
var GeoTIFFSource = class extends DataTile_default3 {
/**
* @param {Options} options Data tile options.
*/
constructor(options) {
super({
state: "loading",
tileGrid: null,
projection: options.projection || null,
transition: options.transition,
interpolate: options.interpolate !== false,
wrapX: options.wrapX
});
this.sourceInfo_ = options.sources;
const numSources = this.sourceInfo_.length;
this.sourceOptions_ = options.sourceOptions;
this.sourceImagery_ = new Array(numSources);
this.sourceMasks_ = new Array(numSources);
this.resolutionFactors_ = new Array(numSources);
this.samplesPerPixel_;
this.nodataValues_;
this.metadata_;
this.normalize_ = options.normalize !== false;
this.addAlpha_ = false;
this.error_ = null;
this.convertToRGB_ = options.convertToRGB || false;
this.setKey(this.sourceInfo_.map((source) => source.url).join(","));
const self = this;
const requests = new Array(numSources);
for (let i = 0; i < numSources; ++i) {
requests[i] = getImagesForSource(
this.sourceInfo_[i],
this.sourceOptions_
);
}
Promise.all(requests).then(function(sources) {
self.configure_(sources);
}).catch(function(error2) {
error(error2);
self.error_ = error2;
self.setState("error");
});
}
/**
* @return {Error} A source loading error. When the source state is `error`, use this function
* to get more information about the error. To debug a faulty configuration, you may want to use
* a listener like
* ```js
* geotiffSource.on('change', () => {
* if (geotiffSource.getState() === 'error') {
* console.error(geotiffSource.getError());
* }
* });
* ```
*/
getError() {
return this.error_;
}
/**
* Determine the projection of the images in this GeoTIFF.
* The default implementation looks at the ProjectedCSTypeGeoKey and the GeographicTypeGeoKey
* of each image in turn.
* You can override this method in a subclass to support more projections.
*
* @param {Array<Array<GeoTIFFImage>>} sources Each source is a list of images
* from a single GeoTIFF.
*/
determineProjection(sources) {
const firstSource = sources[0];
for (let i = firstSource.length - 1; i >= 0; --i) {
const image = firstSource[i];
const projection = getProjection(image);
if (projection) {
this.projection = projection;
break;
}
}
}
/**
* Determine any transform matrix for the images in this GeoTIFF.
*
* @param {Array<Array<GeoTIFFImage>>} sources Each source is a list of images
* from a single GeoTIFF.
*/
determineTransformMatrix(sources) {
const firstSource = sources[0];
for (let i = firstSource.length - 1; i >= 0; --i) {
const image = firstSource[i];
const modelTransformation = image.fileDirectory.ModelTransformation;
if (modelTransformation) {
const [a, b, c, d, e, f, g, h] = modelTransformation;
const matrix = multiply(
multiply(
[
1 / Math.sqrt(a * a + e * e),
0,
0,
-1 / Math.sqrt(b * b + f * f),
d,
h
],
[a, e, b, f, 0, 0]
),
[1, 0, 0, 1, -d, -h]
);
this.transformMatrix = matrix;
this.addAlpha_ = true;
break;
}
}
}
/**
* Configure the tile grid based on images within the source GeoTIFFs. Each GeoTIFF
* must have the same internal tiled structure.
* @param {Array<Array<GeoTIFFImage>>} sources Each source is a list of images
* from a single GeoTIFF.
* @private
*/
configure_(sources) {
let extent;
let origin;
let commonRenderTileSizes;
let commonSourceTileSizes;
let resolutions;
const samplesPerPixel = new Array(sources.length);
const nodataValues = new Array(sources.length);
const metadata = new Array(sources.length);
let minZoom = 0;
const sourceCount = sources.length;
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
const images = [];
const masks = [];
sources[sourceIndex].forEach((item) => {
if (isMask(item)) {
masks.push(item);
} else {
images.push(item);
}
});
const imageCount = images.length;
if (masks.length > 0 && masks.length !== imageCount) {
throw new Error(
`Expected one mask per image found ${masks.length} masks and ${imageCount} images`
);
}
let sourceExtent;
let sourceOrigin;
const sourceTileSizes = new Array(imageCount);
const renderTileSizes = new Array(imageCount);
const sourceResolutions = new Array(imageCount);
nodataValues[sourceIndex] = new Array(imageCount);
metadata[sourceIndex] = new Array(imageCount);
for (let imageIndex = 0; imageIndex < imageCount; ++imageIndex) {
const image = images[imageIndex];
const nodataValue = image.getGDALNoData();
metadata[sourceIndex][imageIndex] = image.getGDALMetadata(0);
nodataValues[sourceIndex][imageIndex] = nodataValue;
const wantedSamples = this.sourceInfo_[sourceIndex].bands;
samplesPerPixel[sourceIndex] = wantedSamples ? wantedSamples.length : image.getSamplesPerPixel();
const level = imageCount - (imageIndex + 1);
if (!sourceExtent) {
sourceExtent = getBoundingBox(image);
}
if (!sourceOrigin) {
sourceOrigin = getOrigin(image);
}
const imageResolutions = getResolutions(image, images[0]);
sourceResolutions[level] = imageResolutions[0];
const sourceTileSize = [image.getTileWidth(), image.getTileHeight()];
if (sourceTileSize[0] !== sourceTileSize[1] && sourceTileSize[1] < defaultTileSize) {
sourceTileSize[0] = defaultTileSize;
sourceTileSize[1] = defaultTileSize;
}
sourceTileSizes[level] = sourceTileSize;
const aspectRatio = imageResolutions[0] / Math.abs(imageResolutions[1]);
renderTileSizes[level] = [
sourceTileSize[0],
sourceTileSize[1] / aspectRatio
];
}
if (!extent) {
extent = sourceExtent;
} else {
getIntersection(extent, sourceExtent, extent);
}
if (!origin) {
origin = sourceOrigin;
} else {
const message = `Origin mismatch for source ${sourceIndex}, got [${sourceOrigin}] but expected [${origin}]`;
assertEqual(origin, sourceOrigin, 0, message, this.viewRejector);
}
if (!resolutions) {
resolutions = sourceResolutions;
this.resolutionFactors_[sourceIndex] = 1;
} else {
if (resolutions.length - minZoom > sourceResolutions.length) {
minZoom = resolutions.length - sourceResolutions.length;
}
const resolutionFactor = resolutions[resolutions.length - 1] / sourceResolutions[sourceResolutions.length - 1];
this.resolutionFactors_[sourceIndex] = resolutionFactor;
const scaledSourceResolutions = sourceResolutions.map(
(resolution) => resolution *= resolutionFactor
);
const message = `Resolution mismatch for source ${sourceIndex}, got [${scaledSourceResolutions}] but expected [${resolutions}]`;
assertEqual(
resolutions.slice(minZoom, resolutions.length),
scaledSourceResolutions,
0.02,
message,
this.viewRejector
);
}
if (!commonRenderTileSizes) {
commonRenderTileSizes = renderTileSizes;
} else {
assertEqual(
commonRenderTileSizes.slice(minZoom, commonRenderTileSizes.length),
renderTileSizes,
0.01,
`Tile size mismatch for source ${sourceIndex}`,
this.viewRejector
);
}
if (!commonSourceTileSizes) {
commonSourceTileSizes = sourceTileSizes;
} else {
assertEqual(
commonSourceTileSizes.slice(minZoom, commonSourceTileSizes.length),
sourceTileSizes,
0,
`Tile size mismatch for source ${sourceIndex}`,
this.viewRejector
);
}
this.sourceImagery_[sourceIndex] = images.reverse();
this.sourceMasks_[sourceIndex] = masks.reverse();
}
for (let i = 0, ii = this.sourceImagery_.length; i < ii; ++i) {
const sourceImagery = this.sourceImagery_[i];
while (sourceImagery.length < resolutions.length) {
sourceImagery.unshift(void 0);
}
}
if (!this.getProjection()) {
this.determineProjection(sources);
}
this.determineTransformMatrix(sources);
this.samplesPerPixel_ = samplesPerPixel;
this.nodataValues_ = nodataValues;
this.metadata_ = metadata;
outer: for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
if (this.sourceInfo_[sourceIndex].nodata !== void 0) {
this.addAlpha_ = true;
break;
}
if (this.sourceMasks_[sourceIndex].length) {
this.addAlpha_ = true;
break;
}
const values2 = nodataValues[sourceIndex];
const bands = this.sourceInfo_[sourceIndex].bands;
if (bands) {
for (let i = 0; i < bands.length; ++i) {
if (values2[bands[i] - 1] !== null) {
this.addAlpha_ = true;
break outer;
}
}
continue;
}
for (let imageIndex = 0; imageIndex < values2.length; ++imageIndex) {
if (values2[imageIndex] !== null) {
this.addAlpha_ = true;
break outer;
}
}
}
let bandCount = this.addAlpha_ ? 1 : 0;
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
bandCount += samplesPerPixel[sourceIndex];
}
this.bandCount = bandCount;
const tileGrid = new TileGrid_default({
extent,
minZoom,
origin,
resolutions,
tileSizes: commonRenderTileSizes
});
this.tileGrid = tileGrid;
this.setTileSizes(commonSourceTileSizes);
this.setLoader(this.loadTile_.bind(this));
this.setState("ready");
const zoom = 1;
if (resolutions.length === 2) {
resolutions = [resolutions[0], resolutions[1], resolutions[1] / 2];
} else if (resolutions.length === 1) {
resolutions = [resolutions[0] * 2, resolutions[0], resolutions[0] / 2];
}
let viewExtent = extent;
if (this.transformMatrix) {
const matrix = makeInverse(create(), this.transformMatrix.slice());
const transformFn = createTransformFromCoordinateTransform(
(input) => apply(matrix, input)
);
viewExtent = applyTransform(extent, transformFn);
}
this.viewResolver({
showFullExtent: true,
projection: this.projection,
resolutions,
center: toUserCoordinate(getCenter(viewExtent), this.projection),
extent: toUserExtent(viewExtent, this.projection),
zoom
});
}
/**
* @param {number} z The z tile index.
* @param {number} x The x tile index.
* @param {number} y The y tile index.
* @param {import('./DataTile.js').LoaderOptions} options The loader options.
* @return {Promise} The composed tile data.
* @private
*/
loadTile_(z, x, y, options) {
const sourceTileSize = this.getTileSize(z);
const sourceCount = this.sourceImagery_.length;
const requests = new Array(sourceCount * 2);
const nodataValues = this.nodataValues_;
const sourceInfo = this.sourceInfo_;
const pool = getWorkerPool();
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
const source = sourceInfo[sourceIndex];
const resolutionFactor = this.resolutionFactors_[sourceIndex];
const pixelBounds = [
Math.round(x * (sourceTileSize[0] * resolutionFactor)),
Math.round(y * (sourceTileSize[1] * resolutionFactor)),
Math.round((x + 1) * (sourceTileSize[0] * resolutionFactor)),
Math.round((y + 1) * (sourceTileSize[1] * resolutionFactor))
];
const image = this.sourceImagery_[sourceIndex][z];
let samples;
if (source.bands) {
samples = source.bands.map(function(bandNumber) {
return bandNumber - 1;
});
}
let fillValue;
if ("nodata" in source && source.nodata !== null) {
fillValue = source.nodata;
} else {
if (!samples) {
fillValue = nodataValues[sourceIndex];
} else {
fillValue = samples.map(function(sampleIndex) {
return nodataValues[sourceIndex][sampleIndex];
});
}
}
const readOptions = {
window: pixelBounds,
width: sourceTileSize[0],
height: sourceTileSize[1],
samples,
fillValue,
pool,
interleave: false,
signal: options.signal
};
if (readRGB(this.convertToRGB_, image)) {
requests[sourceIndex] = image.readRGB(readOptions);
} else {
requests[sourceIndex] = image.readRasters(readOptions);
}
const maskIndex = sourceCount + sourceIndex;
const mask = this.sourceMasks_[sourceIndex][z];
if (!mask) {
requests[maskIndex] = Promise.resolve(null);
continue;
}
requests[maskIndex] = mask.readRasters({
window: pixelBounds,
width: sourceTileSize[0],
height: sourceTileSize[1],
samples: [0],
pool,
interleave: false
});
}
return Promise.all(requests).then(this.composeTile_.bind(this, sourceTileSize)).catch(function(error2) {
error(error2);
throw error2;
});
}
/**
* @param {import("../size.js").Size} sourceTileSize The source tile size.
* @param {Array} sourceSamples The source samples.
* @return {import("../DataTile.js").Data} The composed tile data.
* @private
*/
composeTile_(sourceTileSize, sourceSamples) {
const metadata = this.metadata_;
const sourceInfo = this.sourceInfo_;
const sourceCount = this.sourceImagery_.length;
const bandCount = this.bandCount;
const samplesPerPixel = this.samplesPerPixel_;
const nodataValues = this.nodataValues_;
const normalize = this.normalize_;
const addAlpha = this.addAlpha_;
const pixelCount = sourceTileSize[0] * sourceTileSize[1];
const dataLength = pixelCount * bandCount;
let data;
if (normalize) {
data = new Uint8Array(dataLength);
} else {
data = new Float32Array(dataLength);
}
let dataIndex = 0;
for (let pixelIndex = 0; pixelIndex < pixelCount; ++pixelIndex) {
let transparent = addAlpha;
for (let sourceIndex = 0; sourceIndex < sourceCount; ++sourceIndex) {
const source = sourceInfo[sourceIndex];
let min = source.min;
let max = source.max;
let gain, bias;
if (normalize) {
const stats = metadata[sourceIndex][0];
if (min === void 0) {
if (stats && STATISTICS_MINIMUM in stats) {
min = parseFloat(stats[STATISTICS_MINIMUM]);
} else {
min = getMinForDataType(sourceSamples[sourceIndex][0]);
}
}
if (max === void 0) {
if (stats && STATISTICS_MAXIMUM in stats) {
max = parseFloat(stats[STATISTICS_MAXIMUM]);
} else {
max = getMaxForDataType(sourceSamples[sourceIndex][0]);
}
}
gain = 255 / (max - min);
bias = -min * gain;
}
for (let sampleIndex = 0; sampleIndex < samplesPerPixel[sourceIndex]; ++sampleIndex) {
const sourceValue = sourceSamples[sourceIndex][sampleIndex][pixelIndex];
let value;
if (normalize) {
value = clamp(gain * sourceValue + bias, 0, 255);
} else {
value = sourceValue;
}
if (!addAlpha) {
data[dataIndex] = value;
} else {
let nodata = source.nodata;
if (nodata === void 0) {
let bandIndex;
if (source.bands) {
bandIndex = source.bands[sampleIndex] - 1;
} else {
bandIndex = sampleIndex;
}
nodata = nodataValues[sourceIndex][bandIndex];
}
const nodataIsNaN = isNaN(nodata);
if (!nodataIsNaN && sourceValue !== nodata || nodataIsNaN && !isNaN(sourceValue)) {
transparent = false;
data[dataIndex] = value;
}
}
dataIndex++;
}
if (!transparent) {
const maskIndex = sourceCount + sourceIndex;
const mask = sourceSamples[maskIndex];
if (mask && !mask[0][pixelIndex]) {
transparent = true;
}
}
}
if (addAlpha) {
if (!transparent) {
data[dataIndex] = 255;
}
dataIndex++;
}
}
return data;
}
};
GeoTIFFSource.prototype.getView;
var GeoTIFF_default = GeoTIFFSource;
// node_modules/ol/source/Google.js
var maxZoom = 22;
var Google = class extends TileImage_default {
/**
* @param {Options} options Google Maps options.
*/
constructor(options) {
const highDpi = !!options.highDpi;
super({
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
crossOrigin: "anonymous",
interpolate: options.interpolate,
projection: "EPSG:3857",
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: "loading",
tileLoadFunction: options.tileLoadFunction,
tilePixelRatio: highDpi ? 2 : 1,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition,
zDirection: options.zDirection
});
this.apiKey_ = options.key;
this.error_ = null;
const sessionTokenRequest = {
mapType: options.mapType || "roadmap",
language: options.language || "en-US",
region: options.region || "US"
};
if (options.imageFormat) {
sessionTokenRequest.imageFormat = options.imageFormat;
}
if (options.scale) {
sessionTokenRequest.scale = options.scale;
}
if (highDpi) {
sessionTokenRequest.highDpi = true;
}
if (options.layerTypes) {
sessionTokenRequest.layerTypes = options.layerTypes;
}
if (options.styles) {
sessionTokenRequest.styles = options.styles;
}
if (options.overlay === true) {
sessionTokenRequest.overlay = true;
}
if (options.apiOptions) {
sessionTokenRequest.apiOptions = options.apiOptions;
}
this.sessionTokenRequest_ = sessionTokenRequest;
this.sessionTokenValue_;
this.sessionRefreshId_;
this.previousViewportAttribution_;
this.previousViewportExtent_;
const baseUrl = options.url || "https://tile.googleapis.com/";
this.createSessionUrl_ = baseUrl + "v1/createSession";
this.tileUrl_ = baseUrl + "v1/2dtiles";
this.attributionUrl_ = baseUrl + "tile/v1/viewport";
this.createSession_();
}
/**
* @return {Error|null} A source loading error. When the source state is `error`, use this function
* to get more information about the error. To debug a faulty configuration, you may want to use
* a listener like
* ```js
* source.on('change', () => {
* if (source.getState() === 'error') {
* console.error(source.getError());
* }
* });
* ```
*/
getError() {
return this.error_;
}
/**
* Exposed here so it can be overridden in the tests.
* @param {string} url The URL.
* @param {RequestInit} config The config.
* @return {Promise<Response>} A promise that resolves with the response.
*/
fetchSessionToken(url, config) {
return fetch(url, config);
}
/**
* Get or renew a session token for use with tile requests.
* @private
*/
async createSession_() {
const url = this.createSessionUrl_ + "?key=" + this.apiKey_;
const config = {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify(this.sessionTokenRequest_)
};
const response = await this.fetchSessionToken(url, config);
if (!response.ok) {
try {
const body = await response.json();
this.error_ = new Error(body.error.message);
} catch {
this.error_ = new Error("Error fetching session token");
}
this.setState("error");
return;
}
const sessionTokenResponse = await response.json();
const tilePixelRatio = this.getTilePixelRatio(1);
const tileSize = [
sessionTokenResponse.tileWidth / tilePixelRatio,
sessionTokenResponse.tileHeight / tilePixelRatio
];
this.tileGrid = createXYZ({
extent: extentFromProjection(this.getProjection()),
maxZoom,
tileSize
});
const session = sessionTokenResponse.session;
this.sessionTokenValue_ = session;
const key = this.apiKey_;
const tileUrl = this.tileUrl_;
this.tileUrlFunction = function(tileCoord, pixelRatio, projection) {
const z = tileCoord[0];
const x = tileCoord[1];
const y = tileCoord[2];
const url2 = `${tileUrl}/${z}/${x}/${y}?session=${session}&key=${key}`;
return url2;
};
const expiry = parseInt(sessionTokenResponse.expiry, 10) * 1e3;
const timeout = Math.max(expiry - Date.now() - 60 * 1e3, 1);
this.sessionRefreshId_ = setTimeout(() => this.createSession_(), timeout);
this.setAttributions(this.fetchAttributions_.bind(this));
this.setState("ready");
}
/**
* @param {import('../Map.js').FrameState} frameState The frame state.
* @return {Promise<string>} The attributions.
* @private
*/
async fetchAttributions_(frameState) {
if (frameState.viewHints[ViewHint_default.ANIMATING] || frameState.viewHints[ViewHint_default.INTERACTING] || frameState.animate) {
return this.previousViewportAttribution_;
}
const [west, south] = toLonLat(
getBottomLeft(frameState.extent),
frameState.viewState.projection
);
const [east, north] = toLonLat(
getTopRight(frameState.extent),
frameState.viewState.projection
);
const tileGrid = this.getTileGrid();
const zoom = tileGrid.getZForResolution(
frameState.viewState.resolution,
this.zDirection
);
const viewportExtent = `zoom=${zoom}&north=${north}&south=${south}&east=${east}&west=${west}`;
if (this.previousViewportExtent_ == viewportExtent) {
return this.previousViewportAttribution_;
}
this.previousViewportExtent_ = viewportExtent;
const session = this.sessionTokenValue_;
const key = this.apiKey_;
const attributionUrl = this.attributionUrl_;
const url = `${attributionUrl}?session=${session}&key=${key}&${viewportExtent}`;
this.previousViewportAttribution_ = await fetch(url).then((response) => response.json()).then((json) => json.copyright);
return this.previousViewportAttribution_;
}
/**
* @override
*/
disposeInternal() {
clearTimeout(this.sessionRefreshId_);
super.disposeInternal();
}
};
var Google_default = Google;
// node_modules/ol/format/IIIFInfo.js
var Versions = {
VERSION1: "version1",
VERSION2: "version2",
VERSION3: "version3"
};
var IIIF_PROFILE_VALUES = {};
IIIF_PROFILE_VALUES[Versions.VERSION1] = {
"level0": {
supports: [],
formats: [],
qualities: ["native"]
},
"level1": {
supports: ["regionByPx", "sizeByW", "sizeByH", "sizeByPct"],
formats: ["jpg"],
qualities: ["native"]
},
"level2": {
supports: [
"regionByPx",
"regionByPct",
"sizeByW",
"sizeByH",
"sizeByPct",
"sizeByConfinedWh",
"sizeByWh"
],
formats: ["jpg", "png"],
qualities: ["native", "color", "grey", "bitonal"]
}
};
IIIF_PROFILE_VALUES[Versions.VERSION2] = {
"level0": {
supports: [],
formats: ["jpg"],
qualities: ["default"]
},
"level1": {
supports: ["regionByPx", "sizeByW", "sizeByH", "sizeByPct"],
formats: ["jpg"],
qualities: ["default"]
},
"level2": {
supports: [
"regionByPx",
"regionByPct",
"sizeByW",
"sizeByH",
"sizeByPct",
"sizeByConfinedWh",
"sizeByDistortedWh",
"sizeByWh"
],
formats: ["jpg", "png"],
qualities: ["default", "bitonal"]
}
};
IIIF_PROFILE_VALUES[Versions.VERSION3] = {
"level0": {
supports: [],
formats: ["jpg"],
qualities: ["default"]
},
"level1": {
supports: ["regionByPx", "regionSquare", "sizeByW", "sizeByH", "sizeByWh"],
formats: ["jpg"],
qualities: ["default"]
},
"level2": {
supports: [
"regionByPx",
"regionSquare",
"regionByPct",
"sizeByW",
"sizeByH",
"sizeByPct",
"sizeByConfinedWh",
"sizeByWh"
],
formats: ["jpg", "png"],
qualities: ["default"]
}
};
IIIF_PROFILE_VALUES["none"] = {
"none": {
supports: [],
formats: [],
qualities: []
}
};
function generateVersion1Options(iiifInfo) {
let levelProfile = iiifInfo.getComplianceLevelSupportedFeatures();
if (levelProfile === void 0) {
levelProfile = IIIF_PROFILE_VALUES[Versions.VERSION1]["level0"];
}
return {
url: iiifInfo.imageInfo["@id"] === void 0 ? void 0 : iiifInfo.imageInfo["@id"].replace(/\/?(?:info\.json)?$/g, ""),
supports: levelProfile.supports,
formats: [
...levelProfile.formats,
iiifInfo.imageInfo.formats === void 0 ? [] : iiifInfo.imageInfo.formats
],
qualities: [
...levelProfile.qualities,
iiifInfo.imageInfo.qualities === void 0 ? [] : iiifInfo.imageInfo.qualities
],
resolutions: iiifInfo.imageInfo.scale_factors,
tileSize: iiifInfo.imageInfo.tile_width !== void 0 ? iiifInfo.imageInfo.tile_height !== void 0 ? [iiifInfo.imageInfo.tile_width, iiifInfo.imageInfo.tile_height] : [iiifInfo.imageInfo.tile_width, iiifInfo.imageInfo.tile_width] : iiifInfo.imageInfo.tile_height != void 0 ? [iiifInfo.imageInfo.tile_height, iiifInfo.imageInfo.tile_height] : void 0
};
}
function generateVersion2Options(iiifInfo) {
const levelProfile = iiifInfo.getComplianceLevelSupportedFeatures(), additionalProfile = Array.isArray(iiifInfo.imageInfo.profile) && iiifInfo.imageInfo.profile.length > 1, profileSupports = additionalProfile && iiifInfo.imageInfo.profile[1].supports ? iiifInfo.imageInfo.profile[1].supports : [], profileFormats = additionalProfile && iiifInfo.imageInfo.profile[1].formats ? iiifInfo.imageInfo.profile[1].formats : [], profileQualities = additionalProfile && iiifInfo.imageInfo.profile[1].qualities ? iiifInfo.imageInfo.profile[1].qualities : [];
return {
url: iiifInfo.imageInfo["@id"].replace(/\/?(?:info\.json)?$/g, ""),
sizes: iiifInfo.imageInfo.sizes === void 0 ? void 0 : iiifInfo.imageInfo.sizes.map(function(size) {
return [size.width, size.height];
}),
tileSize: iiifInfo.imageInfo.tiles === void 0 ? void 0 : [
iiifInfo.imageInfo.tiles.map(function(tile) {
return tile.width;
})[0],
iiifInfo.imageInfo.tiles.map(function(tile) {
return tile.height === void 0 ? tile.width : tile.height;
})[0]
],
resolutions: iiifInfo.imageInfo.tiles === void 0 ? void 0 : iiifInfo.imageInfo.tiles.map(function(tile) {
return tile.scaleFactors;
})[0],
supports: [...levelProfile.supports, ...profileSupports],
formats: [...levelProfile.formats, ...profileFormats],
qualities: [...levelProfile.qualities, ...profileQualities]
};
}
function generateVersion3Options(iiifInfo) {
const levelProfile = iiifInfo.getComplianceLevelSupportedFeatures(), formats = iiifInfo.imageInfo.extraFormats === void 0 ? levelProfile.formats : [...levelProfile.formats, ...iiifInfo.imageInfo.extraFormats], preferredFormat = iiifInfo.imageInfo.preferredFormats !== void 0 && Array.isArray(iiifInfo.imageInfo.preferredFormats) && iiifInfo.imageInfo.preferredFormats.length > 0 ? iiifInfo.imageInfo.preferredFormats.filter(function(format) {
return ["jpg", "png", "gif"].includes(format);
}).reduce(function(acc, format) {
return acc === void 0 && formats.includes(format) ? format : acc;
}, void 0) : void 0;
return {
url: iiifInfo.imageInfo["id"],
sizes: iiifInfo.imageInfo.sizes === void 0 ? void 0 : iiifInfo.imageInfo.sizes.map(function(size) {
return [size.width, size.height];
}),
tileSize: iiifInfo.imageInfo.tiles === void 0 ? void 0 : [
iiifInfo.imageInfo.tiles.map(function(tile) {
return tile.width;
})[0],
iiifInfo.imageInfo.tiles.map(function(tile) {
return tile.height;
})[0]
],
resolutions: iiifInfo.imageInfo.tiles === void 0 ? void 0 : iiifInfo.imageInfo.tiles.map(function(tile) {
return tile.scaleFactors;
})[0],
supports: iiifInfo.imageInfo.extraFeatures === void 0 ? levelProfile.supports : [...levelProfile.supports, ...iiifInfo.imageInfo.extraFeatures],
formats,
qualities: iiifInfo.imageInfo.extraQualities === void 0 ? levelProfile.qualities : [...levelProfile.qualities, ...iiifInfo.imageInfo.extraQualities],
preferredFormat
};
}
var versionFunctions = {};
versionFunctions[Versions.VERSION1] = generateVersion1Options;
versionFunctions[Versions.VERSION2] = generateVersion2Options;
versionFunctions[Versions.VERSION3] = generateVersion3Options;
// node_modules/ol/source/Zoomify.js
var CustomTile = class extends ImageTile_default {
/**
* @param {import("../size.js").Size} tileSize Full tile size.
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("../TileState.js").default} state State.
* @param {string} src Image source URI.
* @param {?string} crossOrigin Cross origin.
* @param {import("../Tile.js").LoadFunction} tileLoadFunction Tile load function.
* @param {import("../Tile.js").Options} [options] Tile options.
*/
constructor(tileSize, tileCoord, state, src, crossOrigin, tileLoadFunction, options) {
super(tileCoord, state, src, crossOrigin, tileLoadFunction, options);
this.zoomifyImage_ = null;
this.tileSize_ = tileSize;
}
/**
* Get the image element for this tile.
* @return {HTMLCanvasElement|OffscreenCanvas|HTMLImageElement|HTMLVideoElement} Image.
* @override
*/
getImage() {
if (this.zoomifyImage_) {
return this.zoomifyImage_;
}
const image = super.getImage();
if (this.state == TileState_default.LOADED) {
const tileSize = this.tileSize_;
if (image.width == tileSize[0] && image.height == tileSize[1]) {
this.zoomifyImage_ = image;
return image;
}
const context = createCanvasContext2D(tileSize[0], tileSize[1]);
context.drawImage(image, 0, 0);
this.zoomifyImage_ = context.canvas;
return context.canvas;
}
return image;
}
};
var Zoomify = class extends TileImage_default {
/**
* @param {Options} options Options.
*/
constructor(options) {
const size = options.size;
const tierSizeCalculation = options.tierSizeCalculation !== void 0 ? options.tierSizeCalculation : "default";
const tilePixelRatio = options.tilePixelRatio || 1;
const imageWidth = size[0];
const imageHeight = size[1];
const tierSizeInTiles = [];
const tileSize = options.tileSize || DEFAULT_TILE_SIZE;
let tileSizeForTierSizeCalculation = tileSize * tilePixelRatio;
switch (tierSizeCalculation) {
case "default":
while (imageWidth > tileSizeForTierSizeCalculation || imageHeight > tileSizeForTierSizeCalculation) {
tierSizeInTiles.push([
Math.ceil(imageWidth / tileSizeForTierSizeCalculation),
Math.ceil(imageHeight / tileSizeForTierSizeCalculation)
]);
tileSizeForTierSizeCalculation += tileSizeForTierSizeCalculation;
}
break;
case "truncated":
let width = imageWidth;
let height = imageHeight;
while (width > tileSizeForTierSizeCalculation || height > tileSizeForTierSizeCalculation) {
tierSizeInTiles.push([
Math.ceil(width / tileSizeForTierSizeCalculation),
Math.ceil(height / tileSizeForTierSizeCalculation)
]);
width >>= 1;
height >>= 1;
}
break;
default:
throw new Error("Unknown `tierSizeCalculation` configured");
}
tierSizeInTiles.push([1, 1]);
tierSizeInTiles.reverse();
const resolutions = [tilePixelRatio];
const tileCountUpToTier = [0];
for (let i = 1, ii = tierSizeInTiles.length; i < ii; i++) {
resolutions.push(tilePixelRatio << i);
tileCountUpToTier.push(
tierSizeInTiles[i - 1][0] * tierSizeInTiles[i - 1][1] + tileCountUpToTier[i - 1]
);
}
resolutions.reverse();
const tileGrid = new TileGrid_default({
tileSize,
extent: options.extent || [0, -imageHeight, imageWidth, 0],
resolutions
});
let url = options.url;
if (url && !url.includes("{TileGroup}") && !url.includes("{tileIndex}")) {
url += "{TileGroup}/{z}-{x}-{y}.jpg";
}
const urls = expandUrl(url);
let tileWidth = tileSize * tilePixelRatio;
function createFromTemplate(template) {
return (
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile Coordinate.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {string|undefined} Tile URL.
*/
(function(tileCoord, pixelRatio, projection) {
if (!tileCoord) {
return void 0;
}
const tileCoordZ = tileCoord[0];
const tileCoordX = tileCoord[1];
const tileCoordY = tileCoord[2];
const tileIndex = tileCoordX + tileCoordY * tierSizeInTiles[tileCoordZ][0];
const tileGroup = (tileIndex + tileCountUpToTier[tileCoordZ]) / tileWidth | 0;
const localContext = {
"z": tileCoordZ,
"x": tileCoordX,
"y": tileCoordY,
"tileIndex": tileIndex,
"TileGroup": "TileGroup" + tileGroup
};
return template.replace(/\{(\w+?)\}/g, function(m, p) {
return localContext[p];
});
})
);
}
const tileUrlFunction = createFromTileUrlFunctions(
urls.map(createFromTemplate)
);
const ZoomifyTileClass = CustomTile.bind(
null,
toSize(tileSize * tilePixelRatio)
);
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
interpolate: options.interpolate,
projection: options.projection,
tilePixelRatio,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileClass: ZoomifyTileClass,
tileGrid,
tileUrlFunction,
transition: options.transition
});
this.zDirection = options.zDirection;
const tileUrl = tileGrid.getTileCoordForCoordAndResolution(
getCenter(tileGrid.getExtent()),
resolutions[resolutions.length - 1]
);
const testTileUrl = tileUrlFunction(tileUrl, 1, null);
const image = new Image();
image.addEventListener("error", () => {
tileWidth = tileSize;
this.changed();
});
image.src = testTileUrl;
}
};
var Zoomify_default = Zoomify;
// node_modules/ol/source/IIIF.js
function formatPercentage(percentage) {
return percentage.toLocaleString("en", { maximumFractionDigits: 10 });
}
var IIIF = class extends TileImage_default {
/**
* @param {Options} [options] Tile source options. Use {@link import("../format/IIIFInfo.js").IIIFInfo}
* to parse Image API service information responses into constructor options.
* @api
*/
constructor(options) {
const partialOptions = options || {};
let baseUrl = partialOptions.url || "";
baseUrl = baseUrl + (baseUrl.lastIndexOf("/") === baseUrl.length - 1 || baseUrl === "" ? "" : "/");
const version = partialOptions.version || Versions.VERSION2;
const sizes = partialOptions.sizes || [];
const size = partialOptions.size;
assert(
size != void 0 && Array.isArray(size) && size.length == 2 && !isNaN(size[0]) && size[0] > 0 && !isNaN(size[1]) && size[1] > 0,
"Missing or invalid `size`"
);
const width = size[0];
const height = size[1];
const tileSize = partialOptions.tileSize;
const tilePixelRatio = partialOptions.tilePixelRatio || 1;
const format = partialOptions.format || "jpg";
const quality = partialOptions.quality || (partialOptions.version == Versions.VERSION1 ? "native" : "default");
let resolutions = partialOptions.resolutions || [];
const supports = partialOptions.supports || [];
const extent = partialOptions.extent || [0, -height, width, 0];
const supportsListedSizes = sizes != void 0 && Array.isArray(sizes) && sizes.length > 0;
const supportsListedTiles = tileSize !== void 0 && (typeof tileSize === "number" && Number.isInteger(tileSize) && tileSize > 0 || Array.isArray(tileSize) && tileSize.length > 0);
const supportsArbitraryTiling = supports != void 0 && Array.isArray(supports) && (supports.includes("regionByPx") || supports.includes("regionByPct")) && (supports.includes("sizeByWh") || supports.includes("sizeByH") || supports.includes("sizeByW") || supports.includes("sizeByPct"));
let tileWidth, tileHeight, maxZoom2;
resolutions.sort(function(a, b) {
return b - a;
});
if (supportsListedTiles || supportsArbitraryTiling) {
if (tileSize != void 0) {
if (typeof tileSize === "number" && Number.isInteger(tileSize) && tileSize > 0) {
tileWidth = tileSize;
tileHeight = tileSize;
} else if (Array.isArray(tileSize) && tileSize.length > 0) {
if (tileSize.length == 1 || tileSize[1] == void 0 && Number.isInteger(tileSize[0])) {
tileWidth = tileSize[0];
tileHeight = tileSize[0];
}
if (tileSize.length == 2) {
if (Number.isInteger(tileSize[0]) && Number.isInteger(tileSize[1])) {
tileWidth = tileSize[0];
tileHeight = tileSize[1];
} else if (tileSize[0] == void 0 && Number.isInteger(tileSize[1])) {
tileWidth = tileSize[1];
tileHeight = tileSize[1];
}
}
}
}
if (tileWidth === void 0 || tileHeight === void 0) {
tileWidth = DEFAULT_TILE_SIZE;
tileHeight = DEFAULT_TILE_SIZE;
}
if (resolutions.length == 0) {
maxZoom2 = Math.max(
Math.ceil(Math.log(width / tileWidth) / Math.LN2),
Math.ceil(Math.log(height / tileHeight) / Math.LN2)
);
for (let i = maxZoom2; i >= 0; i--) {
resolutions.push(Math.pow(2, i));
}
} else {
const maxScaleFactor = Math.max(...resolutions);
maxZoom2 = Math.round(Math.log(maxScaleFactor) / Math.LN2);
}
} else {
tileWidth = width;
tileHeight = height;
resolutions = [];
if (supportsListedSizes) {
sizes.sort(function(a, b) {
return a[0] - b[0];
});
maxZoom2 = -1;
const ignoredSizesIndex = [];
for (let i = 0; i < sizes.length; i++) {
const resolution = width / sizes[i][0];
if (resolutions.length > 0 && resolutions[resolutions.length - 1] == resolution) {
ignoredSizesIndex.push(i);
continue;
}
resolutions.push(resolution);
maxZoom2++;
}
if (ignoredSizesIndex.length > 0) {
for (let i = 0; i < ignoredSizesIndex.length; i++) {
sizes.splice(ignoredSizesIndex[i] - i, 1);
}
}
} else {
resolutions.push(1);
sizes.push([width, height]);
maxZoom2 = 0;
}
}
const tileGrid = new TileGrid_default({
tileSize: [tileWidth, tileHeight],
extent,
origin: getTopLeft(extent),
resolutions
});
const tileUrlFunction = function(tileCoord, pixelRatio, projection) {
let regionParam, sizeParam;
const zoom = tileCoord[0];
if (zoom > maxZoom2) {
return;
}
const tileX = tileCoord[1], tileY = tileCoord[2], scale4 = resolutions[zoom];
if (tileX === void 0 || tileY === void 0 || scale4 === void 0 || tileX < 0 || Math.ceil(width / scale4 / tileWidth) <= tileX || tileY < 0 || Math.ceil(height / scale4 / tileHeight) <= tileY) {
return;
}
if (supportsArbitraryTiling || supportsListedTiles) {
const regionX = tileX * tileWidth * scale4, regionY = tileY * tileHeight * scale4;
let regionW = tileWidth * scale4, regionH = tileHeight * scale4, sizeW = tileWidth, sizeH = tileHeight;
if (regionX + regionW > width) {
regionW = width - regionX;
}
if (regionY + regionH > height) {
regionH = height - regionY;
}
if (regionX + tileWidth * scale4 > width) {
sizeW = Math.floor((width - regionX + scale4 - 1) / scale4);
}
if (regionY + tileHeight * scale4 > height) {
sizeH = Math.floor((height - regionY + scale4 - 1) / scale4);
}
if (regionX == 0 && regionW == width && regionY == 0 && regionH == height) {
regionParam = "full";
} else if (!supportsArbitraryTiling || supports.includes("regionByPx")) {
regionParam = regionX + "," + regionY + "," + regionW + "," + regionH;
} else if (supports.includes("regionByPct")) {
const pctX = formatPercentage(regionX / width * 100), pctY = formatPercentage(regionY / height * 100), pctW = formatPercentage(regionW / width * 100), pctH = formatPercentage(regionH / height * 100);
regionParam = "pct:" + pctX + "," + pctY + "," + pctW + "," + pctH;
}
if (version == Versions.VERSION3 && (!supportsArbitraryTiling || supports.includes("sizeByWh"))) {
sizeParam = sizeW + "," + sizeH;
} else if (!supportsArbitraryTiling || supports.includes("sizeByW")) {
sizeParam = sizeW + ",";
} else if (supports.includes("sizeByH")) {
sizeParam = "," + sizeH;
} else if (supports.includes("sizeByWh")) {
sizeParam = sizeW + "," + sizeH;
} else if (supports.includes("sizeByPct")) {
sizeParam = "pct:" + formatPercentage(100 / scale4);
}
} else {
regionParam = "full";
if (supportsListedSizes) {
const regionWidth = sizes[zoom][0], regionHeight = sizes[zoom][1];
if (version == Versions.VERSION3) {
if (regionWidth == width && regionHeight == height) {
sizeParam = "max";
} else {
sizeParam = regionWidth + "," + regionHeight;
}
} else {
if (regionWidth == width) {
sizeParam = "full";
} else {
sizeParam = regionWidth + ",";
}
}
} else {
sizeParam = version == Versions.VERSION3 ? "max" : "full";
}
}
return baseUrl + regionParam + "/" + sizeParam + "/0/" + quality + "." + format;
};
const IiifTileClass = CustomTile.bind(
null,
toSize(tileSize || 256).map(function(size2) {
return size2 * tilePixelRatio;
})
);
super({
attributions: partialOptions.attributions,
attributionsCollapsible: partialOptions.attributionsCollapsible,
cacheSize: partialOptions.cacheSize,
crossOrigin: partialOptions.crossOrigin,
interpolate: partialOptions.interpolate,
projection: partialOptions.projection,
reprojectionErrorThreshold: partialOptions.reprojectionErrorThreshold,
state: partialOptions.state,
tileClass: IiifTileClass,
tileGrid,
tilePixelRatio: partialOptions.tilePixelRatio,
tileUrlFunction,
transition: partialOptions.transition
});
this.zDirection = partialOptions.zDirection;
}
};
var IIIF_default = IIIF;
// node_modules/ol/reproj/Image.js
var ReprojImage = class extends Image_default {
/**
* @param {import("../proj/Projection.js").default} sourceProj Source projection (of the data).
* @param {import("../proj/Projection.js").default} targetProj Target projection.
* @param {import("../extent.js").Extent} targetExtent Target extent.
* @param {number} targetResolution Target resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {FunctionType} getImageFunction
* Function returning source images (extent, resolution, pixelRatio).
* @param {boolean} interpolate Use linear interpolation when resampling.
*/
constructor(sourceProj, targetProj, targetExtent, targetResolution, pixelRatio, getImageFunction, interpolate) {
let maxSourceExtent = sourceProj.getExtent();
if (maxSourceExtent && sourceProj.canWrapX()) {
maxSourceExtent = maxSourceExtent.slice();
maxSourceExtent[0] = -Infinity;
maxSourceExtent[2] = Infinity;
}
let maxTargetExtent = targetProj.getExtent();
if (maxTargetExtent && targetProj.canWrapX()) {
maxTargetExtent = maxTargetExtent.slice();
maxTargetExtent[0] = -Infinity;
maxTargetExtent[2] = Infinity;
}
const limitedTargetExtent = maxTargetExtent ? getIntersection(targetExtent, maxTargetExtent) : targetExtent;
const targetCenter = getCenter(limitedTargetExtent);
const sourceResolution = calculateSourceResolution(
sourceProj,
targetProj,
targetCenter,
targetResolution
);
const errorThresholdInPixels = ERROR_THRESHOLD;
const triangulation = new Triangulation_default(
sourceProj,
targetProj,
limitedTargetExtent,
maxSourceExtent,
sourceResolution * errorThresholdInPixels,
targetResolution
);
const sourceExtent = triangulation.calculateSourceExtent();
const sourceImage = isEmpty2(sourceExtent) ? null : getImageFunction(sourceExtent, sourceResolution, pixelRatio);
const state = sourceImage ? ImageState_default.IDLE : ImageState_default.EMPTY;
const sourcePixelRatio = sourceImage ? sourceImage.getPixelRatio() : 1;
super(targetExtent, targetResolution, sourcePixelRatio, state);
this.targetProj_ = targetProj;
this.maxSourceExtent_ = maxSourceExtent;
this.triangulation_ = triangulation;
this.targetResolution_ = targetResolution;
this.targetExtent_ = targetExtent;
this.sourceImage_ = sourceImage;
this.sourcePixelRatio_ = sourcePixelRatio;
this.interpolate_ = interpolate;
this.canvas_ = null;
this.sourceListenerKey_ = null;
}
/**
* Clean up.
* @override
*/
disposeInternal() {
if (this.state == ImageState_default.LOADING) {
this.unlistenSource_();
}
super.disposeInternal();
}
/**
* @return {HTMLCanvasElement|OffscreenCanvas} Image.
* @override
*/
getImage() {
return this.canvas_;
}
/**
* @return {import("../proj/Projection.js").default} Projection.
*/
getProjection() {
return this.targetProj_;
}
/**
* @private
*/
reproject_() {
const sourceState = this.sourceImage_.getState();
if (sourceState == ImageState_default.LOADED) {
const width = getWidth(this.targetExtent_) / this.targetResolution_;
const height = getHeight(this.targetExtent_) / this.targetResolution_;
this.canvas_ = render(
width,
height,
this.sourcePixelRatio_,
fromResolutionLike(this.sourceImage_.getResolution()),
this.maxSourceExtent_,
this.targetResolution_,
this.targetExtent_,
this.triangulation_,
[
{
extent: this.sourceImage_.getExtent(),
image: this.sourceImage_.getImage()
}
],
0,
void 0,
this.interpolate_,
true
);
}
this.state = sourceState;
this.changed();
}
/**
* Load not yet loaded URI.
* @override
*/
load() {
if (this.state == ImageState_default.IDLE) {
this.state = ImageState_default.LOADING;
this.changed();
const sourceState = this.sourceImage_.getState();
if (sourceState == ImageState_default.LOADED || sourceState == ImageState_default.ERROR) {
this.reproject_();
} else {
this.sourceListenerKey_ = listen(
this.sourceImage_,
EventType_default.CHANGE,
(e) => {
const sourceState2 = this.sourceImage_.getState();
if (sourceState2 == ImageState_default.LOADED || sourceState2 == ImageState_default.ERROR) {
this.unlistenSource_();
this.reproject_();
}
}
);
this.sourceImage_.load();
}
}
}
/**
* @private
*/
unlistenSource_() {
unlistenByKey(
/** @type {!import("../events.js").EventsKey} */
this.sourceListenerKey_
);
this.sourceListenerKey_ = null;
}
};
var Image_default3 = ReprojImage;
// node_modules/ol/source/common.js
var DECIMALS = 4;
// node_modules/ol/source/Image.js
var ImageSourceEventType = {
/**
* Triggered when an image starts loading.
* @event module:ol/source/Image.ImageSourceEvent#imageloadstart
* @api
*/
IMAGELOADSTART: "imageloadstart",
/**
* Triggered when an image finishes loading.
* @event module:ol/source/Image.ImageSourceEvent#imageloadend
* @api
*/
IMAGELOADEND: "imageloadend",
/**
* Triggered if image loading results in an error.
* @event module:ol/source/Image.ImageSourceEvent#imageloaderror
* @api
*/
IMAGELOADERROR: "imageloaderror"
};
var ImageSourceEvent = class extends Event_default {
/**
* @param {string} type Type.
* @param {import("../Image.js").default} image The image.
*/
constructor(type, image) {
super(type);
this.image = image;
}
};
var ImageSource = class extends Source_default {
/**
* @param {Options} options Single image source options.
*/
constructor(options) {
super({
attributions: options.attributions,
projection: options.projection,
state: options.state,
interpolate: options.interpolate !== void 0 ? options.interpolate : true
});
this.on;
this.once;
this.un;
this.loader = options.loader || null;
this.resolutions_ = options.resolutions !== void 0 ? options.resolutions : null;
this.reprojectedImage_ = null;
this.reprojectedRevision_ = 0;
this.image = null;
this.wantedExtent_;
this.wantedResolution_;
this.static_ = options.loader ? options.loader.length === 0 : false;
this.wantedProjection_ = null;
}
/**
* @return {Array<number>|null} Resolutions.
* @override
*/
getResolutions() {
return this.resolutions_;
}
/**
* @param {Array<number>|null} resolutions Resolutions.
*/
setResolutions(resolutions) {
this.resolutions_ = resolutions;
}
/**
* @protected
* @param {number} resolution Resolution.
* @return {number} Resolution.
*/
findNearestResolution(resolution) {
const resolutions = this.getResolutions();
if (resolutions) {
const idx = linearFindNearest(resolutions, resolution, 0);
resolution = resolutions[idx];
}
return resolution;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../Image.js").default} Single image.
*/
getImage(extent, resolution, pixelRatio, projection) {
const sourceProjection = this.getProjection();
if (!sourceProjection || !projection || equivalent(sourceProjection, projection)) {
if (sourceProjection) {
projection = sourceProjection;
}
return this.getImageInternal(extent, resolution, pixelRatio, projection);
}
if (this.reprojectedImage_) {
if (this.reprojectedRevision_ == this.getRevision() && equivalent(this.reprojectedImage_.getProjection(), projection) && this.reprojectedImage_.getResolution() == resolution && equals(this.reprojectedImage_.getExtent(), extent)) {
return this.reprojectedImage_;
}
this.reprojectedImage_.dispose();
this.reprojectedImage_ = null;
}
this.reprojectedImage_ = new Image_default3(
sourceProjection,
projection,
extent,
resolution,
pixelRatio,
(extent2, resolution2, pixelRatio2) => this.getImageInternal(extent2, resolution2, pixelRatio2, sourceProjection),
this.getInterpolate()
);
this.reprojectedRevision_ = this.getRevision();
return this.reprojectedImage_;
}
/**
* @abstract
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../Image.js").default} Single image.
* @protected
*/
getImageInternal(extent, resolution, pixelRatio, projection) {
if (this.loader) {
const requestExtent = getRequestExtent(extent, resolution, pixelRatio, 1);
const requestResolution = this.findNearestResolution(resolution);
if (this.image && (this.static_ || this.wantedProjection_ === projection && (this.wantedExtent_ && containsExtent(this.wantedExtent_, requestExtent) || containsExtent(this.image.getExtent(), requestExtent)) && (this.wantedResolution_ && fromResolutionLike(this.wantedResolution_) === requestResolution || fromResolutionLike(this.image.getResolution()) === requestResolution))) {
return this.image;
}
this.wantedProjection_ = projection;
this.wantedExtent_ = requestExtent;
this.wantedResolution_ = requestResolution;
this.image = new Image_default(
requestExtent,
requestResolution,
pixelRatio,
this.loader
);
this.image.addEventListener(
EventType_default.CHANGE,
this.handleImageChange.bind(this)
);
}
return this.image;
}
/**
* Handle image change events.
* @param {import("../events/Event.js").default} event Event.
* @protected
*/
handleImageChange(event) {
const image = (
/** @type {import("../Image.js").default} */
event.target
);
let type;
switch (image.getState()) {
case ImageState_default.LOADING:
this.loading = true;
type = ImageSourceEventType.IMAGELOADSTART;
break;
case ImageState_default.LOADED:
this.loading = false;
type = ImageSourceEventType.IMAGELOADEND;
break;
case ImageState_default.ERROR:
this.loading = false;
type = ImageSourceEventType.IMAGELOADERROR;
break;
default:
return;
}
if (this.hasListener(type)) {
this.dispatchEvent(new ImageSourceEvent(type, image));
}
}
};
function defaultImageLoadFunction(image, src) {
image.getImage().src = src;
}
function getRequestExtent(extent, resolution, pixelRatio, ratio) {
const imageResolution = resolution / pixelRatio;
const center = getCenter(extent);
const viewWidth = ceil(getWidth(extent) / imageResolution, DECIMALS);
const viewHeight = ceil(getHeight(extent) / imageResolution, DECIMALS);
const marginWidth = ceil((ratio - 1) * viewWidth / 2, DECIMALS);
const requestWidth = viewWidth + 2 * marginWidth;
const marginHeight = ceil((ratio - 1) * viewHeight / 2, DECIMALS);
const requestHeight = viewHeight + 2 * marginHeight;
return getForViewAndSize(center, imageResolution, 0, [
requestWidth,
requestHeight
]);
}
var Image_default4 = ImageSource;
// node_modules/ol/source/arcgisRest.js
function getRequestUrl(baseUrl, extent, resolution, pixelRatio, projection, params) {
const srid = projection.getCode().split(/:(?=\d+$)/).pop();
const imageResolution = resolution / pixelRatio;
const imageSize = [
round(getWidth(extent) / imageResolution, DECIMALS),
round(getHeight(extent) / imageResolution, DECIMALS)
];
params["SIZE"] = imageSize[0] + "," + imageSize[1];
params["BBOX"] = extent.join(",");
params["BBOXSR"] = srid;
params["IMAGESR"] = srid;
params["DPI"] = Math.round(
params["DPI"] ? params["DPI"] * pixelRatio : 90 * pixelRatio
);
const modifiedUrl = baseUrl.replace(/MapServer\/?$/, "MapServer/export").replace(/ImageServer\/?$/, "ImageServer/exportImage");
return appendParams(modifiedUrl, params);
}
function createLoader(options) {
const load = options.load ? options.load : decode;
const projection = get(options.projection || "EPSG:3857");
const ratio = options.ratio ?? 1.5;
const crossOrigin = options.crossOrigin ?? null;
return function(extent, resolution, pixelRatio) {
pixelRatio = options.hidpi ? pixelRatio : 1;
const params = {
"F": "image",
"FORMAT": "PNG32",
"TRANSPARENT": true
};
Object.assign(params, options.params);
extent = getRequestExtent(extent, resolution, pixelRatio, ratio);
const src = getRequestUrl(
options.url,
extent,
resolution,
pixelRatio,
projection,
params
);
const image = new Image();
image.crossOrigin = crossOrigin;
return load(image, src).then((image2) => {
const resolution2 = getWidth(extent) / image2.width * pixelRatio;
return { image: image2, extent, resolution: resolution2, pixelRatio };
});
};
}
// node_modules/ol/source/ImageArcGISRest.js
var ImageArcGISRest = class extends Image_default4 {
/**
* @param {Options} [options] Image ArcGIS Rest Options.
*/
constructor(options) {
options = options ? options : {};
super({
attributions: options.attributions,
interpolate: options.interpolate,
projection: options.projection,
resolutions: options.resolutions
});
this.crossOrigin_ = options.crossOrigin !== void 0 ? options.crossOrigin : null;
this.hidpi_ = options.hidpi !== void 0 ? options.hidpi : true;
this.url_ = options.url;
this.imageLoadFunction_ = options.imageLoadFunction !== void 0 ? options.imageLoadFunction : defaultImageLoadFunction;
this.params_ = Object.assign({}, options.params);
this.imageSize_ = [0, 0];
this.renderedRevision_ = 0;
this.ratio_ = options.ratio !== void 0 ? options.ratio : 1.5;
this.loaderProjection_ = null;
}
/**
* Get the user-provided params, i.e. those passed to the constructor through
* the "params" option, and possibly updated using the updateParams method.
* @return {Object} Params.
* @api
*/
getParams() {
return this.params_;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../Image.js").default} Single image.
* @override
*/
getImageInternal(extent, resolution, pixelRatio, projection) {
if (this.url_ === void 0) {
return null;
}
if (!this.loader || this.loaderProjection_ !== projection) {
this.loaderProjection_ = projection;
this.loader = createLoader({
crossOrigin: this.crossOrigin_,
params: this.params_,
projection,
hidpi: this.hidpi_,
url: this.url_,
ratio: this.ratio_,
load: (image, src) => {
this.image.setImage(image);
this.imageLoadFunction_(this.image, src);
return decode(image);
}
});
}
return super.getImageInternal(extent, resolution, pixelRatio, projection);
}
/**
* Return the image load function of the source.
* @return {import("../Image.js").LoadFunction} The image load function.
* @api
*/
getImageLoadFunction() {
return this.imageLoadFunction_;
}
/**
* Return the URL used for this ArcGIS source.
* @return {string|undefined} URL.
* @api
*/
getUrl() {
return this.url_;
}
/**
* Set the image load function of the source.
* @param {import("../Image.js").LoadFunction} imageLoadFunction Image load function.
* @api
*/
setImageLoadFunction(imageLoadFunction) {
this.imageLoadFunction_ = imageLoadFunction;
this.changed();
}
/**
* Set the URL to use for requests.
* @param {string|undefined} url URL.
* @api
*/
setUrl(url) {
if (url != this.url_) {
this.url_ = url;
this.loader = null;
this.changed();
}
}
/**
* Set the user-provided params.
* @param {Object} params Params.
* @api
*/
setParams(params) {
this.params_ = Object.assign({}, params);
this.changed();
}
/**
* Update the user-provided params.
* @param {Object} params Params.
* @api
*/
updateParams(params) {
Object.assign(this.params_, params);
this.changed();
}
/**
* @override
*/
changed() {
this.image = null;
super.changed();
}
};
var ImageArcGISRest_default = ImageArcGISRest;
// node_modules/ol/source/ImageCanvas.js
var ImageCanvasSource = class extends Image_default4 {
/**
* @param {Options} [options] ImageCanvas options.
*/
constructor(options) {
options = options ? options : {};
super({
attributions: options.attributions,
interpolate: options.interpolate,
projection: options.projection,
resolutions: options.resolutions,
state: options.state
});
this.canvasFunction_ = options.canvasFunction;
this.canvas_ = null;
this.renderedRevision_ = 0;
this.ratio_ = options.ratio !== void 0 ? options.ratio : 1.5;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../ImageCanvas.js").default} Single image.
* @override
*/
getImageInternal(extent, resolution, pixelRatio, projection) {
resolution = this.findNearestResolution(resolution);
let canvas = this.canvas_;
if (canvas && this.renderedRevision_ == this.getRevision() && canvas.getResolution() == resolution && canvas.getPixelRatio() == pixelRatio && containsExtent(canvas.getExtent(), extent)) {
return canvas;
}
extent = extent.slice();
scaleFromCenter(extent, this.ratio_);
const width = getWidth(extent) / resolution;
const height = getHeight(extent) / resolution;
const size = [width * pixelRatio, height * pixelRatio];
const canvasElement = this.canvasFunction_.call(
this,
extent,
resolution,
pixelRatio,
size,
projection
);
if (canvasElement) {
canvas = new ImageCanvas_default(extent, resolution, pixelRatio, canvasElement);
}
this.canvas_ = canvas;
this.renderedRevision_ = this.getRevision();
return canvas;
}
};
var ImageCanvas_default2 = ImageCanvasSource;
// node_modules/ol/source/mapguide.js
function getScale(extent, size, metersPerUnit, dpi) {
const mcsW = getWidth(extent);
const mcsH = getHeight(extent);
const devW = size[0];
const devH = size[1];
const mpp = 0.0254 / dpi;
if (devH * mcsW > devW * mcsH) {
return mcsW * metersPerUnit / (devW * mpp);
}
return mcsH * metersPerUnit / (devH * mpp);
}
function getUrl(baseUrl, params, extent, size, useOverlay, metersPerUnit, displayDpi) {
const scale4 = getScale(extent, size, metersPerUnit, displayDpi);
const center = getCenter(extent);
const baseParams = {
"OPERATION": useOverlay ? "GETDYNAMICMAPOVERLAYIMAGE" : "GETMAPIMAGE",
"VERSION": "2.0.0",
"LOCALE": "en",
"CLIENTAGENT": "ol/source/ImageMapGuide source",
"CLIP": "1",
"SETDISPLAYDPI": displayDpi,
"SETDISPLAYWIDTH": Math.round(size[0]),
"SETDISPLAYHEIGHT": Math.round(size[1]),
"SETVIEWSCALE": scale4,
"SETVIEWCENTERX": center[0],
"SETVIEWCENTERY": center[1]
};
Object.assign(baseParams, params);
return appendParams(baseUrl, baseParams);
}
function createLoader2(options) {
const load = options.load || decode;
const useOverlay = options.useOverlay ?? false;
const metersPerUnit = options.metersPerUnit || 1;
const displayDpi = options.displayDpi || 96;
const ratio = options.ratio ?? 1;
const crossOrigin = options.crossOrigin ?? null;
return function(extent, resolution, pixelRatio) {
const image = new Image();
image.crossOrigin = crossOrigin;
extent = getRequestExtent(extent, resolution, pixelRatio, ratio);
const width = getWidth(extent) / resolution;
const height = getHeight(extent) / resolution;
const size = [width * pixelRatio, height * pixelRatio];
const src = getUrl(
options.url,
options.params,
extent,
size,
useOverlay,
metersPerUnit,
displayDpi
);
return load(image, src).then((image2) => ({ image: image2, extent, pixelRatio }));
};
}
// node_modules/ol/source/ImageMapGuide.js
var ImageMapGuide = class extends Image_default4 {
/**
* @param {Options} options ImageMapGuide options.
*/
constructor(options) {
super({
interpolate: options.interpolate,
projection: options.projection,
resolutions: options.resolutions
});
this.crossOrigin_ = options.crossOrigin !== void 0 ? options.crossOrigin : null;
this.displayDpi_ = options.displayDpi !== void 0 ? options.displayDpi : 96;
this.params_ = Object.assign({}, options.params);
this.url_ = options.url;
this.imageLoadFunction_ = options.imageLoadFunction !== void 0 ? options.imageLoadFunction : defaultImageLoadFunction;
this.hidpi_ = options.hidpi !== void 0 ? options.hidpi : true;
this.metersPerUnit_ = options.metersPerUnit !== void 0 ? options.metersPerUnit : 1;
this.ratio_ = options.ratio !== void 0 ? options.ratio : 1;
this.useOverlay_ = options.useOverlay !== void 0 ? options.useOverlay : false;
this.renderedRevision_ = 0;
this.loaderProjection_ = null;
}
/**
* Get the user-provided params, i.e. those passed to the constructor through
* the "params" option, and possibly updated using the updateParams method.
* @return {Object} Params.
* @api
*/
getParams() {
return this.params_;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../Image.js").default} Single image.
* @override
*/
getImageInternal(extent, resolution, pixelRatio, projection) {
if (this.url_ === void 0) {
return null;
}
if (!this.loader || this.loaderProjection_ !== projection) {
this.loaderProjection_ = projection;
this.loader = createLoader2({
crossOrigin: this.crossOrigin_,
params: this.params_,
hidpi: this.hidpi_,
metersPerUnit: this.metersPerUnit_,
url: this.url_,
useOverlay: this.useOverlay_,
ratio: this.ratio_,
load: (image, src) => {
this.image.setImage(image);
this.imageLoadFunction_(this.image, src);
return decode(image);
}
});
}
return super.getImageInternal(extent, resolution, pixelRatio, projection);
}
/**
* Return the image load function of the source.
* @return {import("../Image.js").LoadFunction} The image load function.
* @api
*/
getImageLoadFunction() {
return this.imageLoadFunction_;
}
/**
* Set the user-provided params.
* @param {Object} params Params.
* @api
*/
setParams(params) {
this.params_ = Object.assign({}, params);
this.changed();
}
/**
* Update the user-provided params.
* @param {Object} params Params.
* @api
*/
updateParams(params) {
Object.assign(this.params_, params);
this.changed();
}
/**
* Set the image load function of the MapGuide source.
* @param {import("../Image.js").LoadFunction} imageLoadFunction Image load function.
* @api
*/
setImageLoadFunction(imageLoadFunction) {
this.imageLoadFunction_ = imageLoadFunction;
this.changed();
}
/**
* @override
*/
changed() {
this.image = null;
super.changed();
}
};
var ImageMapGuide_default = ImageMapGuide;
// node_modules/ol/source/static.js
function createLoader3(options) {
const load = options.load || decode;
const extent = options.imageExtent;
const crossOrigin = options.crossOrigin ?? null;
return () => {
const image = new Image();
image.crossOrigin = crossOrigin;
return load(image, options.url).then((image2) => {
const resolutionX = getWidth(extent) / image2.width;
const resolutionY = getHeight(extent) / image2.height;
const resolution = resolutionX !== resolutionY ? [resolutionX, resolutionY] : resolutionY;
return { image: image2, extent, resolution, pixelRatio: 1 };
});
};
}
// node_modules/ol/source/ImageStatic.js
var Static = class extends Image_default4 {
/**
* @param {Options} options ImageStatic options.
*/
constructor(options) {
const crossOrigin = options.crossOrigin !== void 0 ? options.crossOrigin : null;
const imageLoadFunction = options.imageLoadFunction !== void 0 ? options.imageLoadFunction : defaultImageLoadFunction;
super({
attributions: options.attributions,
interpolate: options.interpolate,
projection: get(options.projection)
});
this.url_ = options.url;
this.imageExtent_ = options.imageExtent;
this.image = null;
this.image = new Image_default(
this.imageExtent_,
void 0,
1,
createLoader3({
url: options.url,
imageExtent: options.imageExtent,
crossOrigin,
load: (image, src) => {
this.image.setImage(image);
imageLoadFunction(this.image, src);
return decode(image);
}
})
);
this.image.addEventListener(
EventType_default.CHANGE,
this.handleImageChange.bind(this)
);
}
/**
* Returns the image extent
* @return {import("../extent.js").Extent} image extent.
* @api
*/
getImageExtent() {
return this.imageExtent_;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../Image.js").default} Single image.
* @override
*/
getImageInternal(extent, resolution, pixelRatio, projection) {
if (intersects(extent, this.image.getExtent())) {
return this.image;
}
return null;
}
/**
* Return the URL used for this image source.
* @return {string} URL.
* @api
*/
getUrl() {
return this.url_;
}
};
var ImageStatic_default = Static;
// node_modules/ol/source/ImageTile.js
var loadError = new Error("Image failed to load");
function loadImage(template, z, x, y, options) {
return new Promise((resolve, reject) => {
const image = new Image();
image.crossOrigin = options.crossOrigin ?? null;
image.addEventListener("load", () => resolve(image));
image.addEventListener("error", () => reject(loadError));
image.src = renderXYZTemplate(template, z, x, y, options.maxY);
});
}
function makeLoaderFromTemplates(templates) {
return function(z, x, y, options) {
const template = pickUrl(templates, z, x, y);
return loadImage(template, z, x, y, options);
};
}
function makeLoaderFromGetter(getter) {
return function(z, x, y, options) {
const url = getter(z, x, y, options);
return loadImage(url, z, x, y, options);
};
}
function makeLoaderFromUrlLike(url) {
let loader;
if (Array.isArray(url)) {
loader = makeLoaderFromTemplates(url);
} else if (typeof url === "string") {
const urls = expandUrl(url);
loader = makeLoaderFromTemplates(urls);
} else if (typeof url === "function") {
loader = makeLoaderFromGetter(url);
} else {
throw new Error(
"The url option must be a single template, an array of templates, or a function for getting a URL"
);
}
return loader;
}
var keyCount = 0;
function keyFromUrlLike(url) {
if (Array.isArray(url)) {
return url.join("\n");
}
if (typeof url === "string") {
return url;
}
++keyCount;
return "url-function-key-" + keyCount;
}
var ImageTileSource = class extends DataTile_default3 {
/**
* @param {Options} [options] DataTile source options.
*/
constructor(options) {
options = options || {};
let loader = options.loader;
let key;
if (options.url) {
loader = makeLoaderFromUrlLike(options.url);
key = keyFromUrlLike(options.url);
}
const state = !loader ? "loading" : options.state;
const wrapX = options.wrapX === void 0 ? true : options.wrapX;
super({
loader,
key,
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
maxZoom: options.maxZoom,
minZoom: options.minZoom,
tileSize: options.tileSize,
gutter: options.gutter,
maxResolution: options.maxResolution,
projection: options.projection,
tileGrid: options.tileGrid,
state,
wrapX,
transition: options.transition,
interpolate: options.interpolate !== false,
crossOrigin: options.crossOrigin,
zDirection: options.zDirection
});
}
/**
* @param {UrlLike} url The new URL.
* @api
*/
setUrl(url) {
const loader = makeLoaderFromUrlLike(url);
this.setLoader(loader);
this.setKey(keyFromUrlLike(url));
if (this.getState() !== "ready") {
this.setState("ready");
}
}
};
var ImageTile_default2 = ImageTileSource;
// node_modules/ol/source/wms.js
var DEFAULT_VERSION = "1.3.0";
var GETFEATUREINFO_IMAGE_SIZE = [101, 101];
function getRequestUrl2(baseUrl, extent, size, projection, params) {
params["WIDTH"] = size[0];
params["HEIGHT"] = size[1];
const axisOrientation = projection.getAxisOrientation();
const v13 = compareVersions(params["VERSION"], "1.3") >= 0;
params[v13 ? "CRS" : "SRS"] = projection.getCode();
const bbox = v13 && axisOrientation.startsWith("ne") ? [extent[1], extent[0], extent[3], extent[2]] : extent;
params["BBOX"] = bbox.join(",");
return appendParams(baseUrl, params);
}
function getImageSrc(extent, resolution, pixelRatio, projection, url, params, serverType) {
params = Object.assign({ REQUEST: "GetMap" }, params);
const imageResolution = resolution / pixelRatio;
const imageSize = [
round(getWidth(extent) / imageResolution, DECIMALS),
round(getHeight(extent) / imageResolution, DECIMALS)
];
if (pixelRatio != 1) {
switch (serverType) {
case "geoserver":
const dpi = 90 * pixelRatio + 0.5 | 0;
if ("FORMAT_OPTIONS" in params) {
params["FORMAT_OPTIONS"] += ";dpi:" + dpi;
} else {
params["FORMAT_OPTIONS"] = "dpi:" + dpi;
}
break;
case "mapserver":
params["MAP_RESOLUTION"] = 90 * pixelRatio;
break;
case "carmentaserver":
case "qgis":
params["DPI"] = 90 * pixelRatio;
break;
default:
throw new Error("Unknown `serverType` configured");
}
}
const src = getRequestUrl2(url, extent, imageSize, projection, params);
return src;
}
function getRequestParams(params, request) {
return Object.assign(
{
"REQUEST": request,
"SERVICE": "WMS",
"VERSION": DEFAULT_VERSION,
"FORMAT": "image/png",
"STYLES": "",
"TRANSPARENT": "TRUE"
},
params
);
}
function createLoader4(options) {
const hidpi = options.hidpi === void 0 ? true : options.hidpi;
const projection = get(options.projection || "EPSG:3857");
const ratio = options.ratio || 1.5;
const load = options.load || decode;
const crossOrigin = options.crossOrigin ?? null;
return (extent, resolution, pixelRatio) => {
extent = getRequestExtent(extent, resolution, pixelRatio, ratio);
if (pixelRatio != 1 && (!hidpi || options.serverType === void 0)) {
pixelRatio = 1;
}
const src = getImageSrc(
extent,
resolution,
pixelRatio,
projection,
options.url,
getRequestParams(options.params, "GetMap"),
options.serverType
);
const image = new Image();
image.crossOrigin = crossOrigin;
return load(image, src).then((image2) => ({ image: image2, extent, pixelRatio }));
};
}
function getFeatureInfoUrl(options, coordinate, resolution) {
if (options.url === void 0) {
return void 0;
}
const projectionObj = get(options.projection || "EPSG:3857");
const extent = getForViewAndSize(
coordinate,
resolution,
0,
GETFEATUREINFO_IMAGE_SIZE
);
const baseParams = {
"QUERY_LAYERS": options.params["LAYERS"],
"INFO_FORMAT": "application/json"
};
Object.assign(
baseParams,
getRequestParams(options.params, "GetFeatureInfo"),
options.params
);
const x = floor((coordinate[0] - extent[0]) / resolution, DECIMALS);
const y = floor((extent[3] - coordinate[1]) / resolution, DECIMALS);
const v13 = compareVersions(baseParams["VERSION"], "1.3") >= 0;
baseParams[v13 ? "I" : "X"] = x;
baseParams[v13 ? "J" : "Y"] = y;
return getRequestUrl2(
options.url,
extent,
GETFEATUREINFO_IMAGE_SIZE,
projectionObj,
baseParams
);
}
function getLegendUrl(options, resolution) {
if (options.url === void 0) {
return void 0;
}
const baseParams = {
"SERVICE": "WMS",
"VERSION": DEFAULT_VERSION,
"REQUEST": "GetLegendGraphic",
"FORMAT": "image/png"
};
if (resolution !== void 0) {
const mpu = get(options.projection || "EPSG:3857").getMetersPerUnit() || 1;
const pixelSize = 28e-5;
baseParams["SCALE"] = resolution * mpu / pixelSize;
}
Object.assign(baseParams, options.params);
if (options.params !== void 0 && baseParams["LAYER"] === void 0) {
const layers = baseParams["LAYERS"];
const isSingleLayer = !Array.isArray(layers) || layers.length !== 1;
if (!isSingleLayer) {
return void 0;
}
baseParams["LAYER"] = layers;
}
return appendParams(options.url, baseParams);
}
// node_modules/ol/source/ImageWMS.js
var ImageWMS = class extends Image_default4 {
/**
* @param {Options} [options] ImageWMS options.
*/
constructor(options) {
options = options ? options : {};
super({
attributions: options.attributions,
interpolate: options.interpolate,
projection: options.projection,
resolutions: options.resolutions
});
this.crossOrigin_ = options.crossOrigin !== void 0 ? options.crossOrigin : null;
this.url_ = options.url;
this.imageLoadFunction_ = options.imageLoadFunction !== void 0 ? options.imageLoadFunction : defaultImageLoadFunction;
this.params_ = Object.assign({}, options.params);
this.serverType_ = options.serverType;
this.hidpi_ = options.hidpi !== void 0 ? options.hidpi : true;
this.renderedRevision_ = 0;
this.ratio_ = options.ratio !== void 0 ? options.ratio : 1.5;
this.loaderProjection_ = null;
}
/**
* Return the GetFeatureInfo URL for the passed coordinate, resolution, and
* projection. Return `undefined` if the GetFeatureInfo URL cannot be
* constructed.
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {number} resolution Resolution.
* @param {import("../proj.js").ProjectionLike} projection Projection.
* @param {!Object} params GetFeatureInfo params. `INFO_FORMAT` at least should
* be provided. If `QUERY_LAYERS` is not provided then the layers specified
* in the `LAYERS` parameter will be used. `VERSION` should not be
* specified here.
* @return {string|undefined} GetFeatureInfo URL.
* @api
*/
getFeatureInfoUrl(coordinate, resolution, projection, params) {
const projectionObj = get(projection);
const sourceProjectionObj = this.getProjection();
if (sourceProjectionObj && sourceProjectionObj !== projectionObj) {
resolution = calculateSourceResolution(
sourceProjectionObj,
projectionObj,
coordinate,
resolution
);
coordinate = transform(coordinate, projectionObj, sourceProjectionObj);
}
const options = {
url: this.url_,
params: {
...this.params_,
...params
},
projection: sourceProjectionObj || projectionObj
};
return getFeatureInfoUrl(options, coordinate, resolution);
}
/**
* Return the GetLegendGraphic URL, optionally optimized for the passed
* resolution and possibly including any passed specific parameters. Returns
* `undefined` if the GetLegendGraphic URL cannot be constructed.
*
* @param {number} [resolution] Resolution. If set to undefined, `SCALE`
* will not be calculated and included in URL.
* @param {Object} [params] GetLegendGraphic params. If `LAYER` is set, the
* request is generated for this wms layer, else it will try to use the
* configured wms layer. Default `FORMAT` is `image/png`.
* `VERSION` should not be specified here.
* @return {string|undefined} GetLegendGraphic URL.
* @api
*/
getLegendUrl(resolution, params) {
return getLegendUrl(
{
url: this.url_,
params: {
...this.params_,
...params
}
},
resolution
);
}
/**
* Get the user-provided params, i.e. those passed to the constructor through
* the "params" option, and possibly updated using the updateParams method.
* @return {Object} Params.
* @api
*/
getParams() {
return this.params_;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../Image.js").default} Single image.
* @override
*/
getImageInternal(extent, resolution, pixelRatio, projection) {
if (this.url_ === void 0) {
return null;
}
if (!this.loader || this.loaderProjection_ !== projection) {
this.loaderProjection_ = projection;
this.loader = createLoader4({
crossOrigin: this.crossOrigin_,
params: this.params_,
projection,
serverType: this.serverType_,
hidpi: this.hidpi_,
url: this.url_,
ratio: this.ratio_,
load: (image, src) => {
this.image.setImage(image);
this.imageLoadFunction_(this.image, src);
return decode(image);
}
});
}
return super.getImageInternal(extent, resolution, pixelRatio, projection);
}
/**
* Return the image load function of the source.
* @return {import("../Image.js").LoadFunction} The image load function.
* @api
*/
getImageLoadFunction() {
return this.imageLoadFunction_;
}
/**
* Return the URL used for this WMS source.
* @return {string|undefined} URL.
* @api
*/
getUrl() {
return this.url_;
}
/**
* Set the image load function of the source.
* @param {import("../Image.js").LoadFunction} imageLoadFunction Image load function.
* @api
*/
setImageLoadFunction(imageLoadFunction) {
this.imageLoadFunction_ = imageLoadFunction;
this.changed();
}
/**
* Set the URL to use for requests.
* @param {string|undefined} url URL.
* @api
*/
setUrl(url) {
if (url != this.url_) {
this.url_ = url;
this.loader = null;
this.changed();
}
}
/**
* Set the user-provided params.
* @param {Object} params Params.
* @api
*/
setParams(params) {
this.params_ = Object.assign({}, params);
this.changed();
}
/**
* Update the user-provided params.
* @param {Object} params Params.
* @api
*/
updateParams(params) {
Object.assign(this.params_, params);
this.changed();
}
/**
* @override
*/
changed() {
this.image = null;
super.changed();
}
};
var ImageWMS_default = ImageWMS;
// node_modules/ol/net.js
function jsonp(url, callback, errback, callbackParam) {
const script = document.createElement("script");
const key = "olc_" + getUid(callback);
function cleanup() {
delete window[key];
script.parentNode.removeChild(script);
}
script.async = true;
script.src = url + (url.includes("?") ? "&" : "?") + (callbackParam || "callback") + "=" + key;
const timer = setTimeout(function() {
cleanup();
if (errback) {
errback();
}
}, 1e4);
window[key] = function(data) {
clearTimeout(timer);
cleanup();
callback(data);
};
document.head.appendChild(script);
}
var ResponseError = class extends Error {
/**
* @param {XMLHttpRequest} response The XHR object.
*/
constructor(response) {
const message = "Unexpected response status: " + response.status;
super(message);
this.name = "ResponseError";
this.response = response;
}
};
var ClientError = class extends Error {
/**
* @param {XMLHttpRequest} client The XHR object.
*/
constructor(client) {
super("Failed to issue request");
this.name = "ClientError";
this.client = client;
}
};
function getJSON(url) {
return new Promise(function(resolve, reject) {
function onLoad(event) {
const client2 = event.target;
if (!client2.status || client2.status >= 200 && client2.status < 300) {
let data;
try {
data = JSON.parse(client2.responseText);
} catch (err) {
const message = "Error parsing response text as JSON: " + err.message;
reject(new Error(message));
return;
}
resolve(data);
return;
}
reject(new ResponseError(client2));
}
function onError(event) {
reject(new ClientError(event.target));
}
const client = new XMLHttpRequest();
client.addEventListener("load", onLoad);
client.addEventListener("error", onError);
client.open("GET", url);
client.setRequestHeader("Accept", "application/json");
client.send();
});
}
function resolveUrl(base, url) {
if (url.includes("://")) {
return url;
}
return new URL(url, base).href;
}
// node_modules/ol/source/ogcTileUtil.js
var knownMapMediaTypes = {
"image/png": true,
"image/jpeg": true,
"image/gif": true,
"image/webp": true
};
var knownVectorMediaTypes = {
"application/vnd.mapbox-vector-tile": true,
"application/geo+json": true
};
function appendCollectionsQueryParam(tileUrlTemplate, collections) {
if (!collections.length) {
return tileUrlTemplate;
}
const url = new URL(tileUrlTemplate, "file:/");
if (url.pathname.split("/").includes("collections")) {
error(
'The "collections" query parameter cannot be added to collection endpoints'
);
return tileUrlTemplate;
}
const encodedCollections = collections.map((c) => encodeURIComponent(c)).join(",");
url.searchParams.append("collections", encodedCollections);
const baseUrl = tileUrlTemplate.split("?")[0];
const queryParams = decodeURIComponent(url.searchParams.toString());
return `${baseUrl}?${queryParams}`;
}
function getMapTileUrlTemplate(links, mediaType, collections) {
let tileUrlTemplate;
let fallbackUrlTemplate;
for (let i = 0; i < links.length; ++i) {
const link = links[i];
if (link.rel === "item") {
if (link.type === mediaType) {
tileUrlTemplate = link.href;
break;
}
if (knownMapMediaTypes[link.type]) {
fallbackUrlTemplate = link.href;
} else if (!fallbackUrlTemplate && link.type.startsWith("image/")) {
fallbackUrlTemplate = link.href;
}
}
}
if (!tileUrlTemplate) {
if (fallbackUrlTemplate) {
tileUrlTemplate = fallbackUrlTemplate;
} else {
throw new Error('Could not find "item" link');
}
}
if (collections) {
tileUrlTemplate = appendCollectionsQueryParam(tileUrlTemplate, collections);
}
return tileUrlTemplate;
}
function getVectorTileUrlTemplate(links, mediaType, supportedMediaTypes, collections) {
let tileUrlTemplate;
let fallbackUrlTemplate;
const hrefLookup = {};
for (let i = 0; i < links.length; ++i) {
const link = links[i];
hrefLookup[link.type] = link.href;
if (link.rel === "item") {
if (link.type === mediaType) {
tileUrlTemplate = link.href;
break;
}
if (knownVectorMediaTypes[link.type]) {
fallbackUrlTemplate = link.href;
}
}
}
if (!tileUrlTemplate && supportedMediaTypes) {
for (let i = 0; i < supportedMediaTypes.length; ++i) {
const supportedMediaType = supportedMediaTypes[i];
if (hrefLookup[supportedMediaType]) {
tileUrlTemplate = hrefLookup[supportedMediaType];
break;
}
}
}
if (!tileUrlTemplate) {
if (fallbackUrlTemplate) {
tileUrlTemplate = fallbackUrlTemplate;
} else {
throw new Error('Could not find "item" link');
}
}
if (collections) {
tileUrlTemplate = appendCollectionsQueryParam(tileUrlTemplate, collections);
}
return tileUrlTemplate;
}
function parseTileMatrixSet(sourceInfo, tileMatrixSet, tileUrlTemplate, tileMatrixSetLimits) {
let projection = sourceInfo.projection;
if (!projection) {
if (typeof tileMatrixSet.crs === "string") {
projection = get(tileMatrixSet.crs);
} else if ("uri" in tileMatrixSet.crs) {
projection = get(tileMatrixSet.crs.uri);
}
if (!projection) {
throw new Error(`Unsupported CRS: ${JSON.stringify(tileMatrixSet.crs)}`);
}
}
const orderedAxes = tileMatrixSet.orderedAxes;
const axisOrientation = orderedAxes ? orderedAxes.slice(0, 2).map((s) => s.replace(/E|X|Lon/i, "e").replace(/N|Y|Lat/i, "n")).join("") : projection.getAxisOrientation();
const backwards = !axisOrientation.startsWith("en");
const matrices = tileMatrixSet.tileMatrices;
const matrixLookup = {};
for (let i = 0; i < matrices.length; ++i) {
const matrix = matrices[i];
matrixLookup[matrix.id] = matrix;
}
const limitLookup = {};
const matrixIds = [];
if (tileMatrixSetLimits) {
for (let i = 0; i < tileMatrixSetLimits.length; ++i) {
const limit = tileMatrixSetLimits[i];
const id = limit.tileMatrix;
matrixIds.push(id);
limitLookup[id] = limit;
}
} else {
for (let i = 0; i < matrices.length; ++i) {
const id = matrices[i].id;
matrixIds.push(id);
}
}
const length = matrixIds.length;
const origins = new Array(length);
const resolutions = new Array(length);
const sizes = new Array(length);
const tileSizes = new Array(length);
const extent = [-Infinity, -Infinity, Infinity, Infinity];
for (let i = 0; i < length; ++i) {
const id = matrixIds[i];
const matrix = matrixLookup[id];
const origin = matrix.pointOfOrigin;
if (backwards) {
origins[i] = [origin[1], origin[0]];
} else {
origins[i] = origin;
}
resolutions[i] = matrix.cellSize;
sizes[i] = [matrix.matrixWidth, matrix.matrixHeight];
tileSizes[i] = [matrix.tileWidth, matrix.tileHeight];
const limit = limitLookup[id];
if (limit) {
const tileMapWidth = matrix.cellSize * matrix.tileWidth;
const minX = origins[i][0] + limit.minTileCol * tileMapWidth;
const maxX = origins[i][0] + (limit.maxTileCol + 1) * tileMapWidth;
const tileMapHeight = matrix.cellSize * matrix.tileHeight;
const upsideDown = matrix.cornerOfOrigin === "bottomLeft";
let minY;
let maxY;
if (upsideDown) {
minY = origins[i][1] + limit.minTileRow * tileMapHeight;
maxY = origins[i][1] + (limit.maxTileRow + 1) * tileMapHeight;
} else {
minY = origins[i][1] - (limit.maxTileRow + 1) * tileMapHeight;
maxY = origins[i][1] - limit.minTileRow * tileMapHeight;
}
getIntersection(extent, [minX, minY, maxX, maxY], extent);
}
}
const tileGrid = new TileGrid_default({
origins,
resolutions,
sizes,
tileSizes,
extent: tileMatrixSetLimits ? extent : void 0
});
const context = sourceInfo.context;
const base = sourceInfo.url;
function tileUrlFunction(tileCoord, pixelRatio, projection2) {
if (!tileCoord) {
return void 0;
}
const id = matrixIds[tileCoord[0]];
const matrix = matrixLookup[id];
const upsideDown = matrix.cornerOfOrigin === "bottomLeft";
const localContext = {
tileMatrix: id,
tileCol: tileCoord[1],
tileRow: upsideDown ? -tileCoord[2] - 1 : tileCoord[2]
};
if (tileMatrixSetLimits) {
const limit = limitLookup[matrix.id];
if (localContext.tileCol < limit.minTileCol || localContext.tileCol > limit.maxTileCol || localContext.tileRow < limit.minTileRow || localContext.tileRow > limit.maxTileRow) {
return void 0;
}
}
Object.assign(
localContext,
{
z: localContext.tileMatrix,
x: localContext.tileCol,
y: localContext.tileRow
},
context
);
const url = tileUrlTemplate.replace(/\{(\w+?)\}/g, function(m, p) {
return localContext[p];
});
return resolveUrl(base, url);
}
return {
grid: tileGrid,
projection,
urlTemplate: tileUrlTemplate,
urlFunction: tileUrlFunction
};
}
function parseTileSetMetadata(sourceInfo, tileSet) {
const tileMatrixSetLimits = tileSet.tileMatrixSetLimits;
let tileUrlTemplate;
if (tileSet.dataType === "map") {
tileUrlTemplate = getMapTileUrlTemplate(
tileSet.links,
sourceInfo.mediaType,
sourceInfo.collections
);
} else if (tileSet.dataType === "vector") {
tileUrlTemplate = getVectorTileUrlTemplate(
tileSet.links,
sourceInfo.mediaType,
sourceInfo.supportedMediaTypes,
sourceInfo.collections
);
} else {
throw new Error('Expected tileset data type to be "map" or "vector"');
}
if (tileSet.tileMatrixSet) {
return parseTileMatrixSet(
sourceInfo,
tileSet.tileMatrixSet,
tileUrlTemplate,
tileMatrixSetLimits
);
}
const tileMatrixSetLink = tileSet.links.find(
(link) => link.rel === "http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme"
);
if (!tileMatrixSetLink) {
throw new Error(
"Expected http://www.opengis.net/def/rel/ogc/1.0/tiling-scheme link or tileMatrixSet"
);
}
const tileMatrixSetDefinition = tileMatrixSetLink.href;
const url = resolveUrl(sourceInfo.url, tileMatrixSetDefinition);
return getJSON(url).then(function(tileMatrixSet) {
return parseTileMatrixSet(
sourceInfo,
tileMatrixSet,
tileUrlTemplate,
tileMatrixSetLimits
);
});
}
function getTileSetInfo(sourceInfo) {
return getJSON(sourceInfo.url).then(function(tileSet) {
return parseTileSetMetadata(sourceInfo, tileSet);
});
}
// node_modules/ol/source/OGCMapTile.js
var OGCMapTile = class extends TileImage_default {
/**
* @param {Options} options OGC map tile options.
*/
constructor(options) {
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
interpolate: options.interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: "loading",
tileLoadFunction: options.tileLoadFunction,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition
});
const sourceInfo = {
url: options.url,
projection: this.getProjection(),
mediaType: options.mediaType,
context: options.context || null,
collections: options.collections
};
getTileSetInfo(sourceInfo).then(this.handleTileSetInfo_.bind(this)).catch(this.handleError_.bind(this));
}
/**
* @param {import("./ogcTileUtil.js").TileSetInfo} tileSetInfo Tile set info.
* @private
*/
handleTileSetInfo_(tileSetInfo) {
this.tileGrid = tileSetInfo.grid;
this.projection = tileSetInfo.projection;
this.setTileUrlFunction(tileSetInfo.urlFunction, tileSetInfo.urlTemplate);
this.setState("ready");
}
/**
* @private
* @param {Error} error The error.
*/
handleError_(error2) {
error(error2);
this.setState("error");
}
};
var OGCMapTile_default = OGCMapTile;
// node_modules/ol/VectorRenderTile.js
var canvasPool = [];
var VectorRenderTile = class extends Tile_default {
/**
* @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("./TileState.js").default} state State.
* @param {import("./tilecoord.js").TileCoord} urlTileCoord Wrapped tile coordinate for source urls.
* @param {function(VectorRenderTile):Array<import("./VectorTile").default>} getSourceTiles Function.
* @param {function(VectorRenderTile):void} removeSourceTiles Function.
*/
constructor(tileCoord, state, urlTileCoord, getSourceTiles, removeSourceTiles) {
super(tileCoord, state, { transition: 0 });
this.context_ = null;
this.executorGroups = {};
this.loadingSourceTiles = 0;
this.hitDetectionImageData = {};
this.replayState_ = {};
this.sourceTiles = [];
this.errorTileKeys = {};
this.wantedResolution;
this.getSourceTiles = getSourceTiles.bind(void 0, this);
this.removeSourceTiles_ = removeSourceTiles;
this.wrappedTileCoord = urlTileCoord;
}
/**
* @return {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} The rendering context.
*/
getContext() {
if (!this.context_) {
this.context_ = createCanvasContext2D(1, 1, canvasPool);
}
return this.context_;
}
/**
* @return {boolean} Tile has a rendering context.
*/
hasContext() {
return !!this.context_;
}
/**
* Get the Canvas for this tile.
* @return {HTMLCanvasElement|OffscreenCanvas} Canvas.
*/
getImage() {
return this.hasContext() ? this.getContext().canvas : null;
}
/**
* @param {import("./layer/Layer.js").default} layer Layer.
* @return {ReplayState} The replay state.
*/
getReplayState(layer) {
const key = getUid(layer);
if (!(key in this.replayState_)) {
this.replayState_[key] = {
dirty: false,
renderedRenderOrder: null,
renderedResolution: NaN,
renderedRevision: -1,
renderedTileResolution: NaN,
renderedTileRevision: -1,
renderedTileZ: -1
};
}
return this.replayState_[key];
}
/**
* Load the tile.
* @override
*/
load() {
this.getSourceTiles();
}
/**
* Remove from the cache due to expiry
* @override
*/
release() {
if (this.context_) {
releaseCanvas(this.context_);
canvasPool.push(this.context_.canvas);
this.context_ = null;
}
this.removeSourceTiles_(this);
this.sourceTiles.length = 0;
super.release();
}
};
var VectorRenderTile_default = VectorRenderTile;
// node_modules/ol/VectorTile.js
var VectorTile = class extends Tile_default {
/**
* @param {import("./tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("./TileState.js").default} state State.
* @param {string} src Data source url.
* @param {import("./format/Feature.js").default<FeatureType>} format Feature format.
* @param {import("./Tile.js").LoadFunction} tileLoadFunction Tile load function.
* @param {import("./Tile.js").Options} [options] Tile options.
*/
constructor(tileCoord, state, src, format, tileLoadFunction, options) {
super(tileCoord, state, options);
this.extent = null;
this.format_ = format;
this.features_ = null;
this.loader_;
this.projection = null;
this.resolution;
this.tileLoadFunction_ = tileLoadFunction;
this.url_ = src;
this.key = src;
}
/**
* @return {string} Tile url.
*/
getTileUrl() {
return this.url_;
}
/**
* Get the feature format assigned for reading this tile's features.
* @return {import("./format/Feature.js").default<FeatureType>} Feature format.
* @api
*/
getFormat() {
return this.format_;
}
/**
* Get the features for this tile. Geometries will be in the view projection.
* @return {Array<FeatureType>} Features.
* @api
*/
getFeatures() {
return this.features_;
}
/**
* Load not yet loaded URI.
* @override
*/
load() {
if (this.state == TileState_default.IDLE) {
this.setState(TileState_default.LOADING);
this.tileLoadFunction_(this, this.url_);
if (this.loader_) {
this.loader_(this.extent, this.resolution, this.projection);
}
}
}
/**
* Handler for successful tile load.
* @param {Array<FeatureType>} features The loaded features.
* @param {import("./proj/Projection.js").default} dataProjection Data projection.
*/
onLoad(features, dataProjection) {
this.setFeatures(features);
}
/**
* Handler for tile load errors.
*/
onError() {
this.setState(TileState_default.ERROR);
}
/**
* Function for use in a {@link module:ol/source/VectorTile~VectorTile}'s `tileLoadFunction`.
* Sets the features for the tile.
* @param {Array<FeatureType>} features Features.
* @api
*/
setFeatures(features) {
this.features_ = features;
this.setState(TileState_default.LOADED);
}
/**
* Set the feature loader for reading this tile's features.
* @param {import("./featureloader.js").FeatureLoader<FeatureType>} loader Feature loader.
* @api
*/
setLoader(loader) {
this.loader_ = loader;
}
};
var VectorTile_default = VectorTile;
// node_modules/ol/source/VectorTile.js
var VectorTile2 = class extends UrlTile_default {
/**
* @param {!Options<FeatureType>} options Vector tile options.
*/
constructor(options) {
const projection = options.projection || "EPSG:3857";
const extent = options.extent || extentFromProjection(projection);
const tileGrid = options.tileGrid || createXYZ({
extent,
maxResolution: options.maxResolution,
maxZoom: options.maxZoom !== void 0 ? options.maxZoom : 22,
minZoom: options.minZoom,
tileSize: options.tileSize || 512
});
super({
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
interpolate: true,
projection,
state: options.state,
tileGrid,
tileLoadFunction: options.tileLoadFunction ? options.tileLoadFunction : defaultLoadFunction,
tileUrlFunction: options.tileUrlFunction,
url: options.url,
urls: options.urls,
wrapX: options.wrapX === void 0 ? true : options.wrapX,
transition: options.transition,
zDirection: options.zDirection === void 0 ? 1 : options.zDirection
});
this.format_ = options.format ? options.format : null;
this.tileKeysBySourceTileUrl_ = {};
this.sourceTiles_ = {};
this.overlaps_ = options.overlaps == void 0 ? true : options.overlaps;
this.tileClass = options.tileClass ? options.tileClass : VectorTile_default;
this.tileGrids_ = {};
}
/**
* @return {boolean} The source can have overlapping geometries.
*/
getOverlaps() {
return this.overlaps_;
}
/**
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection").default} projection Projection.
* @param {VectorRenderTile} tile Vector render tile.
* @return {Array<import("../VectorTile").default>} Tile keys.
*/
getSourceTiles(pixelRatio, projection, tile) {
if (tile.getState() === TileState_default.IDLE) {
tile.setState(TileState_default.LOADING);
const urlTileCoord = tile.wrappedTileCoord;
const tileGrid = this.getTileGridForProjection(projection);
let extent = tileGrid.getTileCoordExtent(urlTileCoord);
const z = urlTileCoord[0];
const resolution = tileGrid.getResolution(z);
buffer(extent, -resolution, extent);
const sourceProjection = this.projection;
if (projection && this.projection && !equivalent(projection, sourceProjection)) {
extent = transformExtent(extent, projection, sourceProjection);
}
const sourceTileGrid = this.tileGrid;
const sourceExtent = sourceTileGrid.getExtent();
if (sourceExtent) {
getIntersection(extent, sourceExtent, extent);
}
let sourceResolution = resolution;
if (projection && sourceProjection && !equivalent(projection, sourceProjection)) {
sourceResolution = resolution / sourceProjection.getMetersPerUnit() / projection.getMetersPerUnit();
}
const sourceZ = sourceTileGrid.getZForResolution(
sourceResolution,
this.zDirection
);
sourceTileGrid.forEachTileCoord(extent, sourceZ, (sourceTileCoord) => {
const tileUrl = this.tileUrlFunction(
sourceTileCoord,
pixelRatio,
projection
);
if (!this.sourceTiles_[tileUrl]) {
this.sourceTiles_[tileUrl] = new this.tileClass(
sourceTileCoord,
tileUrl ? TileState_default.IDLE : TileState_default.EMPTY,
tileUrl,
this.format_,
this.tileLoadFunction
);
}
const sourceTile = this.sourceTiles_[tileUrl];
tile.sourceTiles.push(sourceTile);
if (!this.tileKeysBySourceTileUrl_[tileUrl]) {
this.tileKeysBySourceTileUrl_[tileUrl] = [];
}
this.tileKeysBySourceTileUrl_[tileUrl].push(tile.getKey());
const sourceTileState = sourceTile.getState();
if (sourceTileState < TileState_default.LOADED) {
const listenChange = (event) => {
this.handleTileChange(event);
const state = sourceTile.getState();
if (state === TileState_default.LOADED || state === TileState_default.ERROR) {
const sourceTileKey = sourceTile.getKey();
if (sourceTileKey in tile.errorTileKeys) {
if (sourceTile.getState() === TileState_default.LOADED) {
delete tile.errorTileKeys[sourceTileKey];
}
} else {
tile.loadingSourceTiles--;
}
if (state === TileState_default.ERROR) {
tile.errorTileKeys[sourceTileKey] = true;
} else {
sourceTile.removeEventListener(EventType_default.CHANGE, listenChange);
}
if (tile.loadingSourceTiles === 0) {
tile.setState(
isEmpty(tile.errorTileKeys) ? TileState_default.LOADED : TileState_default.ERROR
);
}
}
};
sourceTile.addEventListener(EventType_default.CHANGE, listenChange);
tile.loadingSourceTiles++;
}
if (sourceTileState === TileState_default.IDLE) {
sourceTile.extent = sourceTileGrid.getTileCoordExtent(sourceTileCoord);
sourceTile.projection = this.projection;
sourceTile.resolution = sourceTileGrid.getResolution(
sourceTileCoord[0]
);
sourceTile.load();
}
});
if (!tile.loadingSourceTiles) {
tile.setState(
tile.sourceTiles.some(
(sourceTile) => sourceTile.getState() === TileState_default.ERROR
) ? TileState_default.ERROR : TileState_default.LOADED
);
}
}
return tile.sourceTiles;
}
/**
* @param {VectorRenderTile} tile Vector render tile.
*/
removeSourceTiles(tile) {
const tileKey = tile.getKey();
const sourceTiles = tile.sourceTiles;
for (let i = 0, ii = sourceTiles.length; i < ii; ++i) {
const sourceTileUrl = sourceTiles[i].getTileUrl();
if (!this.tileKeysBySourceTileUrl_[sourceTileUrl]) {
return;
}
const index = this.tileKeysBySourceTileUrl_[sourceTileUrl].indexOf(tileKey);
if (index === -1) {
continue;
}
this.tileKeysBySourceTileUrl_[sourceTileUrl].splice(index, 1);
if (this.tileKeysBySourceTileUrl_[sourceTileUrl].length === 0) {
delete this.tileKeysBySourceTileUrl_[sourceTileUrl];
delete this.sourceTiles_[sourceTileUrl];
}
}
}
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {!VectorRenderTile} Tile.
* @override
*/
getTile(z, x, y, pixelRatio, projection) {
const tileCoord = [z, x, y];
let urlTileCoord = this.getTileCoordForTileUrlFunction(
tileCoord,
projection
);
const sourceExtent = this.getTileGrid().getExtent();
const sourceProjection = this.projection;
const tileGrid = this.getTileGridForProjection(projection);
if (urlTileCoord && sourceExtent) {
const tileExtent = tileGrid.getTileCoordExtent(urlTileCoord);
buffer(tileExtent, -tileGrid.getResolution(z), tileExtent);
if (!intersects(
sourceExtent,
!projection || !sourceProjection || equivalent(projection, sourceProjection) ? tileExtent : transformExtent(tileExtent, projection, sourceProjection)
)) {
urlTileCoord = null;
}
}
let empty = true;
if (urlTileCoord !== null) {
const sourceTileGrid = this.tileGrid;
const resolution = tileGrid.getResolution(z);
let sourceResolution = resolution;
if (projection && sourceProjection && !equivalent(projection, sourceProjection)) {
sourceResolution = resolution / sourceProjection.getMetersPerUnit() / projection.getMetersPerUnit();
}
const sourceZ = sourceTileGrid.getZForResolution(sourceResolution, 1);
const extent = tileGrid.getTileCoordExtent(urlTileCoord);
buffer(extent, -resolution, extent);
sourceTileGrid.forEachTileCoord(
!projection || !sourceProjection || equivalent(projection, sourceProjection) ? extent : transformExtent(extent, projection, sourceProjection),
sourceZ,
(sourceTileCoord) => {
empty = empty && !this.tileUrlFunction(
sourceTileCoord,
pixelRatio,
sourceProjection
);
}
);
}
const newTile = new VectorRenderTile_default(
tileCoord,
empty ? TileState_default.EMPTY : TileState_default.IDLE,
urlTileCoord,
this.getSourceTiles.bind(this, pixelRatio, projection),
this.removeSourceTiles.bind(this)
);
newTile.key = this.getKey();
return newTile;
}
/**
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {!import("../tilegrid/TileGrid.js").default} Tile grid.
* @override
*/
getTileGridForProjection(projection) {
const code = projection.getCode();
let tileGrid = this.tileGrids_[code];
if (!tileGrid) {
const sourceProjection = this.projection;
if (sourceProjection !== null && !equivalent(sourceProjection, projection)) {
return getForProjection(projection);
}
const sourceTileGrid = this.tileGrid;
const resolutions = sourceTileGrid.getResolutions().slice();
const origins = resolutions.map(function(resolution, z) {
return sourceTileGrid.getOrigin(z);
});
const tileSizes = resolutions.map(function(resolution, z) {
return sourceTileGrid.getTileSize(z);
});
const length = DEFAULT_MAX_ZOOM + 1;
for (let z = resolutions.length; z < length; ++z) {
resolutions.push(resolutions[z - 1] / 2);
origins.push(origins[z - 1]);
tileSizes.push(tileSizes[z - 1]);
}
tileGrid = new TileGrid_default({
extent: sourceTileGrid.getExtent(),
origins,
resolutions,
tileSizes
});
this.tileGrids_[code] = tileGrid;
}
return tileGrid;
}
/**
* Get the tile pixel ratio for this source.
* @param {number} pixelRatio Pixel ratio.
* @return {number} Tile pixel ratio.
* @override
*/
getTilePixelRatio(pixelRatio) {
return pixelRatio;
}
/**
* @param {number} z Z.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../size.js").Size} Tile size.
* @override
*/
getTilePixelSize(z, pixelRatio, projection) {
const tileGrid = this.getTileGridForProjection(projection);
const tileSize = toSize(tileGrid.getTileSize(z), this.tmpSize);
return [
Math.round(tileSize[0] * pixelRatio),
Math.round(tileSize[1] * pixelRatio)
];
}
/**
* @param {boolean} overlaps The source has overlapping geometries.
*/
setOverlaps(overlaps) {
this.overlaps_ = overlaps;
this.changed();
}
};
var VectorTile_default2 = VectorTile2;
function defaultLoadFunction(tile, url) {
tile.setLoader(
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {import("../proj/Projection.js").default} projection Projection.
*/
function(extent, resolution, projection) {
loadFeaturesXhr(
url,
tile.getFormat(),
extent,
resolution,
projection,
tile.onLoad.bind(tile),
tile.onError.bind(tile)
);
}
);
}
// node_modules/ol/source/OGCVectorTile.js
var OGCVectorTile = class extends VectorTile_default2 {
/**
* @param {Options<FeatureType>} options OGC vector tile options.
*/
constructor(options) {
super({
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
format: options.format,
overlaps: options.overlaps,
projection: options.projection,
tileClass: options.tileClass,
transition: options.transition,
wrapX: options.wrapX,
zDirection: options.zDirection,
state: "loading"
});
const sourceInfo = {
url: options.url,
projection: this.getProjection(),
mediaType: options.mediaType,
supportedMediaTypes: options.format.supportedMediaTypes,
context: options.context || null,
collections: options.collections
};
getTileSetInfo(sourceInfo).then(this.handleTileSetInfo_.bind(this)).catch(this.handleError_.bind(this));
}
/**
* @param {import("./ogcTileUtil.js").TileSetInfo} tileSetInfo Tile set info.
* @private
*/
handleTileSetInfo_(tileSetInfo) {
this.tileGrid = tileSetInfo.grid;
this.projection = tileSetInfo.projection;
this.setTileUrlFunction(tileSetInfo.urlFunction, tileSetInfo.urlTemplate);
this.setState("ready");
}
/**
* @private
* @param {Error} error The error.
*/
handleError_(error2) {
error(error2);
this.setState("error");
}
};
var OGCVectorTile_default = OGCVectorTile;
// node_modules/ol/source/Raster.js
function createMinion(operation) {
return function(data) {
const buffers = data["buffers"];
const meta = data["meta"];
const imageOps = data["imageOps"];
const width = data["width"];
const height = data["height"];
const numBuffers = buffers.length;
const numBytes = buffers[0].byteLength;
if (imageOps) {
const images = new Array(numBuffers);
for (let b = 0; b < numBuffers; ++b) {
images[b] = new ImageData(
new Uint8ClampedArray(buffers[b]),
width,
height
);
}
const output2 = operation(images, meta).data;
return output2.buffer;
}
const output = new Uint8ClampedArray(numBytes);
const arrays = new Array(numBuffers);
const pixels = new Array(numBuffers);
for (let b = 0; b < numBuffers; ++b) {
arrays[b] = new Uint8ClampedArray(buffers[b]);
pixels[b] = [0, 0, 0, 0];
}
for (let i = 0; i < numBytes; i += 4) {
for (let j = 0; j < numBuffers; ++j) {
const array = arrays[j];
pixels[j][0] = array[i];
pixels[j][1] = array[i + 1];
pixels[j][2] = array[i + 2];
pixels[j][3] = array[i + 3];
}
const pixel = operation(pixels, meta);
output[i] = pixel[0];
output[i + 1] = pixel[1];
output[i + 2] = pixel[2];
output[i + 3] = pixel[3];
}
return output.buffer;
};
}
function createWorker(config, onMessage) {
const lib = Object.keys(config.lib || {}).map(function(name) {
return "const " + name + " = " + config.lib[name].toString() + ";";
});
const lines = lib.concat([
"const __minion__ = (" + createMinion.toString() + ")(",
config.operation.toString(),
");",
'self.addEventListener("message", function(event) {',
" const buffer = __minion__(event.data);",
" self.postMessage({buffer: buffer, meta: event.data.meta}, [buffer]);",
"});"
]);
const worker = new Worker(
typeof Blob === "undefined" ? "data:text/javascript;base64," + Buffer.from(lines.join("\n"), "binary").toString("base64") : URL.createObjectURL(new Blob(lines, { type: "text/javascript" }))
);
worker.addEventListener("message", onMessage);
return worker;
}
function createFauxWorker(config, onMessage) {
const minion = createMinion(config.operation);
let terminated = false;
return {
postMessage: function(data) {
setTimeout(function() {
if (terminated) {
return;
}
onMessage({ data: { buffer: minion(data), meta: data["meta"] } });
}, 0);
},
terminate: function() {
terminated = true;
}
};
}
var Processor = class extends Disposable_default {
/**
* @param {ProcessorOptions} config Configuration.
*/
constructor(config) {
super();
this.imageOps_ = !!config.imageOps;
let threads;
if (config.threads === 0) {
threads = 0;
} else if (this.imageOps_) {
threads = 1;
} else {
threads = config.threads || 1;
}
const workers = new Array(threads);
if (threads) {
for (let i = 0; i < threads; ++i) {
workers[i] = createWorker(config, this.onWorkerMessage_.bind(this, i));
}
} else {
workers[0] = createFauxWorker(
config,
this.onWorkerMessage_.bind(this, 0)
);
}
this.workers_ = workers;
this.queue_ = [];
this.maxQueueLength_ = config.queue || Infinity;
this.running_ = 0;
this.dataLookup_ = {};
this.job_ = null;
}
/**
* Run operation on input data.
* @param {Array<ImageData>} inputs Array of image data.
* @param {Object} meta A user data object. This is passed to all operations
* and must be serializable.
* @param {function(Error, ImageData, Object): void} callback Called when work
* completes. The first argument is any error. The second is the ImageData
* generated by operations. The third is the user data object.
*/
process(inputs, meta, callback) {
this.enqueue_({
inputs,
meta,
callback
});
this.dispatch_();
}
/**
* Add a job to the queue.
* @param {Job} job The job.
*/
enqueue_(job) {
this.queue_.push(job);
while (this.queue_.length > this.maxQueueLength_) {
this.queue_.shift().callback(null, null);
}
}
/**
* Dispatch a job.
*/
dispatch_() {
if (this.running_ || this.queue_.length === 0) {
return;
}
const job = this.queue_.shift();
this.job_ = job;
const width = job.inputs[0].width;
const height = job.inputs[0].height;
const buffers = job.inputs.map(function(input) {
return input.data.buffer;
});
const threads = this.workers_.length;
this.running_ = threads;
if (threads === 1) {
this.workers_[0].postMessage(
{
buffers,
meta: job.meta,
imageOps: this.imageOps_,
width,
height
},
buffers
);
return;
}
const length = job.inputs[0].data.length;
const segmentLength = 4 * Math.ceil(length / 4 / threads);
for (let i = 0; i < threads; ++i) {
const offset = i * segmentLength;
const slices = [];
for (let j = 0, jj = buffers.length; j < jj; ++j) {
slices.push(buffers[j].slice(offset, offset + segmentLength));
}
this.workers_[i].postMessage(
{
buffers: slices,
meta: job.meta,
imageOps: this.imageOps_,
width,
height
},
slices
);
}
}
/**
* Handle messages from the worker.
* @param {number} index The worker index.
* @param {MessageEvent} event The message event.
*/
onWorkerMessage_(index, event) {
if (this.disposed) {
return;
}
this.dataLookup_[index] = event.data;
--this.running_;
if (this.running_ === 0) {
this.resolveJob_();
}
}
/**
* Resolve a job. If there are no more worker threads, the processor callback
* will be called.
*/
resolveJob_() {
const job = this.job_;
const threads = this.workers_.length;
let data, meta;
if (threads === 1) {
data = new Uint8ClampedArray(this.dataLookup_[0]["buffer"]);
meta = this.dataLookup_[0]["meta"];
} else {
const length = job.inputs[0].data.length;
data = new Uint8ClampedArray(length);
meta = new Array(threads);
const segmentLength = 4 * Math.ceil(length / 4 / threads);
for (let i = 0; i < threads; ++i) {
const buffer3 = this.dataLookup_[i]["buffer"];
const offset = i * segmentLength;
data.set(new Uint8ClampedArray(buffer3), offset);
meta[i] = this.dataLookup_[i]["meta"];
}
}
this.job_ = null;
this.dataLookup_ = {};
job.callback(
null,
new ImageData(data, job.inputs[0].width, job.inputs[0].height),
meta
);
this.dispatch_();
}
/**
* Terminate all workers associated with the processor.
* @override
*/
disposeInternal() {
for (let i = 0; i < this.workers_.length; ++i) {
this.workers_[i].terminate();
}
this.workers_.length = 0;
}
};
var RasterEventType = {
/**
* Triggered before operations are run. Listeners will receive an event object with
* a `data` property that can be used to make data available to operations.
* @event module:ol/source/Raster.RasterSourceEvent#beforeoperations
* @api
*/
BEFOREOPERATIONS: "beforeoperations",
/**
* Triggered after operations are run. Listeners will receive an event object with
* a `data` property. If more than one thread is used, `data` will be an array of
* objects. If a single thread is used, `data` will be a single object.
* @event module:ol/source/Raster.RasterSourceEvent#afteroperations
* @api
*/
AFTEROPERATIONS: "afteroperations"
};
var RasterSourceEvent = class extends Event_default {
/**
* @param {string} type Type.
* @param {import("../Map.js").FrameState} frameState The frame state.
* @param {Object|Array<Object>} data An object made available to operations. For "afteroperations" evenets
* this will be an array of objects if more than one thread is used.
*/
constructor(type, frameState, data) {
super(type);
this.extent = frameState.extent;
this.resolution = frameState.viewState.resolution / frameState.pixelRatio;
this.data = data;
}
};
var RasterSource = class extends Image_default4 {
/**
* @param {Options} options Options.
*/
constructor(options) {
super({
projection: null
});
this.on;
this.once;
this.un;
this.processor_ = null;
this.operationType_ = options.operationType !== void 0 ? options.operationType : "pixel";
this.threads_ = options.threads !== void 0 ? options.threads : 1;
this.layers_ = createLayers(options.sources);
const changed = this.changed.bind(this);
for (let i = 0, ii = this.layers_.length; i < ii; ++i) {
this.layers_[i].addEventListener(EventType_default.CHANGE, changed);
}
this.useResolutions_ = options.resolutions !== null;
this.tileQueue_ = new TileQueue_default(function() {
return 1;
}, this.processSources_.bind(this));
this.requestedFrameState_;
this.renderedImageCanvas_ = null;
this.renderedRevision_;
this.frameState_ = {
animate: false,
coordinateToPixelTransform: create(),
declutter: null,
extent: null,
index: 0,
layerIndex: 0,
layerStatesArray: getLayerStatesArray(this.layers_),
pixelRatio: 1,
pixelToCoordinateTransform: create(),
postRenderFunctions: [],
size: [0, 0],
tileQueue: this.tileQueue_,
time: Date.now(),
usedTiles: {},
viewState: (
/** @type {import("../View.js").State} */
{
rotation: 0
}
),
viewHints: [],
wantedTiles: {},
mapId: getUid(this),
renderTargets: {}
};
this.setAttributions(function(frameState) {
var _a;
const attributions = [];
for (let i = 0, iMax = options.sources.length; i < iMax; ++i) {
const sourceOrLayer = options.sources[i];
const source = sourceOrLayer instanceof Source_default ? sourceOrLayer : sourceOrLayer.getSource();
if (!source) {
continue;
}
const sourceAttributions = (_a = source.getAttributions()) == null ? void 0 : _a(frameState);
if (typeof sourceAttributions === "string") {
attributions.push(sourceAttributions);
} else if (sourceAttributions !== void 0) {
attributions.push(...sourceAttributions);
}
}
return attributions;
});
if (options.operation !== void 0) {
this.setOperation(options.operation, options.lib);
}
}
/**
* Set the operation.
* @param {Operation} operation New operation.
* @param {Object} [lib] Functions that will be available to operations run
* in a worker.
* @api
*/
setOperation(operation, lib) {
if (this.processor_) {
this.processor_.dispose();
}
this.processor_ = new Processor({
operation,
imageOps: this.operationType_ === "image",
queue: 1,
lib,
threads: this.threads_
});
this.changed();
}
/**
* Update the stored frame state.
* @param {import("../extent.js").Extent} extent The view extent (in map units).
* @param {number} resolution The view resolution.
* @param {import("../proj/Projection.js").default} projection The view projection.
* @return {import("../Map.js").FrameState} The updated frame state.
* @private
*/
updateFrameState_(extent, resolution, projection) {
const frameState = (
/** @type {import("../Map.js").FrameState} */
Object.assign({}, this.frameState_)
);
frameState.viewState = /** @type {import("../View.js").State} */
Object.assign({}, frameState.viewState);
const center = getCenter(extent);
frameState.size[0] = Math.ceil(getWidth(extent) / resolution);
frameState.size[1] = Math.ceil(getHeight(extent) / resolution);
frameState.extent = [
center[0] - frameState.size[0] * resolution / 2,
center[1] - frameState.size[1] * resolution / 2,
center[0] + frameState.size[0] * resolution / 2,
center[1] + frameState.size[1] * resolution / 2
];
frameState.time = Date.now();
const viewState = frameState.viewState;
viewState.center = center;
viewState.projection = projection;
viewState.resolution = resolution;
return frameState;
}
/**
* Determine if all sources are ready.
* @return {boolean} All sources are ready.
* @private
*/
allSourcesReady_() {
let ready = true;
let source;
for (let i = 0, ii = this.layers_.length; i < ii; ++i) {
source = this.layers_[i].getSource();
if (!source || source.getState() !== "ready") {
ready = false;
break;
}
}
return ready;
}
/**
* @param {import("../extent.js").Extent} extent Extent.
* @param {number} resolution Resolution.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {import("../ImageCanvas.js").default} Single image.
* @override
*/
getImage(extent, resolution, pixelRatio, projection) {
if (!this.allSourcesReady_()) {
return null;
}
this.tileQueue_.loadMoreTiles(16, 16);
resolution = this.findNearestResolution(resolution);
const frameState = this.updateFrameState_(extent, resolution, projection);
this.requestedFrameState_ = frameState;
if (this.renderedImageCanvas_) {
const renderedResolution = this.renderedImageCanvas_.getResolution();
const renderedExtent = this.renderedImageCanvas_.getExtent();
if (resolution !== renderedResolution || !equals(frameState.extent, renderedExtent)) {
this.renderedImageCanvas_ = null;
}
}
if (!this.renderedImageCanvas_ || this.getRevision() !== this.renderedRevision_) {
this.processSources_();
}
if (frameState.animate) {
requestAnimationFrame(this.changed.bind(this));
}
return this.renderedImageCanvas_;
}
/**
* Start processing source data.
* @private
*/
processSources_() {
const frameState = this.requestedFrameState_;
const len = this.layers_.length;
const imageDatas = new Array(len);
for (let i = 0; i < len; ++i) {
frameState.layerIndex = i;
frameState.renderTargets = {};
const imageData = getImageData(this.layers_[i], frameState);
if (imageData) {
imageDatas[i] = imageData;
} else {
return;
}
}
const data = {};
this.dispatchEvent(
new RasterSourceEvent(RasterEventType.BEFOREOPERATIONS, frameState, data)
);
this.processor_.process(
imageDatas,
data,
this.onWorkerComplete_.bind(this, frameState)
);
}
/**
* Called when pixel processing is complete.
* @param {import("../Map.js").FrameState} frameState The frame state.
* @param {Error} err Any error during processing.
* @param {ImageData} output The output image data.
* @param {Object|Array<Object>} data The user data (or an array if more than one thread).
* @private
*/
onWorkerComplete_(frameState, err, output, data) {
if (err || !output) {
return;
}
const extent = frameState.extent;
const resolution = frameState.viewState.resolution;
if (resolution !== this.requestedFrameState_.viewState.resolution || !equals(extent, this.requestedFrameState_.extent)) {
return;
}
let context;
if (this.renderedImageCanvas_) {
context = /** @type {CanvasRenderingContext2D|OffscreenCanvasRenderingContext2D} */
this.renderedImageCanvas_.getImage().getContext("2d");
} else {
const width = Math.round(getWidth(extent) / resolution);
const height = Math.round(getHeight(extent) / resolution);
context = createCanvasContext2D(width, height);
this.renderedImageCanvas_ = new ImageCanvas_default(
extent,
resolution,
1,
context.canvas
);
}
context.putImageData(output, 0, 0);
if (frameState.animate) {
requestAnimationFrame(this.changed.bind(this));
} else {
this.changed();
}
this.renderedRevision_ = this.getRevision();
this.dispatchEvent(
new RasterSourceEvent(RasterEventType.AFTEROPERATIONS, frameState, data)
);
}
/**
* @param {import("../proj/Projection").default} [projection] Projection.
* @return {Array<number>|null} Resolutions.
* @override
*/
getResolutions(projection) {
if (!this.useResolutions_) {
return null;
}
let resolutions = super.getResolutions();
if (!resolutions) {
for (let i = 0, ii = this.layers_.length; i < ii; ++i) {
const source = this.layers_[i].getSource();
resolutions = source.getResolutions(projection);
if (resolutions) {
break;
}
}
}
return resolutions;
}
/**
* @override
*/
disposeInternal() {
if (this.processor_) {
this.processor_.dispose();
}
super.disposeInternal();
}
};
RasterSource.prototype.dispose;
var sharedContext = null;
function getImageData(layer, frameState) {
const renderer = layer.getRenderer();
if (!renderer) {
throw new Error("Unsupported layer type: " + layer);
}
if (!renderer.prepareFrame(frameState)) {
return null;
}
const width = frameState.size[0];
const height = frameState.size[1];
if (width === 0 || height === 0) {
return null;
}
const container = renderer.renderFrame(frameState, null);
let element;
if (container instanceof HTMLCanvasElement) {
element = container;
} else {
if (container) {
element = container.firstElementChild;
}
if (!(element instanceof HTMLCanvasElement)) {
throw new Error("Unsupported rendered element: " + element);
}
if (element.width === width && element.height === height) {
const context = element.getContext("2d");
return context.getImageData(0, 0, width, height);
}
}
if (!sharedContext) {
sharedContext = createCanvasContext2D(width, height, void 0, {
willReadFrequently: true
});
} else {
const canvas = sharedContext.canvas;
if (canvas.width !== width || canvas.height !== height) {
sharedContext = createCanvasContext2D(width, height, void 0, {
willReadFrequently: true
});
} else {
sharedContext.clearRect(0, 0, width, height);
}
}
sharedContext.drawImage(element, 0, 0, width, height);
return sharedContext.getImageData(0, 0, width, height);
}
function getLayerStatesArray(layers) {
return layers.map(function(layer) {
return layer.getLayerState();
});
}
function createLayers(sources) {
const len = sources.length;
const layers = new Array(len);
for (let i = 0; i < len; ++i) {
layers[i] = createLayer(sources[i]);
}
return layers;
}
function createLayer(layerOrSource) {
let layer;
if (layerOrSource instanceof Source_default) {
if (layerOrSource instanceof Tile_default3) {
layer = new Tile_default2({ source: layerOrSource });
} else if (layerOrSource instanceof Image_default4) {
layer = new Image_default2({ source: layerOrSource });
}
} else {
layer = layerOrSource;
}
return layer;
}
var Raster_default = RasterSource;
// node_modules/ol/source/StadiaMaps.js
var STADIA_ATTRIBUTION = '&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a>';
var OMT_ATTRIBUTION = '&copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a>';
var STAMEN_ATTRIBUTION = '&copy; <a href="https://stamen.com/" target="_blank">Stamen Design</a>';
var LayerConfig = {
"stamen_terrain": {
extension: "png"
},
"stamen_terrain_background": {
extension: "png"
},
"stamen_terrain_labels": {
extension: "png"
},
"stamen_terrain_lines": {
extension: "png"
},
"stamen_toner_background": {
extension: "png"
},
"stamen_toner": {
extension: "png"
},
"stamen_toner_labels": {
extension: "png"
},
"stamen_toner_lines": {
extension: "png"
},
"stamen_toner_lite": {
extension: "png"
},
"stamen_toner_dark": {
extension: "png"
},
"stamen_toner_blacklite": {
extension: "png"
},
"stamen_watercolor": {
extension: "jpg"
},
"alidade_smooth": {
extension: "png"
},
"alidade_smooth_dark": {
extension: "png"
},
"alidade_satellite": {
extension: "png"
},
"outdoors": {
extension: "png"
},
"osm_bright": {
extension: "png"
}
};
var ProviderConfig = {
"stamen_terrain": {
minZoom: 0,
maxZoom: 18,
retina: true
},
"stamen_toner": {
minZoom: 0,
maxZoom: 20,
retina: true
},
"stamen_toner_dark": {
minZoom: 0,
maxZoom: 20,
retina: true
},
"stamen_toner_blacklite": {
minZoom: 0,
maxZoom: 20,
retina: true
},
"stamen_watercolor": {
minZoom: 1,
maxZoom: 18,
retina: false
}
};
var StadiaMaps = class extends XYZ_default {
/**
* @param {Options} options StadiaMaps options.
*/
constructor(options) {
const i = options.layer.indexOf("-");
const provider = i == -1 ? options.layer : options.layer.slice(0, i);
const providerConfig = ProviderConfig[provider] || {
"minZoom": 0,
"maxZoom": 20,
"retina": true
};
const layerConfig = LayerConfig[options.layer];
const query = options.apiKey ? "?api_key=" + options.apiKey : "";
const retina = providerConfig.retina && options.retina ? "@2x" : "";
const url = options.url !== void 0 ? options.url : "https://tiles.stadiamaps.com/tiles/" + options.layer + "/{z}/{x}/{y}" + retina + "." + layerConfig.extension + query;
const attributions = [STADIA_ATTRIBUTION, OMT_ATTRIBUTION, ATTRIBUTION];
if (options.layer.startsWith("stamen_")) {
attributions.splice(1, 0, STAMEN_ATTRIBUTION);
}
super({
attributions,
cacheSize: options.cacheSize,
crossOrigin: "anonymous",
interpolate: options.interpolate,
maxZoom: options.maxZoom !== void 0 ? options.maxZoom : providerConfig.maxZoom,
minZoom: options.minZoom !== void 0 ? options.minZoom : providerConfig.minZoom,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileLoadFunction: options.tileLoadFunction,
transition: options.transition,
url,
tilePixelRatio: retina ? 2 : 1,
wrapX: options.wrapX,
zDirection: options.zDirection
});
}
};
var StadiaMaps_default = StadiaMaps;
// node_modules/ol/source/TileArcGISRest.js
var TileArcGISRest = class extends TileImage_default {
/**
* @param {Options} [options] Tile ArcGIS Rest options.
*/
constructor(options) {
options = options ? options : {};
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
interpolate: options.interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileGrid: options.tileGrid,
tileLoadFunction: options.tileLoadFunction,
url: options.url,
urls: options.urls,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition,
zDirection: options.zDirection
});
this.params_ = Object.assign({}, options.params);
this.hidpi_ = options.hidpi !== void 0 ? options.hidpi : true;
this.tmpExtent_ = createEmpty();
this.setKey(this.getKeyForParams_());
}
/**
* @private
* @return {string} The key for the current params.
*/
getKeyForParams_() {
let i = 0;
const res = [];
for (const key in this.params_) {
res[i++] = key + "-" + this.params_[key];
}
return res.join("/");
}
/**
* Get the user-provided params, i.e. those passed to the constructor through
* the "params" option, and possibly updated using the updateParams method.
* @return {Object} Params.
* @api
*/
getParams() {
return this.params_;
}
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("../size.js").Size} tileSize Tile size.
* @param {import("../extent.js").Extent} tileExtent Tile extent.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @param {Object} params Params.
* @return {string|undefined} Request URL.
* @private
*/
getRequestUrl_(tileCoord, tileSize, tileExtent, pixelRatio, projection, params) {
const urls = this.urls;
if (!urls) {
return void 0;
}
let url;
if (urls.length == 1) {
url = urls[0];
} else {
const index = modulo(hash(tileCoord), urls.length);
url = urls[index];
}
return getRequestUrl(
url,
tileExtent,
(this.tileGrid || this.getTileGridForProjection(projection)).getResolution(tileCoord[0]),
pixelRatio,
projection,
params
);
}
/**
* Get the tile pixel ratio for this source.
* @param {number} pixelRatio Pixel ratio.
* @return {number} Tile pixel ratio.
* @override
*/
getTilePixelRatio(pixelRatio) {
return this.hidpi_ ? pixelRatio : 1;
}
/**
* Set the user-provided params.
* @param {Object} params Params.
* @api
*/
setParams(params) {
this.params_ = Object.assign({}, params);
this.setKey(this.getKeyForParams_());
}
/**
* Update the user-provided params.
* @param {Object} params Params.
* @api
*/
updateParams(params) {
Object.assign(this.params_, params);
this.setKey(this.getKeyForParams_());
}
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord The tile coordinate
* @param {number} pixelRatio The pixel ratio
* @param {import("../proj/Projection.js").default} projection The projection
* @return {string|undefined} The tile URL
* @override
*/
tileUrlFunction(tileCoord, pixelRatio, projection) {
let tileGrid = this.getTileGrid();
if (!tileGrid) {
tileGrid = this.getTileGridForProjection(projection);
}
if (tileGrid.getResolutions().length <= tileCoord[0]) {
return void 0;
}
if (pixelRatio != 1 && !this.hidpi_) {
pixelRatio = 1;
}
const tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
let tileSize = toSize(tileGrid.getTileSize(tileCoord[0]), this.tmpSize);
if (pixelRatio != 1) {
tileSize = scale2(tileSize, pixelRatio, this.tmpSize);
}
const baseParams = {
"F": "image",
"FORMAT": "PNG32",
"TRANSPARENT": true
};
Object.assign(baseParams, this.params_);
return this.getRequestUrl_(
tileCoord,
tileSize,
tileExtent,
pixelRatio,
projection,
baseParams
);
}
};
var TileArcGISRest_default = TileArcGISRest;
// node_modules/ol/source/TileDebug.js
var TileDebug = class extends ImageTile_default2 {
/**
* @param {Options} [options] Debug tile options.
*/
constructor(options) {
options = options || {};
const template = options.template || "z:{z} x:{x} y:{y}";
const source = options.source;
const color = options.color || "grey";
super({
transition: 0,
wrapX: options.wrapX !== void 0 ? options.wrapX : source !== void 0 ? source.getWrapX() : void 0
});
const setReady = () => {
var _a;
this.projection = options.projection !== void 0 ? get(options.projection) : source !== void 0 ? source.getProjection() : this.projection;
this.tileGrid = options.tileGrid !== void 0 ? options.tileGrid : source !== void 0 ? source.getTileGrid() : this.tileGrid;
this.zDirection = options.zDirection !== void 0 ? options.zDirection : source !== void 0 ? source.zDirection : this.zDirection;
if (source instanceof DataTile_default3) {
this.transformMatrix = ((_a = source.transformMatrix) == null ? void 0 : _a.slice()) || null;
}
const tileGrid = this.tileGrid;
if (tileGrid) {
this.setTileSizes(
tileGrid.getResolutions().map(
(r, i) => toSize(tileGrid.getTileSize(i)).map(
(s) => Math.max(Math.floor(s), 1)
)
)
);
}
this.setLoader((z, x, y, loaderOptions) => {
const text = renderXYZTemplate(template, z, x, y, loaderOptions.maxY);
const [width, height] = this.getTileSize(z);
const context = createCanvasContext2D(width, height);
context.strokeStyle = color;
context.strokeRect(0.5, 0.5, width + 0.5, height + 0.5);
context.fillStyle = color;
context.strokeStyle = "white";
context.textAlign = "center";
context.textBaseline = "middle";
context.font = "24px sans-serif";
context.lineWidth = 4;
context.strokeText(text, width / 2, height / 2, width);
context.fillText(text, width / 2, height / 2, width);
return Promise.resolve(context.canvas);
});
this.setState("ready");
};
if (source === void 0 || source.getState() === "ready") {
setReady();
} else {
const handler2 = () => {
if (source.getState() === "ready") {
source.removeEventListener(EventType_default.CHANGE, handler2);
setReady();
}
};
source.addEventListener(EventType_default.CHANGE, handler2);
}
}
};
var TileDebug_default = TileDebug;
// node_modules/ol/source/TileJSON.js
var TileJSON = class extends TileImage_default {
/**
* @param {Options} options TileJSON options.
*/
constructor(options) {
super({
attributions: options.attributions,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
interpolate: options.interpolate,
projection: get("EPSG:3857"),
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
state: "loading",
tileLoadFunction: options.tileLoadFunction,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition,
zDirection: options.zDirection
});
this.tileJSON_ = null;
this.tileSize_ = options.tileSize;
if (options.url) {
if (options.jsonp) {
jsonp(
options.url,
this.handleTileJSONResponse.bind(this),
this.handleTileJSONError.bind(this)
);
} else {
const client = new XMLHttpRequest();
client.addEventListener("load", this.onXHRLoad_.bind(this));
client.addEventListener("error", this.onXHRError_.bind(this));
client.open("GET", options.url);
client.send();
}
} else if (options.tileJSON) {
this.handleTileJSONResponse(options.tileJSON);
} else {
throw new Error("Either `url` or `tileJSON` options must be provided");
}
}
/**
* @private
* @param {Event} event The load event.
*/
onXHRLoad_(event) {
const client = (
/** @type {XMLHttpRequest} */
event.target
);
if (!client.status || client.status >= 200 && client.status < 300) {
let response;
try {
response = /** @type {Config} */
JSON.parse(client.responseText);
} catch {
this.handleTileJSONError();
return;
}
this.handleTileJSONResponse(response);
} else {
this.handleTileJSONError();
}
}
/**
* @private
* @param {Event} event The error event.
*/
onXHRError_(event) {
this.handleTileJSONError();
}
/**
* @return {Config} The tilejson object.
* @api
*/
getTileJSON() {
return this.tileJSON_;
}
/**
* @protected
* @param {Config} tileJSON Tile JSON.
*/
handleTileJSONResponse(tileJSON) {
const epsg4326Projection = get("EPSG:4326");
const sourceProjection = this.getProjection();
let extent;
if (tileJSON["bounds"] !== void 0) {
const transform2 = getTransformFromProjections(
epsg4326Projection,
sourceProjection
);
extent = applyTransform(tileJSON["bounds"], transform2);
}
const gridExtent = extentFromProjection(sourceProjection);
const minZoom = tileJSON["minzoom"] || 0;
const maxZoom2 = tileJSON["maxzoom"] || 22;
const tileGrid = createXYZ({
extent: gridExtent,
maxZoom: maxZoom2,
minZoom,
tileSize: this.tileSize_
});
this.tileGrid = tileGrid;
this.tileUrlFunction = createFromTemplates(tileJSON["tiles"], tileGrid);
if (tileJSON["attribution"] && !this.getAttributions()) {
const attributionExtent = extent !== void 0 ? extent : gridExtent;
this.setAttributions(function(frameState) {
if (intersects(attributionExtent, frameState.extent)) {
return [tileJSON["attribution"]];
}
return null;
});
}
this.tileJSON_ = tileJSON;
this.setState("ready");
}
/**
* @protected
*/
handleTileJSONError() {
this.setState("error");
}
};
var TileJSON_default = TileJSON;
// node_modules/ol/source/TileWMS.js
var TileWMS = class extends TileImage_default {
/**
* @param {Options} [options] Tile WMS options.
*/
constructor(options) {
options = options ? options : (
/** @type {Options} */
{}
);
const params = Object.assign({}, options.params);
super({
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
interpolate: options.interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileClass: options.tileClass,
tileGrid: options.tileGrid,
tileLoadFunction: options.tileLoadFunction,
url: options.url,
urls: options.urls,
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
transition: options.transition,
zDirection: options.zDirection
});
this.gutter_ = options.gutter !== void 0 ? options.gutter : 0;
this.params_ = params;
this.v13_ = true;
this.serverType_ = options.serverType;
this.hidpi_ = options.hidpi !== void 0 ? options.hidpi : true;
this.tmpExtent_ = createEmpty();
this.updateV13_();
this.setKey(this.getKeyForParams_());
}
/**
* Return the GetFeatureInfo URL for the passed coordinate, resolution, and
* projection. Return `undefined` if the GetFeatureInfo URL cannot be
* constructed.
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {number} resolution Resolution.
* @param {import("../proj.js").ProjectionLike} projection Projection.
* @param {!Object} params GetFeatureInfo params. `INFO_FORMAT` at least should
* be provided. If `QUERY_LAYERS` is not provided then the layers specified
* in the `LAYERS` parameter will be used. `VERSION` should not be
* specified here.
* @return {string|undefined} GetFeatureInfo URL.
* @api
*/
getFeatureInfoUrl(coordinate, resolution, projection, params) {
const projectionObj = get(projection);
const sourceProjectionObj = this.getProjection() || projectionObj;
let tileGrid = this.getTileGrid();
if (!tileGrid) {
tileGrid = this.getTileGridForProjection(sourceProjectionObj);
}
const sourceProjCoord = transform(
coordinate,
projectionObj,
sourceProjectionObj
);
const sourceResolution = calculateSourceResolution(
sourceProjectionObj,
projectionObj,
coordinate,
resolution
);
const z = tileGrid.getZForResolution(sourceResolution, this.zDirection);
const tileResolution = tileGrid.getResolution(z);
const tileCoord = tileGrid.getTileCoordForCoordAndZ(sourceProjCoord, z);
if (tileGrid.getResolutions().length <= tileCoord[0]) {
return void 0;
}
let tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
const gutter = this.gutter_;
if (gutter !== 0) {
tileExtent = buffer(tileExtent, tileResolution * gutter, tileExtent);
}
const baseParams = {
"QUERY_LAYERS": this.params_["LAYERS"]
};
Object.assign(
baseParams,
getRequestParams(this.params_, "GetFeatureInfo"),
params
);
const x = Math.floor((sourceProjCoord[0] - tileExtent[0]) / tileResolution);
const y = Math.floor((tileExtent[3] - sourceProjCoord[1]) / tileResolution);
baseParams[this.v13_ ? "I" : "X"] = x;
baseParams[this.v13_ ? "J" : "Y"] = y;
return this.getRequestUrl_(
tileCoord,
tileExtent,
1,
sourceProjectionObj || projectionObj,
baseParams
);
}
/**
* Return the GetLegendGraphic URL, optionally optimized for the passed
* resolution and possibly including any passed specific parameters. Returns
* `undefined` if the GetLegendGraphic URL cannot be constructed.
*
* @param {number} [resolution] Resolution. If set to undefined, `SCALE`
* will not be calculated and included in URL.
* @param {Object} [params] GetLegendGraphic params. If `LAYER` is set, the
* request is generated for this wms layer, else it will try to use the
* configured wms layer. Default `FORMAT` is `image/png`.
* `VERSION` should not be specified here.
* @return {string|undefined} GetLegendGraphic URL.
* @api
*/
getLegendUrl(resolution, params) {
if (this.urls[0] === void 0) {
return void 0;
}
const baseParams = {
"SERVICE": "WMS",
"VERSION": DEFAULT_VERSION,
"REQUEST": "GetLegendGraphic",
"FORMAT": "image/png"
};
if (params === void 0 || params["LAYER"] === void 0) {
const layers = this.params_.LAYERS;
const isSingleLayer = !Array.isArray(layers) || layers.length === 1;
if (!isSingleLayer) {
return void 0;
}
baseParams["LAYER"] = layers;
}
if (resolution !== void 0) {
const mpu = this.getProjection() ? this.getProjection().getMetersPerUnit() : 1;
const pixelSize = 28e-5;
baseParams["SCALE"] = resolution * mpu / pixelSize;
}
Object.assign(baseParams, params);
return appendParams(
/** @type {string} */
this.urls[0],
baseParams
);
}
/**
* @return {number} Gutter.
* @override
*/
getGutter() {
return this.gutter_;
}
/**
* Get the user-provided params, i.e. those passed to the constructor through
* the "params" option, and possibly updated using the updateParams method.
* @return {Object} Params.
* @api
*/
getParams() {
return this.params_;
}
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("../extent.js").Extent} tileExtent Tile extent.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @param {Object} params Params.
* @return {string|undefined} Request URL.
* @private
*/
getRequestUrl_(tileCoord, tileExtent, pixelRatio, projection, params) {
const urls = this.urls;
if (!urls) {
return void 0;
}
let url;
if (urls.length == 1) {
url = urls[0];
} else {
const index = modulo(hash(tileCoord), urls.length);
url = urls[index];
}
return getImageSrc(
tileExtent,
(this.tileGrid || this.getTileGridForProjection(projection)).getResolution(tileCoord[0]),
pixelRatio,
projection,
url,
params,
this.serverType_
);
}
/**
* Get the tile pixel ratio for this source.
* @param {number} pixelRatio Pixel ratio.
* @return {number} Tile pixel ratio.
* @override
*/
getTilePixelRatio(pixelRatio) {
return !this.hidpi_ || this.serverType_ === void 0 ? 1 : pixelRatio;
}
/**
* @private
* @return {string} The key for the current params.
*/
getKeyForParams_() {
let i = 0;
const res = [];
for (const key in this.params_) {
res[i++] = key + "-" + this.params_[key];
}
return res.join("/");
}
/**
* @param {Object} params New URL paremeters.
* @private
*/
setParams_(params) {
this.params_ = params;
this.updateV13_();
this.setKey(this.getKeyForParams_());
}
/**
* Set the URL parameters passed to the WMS source.
* @param {Object} params New URL paremeters.
* @api
*/
setParams(params) {
this.setParams_(Object.assign({}, params));
}
/**
* Update the URL parameters. This method can be used to update a subset of the WMS
* parameters. Call `setParams` to set all of the parameters.
* @param {Object} params Updated URL parameters.
* @api
*/
updateParams(params) {
this.setParams_(Object.assign(this.params_, params));
}
/**
* @private
*/
updateV13_() {
const version = this.params_["VERSION"] || DEFAULT_VERSION;
this.v13_ = compareVersions(version, "1.3") >= 0;
}
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord The tile coordinate
* @param {number} pixelRatio The pixel ratio
* @param {import("../proj/Projection.js").default} projection The projection
* @return {string|undefined} The tile URL
* @override
*/
tileUrlFunction(tileCoord, pixelRatio, projection) {
let tileGrid = this.getTileGrid();
if (!tileGrid) {
tileGrid = this.getTileGridForProjection(projection);
}
if (tileGrid.getResolutions().length <= tileCoord[0]) {
return void 0;
}
if (pixelRatio != 1 && (!this.hidpi_ || this.serverType_ === void 0)) {
pixelRatio = 1;
}
const tileResolution = tileGrid.getResolution(tileCoord[0]);
let tileExtent = tileGrid.getTileCoordExtent(tileCoord, this.tmpExtent_);
const gutter = this.gutter_;
if (gutter !== 0) {
tileExtent = buffer(tileExtent, tileResolution * gutter, tileExtent);
}
const baseParams = Object.assign(
{},
getRequestParams(this.params_, "GetMap")
);
return this.getRequestUrl_(
tileCoord,
tileExtent,
pixelRatio,
projection,
baseParams
);
}
};
var TileWMS_default = TileWMS;
// node_modules/ol/source/UTFGrid.js
var CustomTile2 = class extends Tile_default {
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {import("../TileState.js").default} state State.
* @param {string} src Image source URI.
* @param {import("../extent.js").Extent} extent Extent of the tile.
* @param {boolean} preemptive Load the tile when visible (before it's needed).
* @param {boolean} jsonp Load the tile as a script.
*/
constructor(tileCoord, state, src, extent, preemptive, jsonp2) {
super(tileCoord, state);
this.src_ = src;
this.extent_ = extent;
this.preemptive_ = preemptive;
this.grid_ = null;
this.keys_ = null;
this.data_ = null;
this.jsonp_ = jsonp2;
}
/**
* Get the image element for this tile.
* @return {HTMLImageElement} Image.
*/
getImage() {
return null;
}
/**
* Synchronously returns data at given coordinate (if available).
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @return {*} The data.
*/
getData(coordinate) {
if (!this.grid_ || !this.keys_) {
return null;
}
const xRelative = (coordinate[0] - this.extent_[0]) / (this.extent_[2] - this.extent_[0]);
const yRelative = (coordinate[1] - this.extent_[1]) / (this.extent_[3] - this.extent_[1]);
const row = this.grid_[Math.floor((1 - yRelative) * this.grid_.length)];
if (typeof row !== "string") {
return null;
}
let code = row.charCodeAt(Math.floor(xRelative * row.length));
if (code >= 93) {
code--;
}
if (code >= 35) {
code--;
}
code -= 32;
let data = null;
if (code in this.keys_) {
const id = this.keys_[code];
if (this.data_ && id in this.data_) {
data = this.data_[id];
} else {
data = id;
}
}
return data;
}
/**
* Calls the callback (synchronously by default) with the available data
* for given coordinate (or `null` if not yet loaded).
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {function(*): void} callback Callback.
* @param {boolean} [request] If `true` the callback is always async.
* The tile data is requested if not yet loaded.
*/
forDataAtCoordinate(coordinate, callback, request) {
if (this.state == TileState_default.EMPTY && request === true) {
this.state = TileState_default.IDLE;
listenOnce(this, EventType_default.CHANGE, (e) => {
callback(this.getData(coordinate));
});
this.loadInternal_();
} else {
if (request === true) {
setTimeout(() => {
callback(this.getData(coordinate));
}, 0);
} else {
callback(this.getData(coordinate));
}
}
}
/**
* Return the key to be used for all tiles in the source.
* @return {string} The key for all tiles.
* @override
*/
getKey() {
return this.src_;
}
/**
* @private
*/
handleError_() {
this.state = TileState_default.ERROR;
this.changed();
}
/**
* @param {!UTFGridJSON} json UTFGrid data.
* @private
*/
handleLoad_(json) {
this.grid_ = json["grid"];
this.keys_ = json["keys"];
this.data_ = json["data"];
this.state = TileState_default.LOADED;
this.changed();
}
/**
* @private
*/
loadInternal_() {
if (this.state == TileState_default.IDLE) {
this.state = TileState_default.LOADING;
if (this.jsonp_) {
jsonp(
this.src_,
this.handleLoad_.bind(this),
this.handleError_.bind(this)
);
} else {
const client = new XMLHttpRequest();
client.addEventListener("load", this.onXHRLoad_.bind(this));
client.addEventListener("error", this.onXHRError_.bind(this));
client.open("GET", this.src_);
client.send();
}
}
}
/**
* @private
* @param {Event} event The load event.
*/
onXHRLoad_(event) {
const client = (
/** @type {XMLHttpRequest} */
event.target
);
if (!client.status || client.status >= 200 && client.status < 300) {
let response;
try {
response = /** @type {!UTFGridJSON} */
JSON.parse(client.responseText);
} catch {
this.handleError_();
return;
}
this.handleLoad_(response);
} else {
this.handleError_();
}
}
/**
* @private
* @param {Event} event The error event.
*/
onXHRError_(event) {
this.handleError_();
}
/**
* @override
*/
load() {
if (this.preemptive_) {
this.loadInternal_();
} else {
this.setState(TileState_default.EMPTY);
}
}
};
var UTFGrid = class extends Tile_default3 {
/**
* @param {Options} options Source options.
*/
constructor(options) {
super({
projection: get("EPSG:3857"),
state: "loading",
wrapX: options.wrapX !== void 0 ? options.wrapX : true,
zDirection: options.zDirection
});
this.preemptive_ = options.preemptive !== void 0 ? options.preemptive : true;
this.tileUrlFunction_ = nullTileUrlFunction;
this.template_ = void 0;
this.jsonp_ = options.jsonp || false;
this.tileCache_ = new LRUCache_default(512);
if (options.url) {
if (this.jsonp_) {
jsonp(
options.url,
this.handleTileJSONResponse.bind(this),
this.handleTileJSONError.bind(this)
);
} else {
const client = new XMLHttpRequest();
client.addEventListener("load", this.onXHRLoad_.bind(this));
client.addEventListener("error", this.onXHRError_.bind(this));
client.open("GET", options.url);
client.send();
}
} else if (options.tileJSON) {
this.handleTileJSONResponse(options.tileJSON);
} else {
throw new Error("Either `url` or `tileJSON` options must be provided");
}
}
/**
* @private
* @param {Event} event The load event.
*/
onXHRLoad_(event) {
const client = (
/** @type {XMLHttpRequest} */
event.target
);
if (!client.status || client.status >= 200 && client.status < 300) {
let response;
try {
response = /** @type {import("./TileJSON.js").Config} */
JSON.parse(client.responseText);
} catch {
this.handleTileJSONError();
return;
}
this.handleTileJSONResponse(response);
} else {
this.handleTileJSONError();
}
}
/**
* @private
* @param {Event} event The error event.
*/
onXHRError_(event) {
this.handleTileJSONError();
}
/**
* Return the template from TileJSON.
* @return {string|undefined} The template from TileJSON.
* @api
*/
getTemplate() {
return this.template_;
}
/**
* Calls the callback (synchronously by default) with the available data
* for given coordinate and resolution (or `null` if not yet loaded or
* in case of an error).
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {number} resolution Resolution.
* @param {function(*): void} callback Callback.
* @param {boolean} [request] If `true` the callback is always async.
* The tile data is requested if not yet loaded.
* @api
*/
forDataAtCoordinateAndResolution(coordinate, resolution, callback, request) {
if (this.tileGrid) {
const z = this.tileGrid.getZForResolution(resolution, this.zDirection);
const tileCoord = this.tileGrid.getTileCoordForCoordAndZ(coordinate, z);
const tile = (
/** @type {!CustomTile} */
this.getTile(
tileCoord[0],
tileCoord[1],
tileCoord[2],
1,
this.getProjection()
)
);
if (tile.getState() == TileState_default.IDLE) {
tile.load();
}
tile.forDataAtCoordinate(coordinate, callback, request);
} else {
if (request === true) {
setTimeout(function() {
callback(null);
}, 0);
} else {
callback(null);
}
}
}
/**
* @protected
*/
handleTileJSONError() {
this.setState("error");
}
/**
* TODO: very similar to ol/source/TileJSON#handleTileJSONResponse
* @protected
* @param {import("./TileJSON.js").Config} tileJSON Tile JSON.
*/
handleTileJSONResponse(tileJSON) {
const epsg4326Projection = get("EPSG:4326");
const sourceProjection = this.getProjection();
let extent;
if (tileJSON["bounds"] !== void 0) {
const transform2 = getTransformFromProjections(
epsg4326Projection,
sourceProjection
);
extent = applyTransform(tileJSON["bounds"], transform2);
}
const gridExtent = extentFromProjection(sourceProjection);
const minZoom = tileJSON["minzoom"] || 0;
const maxZoom2 = tileJSON["maxzoom"] || 22;
const tileGrid = createXYZ({
extent: gridExtent,
maxZoom: maxZoom2,
minZoom
});
this.tileGrid = tileGrid;
this.template_ = tileJSON["template"];
const grids = tileJSON["grids"];
if (!grids) {
this.setState("error");
return;
}
this.tileUrlFunction_ = createFromTemplates(grids, tileGrid);
if (tileJSON["attribution"]) {
const attributionExtent = extent !== void 0 ? extent : gridExtent;
this.setAttributions(function(frameState) {
if (intersects(attributionExtent, frameState.extent)) {
return [tileJSON["attribution"]];
}
return null;
});
}
this.setState("ready");
}
/**
* @param {number} z Tile coordinate z.
* @param {number} x Tile coordinate x.
* @param {number} y Tile coordinate y.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {!CustomTile} Tile.
* @override
*/
getTile(z, x, y, pixelRatio, projection) {
const tileCoord = [z, x, y];
const urlTileCoord = this.getTileCoordForTileUrlFunction(
tileCoord,
projection
);
const tileUrl = this.tileUrlFunction_(urlTileCoord, pixelRatio, projection);
const tileKey = `${this.getKey()},${getKeyZXY(z, x, y)}`;
if (this.tileCache_.containsKey(tileKey)) {
return this.tileCache_.get(tileKey);
}
this.tileCache_.expireCache();
const tile = new CustomTile2(
tileCoord,
tileUrl !== void 0 ? TileState_default.IDLE : TileState_default.EMPTY,
tileUrl !== void 0 ? tileUrl : "",
this.tileGrid.getTileCoordExtent(tileCoord),
this.preemptive_,
this.jsonp_
);
this.tileCache_.set(tileKey, tile);
return tile;
}
};
var UTFGrid_default = UTFGrid;
// node_modules/ol/source/WMTS.js
var WMTS = class extends TileImage_default {
/**
* @param {Options} options WMTS options.
*/
constructor(options) {
const requestEncoding = options.requestEncoding !== void 0 ? options.requestEncoding : "KVP";
const tileGrid = options.tileGrid;
let urls = options.urls;
if (urls === void 0 && options.url !== void 0) {
urls = expandUrl(options.url);
}
super({
attributions: options.attributions,
attributionsCollapsible: options.attributionsCollapsible,
cacheSize: options.cacheSize,
crossOrigin: options.crossOrigin,
interpolate: options.interpolate,
projection: options.projection,
reprojectionErrorThreshold: options.reprojectionErrorThreshold,
tileClass: options.tileClass,
tileGrid,
tileLoadFunction: options.tileLoadFunction,
tilePixelRatio: options.tilePixelRatio,
urls,
wrapX: options.wrapX !== void 0 ? options.wrapX : false,
transition: options.transition,
zDirection: options.zDirection
});
this.version_ = options.version !== void 0 ? options.version : "1.0.0";
this.format_ = options.format !== void 0 ? options.format : "image/jpeg";
this.dimensions_ = options.dimensions !== void 0 ? options.dimensions : {};
this.layer_ = options.layer;
this.matrixSet_ = options.matrixSet;
this.style_ = options.style;
this.requestEncoding_ = requestEncoding;
this.setKey(this.getKeyForDimensions_());
if (urls && urls.length > 0) {
this.tileUrlFunction = createFromTileUrlFunctions(
urls.map(this.createFromWMTSTemplate.bind(this))
);
}
}
/**
* Set the URLs to use for requests.
* URLs may contain OGC conform URL Template Variables: {TileMatrix}, {TileRow}, {TileCol}.
* @param {Array<string>} urls URLs.
* @override
*/
setUrls(urls) {
this.urls = urls;
const key = urls.join("\n");
this.setTileUrlFunction(
createFromTileUrlFunctions(
urls.map(this.createFromWMTSTemplate.bind(this))
),
key
);
}
/**
* Get the dimensions, i.e. those passed to the constructor through the
* "dimensions" option, and possibly updated using the updateDimensions
* method.
* @return {!Object} Dimensions.
* @api
*/
getDimensions() {
return this.dimensions_;
}
/**
* Return the image format of the WMTS source.
* @return {string} Format.
* @api
*/
getFormat() {
return this.format_;
}
/**
* Return the layer of the WMTS source.
* @return {string} Layer.
* @api
*/
getLayer() {
return this.layer_;
}
/**
* Return the matrix set of the WMTS source.
* @return {string} MatrixSet.
* @api
*/
getMatrixSet() {
return this.matrixSet_;
}
/**
* Return the request encoding, either "KVP" or "REST".
* @return {RequestEncoding} Request encoding.
* @api
*/
getRequestEncoding() {
return this.requestEncoding_;
}
/**
* Return the style of the WMTS source.
* @return {string} Style.
* @api
*/
getStyle() {
return this.style_;
}
/**
* Return the version of the WMTS source.
* @return {string} Version.
* @api
*/
getVersion() {
return this.version_;
}
/**
* @private
* @return {string} The key for the current dimensions.
*/
getKeyForDimensions_() {
const res = this.urls ? this.urls.slice(0) : [];
for (const key in this.dimensions_) {
res.push(key + "-" + this.dimensions_[key]);
}
return res.join("/");
}
/**
* Update the dimensions.
* @param {Object} dimensions Dimensions.
* @api
*/
updateDimensions(dimensions) {
Object.assign(this.dimensions_, dimensions);
this.setKey(this.getKeyForDimensions_());
}
/**
* @param {string} template Template.
* @return {import("../Tile.js").UrlFunction} Tile URL function.
*/
createFromWMTSTemplate(template) {
const requestEncoding = this.requestEncoding_;
const context = {
"layer": this.layer_,
"style": this.style_,
"tilematrixset": this.matrixSet_
};
if (requestEncoding == "KVP") {
Object.assign(context, {
"Service": "WMTS",
"Request": "GetTile",
"Version": this.version_,
"Format": this.format_
});
}
template = requestEncoding == "KVP" ? appendParams(template, context) : template.replace(/\{(\w+?)\}/g, function(m, p) {
return p.toLowerCase() in context ? context[p.toLowerCase()] : m;
});
const tileGrid = (
/** @type {import("../tilegrid/WMTS.js").default} */
this.tileGrid
);
const dimensions = this.dimensions_;
return (
/**
* @param {import("../tilecoord.js").TileCoord} tileCoord Tile coordinate.
* @param {number} pixelRatio Pixel ratio.
* @param {import("../proj/Projection.js").default} projection Projection.
* @return {string|undefined} Tile URL.
*/
(function(tileCoord, pixelRatio, projection) {
if (!tileCoord) {
return void 0;
}
const localContext = {
"TileMatrix": tileGrid.getMatrixId(tileCoord[0]),
"TileCol": tileCoord[1],
"TileRow": tileCoord[2]
};
Object.assign(localContext, dimensions);
let url = template;
if (requestEncoding == "KVP") {
url = appendParams(url, localContext);
} else {
url = url.replace(/\{(\w+?)\}/g, function(m, p) {
return encodeURIComponent(localContext[p]);
});
}
return url;
})
);
}
};
var WMTS_default = WMTS;
// node_modules/ol/source.js
function sourcesFromTileGrid(tileGrid, factory) {
const sourceCache = new LRUCache_default(32);
const tileGridExtent = tileGrid.getExtent();
return function(extent, resolution) {
sourceCache.expireCache();
if (tileGridExtent) {
extent = getIntersection(tileGridExtent, extent);
}
const z = tileGrid.getZForResolution(resolution);
const wantedSources = [];
tileGrid.forEachTileCoord(extent, z, (tileCoord) => {
const key = tileCoord.toString();
if (!sourceCache.containsKey(key)) {
const source = factory(tileCoord);
sourceCache.set(key, source);
}
wantedSources.push(sourceCache.get(key));
});
return wantedSources;
};
}
export {
BingMaps_default as BingMaps,
CartoDB_default as CartoDB,
Cluster_default as Cluster,
DataTile_default3 as DataTile,
GeoTIFF_default as GeoTIFF,
Google_default as Google,
IIIF_default as IIIF,
Image_default4 as Image,
ImageArcGISRest_default as ImageArcGISRest,
ImageCanvas_default2 as ImageCanvas,
ImageMapGuide_default as ImageMapGuide,
ImageStatic_default as ImageStatic,
ImageTile_default2 as ImageTile,
ImageWMS_default as ImageWMS,
OGCMapTile_default as OGCMapTile,
OGCVectorTile_default as OGCVectorTile,
OSM_default as OSM,
Raster_default as Raster,
Source_default as Source,
StadiaMaps_default as StadiaMaps,
Tile_default3 as Tile,
TileArcGISRest_default as TileArcGISRest,
TileDebug_default as TileDebug,
TileImage_default as TileImage,
TileJSON_default as TileJSON,
TileWMS_default as TileWMS,
UTFGrid_default as UTFGrid,
UrlTile_default as UrlTile,
Vector_default as Vector,
VectorTile_default2 as VectorTile,
WMTS_default as WMTS,
XYZ_default as XYZ,
Zoomify_default as Zoomify,
createLoader as createArcGISRestLoader,
createLoader2 as createMapGuideLoader,
createLoader3 as createStaticLoader,
createLoader4 as createWMSLoader,
sourcesFromTileGrid
};
//# sourceMappingURL=ol_source.js.map