`.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} event Map browser event.\n * @return {boolean} The map has the focus.\n * @api\n */\nexport const focus = function (event) {\n const targetElement = event.map.getTargetElement();\n const rootNode = targetElement.getRootNode();\n const activeElement = event.map.getOwnerDocument().activeElement;\n\n return rootNode instanceof ShadowRoot\n ? rootNode.host.contains(activeElement)\n : targetElement.contains(activeElement);\n};\n\n/**\n * Return `true` if the map has the focus or no 'tabindex' attribute set.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} event Map browser event.\n * @return {boolean} The map container has the focus or no 'tabindex' attribute.\n */\nexport const focusWithTabindex = function (event) {\n const targetElement = event.map.getTargetElement();\n const rootNode = targetElement.getRootNode();\n const tabIndexCandidate =\n rootNode instanceof ShadowRoot ? rootNode.host : targetElement;\n\n return tabIndexCandidate.hasAttribute('tabindex') ? focus(event) : true;\n};\n\n/**\n * Return always true.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True.\n * @api\n */\nexport const always = TRUE;\n\n/**\n * Return `true` if the event is a `click` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `click` event.\n * @api\n */\nexport const click = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.CLICK;\n};\n\n/**\n * Return `true` if the event has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} The result.\n */\nexport const mouseActionButton = function (mapBrowserEvent) {\n const originalEvent = /** @type {MouseEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return originalEvent.button == 0 && !(WEBKIT && MAC && originalEvent.ctrlKey);\n};\n\n/**\n * Return always false.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} False.\n * @api\n */\nexport const never = FALSE;\n\n/**\n * Return `true` if the browser event is a `pointermove` event, `false`\n * otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the browser event is a `pointermove` event.\n * @api\n */\nexport const pointerMove = function (mapBrowserEvent) {\n return mapBrowserEvent.type == 'pointermove';\n};\n\n/**\n * Return `true` if the event is a map `singleclick` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `singleclick` event.\n * @api\n */\nexport const singleClick = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;\n};\n\n/**\n * Return `true` if the event is a map `dblclick` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `dblclick` event.\n * @api\n */\nexport const doubleClick = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;\n};\n\n/**\n * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is\n * pressed.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if there no modifier keys are pressed.\n * @api\n */\nexport const noModifierKeys = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n !originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n !originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if only the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally\n * the shift-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the platform modifier key is pressed.\n * @api\n */\nexport const platformModifierKeyOnly = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n !originalEvent.altKey &&\n (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&\n !originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the platform modifier key is pressed.\n * @api\n */\nexport const platformModifierKey = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return MAC ? originalEvent.metaKey : originalEvent.ctrlKey;\n};\n\n/**\n * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when\n * additionally the alt-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the shift key is pressed.\n * @api\n */\nexport const shiftKeyOnly = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n !originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if the target element is not editable, i.e. not an `input`,\n * `select`, or `textarea` element and no `contenteditable` attribute is\n * set or inherited, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if the target element is not editable.\n * @api\n */\nexport const targetNotEditable = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n const tagName = /** @type {Element} */ (originalEvent.target).tagName;\n return (\n tagName !== 'INPUT' &&\n tagName !== 'SELECT' &&\n tagName !== 'TEXTAREA' &&\n // `isContentEditable` is only available on `HTMLElement`, but it may also be a\n // different type like `SVGElement`.\n // @ts-ignore\n !originalEvent.target.isContentEditable\n );\n};\n\n/**\n * Return `true` if the event originates from a mouse device.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a mouse device.\n * @api\n */\nexport const mouseOnly = function (mapBrowserEvent) {\n const pointerEvent = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvent !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvent.pointerType == 'mouse';\n};\n\n/**\n * Return `true` if the event originates from a touchable device.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a touchable device.\n * @api\n */\nexport const touchOnly = function (mapBrowserEvent) {\n const pointerEvt = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvt !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvt.pointerType === 'touch';\n};\n\n/**\n * Return `true` if the event originates from a digital pen.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a digital pen.\n * @api\n */\nexport const penOnly = function (mapBrowserEvent) {\n const pointerEvt = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvt !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvt.pointerType === 'pen';\n};\n\n/**\n * Return `true` if the event originates from a primary pointer in\n * contact with the surface or if the left mouse button is pressed.\n * See https://www.w3.org/TR/pointerevents/#button-states.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a primary pointer.\n * @api\n */\nexport const primaryAction = function (mapBrowserEvent) {\n const pointerEvent = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvent !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n return pointerEvent.isPrimary && pointerEvent.button === 0;\n};\n"],
- "mappings": "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",
- "names": []
-}
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-POVGKIBQ.js b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-POVGKIBQ.js
new file mode 100644
index 0000000..f58d2f1
--- /dev/null
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-POVGKIBQ.js
@@ -0,0 +1,51 @@
+import {
+ EventType_default
+} from "./chunk-33VDV4DG.js";
+
+// node_modules/ol/MapBrowserEventType.js
+var MapBrowserEventType_default = {
+ /**
+ * A true single click with no dragging and no double click. Note that this
+ * event is delayed by 250 ms to ensure that it is not a double click.
+ * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick
+ * @api
+ */
+ SINGLECLICK: "singleclick",
+ /**
+ * A click with no dragging. A double click will fire two of this.
+ * @event module:ol/MapBrowserEvent~MapBrowserEvent#click
+ * @api
+ */
+ CLICK: EventType_default.CLICK,
+ /**
+ * A true double click, with no dragging.
+ * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick
+ * @api
+ */
+ DBLCLICK: EventType_default.DBLCLICK,
+ /**
+ * Triggered when a pointer is dragged.
+ * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag
+ * @api
+ */
+ POINTERDRAG: "pointerdrag",
+ /**
+ * Triggered when a pointer is moved. Note that on touch devices this is
+ * triggered when the map is panned, so is not the same as mousemove.
+ * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove
+ * @api
+ */
+ POINTERMOVE: "pointermove",
+ POINTERDOWN: "pointerdown",
+ POINTERUP: "pointerup",
+ POINTEROVER: "pointerover",
+ POINTEROUT: "pointerout",
+ POINTERENTER: "pointerenter",
+ POINTERLEAVE: "pointerleave",
+ POINTERCANCEL: "pointercancel"
+};
+
+export {
+ MapBrowserEventType_default
+};
+//# sourceMappingURL=chunk-POVGKIBQ.js.map
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-POVGKIBQ.js.map b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-POVGKIBQ.js.map
new file mode 100644
index 0000000..5884953
--- /dev/null
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-POVGKIBQ.js.map
@@ -0,0 +1,7 @@
+{
+ "version": 3,
+ "sources": ["../../ol/MapBrowserEventType.js"],
+ "sourcesContent": ["/**\n * @module ol/MapBrowserEventType\n */\nimport EventType from './events/EventType.js';\n\n/**\n * Constants for event names.\n * @enum {string}\n */\nexport default {\n /**\n * A true single click with no dragging and no double click. Note that this\n * event is delayed by 250 ms to ensure that it is not a double click.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick\n * @api\n */\n SINGLECLICK: 'singleclick',\n\n /**\n * A click with no dragging. A double click will fire two of this.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#click\n * @api\n */\n CLICK: EventType.CLICK,\n\n /**\n * A true double click, with no dragging.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick\n * @api\n */\n DBLCLICK: EventType.DBLCLICK,\n\n /**\n * Triggered when a pointer is dragged.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag\n * @api\n */\n POINTERDRAG: 'pointerdrag',\n\n /**\n * Triggered when a pointer is moved. Note that on touch devices this is\n * triggered when the map is panned, so is not the same as mousemove.\n * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove\n * @api\n */\n POINTERMOVE: 'pointermove',\n\n POINTERDOWN: 'pointerdown',\n POINTERUP: 'pointerup',\n POINTEROVER: 'pointerover',\n POINTEROUT: 'pointerout',\n POINTERENTER: 'pointerenter',\n POINTERLEAVE: 'pointerleave',\n POINTERCANCEL: 'pointercancel',\n};\n\n/***\n * @typedef {'singleclick'|'click'|'dblclick'|'pointerdrag'|'pointermove'} Types\n */\n"],
+ "mappings": ";;;;;AASA,IAAO,8BAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOb,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOb,OAAO,kBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjB,UAAU,kBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOpB,aAAa;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQb,aAAa;AAAA,EAEb,aAAa;AAAA,EACb,WAAW;AAAA,EACX,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,cAAc;AAAA,EACd,eAAe;AACjB;",
+ "names": []
+}
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-RMGZ5HGX.js b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-RMGZ5HGX.js
new file mode 100644
index 0000000..8f15bf9
--- /dev/null
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-RMGZ5HGX.js
@@ -0,0 +1,64 @@
+import {
+ toRadians
+} from "./chunk-V7KTD4MH.js";
+
+// node_modules/ol/rotationconstraint.js
+function disable(rotation) {
+ if (rotation !== void 0) {
+ return 0;
+ }
+ return void 0;
+}
+function none(rotation) {
+ if (rotation !== void 0) {
+ return rotation;
+ }
+ return void 0;
+}
+function createSnapToN(n) {
+ const theta = 2 * Math.PI / n;
+ return (
+ /**
+ * @param {number|undefined} rotation Rotation.
+ * @param {boolean} [isMoving] True if an interaction or animation is in progress.
+ * @return {number|undefined} Rotation.
+ */
+ function(rotation, isMoving) {
+ if (isMoving) {
+ return rotation;
+ }
+ if (rotation !== void 0) {
+ rotation = Math.floor(rotation / theta + 0.5) * theta;
+ return rotation;
+ }
+ return void 0;
+ }
+ );
+}
+function createSnapToZero(tolerance) {
+ const t = tolerance === void 0 ? toRadians(5) : tolerance;
+ return (
+ /**
+ * @param {number|undefined} rotation Rotation.
+ * @param {boolean} [isMoving] True if an interaction or animation is in progress.
+ * @return {number|undefined} Rotation.
+ */
+ function(rotation, isMoving) {
+ if (isMoving || rotation === void 0) {
+ return rotation;
+ }
+ if (Math.abs(rotation) <= t) {
+ return 0;
+ }
+ return rotation;
+ }
+ );
+}
+
+export {
+ disable,
+ none,
+ createSnapToN,
+ createSnapToZero
+};
+//# sourceMappingURL=chunk-RMGZ5HGX.js.map
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-RMGZ5HGX.js.map b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-RMGZ5HGX.js.map
new file mode 100644
index 0000000..445f24d
--- /dev/null
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-RMGZ5HGX.js.map
@@ -0,0 +1,7 @@
+{
+ "version": 3,
+ "sources": ["../../ol/rotationconstraint.js"],
+ "sourcesContent": ["/**\n * @module ol/rotationconstraint\n */\nimport {toRadians} from './math.js';\n\n/**\n * @typedef {function((number|undefined), boolean=): (number|undefined)} Type\n */\n\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\nexport function disable(rotation) {\n if (rotation !== undefined) {\n return 0;\n }\n return undefined;\n}\n\n/**\n * @param {number|undefined} rotation Rotation.\n * @return {number|undefined} Rotation.\n */\nexport function none(rotation) {\n if (rotation !== undefined) {\n return rotation;\n }\n return undefined;\n}\n\n/**\n * @param {number} n N.\n * @return {Type} Rotation constraint.\n */\nexport function createSnapToN(n) {\n const theta = (2 * Math.PI) / n;\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean} [isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, isMoving) {\n if (isMoving) {\n return rotation;\n }\n\n if (rotation !== undefined) {\n rotation = Math.floor(rotation / theta + 0.5) * theta;\n return rotation;\n }\n return undefined;\n }\n );\n}\n\n/**\n * @param {number} [tolerance] Tolerance.\n * @return {Type} Rotation constraint.\n */\nexport function createSnapToZero(tolerance) {\n const t = tolerance === undefined ? toRadians(5) : tolerance;\n return (\n /**\n * @param {number|undefined} rotation Rotation.\n * @param {boolean} [isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Rotation.\n */\n function (rotation, isMoving) {\n if (isMoving || rotation === undefined) {\n return rotation;\n }\n\n if (Math.abs(rotation) <= t) {\n return 0;\n }\n return rotation;\n }\n );\n}\n"],
+ "mappings": ";;;;;AAaO,SAAS,QAAQ,UAAU;AAChC,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAMO,SAAS,KAAK,UAAU;AAC7B,MAAI,aAAa,QAAW;AAC1B,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAMO,SAAS,cAAc,GAAG;AAC/B,QAAM,QAAS,IAAI,KAAK,KAAM;AAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAME,SAAU,UAAU,UAAU;AAC5B,UAAI,UAAU;AACZ,eAAO;AAAA,MACT;AAEA,UAAI,aAAa,QAAW;AAC1B,mBAAW,KAAK,MAAM,WAAW,QAAQ,GAAG,IAAI;AAChD,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA;AAEJ;AAMO,SAAS,iBAAiB,WAAW;AAC1C,QAAM,IAAI,cAAc,SAAY,UAAU,CAAC,IAAI;AACnD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAME,SAAU,UAAU,UAAU;AAC5B,UAAI,YAAY,aAAa,QAAW;AACtC,eAAO;AAAA,MACT;AAEA,UAAI,KAAK,IAAI,QAAQ,KAAK,GAAG;AAC3B,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAAA;AAEJ;",
+ "names": []
+}
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-OOF5364O.js b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VAUZYTLA.js
similarity index 79%
rename from VentusFlowWebGUI/node_modules/.vite/deps/chunk-OOF5364O.js
rename to VentusFlowWebGUI/node_modules/.vite/deps/chunk-VAUZYTLA.js
index e3d246a..749d1c3 100644
--- a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-OOF5364O.js
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VAUZYTLA.js
@@ -2,58 +2,17 @@ import {
MAC,
WEBKIT
} from "./chunk-ZPDML4Q3.js";
+import {
+ MapBrowserEventType_default
+} from "./chunk-POVGKIBQ.js";
import {
assert
} from "./chunk-QFCIXVZ3.js";
import {
- EventType_default,
FALSE,
TRUE
} from "./chunk-33VDV4DG.js";
-// node_modules/ol/MapBrowserEventType.js
-var MapBrowserEventType_default = {
- /**
- * A true single click with no dragging and no double click. Note that this
- * event is delayed by 250 ms to ensure that it is not a double click.
- * @event module:ol/MapBrowserEvent~MapBrowserEvent#singleclick
- * @api
- */
- SINGLECLICK: "singleclick",
- /**
- * A click with no dragging. A double click will fire two of this.
- * @event module:ol/MapBrowserEvent~MapBrowserEvent#click
- * @api
- */
- CLICK: EventType_default.CLICK,
- /**
- * A true double click, with no dragging.
- * @event module:ol/MapBrowserEvent~MapBrowserEvent#dblclick
- * @api
- */
- DBLCLICK: EventType_default.DBLCLICK,
- /**
- * Triggered when a pointer is dragged.
- * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointerdrag
- * @api
- */
- POINTERDRAG: "pointerdrag",
- /**
- * Triggered when a pointer is moved. Note that on touch devices this is
- * triggered when the map is panned, so is not the same as mousemove.
- * @event module:ol/MapBrowserEvent~MapBrowserEvent#pointermove
- * @api
- */
- POINTERMOVE: "pointermove",
- POINTERDOWN: "pointerdown",
- POINTERUP: "pointerup",
- POINTEROVER: "pointerover",
- POINTEROUT: "pointerout",
- POINTERENTER: "pointerenter",
- POINTERLEAVE: "pointerleave",
- POINTERCANCEL: "pointercancel"
-};
-
// node_modules/ol/events/condition.js
function all(var_args) {
const conditions = arguments;
@@ -203,7 +162,6 @@ var primaryAction = function(mapBrowserEvent) {
};
export {
- MapBrowserEventType_default,
all,
altKeyOnly,
altShiftKeysOnly,
@@ -226,4 +184,4 @@ export {
penOnly,
primaryAction
};
-//# sourceMappingURL=chunk-OOF5364O.js.map
+//# sourceMappingURL=chunk-VAUZYTLA.js.map
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VAUZYTLA.js.map b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VAUZYTLA.js.map
new file mode 100644
index 0000000..41f59e5
--- /dev/null
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VAUZYTLA.js.map
@@ -0,0 +1,7 @@
+{
+ "version": 3,
+ "sources": ["../../ol/events/condition.js"],
+ "sourcesContent": ["/**\n * @module ol/events/condition\n */\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport {assert} from '../asserts.js';\nimport {FALSE, TRUE} from '../functions.js';\nimport {MAC, WEBKIT} from '../has.js';\n\n/**\n * A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * `{boolean}`. If the condition is met, true should be returned.\n *\n * @typedef {function(this: ?, import(\"../MapBrowserEvent.js\").default): boolean} Condition\n */\n\n/**\n * Creates a condition function that passes when all provided conditions pass.\n * @param {...Condition} var_args Conditions to check.\n * @return {Condition} Condition function.\n */\nexport function all(var_args) {\n const conditions = arguments;\n /**\n * @param {import(\"../MapBrowserEvent.js\").default} event Event.\n * @return {boolean} All conditions passed.\n */\n return function (event) {\n let pass = true;\n for (let i = 0, ii = conditions.length; i < ii; ++i) {\n pass = pass && conditions[i](event);\n if (!pass) {\n break;\n }\n }\n return pass;\n };\n}\n\n/**\n * Return `true` if only the alt-key is pressed, `false` otherwise (e.g. when\n * additionally the shift-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt key is pressed.\n * @api\n */\nexport const altKeyOnly = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n !originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if only the alt-key and shift-key is pressed, `false` otherwise\n * (e.g. when additionally the platform-modifier-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the alt and shift keys are pressed.\n * @api\n */\nexport const altShiftKeysOnly = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if the map has the focus. This condition requires a map target\n * element with a `tabindex` attribute, e.g. `
`.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} event Map browser event.\n * @return {boolean} The map has the focus.\n * @api\n */\nexport const focus = function (event) {\n const targetElement = event.map.getTargetElement();\n const rootNode = targetElement.getRootNode();\n const activeElement = event.map.getOwnerDocument().activeElement;\n\n return rootNode instanceof ShadowRoot\n ? rootNode.host.contains(activeElement)\n : targetElement.contains(activeElement);\n};\n\n/**\n * Return `true` if the map has the focus or no 'tabindex' attribute set.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} event Map browser event.\n * @return {boolean} The map container has the focus or no 'tabindex' attribute.\n */\nexport const focusWithTabindex = function (event) {\n const targetElement = event.map.getTargetElement();\n const rootNode = targetElement.getRootNode();\n const tabIndexCandidate =\n rootNode instanceof ShadowRoot ? rootNode.host : targetElement;\n\n return tabIndexCandidate.hasAttribute('tabindex') ? focus(event) : true;\n};\n\n/**\n * Return always true.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True.\n * @api\n */\nexport const always = TRUE;\n\n/**\n * Return `true` if the event is a `click` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `click` event.\n * @api\n */\nexport const click = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.CLICK;\n};\n\n/**\n * Return `true` if the event has an \"action\"-producing mouse button.\n *\n * By definition, this includes left-click on windows/linux, and left-click\n * without the ctrl key on Macs.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} The result.\n */\nexport const mouseActionButton = function (mapBrowserEvent) {\n const originalEvent = /** @type {MouseEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return originalEvent.button == 0 && !(WEBKIT && MAC && originalEvent.ctrlKey);\n};\n\n/**\n * Return always false.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} False.\n * @api\n */\nexport const never = FALSE;\n\n/**\n * Return `true` if the browser event is a `pointermove` event, `false`\n * otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the browser event is a `pointermove` event.\n * @api\n */\nexport const pointerMove = function (mapBrowserEvent) {\n return mapBrowserEvent.type == 'pointermove';\n};\n\n/**\n * Return `true` if the event is a map `singleclick` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `singleclick` event.\n * @api\n */\nexport const singleClick = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.SINGLECLICK;\n};\n\n/**\n * Return `true` if the event is a map `dblclick` event, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event is a map `dblclick` event.\n * @api\n */\nexport const doubleClick = function (mapBrowserEvent) {\n return mapBrowserEvent.type == MapBrowserEventType.DBLCLICK;\n};\n\n/**\n * Return `true` if no modifier key (alt-, shift- or platform-modifier-key) is\n * pressed.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if there no modifier keys are pressed.\n * @api\n */\nexport const noModifierKeys = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n !originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n !originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if only the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed, `false` otherwise (e.g. when additionally\n * the shift-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the platform modifier key is pressed.\n * @api\n */\nexport const platformModifierKeyOnly = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n !originalEvent.altKey &&\n (MAC ? originalEvent.metaKey : originalEvent.ctrlKey) &&\n !originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if the platform-modifier-key (the meta-key on Mac,\n * ctrl-key otherwise) is pressed.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the platform modifier key is pressed.\n * @api\n */\nexport const platformModifierKey = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return MAC ? originalEvent.metaKey : originalEvent.ctrlKey;\n};\n\n/**\n * Return `true` if only the shift-key is pressed, `false` otherwise (e.g. when\n * additionally the alt-key is pressed).\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if only the shift key is pressed.\n * @api\n */\nexport const shiftKeyOnly = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n return (\n !originalEvent.altKey &&\n !(originalEvent.metaKey || originalEvent.ctrlKey) &&\n originalEvent.shiftKey\n );\n};\n\n/**\n * Return `true` if the target element is not editable, i.e. not an `input`,\n * `select`, or `textarea` element and no `contenteditable` attribute is\n * set or inherited, `false` otherwise.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True only if the target element is not editable.\n * @api\n */\nexport const targetNotEditable = function (mapBrowserEvent) {\n const originalEvent = /** @type {KeyboardEvent|MouseEvent|TouchEvent} */ (\n mapBrowserEvent.originalEvent\n );\n const tagName = /** @type {Element} */ (originalEvent.target).tagName;\n return (\n tagName !== 'INPUT' &&\n tagName !== 'SELECT' &&\n tagName !== 'TEXTAREA' &&\n // `isContentEditable` is only available on `HTMLElement`, but it may also be a\n // different type like `SVGElement`.\n // @ts-ignore\n !originalEvent.target.isContentEditable\n );\n};\n\n/**\n * Return `true` if the event originates from a mouse device.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a mouse device.\n * @api\n */\nexport const mouseOnly = function (mapBrowserEvent) {\n const pointerEvent = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvent !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvent.pointerType == 'mouse';\n};\n\n/**\n * Return `true` if the event originates from a touchable device.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a touchable device.\n * @api\n */\nexport const touchOnly = function (mapBrowserEvent) {\n const pointerEvt = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvt !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvt.pointerType === 'touch';\n};\n\n/**\n * Return `true` if the event originates from a digital pen.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a digital pen.\n * @api\n */\nexport const penOnly = function (mapBrowserEvent) {\n const pointerEvt = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvt !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n // see https://www.w3.org/TR/pointerevents/#widl-PointerEvent-pointerType\n return pointerEvt.pointerType === 'pen';\n};\n\n/**\n * Return `true` if the event originates from a primary pointer in\n * contact with the surface or if the left mouse button is pressed.\n * See https://www.w3.org/TR/pointerevents/#button-states.\n *\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} True if the event originates from a primary pointer.\n * @api\n */\nexport const primaryAction = function (mapBrowserEvent) {\n const pointerEvent = /** @type {import(\"../MapBrowserEvent\").default} */ (\n mapBrowserEvent\n ).originalEvent;\n assert(\n pointerEvent !== undefined,\n 'mapBrowserEvent must originate from a pointer event',\n );\n return pointerEvent.isPrimary && pointerEvent.button === 0;\n};\n"],
+ "mappings": "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",
+ "names": []
+}
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-6SP66AVH.js b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VWBYIKLE.js
similarity index 98%
rename from VentusFlowWebGUI/node_modules/.vite/deps/chunk-6SP66AVH.js
rename to VentusFlowWebGUI/node_modules/.vite/deps/chunk-VWBYIKLE.js
index 8c338c3..8db2e35 100644
--- a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-6SP66AVH.js
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VWBYIKLE.js
@@ -1,6 +1,3 @@
-import {
- asArray
-} from "./chunk-33EAEVLP.js";
import {
DEFAULT_TILE_SIZE
} from "./chunk-FM44FOIC.js";
@@ -9,13 +6,22 @@ import {
createCanvasContext2D,
getSharedCanvasContext2D
} from "./chunk-WEQYAO4O.js";
+import {
+ createSnapToN,
+ createSnapToZero,
+ disable,
+ none
+} from "./chunk-RMGZ5HGX.js";
+import {
+ fromExtent
+} from "./chunk-47JK3GLV.js";
import {
easeOut,
inAndOut
} from "./chunk-LMC3RO5P.js";
import {
- fromExtent
-} from "./chunk-5CPSJRE2.js";
+ asArray
+} from "./chunk-33EAEVLP.js";
import {
apply,
compose,
@@ -33,25 +39,6 @@ import {
toUserCoordinate,
toUserExtent
} from "./chunk-5ACH5F45.js";
-import {
- assert
-} from "./chunk-QFCIXVZ3.js";
-import {
- Event_default,
- Object_default,
- Observable_default,
- abstract,
- listen,
- unlistenByKey
-} from "./chunk-V2VQBN44.js";
-import {
- EventType_default,
- VOID
-} from "./chunk-33VDV4DG.js";
-import {
- equals,
- linearFindNearest
-} from "./chunk-FQY6EMA7.js";
import {
add,
equals2,
@@ -67,11 +54,29 @@ import {
isEmpty,
rotate
} from "./chunk-WXT7AISE.js";
+import {
+ Event_default,
+ Object_default,
+ Observable_default,
+ abstract,
+ listen,
+ unlistenByKey
+} from "./chunk-V2VQBN44.js";
import {
clamp,
- modulo,
- toRadians
+ modulo
} from "./chunk-V7KTD4MH.js";
+import {
+ assert
+} from "./chunk-QFCIXVZ3.js";
+import {
+ EventType_default,
+ VOID
+} from "./chunk-33VDV4DG.js";
+import {
+ equals,
+ linearFindNearest
+} from "./chunk-FQY6EMA7.js";
import {
__publicField
} from "./chunk-V6TY7KAL.js";
@@ -134,7 +139,7 @@ function createExtent(extent, onlyCenter, smooth) {
}
);
}
-function none(center) {
+function none2(center) {
return center;
}
@@ -276,59 +281,6 @@ function createMinMaxResolution(maxResolution, minResolution, smooth, maxExtent,
);
}
-// node_modules/ol/rotationconstraint.js
-function disable(rotation) {
- if (rotation !== void 0) {
- return 0;
- }
- return void 0;
-}
-function none2(rotation) {
- if (rotation !== void 0) {
- return rotation;
- }
- return void 0;
-}
-function createSnapToN(n) {
- const theta = 2 * Math.PI / n;
- return (
- /**
- * @param {number|undefined} rotation Rotation.
- * @param {boolean} [isMoving] True if an interaction or animation is in progress.
- * @return {number|undefined} Rotation.
- */
- function(rotation, isMoving) {
- if (isMoving) {
- return rotation;
- }
- if (rotation !== void 0) {
- rotation = Math.floor(rotation / theta + 0.5) * theta;
- return rotation;
- }
- return void 0;
- }
- );
-}
-function createSnapToZero(tolerance) {
- const t = tolerance === void 0 ? toRadians(5) : tolerance;
- return (
- /**
- * @param {number|undefined} rotation Rotation.
- * @param {boolean} [isMoving] True if an interaction or animation is in progress.
- * @return {number|undefined} Rotation.
- */
- function(rotation, isMoving) {
- if (isMoving || rotation === void 0) {
- return rotation;
- }
- if (Math.abs(rotation) <= t) {
- return 0;
- }
- return rotation;
- }
- );
-}
-
// node_modules/ol/View.js
var DEFAULT_MIN_ZOOM = 0;
var View = class extends Object_default {
@@ -1700,7 +1652,7 @@ function createCenterConstraint(options) {
extent[2] = Infinity;
return createExtent(extent, false, false);
}
- return none;
+ return none2;
}
function createResolutionConstraint(options) {
let resolutionConstraint;
@@ -1806,12 +1758,12 @@ function createRotationConstraint(options) {
return createSnapToZero();
}
if (constrainRotation === false) {
- return none2;
+ return none;
}
if (typeof constrainRotation === "number") {
return createSnapToN(constrainRotation);
}
- return none2;
+ return none;
}
return disable;
}
@@ -3135,10 +3087,9 @@ export {
Event_default2 as Event_default,
canvasPool,
Layer_default2 as Layer_default,
- disable,
View_default,
Base_default,
inView,
Layer_default3 as Layer_default2
};
-//# sourceMappingURL=chunk-6SP66AVH.js.map
+//# sourceMappingURL=chunk-VWBYIKLE.js.map
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VWBYIKLE.js.map b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VWBYIKLE.js.map
new file mode 100644
index 0000000..4926e61
--- /dev/null
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/chunk-VWBYIKLE.js.map
@@ -0,0 +1,7 @@
+{
+ "version": 3,
+ "sources": ["../../ol/ViewHint.js", "../../ol/ViewProperty.js", "../../ol/centerconstraint.js", "../../ol/resolutionconstraint.js", "../../ol/View.js", "../../ol/render/EventType.js", "../../ol/render/Event.js", "../../ol/render/canvas/ZIndexContext.js", "../../ol/renderer/Layer.js", "../../ol/renderer/canvas/Layer.js", "../../ol/layer/Property.js", "../../ol/layer/Base.js", "../../ol/layer/Layer.js"],
+ "sourcesContent": ["/**\n * @module ol/ViewHint\n */\n\n/**\n * @enum {number}\n */\nexport default {\n ANIMATING: 0,\n INTERACTING: 1,\n};\n", "/**\n * @module ol/ViewProperty\n */\n\n/**\n * @enum {string}\n */\nexport default {\n CENTER: 'center',\n RESOLUTION: 'resolution',\n ROTATION: 'rotation',\n};\n", "/**\n * @module ol/centerconstraint\n */\nimport {clamp} from './math.js';\n\n/**\n * @typedef {function((import(\"./coordinate.js\").Coordinate|undefined), number, import(\"./size.js\").Size, boolean=, Array
=): (import(\"./coordinate.js\").Coordinate|undefined)} Type\n */\n\n/**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {boolean} onlyCenter If true, the constraint will only apply to the view center.\n * @param {boolean} smooth If true, the view will be able to go slightly out of the given extent\n * (only during interaction and animation).\n * @return {Type} The constraint.\n */\nexport function createExtent(extent, onlyCenter, smooth) {\n return (\n /**\n * @param {import(\"./coordinate.js\").Coordinate|undefined} center Center.\n * @param {number|undefined} resolution Resolution.\n * @param {import(\"./size.js\").Size} size Viewport size; unused if `onlyCenter` was specified.\n * @param {boolean} [isMoving] True if an interaction or animation is in progress.\n * @param {Array} [centerShift] Shift between map center and viewport center.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center.\n */\n function (center, resolution, size, isMoving, centerShift) {\n if (!center) {\n return undefined;\n }\n if (!resolution && !onlyCenter) {\n return center;\n }\n const viewWidth = onlyCenter ? 0 : size[0] * resolution;\n const viewHeight = onlyCenter ? 0 : size[1] * resolution;\n const shiftX = centerShift ? centerShift[0] : 0;\n const shiftY = centerShift ? centerShift[1] : 0;\n let minX = extent[0] + viewWidth / 2 + shiftX;\n let maxX = extent[2] - viewWidth / 2 + shiftX;\n let minY = extent[1] + viewHeight / 2 + shiftY;\n let maxY = extent[3] - viewHeight / 2 + shiftY;\n\n // note: when zooming out of bounds, min and max values for x and y may\n // end up inverted (min > max); this has to be accounted for\n if (minX > maxX) {\n minX = (maxX + minX) / 2;\n maxX = minX;\n }\n if (minY > maxY) {\n minY = (maxY + minY) / 2;\n maxY = minY;\n }\n\n let x = clamp(center[0], minX, maxX);\n let y = clamp(center[1], minY, maxY);\n\n // during an interaction, allow some overscroll\n if (isMoving && smooth && resolution) {\n const ratio = 30 * resolution;\n x +=\n -ratio * Math.log(1 + Math.max(0, minX - center[0]) / ratio) +\n ratio * Math.log(1 + Math.max(0, center[0] - maxX) / ratio);\n y +=\n -ratio * Math.log(1 + Math.max(0, minY - center[1]) / ratio) +\n ratio * Math.log(1 + Math.max(0, center[1] - maxY) / ratio);\n }\n\n return [x, y];\n }\n );\n}\n\n/**\n * @param {import(\"./coordinate.js\").Coordinate} [center] Center.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center.\n */\nexport function none(center) {\n return center;\n}\n", "/**\n * @module ol/resolutionconstraint\n */\nimport {linearFindNearest} from './array.js';\nimport {getHeight, getWidth} from './extent.js';\nimport {clamp} from './math.js';\n\n/**\n * @typedef {function((number|undefined), number, import(\"./size.js\").Size, boolean=): (number|undefined)} Type\n */\n\n/**\n * Returns a modified resolution taking into account the viewport size and maximum\n * allowed extent.\n * @param {number} resolution Resolution\n * @param {import(\"./extent.js\").Extent} maxExtent Maximum allowed extent.\n * @param {import(\"./size.js\").Size} viewportSize Viewport size.\n * @param {boolean} showFullExtent Whether to show the full extent.\n * @return {number} Capped resolution.\n */\nfunction getViewportClampedResolution(\n resolution,\n maxExtent,\n viewportSize,\n showFullExtent,\n) {\n const xResolution = getWidth(maxExtent) / viewportSize[0];\n const yResolution = getHeight(maxExtent) / viewportSize[1];\n\n if (showFullExtent) {\n return Math.min(resolution, Math.max(xResolution, yResolution));\n }\n return Math.min(resolution, Math.min(xResolution, yResolution));\n}\n\n/**\n * Returns a modified resolution to be between maxResolution and minResolution while\n * still allowing the value to be slightly out of bounds.\n * Note: the computation is based on the logarithm function (ln):\n * - at 1, ln(x) is 0\n * - above 1, ln(x) keeps increasing but at a much slower pace than x\n * The final result is clamped to prevent getting too far away from bounds.\n * @param {number} resolution Resolution.\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @return {number} Smoothed resolution.\n */\nfunction getSmoothClampedResolution(resolution, maxResolution, minResolution) {\n let result = Math.min(resolution, maxResolution);\n const ratio = 50;\n\n result *=\n Math.log(1 + ratio * Math.max(0, resolution / maxResolution - 1)) / ratio +\n 1;\n if (minResolution) {\n result = Math.max(result, minResolution);\n result /=\n Math.log(1 + ratio * Math.max(0, minResolution / resolution - 1)) /\n ratio +\n 1;\n }\n return clamp(result, minResolution / 2, maxResolution * 2);\n}\n\n/**\n * @param {Array} resolutions Resolutions.\n * @param {boolean} [smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import(\"./extent.js\").Extent} [maxExtent] Maximum allowed extent.\n * @param {boolean} [showFullExtent] If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\nexport function createSnapToResolutions(\n resolutions,\n smooth,\n maxExtent,\n showFullExtent,\n) {\n smooth = smooth !== undefined ? smooth : true;\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import(\"./size.js\").Size} size Viewport size.\n * @param {boolean} [isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, isMoving) {\n if (resolution !== undefined) {\n const maxResolution = resolutions[0];\n const minResolution = resolutions[resolutions.length - 1];\n const cappedMaxRes = maxExtent\n ? getViewportClampedResolution(\n maxResolution,\n maxExtent,\n size,\n showFullExtent,\n )\n : maxResolution;\n\n // during interacting or animating, allow intermediary values\n if (isMoving) {\n if (!smooth) {\n return clamp(resolution, minResolution, cappedMaxRes);\n }\n return getSmoothClampedResolution(\n resolution,\n cappedMaxRes,\n minResolution,\n );\n }\n\n const capped = Math.min(cappedMaxRes, resolution);\n const z = Math.floor(linearFindNearest(resolutions, capped, direction));\n if (resolutions[z] > cappedMaxRes && z < resolutions.length - 1) {\n return resolutions[z + 1];\n }\n return resolutions[z];\n }\n return undefined;\n }\n );\n}\n\n/**\n * @param {number} power Power.\n * @param {number} maxResolution Maximum resolution.\n * @param {number} [minResolution] Minimum resolution.\n * @param {boolean} [smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import(\"./extent.js\").Extent} [maxExtent] Maximum allowed extent.\n * @param {boolean} [showFullExtent] If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\nexport function createSnapToPower(\n power,\n maxResolution,\n minResolution,\n smooth,\n maxExtent,\n showFullExtent,\n) {\n smooth = smooth !== undefined ? smooth : true;\n minResolution = minResolution !== undefined ? minResolution : 0;\n\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import(\"./size.js\").Size} size Viewport size.\n * @param {boolean} [isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, isMoving) {\n if (resolution !== undefined) {\n const cappedMaxRes = maxExtent\n ? getViewportClampedResolution(\n maxResolution,\n maxExtent,\n size,\n showFullExtent,\n )\n : maxResolution;\n\n // during interacting or animating, allow intermediary values\n if (isMoving) {\n if (!smooth) {\n return clamp(resolution, minResolution, cappedMaxRes);\n }\n return getSmoothClampedResolution(\n resolution,\n cappedMaxRes,\n minResolution,\n );\n }\n\n const tolerance = 1e-9;\n const minZoomLevel = Math.ceil(\n Math.log(maxResolution / cappedMaxRes) / Math.log(power) - tolerance,\n );\n const offset = -direction * (0.5 - tolerance) + 0.5;\n const capped = Math.min(cappedMaxRes, resolution);\n const cappedZoomLevel = Math.floor(\n Math.log(maxResolution / capped) / Math.log(power) + offset,\n );\n const zoomLevel = Math.max(minZoomLevel, cappedZoomLevel);\n const newResolution = maxResolution / Math.pow(power, zoomLevel);\n return clamp(newResolution, minResolution, cappedMaxRes);\n }\n return undefined;\n }\n );\n}\n\n/**\n * @param {number} maxResolution Max resolution.\n * @param {number} minResolution Min resolution.\n * @param {boolean} [smooth] If true, the view will be able to slightly exceed resolution limits. Default: true.\n * @param {import(\"./extent.js\").Extent} [maxExtent] Maximum allowed extent.\n * @param {boolean} [showFullExtent] If true, allows us to show the full extent. Default: false.\n * @return {Type} Zoom function.\n */\nexport function createMinMaxResolution(\n maxResolution,\n minResolution,\n smooth,\n maxExtent,\n showFullExtent,\n) {\n smooth = smooth !== undefined ? smooth : true;\n\n return (\n /**\n * @param {number|undefined} resolution Resolution.\n * @param {number} direction Direction.\n * @param {import(\"./size.js\").Size} size Viewport size.\n * @param {boolean} [isMoving] True if an interaction or animation is in progress.\n * @return {number|undefined} Resolution.\n */\n function (resolution, direction, size, isMoving) {\n if (resolution !== undefined) {\n const cappedMaxRes = maxExtent\n ? getViewportClampedResolution(\n maxResolution,\n maxExtent,\n size,\n showFullExtent,\n )\n : maxResolution;\n\n if (!smooth || !isMoving) {\n return clamp(resolution, minResolution, cappedMaxRes);\n }\n return getSmoothClampedResolution(\n resolution,\n cappedMaxRes,\n minResolution,\n );\n }\n return undefined;\n }\n );\n}\n", "/**\n * @module ol/View\n */\nimport BaseObject from './Object.js';\nimport ViewHint from './ViewHint.js';\nimport ViewProperty from './ViewProperty.js';\nimport {linearFindNearest} from './array.js';\nimport {assert} from './asserts.js';\nimport {createExtent, none as centerNone} from './centerconstraint.js';\nimport {\n add as addCoordinate,\n equals,\n equals as coordinatesEqual,\n rotate as rotateCoordinate,\n} from './coordinate.js';\nimport {easeOut, inAndOut} from './easing.js';\nimport {\n getCenter,\n getForViewAndSize,\n getHeight,\n getWidth,\n isEmpty,\n} from './extent.js';\nimport {VOID} from './functions.js';\nimport {fromExtent as polygonFromExtent} from './geom/Polygon.js';\nimport {clamp, modulo} from './math.js';\nimport {\n METERS_PER_UNIT,\n createProjection,\n disableCoordinateWarning,\n fromUserCoordinate,\n fromUserExtent,\n getUserProjection,\n toUserCoordinate,\n toUserExtent,\n} from './proj.js';\nimport {\n createMinMaxResolution,\n createSnapToPower,\n createSnapToResolutions,\n} from './resolutionconstraint.js';\nimport {\n createSnapToN,\n createSnapToZero,\n disable,\n none as rotationNone,\n} from './rotationconstraint.js';\nimport {DEFAULT_TILE_SIZE} from './tilegrid/common.js';\n\n/**\n * An animation configuration\n *\n * @typedef {Object} Animation\n * @property {import(\"./coordinate.js\").Coordinate} [sourceCenter] Source center.\n * @property {import(\"./coordinate.js\").Coordinate} [targetCenter] Target center.\n * @property {number} [sourceResolution] Source resolution.\n * @property {number} [targetResolution] Target resolution.\n * @property {number} [sourceRotation] Source rotation.\n * @property {number} [targetRotation] Target rotation.\n * @property {import(\"./coordinate.js\").Coordinate} [anchor] Anchor.\n * @property {number} start Start.\n * @property {number} duration Duration.\n * @property {boolean} complete Complete.\n * @property {function(number):number} easing Easing.\n * @property {function(boolean):void} callback Callback.\n */\n\n/**\n * @typedef {Object} Constraints\n * @property {import(\"./centerconstraint.js\").Type} center Center.\n * @property {import(\"./resolutionconstraint.js\").Type} resolution Resolution.\n * @property {import(\"./rotationconstraint.js\").Type} rotation Rotation.\n */\n\n/**\n * @typedef {Object} FitOptions\n * @property {import(\"./size.js\").Size} [size] The size in pixels of the box to\n * fit the extent into. Defaults to the size of the map the view is associated with.\n * If no map or multiple maps are connected to the view, provide the desired box size\n * (e.g. `map.getSize()`).\n * @property {!Array} [padding=[0, 0, 0, 0]] Padding (in pixels) to be\n * cleared inside the view. Values in the array are top, right, bottom and left\n * padding.\n * @property {boolean} [nearest=false] If the view `constrainResolution` option is `true`,\n * get the nearest extent instead of the closest that actually fits the view.\n * @property {number} [minResolution=0] Minimum resolution that we zoom to.\n * @property {number} [maxZoom] Maximum zoom level that we zoom to. If\n * `minResolution` is given, this property is ignored.\n * @property {number} [duration] The duration of the animation in milliseconds.\n * By default, there is no animation to the target extent.\n * @property {function(number):number} [easing] The easing function used during\n * the animation (defaults to {@link module:ol/easing.inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation's duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n * @property {function(boolean):void} [callback] Function called when the view is in\n * its final position. The callback will be called with `true` if the animation\n * series completed on its own or `false` if it was cancelled.\n */\n\n/**\n * @typedef {Object} ViewOptions\n * @property {import(\"./coordinate.js\").Coordinate} [center] The initial center for\n * the view. If a user projection is not set, the coordinate system for the center is\n * specified with the `projection` option. Layer sources will not be fetched if this\n * is not set, but the center can be set later with {@link #setCenter}.\n * @property {boolean|number} [constrainRotation=true] Rotation constraint.\n * `false` means no constraint. `true` means no constraint, but snap to zero\n * near zero. A number constrains the rotation to that number of values. For\n * example, `4` will constrain the rotation to 0, 90, 180, and 270 degrees.\n * @property {boolean} [enableRotation=true] Enable rotation.\n * If `false`, a rotation constraint that always sets the rotation to zero is\n * used. The `constrainRotation` option has no effect if `enableRotation` is\n * `false`.\n * @property {import(\"./extent.js\").Extent} [extent] The extent that constrains the\n * view, in other words, nothing outside of this extent can be visible on the map.\n * @property {boolean} [constrainOnlyCenter=false] If true, the extent\n * constraint will only apply to the view center and not the whole extent.\n * @property {boolean} [smoothExtentConstraint=true] If true, the extent\n * constraint will be applied smoothly, i.e. allow the view to go slightly outside\n * of the given `extent`.\n * @property {number} [maxResolution] The maximum resolution used to determine\n * the resolution constraint. It is used together with `minResolution` (or\n * `maxZoom`) and `zoomFactor`. If unspecified it is calculated in such a way\n * that the projection's validity extent fits in a 256x256 px tile. If the\n * projection is Spherical Mercator (the default) then `maxResolution` defaults\n * to `40075016.68557849 / 256 = 156543.03392804097`.\n * @property {number} [minResolution] The minimum resolution used to determine\n * the resolution constraint. It is used together with `maxResolution` (or\n * `minZoom`) and `zoomFactor`. If unspecified it is calculated assuming 29\n * zoom levels (with a factor of 2). If the projection is Spherical Mercator\n * (the default) then `minResolution` defaults to\n * `40075016.68557849 / 256 / Math.pow(2, 28) = 0.0005831682455839253`.\n * @property {number} [maxZoom=28] The maximum zoom level used to determine the\n * resolution constraint. It is used together with `minZoom` (or\n * `maxResolution`) and `zoomFactor`. Note that if `minResolution` is also\n * provided, it is given precedence over `maxZoom`.\n * @property {number} [minZoom=0] The minimum zoom level used to determine the\n * resolution constraint. It is used together with `maxZoom` (or\n * `minResolution`) and `zoomFactor`. Note that if `maxResolution` is also\n * provided, it is given precedence over `minZoom`.\n * @property {boolean} [multiWorld=false] If `false` the view is constrained so\n * only one world is visible, and you cannot pan off the edge. If `true` the map\n * may show multiple worlds at low zoom levels. Only used if the `projection` is\n * global. Note that if `extent` is also provided it is given precedence.\n * @property {boolean} [constrainResolution=false] If true, the view will always\n * animate to the closest zoom level after an interaction; false means\n * intermediary zoom levels are allowed.\n * @property {boolean} [smoothResolutionConstraint=true] If true, the resolution\n * min/max values will be applied smoothly, i. e. allow the view to exceed slightly\n * the given resolution or zoom bounds.\n * @property {boolean} [showFullExtent=false] Allow the view to be zoomed out to\n * show the full configured extent. By default, when a view is configured with an\n * extent, users will not be able to zoom out so the viewport exceeds the extent in\n * either dimension. This means the full extent may not be visible if the viewport\n * is taller or wider than the aspect ratio of the configured extent. If\n * showFullExtent is true, the user will be able to zoom out so that the viewport\n * exceeds the height or width of the configured extent, but not both, allowing the\n * full extent to be shown.\n * @property {import(\"./proj.js\").ProjectionLike} [projection='EPSG:3857'] The\n * projection. The default is Spherical Mercator.\n * @property {number} [resolution] The initial resolution for the view. The\n * units are `projection` units per pixel (e.g. meters per pixel). An\n * alternative to setting this is to set `zoom`. Layer sources will not be\n * fetched if neither this nor `zoom` are defined, but they can be set later\n * with {@link #setZoom} or {@link #setResolution}.\n * @property {Array} [resolutions] Resolutions that determine the\n * zoom levels if specified. The index in the array corresponds to the zoom level,\n * therefore the resolution values have to be in descending order. It also constrains\n * the resolution by the minimum and maximum value. If set the `maxResolution`,\n * `minResolution`, `minZoom`, `maxZoom`, and `zoomFactor` options are ignored.\n * @property {number} [rotation=0] The initial rotation for the view in radians\n * (positive rotation clockwise, 0 means North).\n * @property {number} [zoom] Only used if `resolution` is not defined. Zoom\n * level used to calculate the initial resolution for the view.\n * @property {number} [zoomFactor=2] The zoom factor used to compute the\n * corresponding resolution.\n * @property {!Array} [padding=[0, 0, 0, 0]] Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from\n * that content. The order of the values is top, right, bottom, left.\n */\n\n/**\n * @typedef {Object} AnimationOptions\n * @property {import(\"./coordinate.js\").Coordinate} [center] The center of the view at the end of\n * the animation.\n * @property {number} [zoom] The zoom level of the view at the end of the\n * animation. This takes precedence over `resolution`.\n * @property {number} [resolution] The resolution of the view at the end\n * of the animation. If `zoom` is also provided, this option will be ignored.\n * @property {number} [rotation] The rotation of the view at the end of\n * the animation.\n * @property {import(\"./coordinate.js\").Coordinate} [anchor] Optional anchor to remain fixed\n * during a rotation or resolution animation.\n * @property {number} [duration=1000] The duration of the animation in milliseconds.\n * @property {function(number):number} [easing] The easing function used\n * during the animation (defaults to {@link module:ol/easing.inAndOut}).\n * The function will be called for each frame with a number representing a\n * fraction of the animation's duration. The function should return a number\n * between 0 and 1 representing the progress toward the destination state.\n */\n\n/**\n * @typedef {Object} State\n * @property {import(\"./coordinate.js\").Coordinate} center Center (in view projection coordinates).\n * @property {import(\"./proj/Projection.js\").default} projection Projection.\n * @property {number} resolution Resolution.\n * @property {import(\"./coordinate.js\").Coordinate} [nextCenter] The next center during an animation series.\n * @property {number} [nextResolution] The next resolution during an animation series.\n * @property {number} [nextRotation] The next rotation during an animation series.\n * @property {number} rotation Rotation.\n * @property {number} zoom Zoom.\n */\n\n/**\n * Like {@link import(\"./Map.js\").FrameState}, but just `viewState` and `extent`.\n * @typedef {Object} ViewStateLayerStateExtent\n * @property {State} viewState View state.\n * @property {import(\"./extent.js\").Extent} extent Extent (in user projection coordinates).\n * @property {Array} [layerStatesArray] Layer states.\n */\n\n/**\n * Default min zoom level for the map view.\n * @type {number}\n */\nconst DEFAULT_MIN_ZOOM = 0;\n\n/**\n * @typedef {import(\"./ObjectEventType\").Types|'change:center'|'change:resolution'|'change:rotation'} ViewObjectEventTypes\n */\n\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature &\n * import(\"./Observable\").OnSignature &\n * import(\"./Observable\").CombinedOnSignature} ViewOnSignature\n */\n\n/**\n * @classdesc\n * A View object represents a simple 2D view of the map.\n *\n * This is the object to act upon to change the center, resolution,\n * and rotation of the map.\n *\n * A View has a `projection`. The projection determines the\n * coordinate system of the center, and its units determine the units of the\n * resolution (projection units per pixel). The default projection is\n * Web Mercator (EPSG:3857).\n *\n * ### The view states\n *\n * A View is determined by three states: `center`, `resolution`,\n * and `rotation`. Each state has a corresponding getter and setter, e.g.\n * `getCenter` and `setCenter` for the `center` state.\n *\n * The `zoom` state is actually not saved on the view: all computations\n * internally use the `resolution` state. Still, the `setZoom` and `getZoom`\n * methods are available, as well as `getResolutionForZoom` and\n * `getZoomForResolution` to switch from one system to the other.\n *\n * ### The constraints\n *\n * `setCenter`, `setResolution` and `setRotation` can be used to change the\n * states of the view, but any constraint defined in the constructor will\n * be applied along the way.\n *\n * A View object can have a *resolution constraint*, a *rotation constraint*\n * and a *center constraint*.\n *\n * The *resolution constraint* typically restricts min/max values and\n * snaps to specific resolutions. It is determined by the following\n * options: `resolutions`, `maxResolution`, `maxZoom` and `zoomFactor`.\n * If `resolutions` is set, the other three options are ignored. See\n * documentation for each option for more information. By default, the view\n * only has a min/max restriction and allow intermediary zoom levels when\n * pinch-zooming for example.\n *\n * The *rotation constraint* snaps to specific angles. It is determined\n * by the following options: `enableRotation` and `constrainRotation`.\n * By default rotation is allowed and its value is snapped to zero when approaching the\n * horizontal.\n *\n * The *center constraint* is determined by the `extent` option. By\n * default the view center is not constrained at all.\n *\n * ### Changing the view state\n *\n * It is important to note that `setZoom`, `setResolution`, `setCenter` and\n * `setRotation` are subject to the above mentioned constraints. As such, it\n * may sometimes not be possible to know in advance the resulting state of the\n * View. For example, calling `setResolution(10)` does not guarantee that\n * `getResolution()` will return `10`.\n *\n * A consequence of this is that, when applying a delta on the view state, one\n * should use `adjustCenter`, `adjustRotation`, `adjustZoom` and `adjustResolution`\n * rather than the corresponding setters. This will let view do its internal\n * computations. Besides, the `adjust*` methods also take an `anchor`\n * argument which allows specifying an origin for the transformation.\n *\n * ### Interacting with the view\n *\n * View constraints are usually only applied when the view is *at rest*, meaning that\n * no interaction or animation is ongoing. As such, if the user puts the view in a\n * state that is not equivalent to a constrained one (e.g. rotating the view when\n * the snap angle is 0), an animation will be triggered at the interaction end to\n * put back the view to a stable state;\n *\n * @api\n */\nclass View extends BaseObject {\n /**\n * @param {ViewOptions} [options] View options.\n */\n constructor(options) {\n super();\n\n /***\n * @type {ViewOnSignature}\n */\n this.on;\n\n /***\n * @type {ViewOnSignature}\n */\n this.once;\n\n /***\n * @type {ViewOnSignature}\n */\n this.un;\n\n options = Object.assign({}, options);\n\n /**\n * @private\n * @type {Array}\n */\n this.hints_ = [0, 0];\n\n /**\n * @private\n * @type {Array>}\n */\n this.animations_ = [];\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.updateAnimationKey_;\n\n /**\n * @private\n * @const\n * @type {import(\"./proj/Projection.js\").default}\n */\n this.projection_ = createProjection(options.projection, 'EPSG:3857');\n\n /**\n * @private\n * @type {import(\"./size.js\").Size}\n */\n this.viewportSize_ = [100, 100];\n\n /**\n * @private\n * @type {import(\"./coordinate.js\").Coordinate|undefined}\n */\n this.targetCenter_ = null;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.targetResolution_;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.targetRotation_;\n\n /**\n * @private\n * @type {import(\"./coordinate.js\").Coordinate}\n */\n this.nextCenter_ = null;\n\n /**\n * @private\n * @type {number}\n */\n this.nextResolution_;\n\n /**\n * @private\n * @type {number}\n */\n this.nextRotation_;\n\n /**\n * @private\n * @type {import(\"./coordinate.js\").Coordinate|undefined}\n */\n this.cancelAnchor_ = undefined;\n\n if (options.projection) {\n disableCoordinateWarning();\n }\n if (options.center) {\n options.center = fromUserCoordinate(options.center, this.projection_);\n }\n if (options.extent) {\n options.extent = fromUserExtent(options.extent, this.projection_);\n }\n\n this.applyOptions_(options);\n }\n\n /**\n * Set up the view with the given options.\n * @param {ViewOptions} options View options.\n */\n applyOptions_(options) {\n const properties = Object.assign({}, options);\n for (const key in ViewProperty) {\n delete properties[key];\n }\n this.setProperties(properties, true);\n\n const resolutionConstraintInfo = createResolutionConstraint(options);\n\n /**\n * @private\n * @type {number}\n */\n this.maxResolution_ = resolutionConstraintInfo.maxResolution;\n\n /**\n * @private\n * @type {number}\n */\n this.minResolution_ = resolutionConstraintInfo.minResolution;\n\n /**\n * @private\n * @type {number}\n */\n this.zoomFactor_ = resolutionConstraintInfo.zoomFactor;\n\n /**\n * @private\n * @type {Array|undefined}\n */\n this.resolutions_ = options.resolutions;\n\n /**\n * @type {Array|undefined}\n * @private\n */\n this.padding_ = options.padding;\n\n /**\n * @private\n * @type {number}\n */\n this.minZoom_ = resolutionConstraintInfo.minZoom;\n\n const centerConstraint = createCenterConstraint(options);\n const resolutionConstraint = resolutionConstraintInfo.constraint;\n const rotationConstraint = createRotationConstraint(options);\n\n /**\n * @private\n * @type {Constraints}\n */\n this.constraints_ = {\n center: centerConstraint,\n resolution: resolutionConstraint,\n rotation: rotationConstraint,\n };\n\n this.setRotation(options.rotation !== undefined ? options.rotation : 0);\n this.setCenterInternal(\n options.center !== undefined ? options.center : null,\n );\n if (options.resolution !== undefined) {\n this.setResolution(options.resolution);\n } else if (options.zoom !== undefined) {\n this.setZoom(options.zoom);\n }\n }\n\n /**\n * Padding (in css pixels).\n * If the map viewport is partially covered with other content (overlays) along\n * its edges, this setting allows to shift the center of the viewport away from that\n * content. The order of the values in the array is top, right, bottom, left.\n * The default is no padding, which is equivalent to `[0, 0, 0, 0]`.\n * @type {Array|undefined}\n * @api\n */\n get padding() {\n return this.padding_;\n }\n set padding(padding) {\n let oldPadding = this.padding_;\n this.padding_ = padding;\n const center = this.getCenterInternal();\n if (center) {\n const newPadding = padding || [0, 0, 0, 0];\n oldPadding = oldPadding || [0, 0, 0, 0];\n const resolution = this.getResolution();\n const offsetX =\n (resolution / 2) *\n (newPadding[3] - oldPadding[3] + oldPadding[1] - newPadding[1]);\n const offsetY =\n (resolution / 2) *\n (newPadding[0] - oldPadding[0] + oldPadding[2] - newPadding[2]);\n this.setCenterInternal([center[0] + offsetX, center[1] - offsetY]);\n }\n }\n\n /**\n * Get an updated version of the view options used to construct the view. The\n * current resolution (or zoom), center, and rotation are applied to any stored\n * options. The provided options can be used to apply new min/max zoom or\n * resolution limits.\n * @param {ViewOptions} newOptions New options to be applied.\n * @return {ViewOptions} New options updated with the current view state.\n */\n getUpdatedOptions_(newOptions) {\n const options = this.getProperties();\n\n // preserve resolution (or zoom)\n if (options.resolution !== undefined) {\n options.resolution = this.getResolution();\n } else {\n options.zoom = this.getZoom();\n }\n\n // preserve center\n options.center = this.getCenterInternal();\n\n // preserve rotation\n options.rotation = this.getRotation();\n\n return Object.assign({}, options, newOptions);\n }\n\n /**\n * Animate the view. The view's center, zoom (or resolution), and rotation\n * can be animated for smooth transitions between view states. For example,\n * to animate the view to a new zoom level:\n *\n * view.animate({zoom: view.getZoom() + 1});\n *\n * By default, the animation lasts one second and uses in-and-out easing. You\n * can customize this behavior by including `duration` (in milliseconds) and\n * `easing` options (see {@link module:ol/easing}).\n *\n * To chain together multiple animations, call the method with multiple\n * animation objects. For example, to first zoom and then pan:\n *\n * view.animate({zoom: 10}, {center: [0, 0]});\n *\n * If you provide a function as the last argument to the animate method, it\n * will get called at the end of an animation series. The callback will be\n * called with `true` if the animation series completed on its own or `false`\n * if it was cancelled.\n *\n * Animations are cancelled by user interactions (e.g. dragging the map) or by\n * calling `view.setCenter()`, `view.setResolution()`, or `view.setRotation()`\n * (or another method that calls one of these).\n *\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation\n * options. Multiple animations can be run in series by passing multiple\n * options objects. To run multiple animations in parallel, call the method\n * multiple times. An optional callback can be provided as a final\n * argument. The callback will be called with a boolean indicating whether\n * the animation completed without being cancelled.\n * @api\n */\n animate(var_args) {\n if (this.isDef() && !this.getAnimating()) {\n this.resolveConstraints(0);\n }\n const args = new Array(arguments.length);\n for (let i = 0; i < args.length; ++i) {\n let options = arguments[i];\n if (options.center) {\n options = Object.assign({}, options);\n options.center = fromUserCoordinate(\n options.center,\n this.getProjection(),\n );\n }\n if (options.anchor) {\n options = Object.assign({}, options);\n options.anchor = fromUserCoordinate(\n options.anchor,\n this.getProjection(),\n );\n }\n args[i] = options;\n }\n this.animateInternal.apply(this, args);\n }\n\n /**\n * @param {...(AnimationOptions|function(boolean): void)} var_args Animation options.\n */\n animateInternal(var_args) {\n let animationCount = arguments.length;\n let callback;\n if (\n animationCount > 1 &&\n typeof arguments[animationCount - 1] === 'function'\n ) {\n callback = arguments[animationCount - 1];\n --animationCount;\n }\n\n let i = 0;\n for (; i < animationCount && !this.isDef(); ++i) {\n // if view properties are not yet set, shortcut to the final state\n const state = arguments[i];\n if (state.center) {\n this.setCenterInternal(state.center);\n }\n if (state.zoom !== undefined) {\n this.setZoom(state.zoom);\n } else if (state.resolution) {\n this.setResolution(state.resolution);\n }\n if (state.rotation !== undefined) {\n this.setRotation(state.rotation);\n }\n }\n if (i === animationCount) {\n if (callback) {\n animationCallback(callback, true);\n }\n return;\n }\n\n let start = Date.now();\n let center = this.targetCenter_.slice();\n let resolution = this.targetResolution_;\n let rotation = this.targetRotation_;\n const series = [];\n for (; i < animationCount; ++i) {\n const options = /** @type {AnimationOptions} */ (arguments[i]);\n\n const animation = {\n start: start,\n complete: false,\n anchor: options.anchor,\n duration: options.duration !== undefined ? options.duration : 1000,\n easing: options.easing || inAndOut,\n callback: callback,\n };\n\n if (options.center) {\n animation.sourceCenter = center;\n animation.targetCenter = options.center.slice();\n center = animation.targetCenter;\n }\n\n if (options.zoom !== undefined) {\n animation.sourceResolution = resolution;\n animation.targetResolution = this.getResolutionForZoom(options.zoom);\n resolution = animation.targetResolution;\n } else if (options.resolution) {\n animation.sourceResolution = resolution;\n animation.targetResolution = options.resolution;\n resolution = animation.targetResolution;\n }\n\n if (options.rotation !== undefined) {\n animation.sourceRotation = rotation;\n const delta =\n modulo(options.rotation - rotation + Math.PI, 2 * Math.PI) - Math.PI;\n animation.targetRotation = rotation + delta;\n rotation = animation.targetRotation;\n }\n\n // check if animation is a no-op\n if (isNoopAnimation(animation)) {\n animation.complete = true;\n // we still push it onto the series for callback handling\n } else {\n start += animation.duration;\n }\n series.push(animation);\n }\n this.animations_.push(series);\n this.setHint(ViewHint.ANIMATING, 1);\n this.updateAnimations_();\n }\n\n /**\n * Determine if the view is being animated.\n * @return {boolean} The view is being animated.\n * @api\n */\n getAnimating() {\n return this.hints_[ViewHint.ANIMATING] > 0;\n }\n\n /**\n * Determine if the user is interacting with the view, such as panning or zooming.\n * @return {boolean} The view is being interacted with.\n * @api\n */\n getInteracting() {\n return this.hints_[ViewHint.INTERACTING] > 0;\n }\n\n /**\n * Cancel any ongoing animations.\n * @api\n */\n cancelAnimations() {\n this.setHint(ViewHint.ANIMATING, -this.hints_[ViewHint.ANIMATING]);\n let anchor;\n for (let i = 0, ii = this.animations_.length; i < ii; ++i) {\n const series = this.animations_[i];\n if (series[0].callback) {\n animationCallback(series[0].callback, false);\n }\n if (!anchor) {\n for (let j = 0, jj = series.length; j < jj; ++j) {\n const animation = series[j];\n if (!animation.complete) {\n anchor = animation.anchor;\n break;\n }\n }\n }\n }\n this.animations_.length = 0;\n this.cancelAnchor_ = anchor;\n this.nextCenter_ = null;\n this.nextResolution_ = NaN;\n this.nextRotation_ = NaN;\n }\n\n /**\n * Update all animations.\n */\n updateAnimations_() {\n if (this.updateAnimationKey_ !== undefined) {\n cancelAnimationFrame(this.updateAnimationKey_);\n this.updateAnimationKey_ = undefined;\n }\n if (!this.getAnimating()) {\n return;\n }\n const now = Date.now();\n let more = false;\n for (let i = this.animations_.length - 1; i >= 0; --i) {\n const series = this.animations_[i];\n let seriesComplete = true;\n for (let j = 0, jj = series.length; j < jj; ++j) {\n const animation = series[j];\n if (animation.complete) {\n continue;\n }\n const elapsed = now - animation.start;\n let fraction =\n animation.duration > 0 ? elapsed / animation.duration : 1;\n if (fraction >= 1) {\n animation.complete = true;\n fraction = 1;\n } else {\n seriesComplete = false;\n }\n const progress = animation.easing(fraction);\n if (animation.sourceCenter) {\n const x0 = animation.sourceCenter[0];\n const y0 = animation.sourceCenter[1];\n const x1 = animation.targetCenter[0];\n const y1 = animation.targetCenter[1];\n this.nextCenter_ = animation.targetCenter;\n const x = x0 + progress * (x1 - x0);\n const y = y0 + progress * (y1 - y0);\n this.targetCenter_ = [x, y];\n }\n if (animation.sourceResolution && animation.targetResolution) {\n const resolution =\n progress === 1\n ? animation.targetResolution\n : animation.sourceResolution +\n progress *\n (animation.targetResolution - animation.sourceResolution);\n if (animation.anchor) {\n const size = this.getViewportSize_(this.getRotation());\n const constrainedResolution = this.constraints_.resolution(\n resolution,\n 0,\n size,\n true,\n );\n this.targetCenter_ = this.calculateCenterZoom(\n constrainedResolution,\n animation.anchor,\n );\n }\n this.nextResolution_ = animation.targetResolution;\n this.targetResolution_ = resolution;\n this.applyTargetState_(true);\n }\n if (\n animation.sourceRotation !== undefined &&\n animation.targetRotation !== undefined\n ) {\n const rotation =\n progress === 1\n ? modulo(animation.targetRotation + Math.PI, 2 * Math.PI) -\n Math.PI\n : animation.sourceRotation +\n progress *\n (animation.targetRotation - animation.sourceRotation);\n if (animation.anchor) {\n const constrainedRotation = this.constraints_.rotation(\n rotation,\n true,\n );\n this.targetCenter_ = this.calculateCenterRotate(\n constrainedRotation,\n animation.anchor,\n );\n }\n this.nextRotation_ = animation.targetRotation;\n this.targetRotation_ = rotation;\n }\n this.applyTargetState_(true);\n more = true;\n if (!animation.complete) {\n break;\n }\n }\n if (seriesComplete) {\n this.animations_[i] = null;\n this.setHint(ViewHint.ANIMATING, -1);\n this.nextCenter_ = null;\n this.nextResolution_ = NaN;\n this.nextRotation_ = NaN;\n const callback = series[0].callback;\n if (callback) {\n animationCallback(callback, true);\n }\n }\n }\n // prune completed series\n this.animations_ = this.animations_.filter(Boolean);\n if (more && this.updateAnimationKey_ === undefined) {\n this.updateAnimationKey_ = requestAnimationFrame(\n this.updateAnimations_.bind(this),\n );\n }\n }\n\n /**\n * @param {number} rotation Target rotation.\n * @param {import(\"./coordinate.js\").Coordinate} anchor Rotation anchor.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center for rotation and anchor.\n */\n calculateCenterRotate(rotation, anchor) {\n let center;\n const currentCenter = this.getCenterInternal();\n if (currentCenter !== undefined) {\n center = [currentCenter[0] - anchor[0], currentCenter[1] - anchor[1]];\n rotateCoordinate(center, rotation - this.getRotation());\n addCoordinate(center, anchor);\n }\n return center;\n }\n\n /**\n * @param {number} resolution Target resolution.\n * @param {import(\"./coordinate.js\").Coordinate} anchor Zoom anchor.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Center for resolution and anchor.\n */\n calculateCenterZoom(resolution, anchor) {\n let center;\n const currentCenter = this.getCenterInternal();\n const currentResolution = this.getResolution();\n if (currentCenter !== undefined && currentResolution !== undefined) {\n const x =\n anchor[0] -\n (resolution * (anchor[0] - currentCenter[0])) / currentResolution;\n const y =\n anchor[1] -\n (resolution * (anchor[1] - currentCenter[1])) / currentResolution;\n center = [x, y];\n }\n return center;\n }\n\n /**\n * Returns the current viewport size.\n * @private\n * @param {number} [rotation] Take into account the rotation of the viewport when giving the size\n * @return {import(\"./size.js\").Size} Viewport size or `[100, 100]` when no viewport is found.\n */\n getViewportSize_(rotation) {\n const size = this.viewportSize_;\n if (rotation) {\n const w = size[0];\n const h = size[1];\n return [\n Math.abs(w * Math.cos(rotation)) + Math.abs(h * Math.sin(rotation)),\n Math.abs(w * Math.sin(rotation)) + Math.abs(h * Math.cos(rotation)),\n ];\n }\n return size;\n }\n\n /**\n * Stores the viewport size on the view. The viewport size is not read every time from the DOM\n * to avoid performance hit and layout reflow.\n * This should be done on map size change.\n * Note: the constraints are not resolved during an animation to avoid stopping it\n * @param {import(\"./size.js\").Size} [size] Viewport size; if undefined, [100, 100] is assumed\n */\n setViewportSize(size) {\n this.viewportSize_ = Array.isArray(size) ? size.slice() : [100, 100];\n if (!this.getAnimating()) {\n this.resolveConstraints(0);\n }\n }\n\n /**\n * Get the view center.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} The center of the view.\n * @observable\n * @api\n */\n getCenter() {\n const center = this.getCenterInternal();\n if (!center) {\n return center;\n }\n return toUserCoordinate(center, this.getProjection());\n }\n\n /**\n * Get the view center without transforming to user projection.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} The center of the view.\n */\n getCenterInternal() {\n return /** @type {import(\"./coordinate.js\").Coordinate|undefined} */ (\n this.get(ViewProperty.CENTER)\n );\n }\n\n /**\n * @return {Constraints} Constraints.\n */\n getConstraints() {\n return this.constraints_;\n }\n\n /**\n * @return {boolean} Resolution constraint is set\n */\n getConstrainResolution() {\n return this.get('constrainResolution');\n }\n\n /**\n * @param {Array} [hints] Destination array.\n * @return {Array} Hint.\n */\n getHints(hints) {\n if (hints !== undefined) {\n hints[0] = this.hints_[0];\n hints[1] = this.hints_[1];\n return hints;\n }\n return this.hints_.slice();\n }\n\n /**\n * Calculate the extent for the current view state and the passed box size.\n * @param {import(\"./size.js\").Size} [size] The pixel dimensions of the box\n * into which the calculated extent should fit. Defaults to the size of the\n * map the view is associated with.\n * If no map or multiple maps are connected to the view, provide the desired\n * box size (e.g. `map.getSize()`).\n * @return {import(\"./extent.js\").Extent} Extent.\n * @api\n */\n calculateExtent(size) {\n const extent = this.calculateExtentInternal(size);\n return toUserExtent(extent, this.getProjection());\n }\n\n /**\n * @param {import(\"./size.js\").Size} [size] Box pixel size. If not provided,\n * the map's last known viewport size will be used.\n * @return {import(\"./extent.js\").Extent} Extent.\n */\n calculateExtentInternal(size) {\n size = size || this.getViewportSizeMinusPadding_();\n const center = /** @type {!import(\"./coordinate.js\").Coordinate} */ (\n this.getCenterInternal()\n );\n assert(center, 'The view center is not defined');\n const resolution = /** @type {!number} */ (this.getResolution());\n assert(resolution !== undefined, 'The view resolution is not defined');\n const rotation = /** @type {!number} */ (this.getRotation());\n assert(rotation !== undefined, 'The view rotation is not defined');\n\n return getForViewAndSize(center, resolution, rotation, size);\n }\n\n /**\n * Get the maximum resolution of the view.\n * @return {number} The maximum resolution of the view.\n * @api\n */\n getMaxResolution() {\n return this.maxResolution_;\n }\n\n /**\n * Get the minimum resolution of the view.\n * @return {number} The minimum resolution of the view.\n * @api\n */\n getMinResolution() {\n return this.minResolution_;\n }\n\n /**\n * Get the maximum zoom level for the view.\n * @return {number} The maximum zoom level.\n * @api\n */\n getMaxZoom() {\n return /** @type {number} */ (\n this.getZoomForResolution(this.minResolution_)\n );\n }\n\n /**\n * Set a new maximum zoom level for the view.\n * @param {number} zoom The maximum zoom level.\n * @api\n */\n setMaxZoom(zoom) {\n this.applyOptions_(this.getUpdatedOptions_({maxZoom: zoom}));\n }\n\n /**\n * Get the minimum zoom level for the view.\n * @return {number} The minimum zoom level.\n * @api\n */\n getMinZoom() {\n return /** @type {number} */ (\n this.getZoomForResolution(this.maxResolution_)\n );\n }\n\n /**\n * Set a new minimum zoom level for the view.\n * @param {number} zoom The minimum zoom level.\n * @api\n */\n setMinZoom(zoom) {\n this.applyOptions_(this.getUpdatedOptions_({minZoom: zoom}));\n }\n\n /**\n * Set whether the view should allow intermediary zoom levels.\n * @param {boolean} enabled Whether the resolution is constrained.\n * @api\n */\n setConstrainResolution(enabled) {\n this.applyOptions_(this.getUpdatedOptions_({constrainResolution: enabled}));\n }\n\n /**\n * Get the view projection.\n * @return {import(\"./proj/Projection.js\").default} The projection of the view.\n * @api\n */\n getProjection() {\n return this.projection_;\n }\n\n /**\n * Get the view resolution.\n * @return {number|undefined} The resolution of the view.\n * @observable\n * @api\n */\n getResolution() {\n return /** @type {number|undefined} */ (this.get(ViewProperty.RESOLUTION));\n }\n\n /**\n * Get the resolutions for the view. This returns the array of resolutions\n * passed to the constructor of the View, or undefined if none were given.\n * @return {Array|undefined} The resolutions of the view.\n * @api\n */\n getResolutions() {\n return this.resolutions_;\n }\n\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {import(\"./size.js\").Size} [size] Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n * @api\n */\n getResolutionForExtent(extent, size) {\n return this.getResolutionForExtentInternal(\n fromUserExtent(extent, this.getProjection()),\n size,\n );\n }\n\n /**\n * Get the resolution for a provided extent (in map units) and size (in pixels).\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {import(\"./size.js\").Size} [size] Box pixel size.\n * @return {number} The resolution at which the provided extent will render at\n * the given size.\n */\n getResolutionForExtentInternal(extent, size) {\n size = size || this.getViewportSizeMinusPadding_();\n const xResolution = getWidth(extent) / size[0];\n const yResolution = getHeight(extent) / size[1];\n return Math.max(xResolution, yResolution);\n }\n\n /**\n * Return a function that returns a value between 0 and 1 for a\n * resolution. Exponential scaling is assumed.\n * @param {number} [power] Power.\n * @return {function(number): number} Resolution for value function.\n */\n getResolutionForValueFunction(power) {\n power = power || 2;\n const maxResolution = this.getConstrainedResolution(this.maxResolution_);\n const minResolution = this.minResolution_;\n const max = Math.log(maxResolution / minResolution) / Math.log(power);\n return (\n /**\n * @param {number} value Value.\n * @return {number} Resolution.\n */\n function (value) {\n const resolution = maxResolution / Math.pow(power, value * max);\n return resolution;\n }\n );\n }\n\n /**\n * Get the view rotation.\n * @return {number} The rotation of the view in radians.\n * @observable\n * @api\n */\n getRotation() {\n return /** @type {number} */ (this.get(ViewProperty.ROTATION));\n }\n\n /**\n * Return a function that returns a resolution for a value between\n * 0 and 1. Exponential scaling is assumed.\n * @param {number} [power] Power.\n * @return {function(number): number} Value for resolution function.\n */\n getValueForResolutionFunction(power) {\n const logPower = Math.log(power || 2);\n const maxResolution = this.getConstrainedResolution(this.maxResolution_);\n const minResolution = this.minResolution_;\n const max = Math.log(maxResolution / minResolution) / logPower;\n return (\n /**\n * @param {number} resolution Resolution.\n * @return {number} Value.\n */\n function (resolution) {\n const value = Math.log(maxResolution / resolution) / logPower / max;\n return value;\n }\n );\n }\n\n /**\n * Returns the size of the viewport minus padding.\n * @private\n * @param {number} [rotation] Take into account the rotation of the viewport when giving the size\n * @return {import(\"./size.js\").Size} Viewport size reduced by the padding.\n */\n getViewportSizeMinusPadding_(rotation) {\n let size = this.getViewportSize_(rotation);\n const padding = this.padding_;\n if (padding) {\n size = [\n size[0] - padding[1] - padding[3],\n size[1] - padding[0] - padding[2],\n ];\n }\n return size;\n }\n\n /**\n * @return {State} View state.\n */\n getState() {\n const projection = this.getProjection();\n const resolution = this.getResolution();\n const rotation = this.getRotation();\n let center = /** @type {import(\"./coordinate.js\").Coordinate} */ (\n this.getCenterInternal()\n );\n const padding = this.padding_;\n if (padding) {\n const reducedSize = this.getViewportSizeMinusPadding_();\n center = calculateCenterOn(\n center,\n this.getViewportSize_(),\n [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],\n resolution,\n rotation,\n );\n }\n return {\n center: center.slice(0),\n projection: projection !== undefined ? projection : null,\n resolution: resolution,\n nextCenter: this.nextCenter_,\n nextResolution: this.nextResolution_,\n nextRotation: this.nextRotation_,\n rotation: rotation,\n zoom: this.getZoom(),\n };\n }\n\n /**\n * @return {ViewStateLayerStateExtent} Like `FrameState`, but just `viewState` and `extent`.\n */\n getViewStateAndExtent() {\n return {\n viewState: this.getState(),\n extent: this.calculateExtent(),\n };\n }\n\n /**\n * Get the current zoom level. This method may return non-integer zoom levels\n * if the view does not constrain the resolution, or if an interaction or\n * animation is underway.\n * @return {number|undefined} Zoom.\n * @api\n */\n getZoom() {\n let zoom;\n const resolution = this.getResolution();\n if (resolution !== undefined) {\n zoom = this.getZoomForResolution(resolution);\n }\n return zoom;\n }\n\n /**\n * Get the zoom level for a resolution.\n * @param {number} resolution The resolution.\n * @return {number|undefined} The zoom level for the provided resolution.\n * @api\n */\n getZoomForResolution(resolution) {\n let offset = this.minZoom_ || 0;\n let max, zoomFactor;\n if (this.resolutions_) {\n const nearest = linearFindNearest(this.resolutions_, resolution, 1);\n offset = nearest;\n max = this.resolutions_[nearest];\n if (nearest == this.resolutions_.length - 1) {\n zoomFactor = 2;\n } else {\n zoomFactor = max / this.resolutions_[nearest + 1];\n }\n } else {\n max = this.maxResolution_;\n zoomFactor = this.zoomFactor_;\n }\n return offset + Math.log(max / resolution) / Math.log(zoomFactor);\n }\n\n /**\n * Get the resolution for a zoom level.\n * @param {number} zoom Zoom level.\n * @return {number} The view resolution for the provided zoom level.\n * @api\n */\n getResolutionForZoom(zoom) {\n if (this.resolutions_?.length) {\n if (this.resolutions_.length === 1) {\n return this.resolutions_[0];\n }\n const baseLevel = clamp(\n Math.floor(zoom),\n 0,\n this.resolutions_.length - 2,\n );\n const zoomFactor =\n this.resolutions_[baseLevel] / this.resolutions_[baseLevel + 1];\n return (\n this.resolutions_[baseLevel] /\n Math.pow(zoomFactor, clamp(zoom - baseLevel, 0, 1))\n );\n }\n return (\n this.maxResolution_ / Math.pow(this.zoomFactor_, zoom - this.minZoom_)\n );\n }\n\n /**\n * Fit the given geometry or extent based on the given map size and border.\n * The size is pixel dimensions of the box to fit the extent into.\n * In most cases you will want to use the map size, that is `map.getSize()`.\n * Takes care of the map angle.\n * @param {import(\"./geom/SimpleGeometry.js\").default|import(\"./extent.js\").Extent} geometryOrExtent The geometry or\n * extent to fit the view to.\n * @param {FitOptions} [options] Options.\n * @api\n */\n fit(geometryOrExtent, options) {\n /** @type {import(\"./geom/SimpleGeometry.js\").default} */\n let geometry;\n assert(\n Array.isArray(geometryOrExtent) ||\n typeof (/** @type {?} */ (geometryOrExtent).getSimplifiedGeometry) ===\n 'function',\n 'Invalid extent or geometry provided as `geometry`',\n );\n if (Array.isArray(geometryOrExtent)) {\n assert(\n !isEmpty(geometryOrExtent),\n 'Cannot fit empty extent provided as `geometry`',\n );\n const extent = fromUserExtent(geometryOrExtent, this.getProjection());\n geometry = polygonFromExtent(extent);\n } else if (geometryOrExtent.getType() === 'Circle') {\n const extent = fromUserExtent(\n geometryOrExtent.getExtent(),\n this.getProjection(),\n );\n geometry = polygonFromExtent(extent);\n geometry.rotate(this.getRotation(), getCenter(extent));\n } else {\n const userProjection = getUserProjection();\n if (userProjection) {\n geometry = /** @type {import(\"./geom/SimpleGeometry.js\").default} */ (\n geometryOrExtent\n .clone()\n .transform(userProjection, this.getProjection())\n );\n } else {\n geometry = geometryOrExtent;\n }\n }\n\n this.fitInternal(geometry, options);\n }\n\n /**\n * Calculate rotated extent\n * @param {import(\"./geom/SimpleGeometry.js\").default} geometry The geometry.\n * @return {import(\"./extent\").Extent} The rotated extent for the geometry.\n */\n rotatedExtentForGeometry(geometry) {\n const rotation = this.getRotation();\n const cosAngle = Math.cos(rotation);\n const sinAngle = Math.sin(-rotation);\n const coords = geometry.getFlatCoordinates();\n const stride = geometry.getStride();\n let minRotX = +Infinity;\n let minRotY = +Infinity;\n let maxRotX = -Infinity;\n let maxRotY = -Infinity;\n for (let i = 0, ii = coords.length; i < ii; i += stride) {\n const rotX = coords[i] * cosAngle - coords[i + 1] * sinAngle;\n const rotY = coords[i] * sinAngle + coords[i + 1] * cosAngle;\n minRotX = Math.min(minRotX, rotX);\n minRotY = Math.min(minRotY, rotY);\n maxRotX = Math.max(maxRotX, rotX);\n maxRotY = Math.max(maxRotY, rotY);\n }\n return [minRotX, minRotY, maxRotX, maxRotY];\n }\n\n /**\n * @param {import(\"./geom/SimpleGeometry.js\").default} geometry The geometry.\n * @param {FitOptions} [options] Options.\n */\n fitInternal(geometry, options) {\n options = options || {};\n let size = options.size;\n if (!size) {\n size = this.getViewportSizeMinusPadding_();\n }\n const padding =\n options.padding !== undefined ? options.padding : [0, 0, 0, 0];\n const nearest = options.nearest !== undefined ? options.nearest : false;\n let minResolution;\n if (options.minResolution !== undefined) {\n minResolution = options.minResolution;\n } else if (options.maxZoom !== undefined) {\n minResolution = this.getResolutionForZoom(options.maxZoom);\n } else {\n minResolution = 0;\n }\n\n const rotatedExtent = this.rotatedExtentForGeometry(geometry);\n\n // calculate resolution\n let resolution = this.getResolutionForExtentInternal(rotatedExtent, [\n size[0] - padding[1] - padding[3],\n size[1] - padding[0] - padding[2],\n ]);\n resolution = isNaN(resolution)\n ? minResolution\n : Math.max(resolution, minResolution);\n resolution = this.getConstrainedResolution(resolution, nearest ? 0 : 1);\n\n // calculate center\n const rotation = this.getRotation();\n const sinAngle = Math.sin(rotation);\n const cosAngle = Math.cos(rotation);\n const centerRot = getCenter(rotatedExtent);\n centerRot[0] += ((padding[1] - padding[3]) / 2) * resolution;\n centerRot[1] += ((padding[0] - padding[2]) / 2) * resolution;\n const centerX = centerRot[0] * cosAngle - centerRot[1] * sinAngle;\n const centerY = centerRot[1] * cosAngle + centerRot[0] * sinAngle;\n const center = this.getConstrainedCenter([centerX, centerY], resolution);\n const callback = options.callback ? options.callback : VOID;\n\n if (options.duration !== undefined) {\n this.animateInternal(\n {\n resolution: resolution,\n center: center,\n duration: options.duration,\n easing: options.easing,\n },\n callback,\n );\n } else {\n this.targetResolution_ = resolution;\n this.targetCenter_ = center;\n this.applyTargetState_(false, true);\n animationCallback(callback, true);\n }\n }\n\n /**\n * Center on coordinate and view position.\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"./size.js\").Size} size Box pixel size.\n * @param {import(\"./pixel.js\").Pixel} position Position on the view to center on.\n * @api\n */\n centerOn(coordinate, size, position) {\n this.centerOnInternal(\n fromUserCoordinate(coordinate, this.getProjection()),\n size,\n position,\n );\n }\n\n /**\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"./size.js\").Size} size Box pixel size.\n * @param {import(\"./pixel.js\").Pixel} position Position on the view to center on.\n */\n centerOnInternal(coordinate, size, position) {\n this.setCenterInternal(\n calculateCenterOn(\n coordinate,\n size,\n position,\n this.getResolution(),\n this.getRotation(),\n ),\n );\n }\n\n /**\n * Calculates the shift between map and viewport center.\n * @param {import(\"./coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {import(\"./size.js\").Size} size Size.\n * @return {Array|undefined} Center shift.\n */\n calculateCenterShift(center, resolution, rotation, size) {\n let centerShift;\n const padding = this.padding_;\n if (padding && center) {\n const reducedSize = this.getViewportSizeMinusPadding_(-rotation);\n const shiftedCenter = calculateCenterOn(\n center,\n size,\n [reducedSize[0] / 2 + padding[3], reducedSize[1] / 2 + padding[0]],\n resolution,\n rotation,\n );\n centerShift = [\n center[0] - shiftedCenter[0],\n center[1] - shiftedCenter[1],\n ];\n }\n return centerShift;\n }\n\n /**\n * @return {boolean} Is defined.\n */\n isDef() {\n return !!this.getCenterInternal() && this.getResolution() !== undefined;\n }\n\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import(\"./coordinate.js\").Coordinate} deltaCoordinates Relative value to add.\n * @api\n */\n adjustCenter(deltaCoordinates) {\n const center = toUserCoordinate(this.targetCenter_, this.getProjection());\n this.setCenter([\n center[0] + deltaCoordinates[0],\n center[1] + deltaCoordinates[1],\n ]);\n }\n\n /**\n * Adds relative coordinates to the center of the view. Any extent constraint will apply.\n * @param {import(\"./coordinate.js\").Coordinate} deltaCoordinates Relative value to add.\n */\n adjustCenterInternal(deltaCoordinates) {\n const center = this.targetCenter_;\n this.setCenterInternal([\n center[0] + deltaCoordinates[0],\n center[1] + deltaCoordinates[1],\n ]);\n }\n\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The origin of the transformation.\n * @api\n */\n adjustResolution(ratio, anchor) {\n anchor = anchor && fromUserCoordinate(anchor, this.getProjection());\n this.adjustResolutionInternal(ratio, anchor);\n }\n\n /**\n * Multiply the view resolution by a ratio, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} ratio The ratio to apply on the view resolution.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The origin of the transformation.\n */\n adjustResolutionInternal(ratio, anchor) {\n const isMoving = this.getAnimating() || this.getInteracting();\n const size = this.getViewportSize_(this.getRotation());\n const newResolution = this.constraints_.resolution(\n this.targetResolution_ * ratio,\n 0,\n size,\n isMoving,\n );\n\n if (anchor) {\n this.targetCenter_ = this.calculateCenterZoom(newResolution, anchor);\n }\n\n this.targetResolution_ *= ratio;\n this.applyTargetState_();\n }\n\n /**\n * Adds a value to the view zoom level, optionally using an anchor. Any resolution\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom level.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The origin of the transformation.\n * @api\n */\n adjustZoom(delta, anchor) {\n this.adjustResolution(Math.pow(this.zoomFactor_, -delta), anchor);\n }\n\n /**\n * Adds a value to the view rotation, optionally using an anchor. Any rotation\n * constraint will apply.\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The rotation center.\n * @api\n */\n adjustRotation(delta, anchor) {\n if (anchor) {\n anchor = fromUserCoordinate(anchor, this.getProjection());\n }\n this.adjustRotationInternal(delta, anchor);\n }\n\n /**\n * @param {number} delta Relative value to add to the zoom rotation, in radians.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The rotation center.\n */\n adjustRotationInternal(delta, anchor) {\n const isMoving = this.getAnimating() || this.getInteracting();\n const newRotation = this.constraints_.rotation(\n this.targetRotation_ + delta,\n isMoving,\n );\n if (anchor) {\n this.targetCenter_ = this.calculateCenterRotate(newRotation, anchor);\n }\n this.targetRotation_ += delta;\n this.applyTargetState_();\n }\n\n /**\n * Set the center of the current view. Any extent constraint will apply.\n * @param {import(\"./coordinate.js\").Coordinate|undefined} center The center of the view.\n * @observable\n * @api\n */\n setCenter(center) {\n this.setCenterInternal(\n center ? fromUserCoordinate(center, this.getProjection()) : center,\n );\n }\n\n /**\n * Set the center using the view projection (not the user projection).\n * @param {import(\"./coordinate.js\").Coordinate|undefined} center The center of the view.\n */\n setCenterInternal(center) {\n this.targetCenter_ = center;\n this.applyTargetState_();\n }\n\n /**\n * @param {import(\"./ViewHint.js\").default} hint Hint.\n * @param {number} delta Delta.\n * @return {number} New value.\n */\n setHint(hint, delta) {\n this.hints_[hint] += delta;\n this.changed();\n return this.hints_[hint];\n }\n\n /**\n * Set the resolution for this view. Any resolution constraint will apply.\n * @param {number|undefined} resolution The resolution of the view.\n * @observable\n * @api\n */\n setResolution(resolution) {\n this.targetResolution_ = resolution;\n this.applyTargetState_();\n }\n\n /**\n * Set the rotation for this view. Any rotation constraint will apply.\n * @param {number} rotation The rotation of the view in radians.\n * @observable\n * @api\n */\n setRotation(rotation) {\n this.targetRotation_ = rotation;\n this.applyTargetState_();\n }\n\n /**\n * Zoom to a specific zoom level. Any resolution constrain will apply.\n * @param {number} zoom Zoom level.\n * @api\n */\n setZoom(zoom) {\n this.setResolution(this.getResolutionForZoom(zoom));\n }\n\n /**\n * Recompute rotation/resolution/center based on target values.\n * Note: we have to compute rotation first, then resolution and center considering that\n * parameters can influence one another in case a view extent constraint is present.\n * @param {boolean} [doNotCancelAnims] Do not cancel animations.\n * @param {boolean} [forceMoving] Apply constraints as if the view is moving.\n * @private\n */\n applyTargetState_(doNotCancelAnims, forceMoving) {\n const isMoving =\n this.getAnimating() || this.getInteracting() || forceMoving;\n\n // compute rotation\n const newRotation = this.constraints_.rotation(\n this.targetRotation_,\n isMoving,\n );\n const size = this.getViewportSize_(newRotation);\n const newResolution = this.constraints_.resolution(\n this.targetResolution_,\n 0,\n size,\n isMoving,\n );\n const newCenter = this.constraints_.center(\n this.targetCenter_,\n newResolution,\n size,\n isMoving,\n this.calculateCenterShift(\n this.targetCenter_,\n newResolution,\n newRotation,\n size,\n ),\n );\n\n if (this.get(ViewProperty.ROTATION) !== newRotation) {\n this.set(ViewProperty.ROTATION, newRotation);\n }\n if (this.get(ViewProperty.RESOLUTION) !== newResolution) {\n this.set(ViewProperty.RESOLUTION, newResolution);\n this.set('zoom', this.getZoom(), true);\n }\n if (\n !newCenter ||\n !this.get(ViewProperty.CENTER) ||\n !equals(this.get(ViewProperty.CENTER), newCenter)\n ) {\n this.set(ViewProperty.CENTER, newCenter);\n }\n\n if (this.getAnimating() && !doNotCancelAnims) {\n this.cancelAnimations();\n }\n this.cancelAnchor_ = undefined;\n }\n\n /**\n * If any constraints need to be applied, an animation will be triggered.\n * This is typically done on interaction end.\n * Note: calling this with a duration of 0 will apply the constrained values straight away,\n * without animation.\n * @param {number} [duration] The animation duration in ms.\n * @param {number} [resolutionDirection] Which direction to zoom.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The origin of the transformation.\n */\n resolveConstraints(duration, resolutionDirection, anchor) {\n duration = duration !== undefined ? duration : 200;\n const direction = resolutionDirection || 0;\n\n const newRotation = this.constraints_.rotation(this.targetRotation_);\n const size = this.getViewportSize_(newRotation);\n const newResolution = this.constraints_.resolution(\n this.targetResolution_,\n direction,\n size,\n );\n const newCenter = this.constraints_.center(\n this.targetCenter_,\n newResolution,\n size,\n false,\n this.calculateCenterShift(\n this.targetCenter_,\n newResolution,\n newRotation,\n size,\n ),\n );\n\n if (duration === 0 && !this.cancelAnchor_) {\n this.targetResolution_ = newResolution;\n this.targetRotation_ = newRotation;\n this.targetCenter_ = newCenter;\n this.applyTargetState_();\n return;\n }\n\n anchor = anchor || (duration === 0 ? this.cancelAnchor_ : undefined);\n this.cancelAnchor_ = undefined;\n\n if (\n this.getResolution() !== newResolution ||\n this.getRotation() !== newRotation ||\n !this.getCenterInternal() ||\n !equals(this.getCenterInternal(), newCenter)\n ) {\n if (this.getAnimating()) {\n this.cancelAnimations();\n }\n\n this.animateInternal({\n rotation: newRotation,\n center: newCenter,\n resolution: newResolution,\n duration: duration,\n easing: easeOut,\n anchor: anchor,\n });\n }\n }\n\n /**\n * Notify the View that an interaction has started.\n * The view state will be resolved to a stable one if needed\n * (depending on its constraints).\n * @api\n */\n beginInteraction() {\n this.resolveConstraints(0);\n\n this.setHint(ViewHint.INTERACTING, 1);\n }\n\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number} [duration] Animation duration in ms.\n * @param {number} [resolutionDirection] Which direction to zoom.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The origin of the transformation.\n * @api\n */\n endInteraction(duration, resolutionDirection, anchor) {\n anchor = anchor && fromUserCoordinate(anchor, this.getProjection());\n this.endInteractionInternal(duration, resolutionDirection, anchor);\n }\n\n /**\n * Notify the View that an interaction has ended. The view state will be resolved\n * to a stable one if needed (depending on its constraints).\n * @param {number} [duration] Animation duration in ms.\n * @param {number} [resolutionDirection] Which direction to zoom.\n * @param {import(\"./coordinate.js\").Coordinate} [anchor] The origin of the transformation.\n */\n endInteractionInternal(duration, resolutionDirection, anchor) {\n if (!this.getInteracting()) {\n return;\n }\n this.setHint(ViewHint.INTERACTING, -1);\n this.resolveConstraints(duration, resolutionDirection, anchor);\n }\n\n /**\n * Get a valid position for the view center according to the current constraints.\n * @param {import(\"./coordinate.js\").Coordinate|undefined} targetCenter Target center position.\n * @param {number} [targetResolution] Target resolution. If not supplied, the current one will be used.\n * This is useful to guess a valid center position at a different zoom level.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} Valid center position.\n */\n getConstrainedCenter(targetCenter, targetResolution) {\n const size = this.getViewportSize_(this.getRotation());\n return this.constraints_.center(\n targetCenter,\n targetResolution || this.getResolution(),\n size,\n );\n }\n\n /**\n * Get a valid zoom level according to the current view constraints.\n * @param {number|undefined} targetZoom Target zoom.\n * @param {number} [direction] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid zoom level.\n */\n getConstrainedZoom(targetZoom, direction) {\n const targetRes = this.getResolutionForZoom(targetZoom);\n return this.getZoomForResolution(\n this.getConstrainedResolution(targetRes, direction),\n );\n }\n\n /**\n * Get a valid resolution according to the current view constraints.\n * @param {number|undefined} targetResolution Target resolution.\n * @param {number} [direction] Indicate which resolution should be used\n * by a renderer if the view resolution does not match any resolution of the tile source.\n * If 0, the nearest resolution will be used. If 1, the nearest lower resolution\n * will be used. If -1, the nearest higher resolution will be used.\n * @return {number|undefined} Valid resolution.\n */\n getConstrainedResolution(targetResolution, direction) {\n direction = direction || 0;\n const size = this.getViewportSize_(this.getRotation());\n\n return this.constraints_.resolution(targetResolution, direction, size);\n }\n}\n\n/**\n * @param {Function} callback Callback.\n * @param {*} returnValue Return value.\n */\nfunction animationCallback(callback, returnValue) {\n setTimeout(function () {\n callback(returnValue);\n }, 0);\n}\n\n/**\n * @param {ViewOptions} options View options.\n * @return {import(\"./centerconstraint.js\").Type} The constraint.\n */\nexport function createCenterConstraint(options) {\n if (options.extent !== undefined) {\n const smooth =\n options.smoothExtentConstraint !== undefined\n ? options.smoothExtentConstraint\n : true;\n return createExtent(options.extent, options.constrainOnlyCenter, smooth);\n }\n\n const projection = createProjection(options.projection, 'EPSG:3857');\n if (options.multiWorld !== true && projection.isGlobal()) {\n const extent = projection.getExtent().slice();\n extent[0] = -Infinity;\n extent[2] = Infinity;\n return createExtent(extent, false, false);\n }\n\n return centerNone;\n}\n\n/**\n * @param {ViewOptions} options View options.\n * @return {{constraint: import(\"./resolutionconstraint.js\").Type, maxResolution: number,\n * minResolution: number, minZoom: number, zoomFactor: number}} The constraint.\n */\nexport function createResolutionConstraint(options) {\n let resolutionConstraint;\n let maxResolution;\n let minResolution;\n\n // TODO: move these to be ol constants\n // see https://github.com/openlayers/openlayers/issues/2076\n const defaultMaxZoom = 28;\n const defaultZoomFactor = 2;\n\n let minZoom =\n options.minZoom !== undefined ? options.minZoom : DEFAULT_MIN_ZOOM;\n\n let maxZoom =\n options.maxZoom !== undefined ? options.maxZoom : defaultMaxZoom;\n\n const zoomFactor =\n options.zoomFactor !== undefined ? options.zoomFactor : defaultZoomFactor;\n\n const multiWorld =\n options.multiWorld !== undefined ? options.multiWorld : false;\n\n const smooth =\n options.smoothResolutionConstraint !== undefined\n ? options.smoothResolutionConstraint\n : true;\n\n const showFullExtent =\n options.showFullExtent !== undefined ? options.showFullExtent : false;\n\n const projection = createProjection(options.projection, 'EPSG:3857');\n const projExtent = projection.getExtent();\n let constrainOnlyCenter = options.constrainOnlyCenter;\n let extent = options.extent;\n if (!multiWorld && !extent && projection.isGlobal()) {\n constrainOnlyCenter = false;\n extent = projExtent;\n }\n\n if (options.resolutions !== undefined) {\n const resolutions = options.resolutions;\n maxResolution = resolutions[minZoom];\n minResolution =\n resolutions[maxZoom] !== undefined\n ? resolutions[maxZoom]\n : resolutions[resolutions.length - 1];\n\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToResolutions(\n resolutions,\n smooth,\n !constrainOnlyCenter && extent,\n showFullExtent,\n );\n } else {\n resolutionConstraint = createMinMaxResolution(\n maxResolution,\n minResolution,\n smooth,\n !constrainOnlyCenter && extent,\n showFullExtent,\n );\n }\n } else {\n // calculate the default min and max resolution\n const size = !projExtent\n ? // use an extent that can fit the whole world if need be\n (360 * METERS_PER_UNIT.degrees) / projection.getMetersPerUnit()\n : Math.max(getWidth(projExtent), getHeight(projExtent));\n\n const defaultMaxResolution =\n size / DEFAULT_TILE_SIZE / Math.pow(defaultZoomFactor, DEFAULT_MIN_ZOOM);\n\n const defaultMinResolution =\n defaultMaxResolution /\n Math.pow(defaultZoomFactor, defaultMaxZoom - DEFAULT_MIN_ZOOM);\n\n // user provided maxResolution takes precedence\n maxResolution = options.maxResolution;\n if (maxResolution !== undefined) {\n minZoom = 0;\n } else {\n maxResolution = defaultMaxResolution / Math.pow(zoomFactor, minZoom);\n }\n\n // user provided minResolution takes precedence\n minResolution = options.minResolution;\n if (minResolution === undefined) {\n if (options.maxZoom !== undefined) {\n if (options.maxResolution !== undefined) {\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom);\n } else {\n minResolution = defaultMaxResolution / Math.pow(zoomFactor, maxZoom);\n }\n } else {\n minResolution = defaultMinResolution;\n }\n }\n\n // given discrete zoom levels, minResolution may be different than provided\n maxZoom =\n minZoom +\n Math.floor(\n Math.log(maxResolution / minResolution) / Math.log(zoomFactor),\n );\n minResolution = maxResolution / Math.pow(zoomFactor, maxZoom - minZoom);\n\n if (options.constrainResolution) {\n resolutionConstraint = createSnapToPower(\n zoomFactor,\n maxResolution,\n minResolution,\n smooth,\n !constrainOnlyCenter && extent,\n showFullExtent,\n );\n } else {\n resolutionConstraint = createMinMaxResolution(\n maxResolution,\n minResolution,\n smooth,\n !constrainOnlyCenter && extent,\n showFullExtent,\n );\n }\n }\n return {\n constraint: resolutionConstraint,\n maxResolution: maxResolution,\n minResolution: minResolution,\n minZoom: minZoom,\n zoomFactor: zoomFactor,\n };\n}\n\n/**\n * @param {ViewOptions} options View options.\n * @return {import(\"./rotationconstraint.js\").Type} Rotation constraint.\n */\nexport function createRotationConstraint(options) {\n const enableRotation =\n options.enableRotation !== undefined ? options.enableRotation : true;\n if (enableRotation) {\n const constrainRotation = options.constrainRotation;\n if (constrainRotation === undefined || constrainRotation === true) {\n return createSnapToZero();\n }\n if (constrainRotation === false) {\n return rotationNone;\n }\n if (typeof constrainRotation === 'number') {\n return createSnapToN(constrainRotation);\n }\n return rotationNone;\n }\n return disable;\n}\n\n/**\n * Determine if an animation involves no view change.\n * @param {Animation} animation The animation.\n * @return {boolean} The animation involves no view change.\n */\nexport function isNoopAnimation(animation) {\n if (animation.sourceCenter && animation.targetCenter) {\n if (!coordinatesEqual(animation.sourceCenter, animation.targetCenter)) {\n return false;\n }\n }\n if (animation.sourceResolution !== animation.targetResolution) {\n return false;\n }\n if (animation.sourceRotation !== animation.targetRotation) {\n return false;\n }\n return true;\n}\n\n/**\n * @param {import(\"./coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"./size.js\").Size} size Box pixel size.\n * @param {import(\"./pixel.js\").Pixel} position Position on the view to center on.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @return {import(\"./coordinate.js\").Coordinate} Shifted center.\n */\nfunction calculateCenterOn(coordinate, size, position, resolution, rotation) {\n // calculate rotated position\n const cosAngle = Math.cos(-rotation);\n let sinAngle = Math.sin(-rotation);\n let rotX = coordinate[0] * cosAngle - coordinate[1] * sinAngle;\n let rotY = coordinate[1] * cosAngle + coordinate[0] * sinAngle;\n rotX += (size[0] / 2 - position[0]) * resolution;\n rotY += (position[1] - size[1] / 2) * resolution;\n\n // go back to original angle\n sinAngle = -sinAngle; // go back to original rotation\n const centerX = rotX * cosAngle - rotY * sinAngle;\n const centerY = rotY * cosAngle + rotX * sinAngle;\n\n return [centerX, centerY];\n}\n\nexport default View;\n", "/**\n * @module ol/render/EventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered before a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#prerender\n * @api\n */\n PRERENDER: 'prerender',\n\n /**\n * Triggered after a layer is rendered.\n * @event module:ol/render/Event~RenderEvent#postrender\n * @api\n */\n POSTRENDER: 'postrender',\n\n /**\n * Triggered before layers are composed. When dispatched by the map, the event object will not have\n * a `context` set. When dispatched by a layer, the event object will have a `context` set. Only\n * WebGL layers currently dispatch this event.\n * @event module:ol/render/Event~RenderEvent#precompose\n * @api\n */\n PRECOMPOSE: 'precompose',\n\n /**\n * Triggered after layers are composed. When dispatched by the map, the event object will not have\n * a `context` set. When dispatched by a layer, the event object will have a `context` set. Only\n * WebGL layers currently dispatch this event.\n * @event module:ol/render/Event~RenderEvent#postcompose\n * @api\n */\n POSTCOMPOSE: 'postcompose',\n\n /**\n * Triggered when rendering is complete, i.e. all sources and tiles have\n * finished loading for the current viewport, and all tiles are faded in.\n * The event object will not have a `context` set.\n * @event module:ol/render/Event~RenderEvent#rendercomplete\n * @api\n */\n RENDERCOMPLETE: 'rendercomplete',\n};\n\n/**\n * @typedef {'postrender'|'precompose'|'postcompose'|'rendercomplete'} MapRenderEventTypes\n */\n\n/**\n * @typedef {'postrender'|'prerender'} LayerRenderEventTypes\n */\n", "/**\n * @module ol/render/Event\n */\n\nimport Event from '../events/Event.js';\n\nclass RenderEvent extends Event {\n /**\n * @param {import(\"./EventType.js\").default} type Type.\n * @param {import(\"../transform.js\").Transform} [inversePixelTransform] Transform for\n * CSS pixels to rendered pixels.\n * @param {import(\"../Map.js\").FrameState} [frameState] Frame state.\n * @param {?(CanvasRenderingContext2D|WebGLRenderingContext)} [context] Context.\n */\n constructor(type, inversePixelTransform, frameState, context) {\n super(type);\n\n /**\n * Transform from CSS pixels (relative to the top-left corner of the map viewport)\n * to rendered pixels on this event's `context`. Only available when a Canvas renderer is used, null otherwise.\n * @type {import(\"../transform.js\").Transform|undefined}\n * @api\n */\n this.inversePixelTransform = inversePixelTransform;\n\n /**\n * An object representing the current render frame state.\n * @type {import(\"../Map.js\").FrameState|undefined}\n * @api\n */\n this.frameState = frameState;\n\n /**\n * Canvas context. Not available when the event is dispatched by the map. For Canvas 2D layers,\n * the context will be the 2D rendering context. For WebGL layers, the context will be the WebGL\n * context.\n * @type {CanvasRenderingContext2D|WebGLRenderingContext|undefined}\n * @api\n */\n this.context = context;\n }\n}\n\nexport default RenderEvent;\n", "/**\n * @module ol/render/canvas/ZIndexContext\n */\n\nimport {getSharedCanvasContext2D} from '../../dom.js';\n\n/** @typedef {CanvasRenderingContext2D & {globalAlpha: any}} ZIndexContextProxy */\n\n/**\n * @extends {CanvasRenderingContext2D}\n */\nclass ZIndexContext {\n constructor() {\n /**\n * @private\n * @type {Array>}\n */\n this.instructions_ = [];\n /**\n * @type {number}\n */\n this.zIndex = 0;\n /**\n * @private\n * @type {number}\n */\n this.offset_ = 0;\n\n /**\n * @private\n * @type {ZIndexContextProxy}\n */\n this.context_ = /** @type {ZIndexContextProxy} */ (\n new Proxy(getSharedCanvasContext2D(), {\n get: (target, property) => {\n if (\n typeof (/** @type {*} */ (getSharedCanvasContext2D())[property]) !==\n 'function'\n ) {\n // we only accept calling functions on the proxy, not accessing properties\n return undefined;\n }\n if (!this.instructions_[this.zIndex + this.offset_]) {\n this.instructions_[this.zIndex + this.offset_] = [];\n }\n this.instructions_[this.zIndex + this.offset_].push(property);\n return this.pushMethodArgs_;\n },\n set: (target, property, value) => {\n if (!this.instructions_[this.zIndex + this.offset_]) {\n this.instructions_[this.zIndex + this.offset_] = [];\n }\n this.instructions_[this.zIndex + this.offset_].push(property, value);\n return true;\n },\n })\n );\n }\n\n /**\n * @private\n * @param {...*} args Args.\n * @return {ZIndexContext} This.\n */\n pushMethodArgs_ = (...args) => {\n this.instructions_[this.zIndex + this.offset_].push(args);\n return this;\n };\n\n /**\n * Push a function that renders to the context directly.\n * @param {function(CanvasRenderingContext2D): void} render Function.\n */\n pushFunction(render) {\n this.instructions_[this.zIndex + this.offset_].push(render);\n }\n\n /**\n * Get a proxy for CanvasRenderingContext2D which does not support getting state\n * (e.g. `context.globalAlpha`, which will return `undefined`). To set state, if it relies on a\n * previous state (e.g. `context.globalAlpha = context.globalAlpha / 2`), set a function,\n * e.g. `context.globalAlpha = (context) => context.globalAlpha / 2`.\n * @return {ZIndexContextProxy} Context.\n */\n getContext() {\n return this.context_;\n }\n\n /**\n * @param {CanvasRenderingContext2D} context Context.\n */\n draw(context) {\n this.instructions_.forEach((instructionsAtIndex) => {\n for (let i = 0, ii = instructionsAtIndex.length; i < ii; ++i) {\n const property = instructionsAtIndex[i];\n if (typeof property === 'function') {\n property(context);\n continue;\n }\n const instructionAtIndex = instructionsAtIndex[++i];\n if (typeof (/** @type {*} */ (context)[property]) === 'function') {\n /** @type {*} */ (context)[property](...instructionAtIndex);\n } else {\n if (typeof instructionAtIndex === 'function') {\n /** @type {*} */ (context)[property] = instructionAtIndex(context);\n continue;\n }\n /** @type {*} */ (context)[property] = instructionAtIndex;\n }\n }\n });\n }\n\n clear() {\n this.instructions_.length = 0;\n this.zIndex = 0;\n this.offset_ = 0;\n }\n\n /**\n * Offsets the zIndex by the highest current zIndex. Useful for rendering multiple worlds or tiles, to\n * avoid conflicting context.clip() or context.save()/restore() calls.\n */\n offset() {\n this.offset_ = this.instructions_.length;\n this.zIndex = 0;\n }\n}\n\nexport default ZIndexContext;\n", "/**\n * @module ol/renderer/Layer\n */\nimport ImageState from '../ImageState.js';\nimport Observable from '../Observable.js';\nimport EventType from '../events/EventType.js';\nimport {abstract} from '../util.js';\n\nconst maxStaleKeys = 5;\n\n/**\n * @template {import(\"../layer/Layer.js\").default} LayerType\n */\nclass LayerRenderer extends Observable {\n /**\n * @param {LayerType} layer Layer.\n */\n constructor(layer) {\n super();\n\n /**\n * The renderer is initialized and ready to render.\n * @type {boolean}\n */\n this.ready = true;\n\n /** @private */\n this.boundHandleImageChange_ = this.handleImageChange_.bind(this);\n\n /**\n * @private\n * @type {LayerType}\n */\n this.layer_ = layer;\n\n /**\n * @type {Array}\n * @private\n */\n this.staleKeys_ = new Array();\n\n /**\n * @type {number}\n * @protected\n */\n this.maxStaleKeys = maxStaleKeys;\n }\n\n /**\n * @return {Array} Get the list of stale keys.\n */\n getStaleKeys() {\n return this.staleKeys_;\n }\n\n /**\n * @param {string} key The new stale key.\n */\n prependStaleKey(key) {\n this.staleKeys_.unshift(key);\n if (this.staleKeys_.length > this.maxStaleKeys) {\n this.staleKeys_.length = this.maxStaleKeys;\n }\n }\n\n /**\n * Asynchronous layer level hit detection.\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @return {Promise>} Promise that resolves with\n * an array of features.\n */\n getFeatures(pixel) {\n return abstract();\n }\n\n /**\n * @param {import(\"../pixel.js\").Pixel} pixel Pixel.\n * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.\n */\n getData(pixel) {\n return null;\n }\n\n /**\n * Determine whether render should be called.\n * @abstract\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @return {boolean} Layer is ready to be rendered.\n */\n prepareFrame(frameState) {\n return abstract();\n }\n\n /**\n * Render the layer.\n * @abstract\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @param {HTMLElement|null} target Target that may be used to render content to.\n * @return {HTMLElement|null} The rendered element.\n */\n renderFrame(frameState, target) {\n return abstract();\n }\n\n /**\n * @abstract\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {import(\"./vector.js\").FeatureCallback} callback Feature callback.\n * @param {Array>} matches The hit detected matches with tolerance.\n * @return {T|undefined} Callback result.\n * @template T\n */\n forEachFeatureAtCoordinate(\n coordinate,\n frameState,\n hitTolerance,\n callback,\n matches,\n ) {\n return undefined;\n }\n\n /**\n * @return {LayerType} Layer.\n */\n getLayer() {\n return this.layer_;\n }\n\n /**\n * Perform action necessary to get the layer rendered after new fonts have loaded\n * @abstract\n */\n handleFontsChanged() {}\n\n /**\n * Handle changes in image state.\n * @param {import(\"../events/Event.js\").default} event Image change event.\n * @private\n */\n handleImageChange_(event) {\n const image = /** @type {import(\"../Image.js\").default} */ (event.target);\n if (\n image.getState() === ImageState.LOADED ||\n image.getState() === ImageState.ERROR\n ) {\n this.renderIfReadyAndVisible();\n }\n }\n\n /**\n * Load the image if not already loaded, and register the image change\n * listener if needed.\n * @param {import(\"../Image.js\").default} image Image.\n * @return {boolean} `true` if the image is already loaded, `false` otherwise.\n * @protected\n */\n loadImage(image) {\n let imageState = image.getState();\n if (imageState != ImageState.LOADED && imageState != ImageState.ERROR) {\n image.addEventListener(EventType.CHANGE, this.boundHandleImageChange_);\n }\n if (imageState == ImageState.IDLE) {\n image.load();\n imageState = image.getState();\n }\n return imageState == ImageState.LOADED;\n }\n\n /**\n * @protected\n */\n renderIfReadyAndVisible() {\n const layer = this.getLayer();\n if (layer && layer.getVisible() && layer.getSourceState() === 'ready') {\n layer.changed();\n }\n }\n\n /**\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n */\n renderDeferred(frameState) {}\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n delete this.layer_;\n super.disposeInternal();\n }\n}\n\nexport default LayerRenderer;\n", "/**\n * @module ol/renderer/canvas/Layer\n */\nimport {equals} from '../../array.js';\nimport {asArray} from '../../color.js';\nimport {createCanvasContext2D} from '../../dom.js';\nimport {\n getBottomLeft,\n getBottomRight,\n getHeight,\n getTopLeft,\n getTopRight,\n getWidth,\n} from '../../extent.js';\nimport RenderEvent from '../../render/Event.js';\nimport RenderEventType from '../../render/EventType.js';\nimport ZIndexContext from '../../render/canvas/ZIndexContext.js';\nimport {\n apply as applyTransform,\n compose as composeTransform,\n create as createTransform,\n makeInverse,\n toString as toTransformString,\n} from '../../transform.js';\nimport LayerRenderer from '../Layer.js';\n\n/**\n * @type {Array}\n */\nexport const canvasPool = [];\n\n/**\n * @type {CanvasRenderingContext2D}\n */\nlet pixelContext = null;\n\nfunction createPixelContext() {\n pixelContext = createCanvasContext2D(1, 1, undefined, {\n willReadFrequently: true,\n });\n}\n\n/**\n * @abstract\n * @template {import(\"../../layer/Layer.js\").default} LayerType\n * @extends {LayerRenderer}\n */\nclass CanvasLayerRenderer extends LayerRenderer {\n /**\n * @param {LayerType} layer Layer.\n */\n constructor(layer) {\n super(layer);\n\n /**\n * @protected\n * @type {HTMLElement}\n */\n this.container = null;\n\n /**\n * @protected\n * @type {number}\n */\n this.renderedResolution;\n\n /**\n * A temporary transform. The values in this transform should only be used in a\n * function that sets the values.\n * @protected\n * @type {import(\"../../transform.js\").Transform}\n */\n this.tempTransform = createTransform();\n\n /**\n * The transform for rendered pixels to viewport CSS pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import(\"../../transform.js\").Transform}\n */\n this.pixelTransform = createTransform();\n\n /**\n * The transform for viewport CSS pixels to rendered pixels. This transform must\n * be set when rendering a frame and may be used by other functions after rendering.\n * @protected\n * @type {import(\"../../transform.js\").Transform}\n */\n this.inversePixelTransform = createTransform();\n\n /**\n * @type {CanvasRenderingContext2D}\n */\n this.context = null;\n\n /**\n * @private\n * @type {ZIndexContext}\n */\n this.deferredContext_ = null;\n\n /**\n * @type {boolean}\n */\n this.containerReused = false;\n\n /**\n * @protected\n * @type {import(\"../../Map.js\").FrameState|null}\n */\n this.frameState = null;\n }\n\n /**\n * @param {import('../../DataTile.js').ImageLike} image Image.\n * @param {number} col The column index.\n * @param {number} row The row index.\n * @return {Uint8ClampedArray|null} The image data.\n */\n getImageData(image, col, row) {\n if (!pixelContext) {\n createPixelContext();\n }\n pixelContext.clearRect(0, 0, 1, 1);\n\n let data;\n try {\n pixelContext.drawImage(image, col, row, 1, 1, 0, 0, 1, 1);\n data = pixelContext.getImageData(0, 0, 1, 1).data;\n } catch {\n pixelContext = null;\n return null;\n }\n return data;\n }\n\n /**\n * @param {import('../../Map.js').FrameState} frameState Frame state.\n * @return {string} Background color.\n */\n getBackground(frameState) {\n const layer = this.getLayer();\n let background = layer.getBackground();\n if (typeof background === 'function') {\n background = background(frameState.viewState.resolution);\n }\n return background || undefined;\n }\n\n /**\n * Get a rendering container from an existing target, if compatible.\n * @param {HTMLElement} target Potential render target.\n * @param {string} transform CSS Transform.\n * @param {string} [backgroundColor] Background color.\n */\n useContainer(target, transform, backgroundColor) {\n const layerClassName = this.getLayer().getClassName();\n let container, context;\n if (\n target &&\n target.className === layerClassName &&\n (!backgroundColor ||\n (target &&\n target.style.backgroundColor &&\n equals(\n asArray(target.style.backgroundColor),\n asArray(backgroundColor),\n )))\n ) {\n const canvas = target.firstElementChild;\n if (canvas instanceof HTMLCanvasElement) {\n context = canvas.getContext('2d');\n }\n }\n if (context && context.canvas.style.transform === transform) {\n // Container of the previous layer renderer can be used.\n this.container = target;\n this.context = context;\n this.containerReused = true;\n } else if (this.containerReused) {\n // Previously reused container cannot be used any more.\n this.container = null;\n this.context = null;\n this.containerReused = false;\n } else if (this.container) {\n this.container.style.backgroundColor = null;\n }\n if (!this.container) {\n container = document.createElement('div');\n container.className = layerClassName;\n let style = container.style;\n style.position = 'absolute';\n style.width = '100%';\n style.height = '100%';\n context = createCanvasContext2D();\n const canvas = context.canvas;\n container.appendChild(canvas);\n style = canvas.style;\n style.position = 'absolute';\n style.left = '0';\n style.transformOrigin = 'top left';\n this.container = container;\n this.context = context;\n }\n if (\n !this.containerReused &&\n backgroundColor &&\n !this.container.style.backgroundColor\n ) {\n this.container.style.backgroundColor = backgroundColor;\n }\n }\n\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @param {import(\"../../extent.js\").Extent} extent Clip extent.\n * @protected\n */\n clipUnrotated(context, frameState, extent) {\n const topLeft = getTopLeft(extent);\n const topRight = getTopRight(extent);\n const bottomRight = getBottomRight(extent);\n const bottomLeft = getBottomLeft(extent);\n\n applyTransform(frameState.coordinateToPixelTransform, topLeft);\n applyTransform(frameState.coordinateToPixelTransform, topRight);\n applyTransform(frameState.coordinateToPixelTransform, bottomRight);\n applyTransform(frameState.coordinateToPixelTransform, bottomLeft);\n\n const inverted = this.inversePixelTransform;\n applyTransform(inverted, topLeft);\n applyTransform(inverted, topRight);\n applyTransform(inverted, bottomRight);\n applyTransform(inverted, bottomLeft);\n\n context.save();\n context.beginPath();\n context.moveTo(Math.round(topLeft[0]), Math.round(topLeft[1]));\n context.lineTo(Math.round(topRight[0]), Math.round(topRight[1]));\n context.lineTo(Math.round(bottomRight[0]), Math.round(bottomRight[1]));\n context.lineTo(Math.round(bottomLeft[0]), Math.round(bottomLeft[1]));\n context.clip();\n }\n\n /**\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target that may be used to render content to.\n * @protected\n */\n prepareContainer(frameState, target) {\n const extent = frameState.extent;\n const resolution = frameState.viewState.resolution;\n const rotation = frameState.viewState.rotation;\n const pixelRatio = frameState.pixelRatio;\n const width = Math.round((getWidth(extent) / resolution) * pixelRatio);\n const height = Math.round((getHeight(extent) / resolution) * pixelRatio);\n // set forward and inverse pixel transforms\n composeTransform(\n this.pixelTransform,\n frameState.size[0] / 2,\n frameState.size[1] / 2,\n 1 / pixelRatio,\n 1 / pixelRatio,\n rotation,\n -width / 2,\n -height / 2,\n );\n makeInverse(this.inversePixelTransform, this.pixelTransform);\n\n const canvasTransform = toTransformString(this.pixelTransform);\n this.useContainer(target, canvasTransform, this.getBackground(frameState));\n\n if (!this.containerReused) {\n const canvas = this.context.canvas;\n if (canvas.width != width || canvas.height != height) {\n canvas.width = width;\n canvas.height = height;\n } else {\n this.context.clearRect(0, 0, width, height);\n }\n if (canvasTransform !== canvas.style.transform) {\n canvas.style.transform = canvasTransform;\n }\n }\n }\n\n /**\n * @param {import(\"../../render/EventType.js\").default} type Event type.\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @private\n */\n dispatchRenderEvent_(type, context, frameState) {\n const layer = this.getLayer();\n if (layer.hasListener(type)) {\n const event = new RenderEvent(\n type,\n this.inversePixelTransform,\n frameState,\n context,\n );\n layer.dispatchEvent(event);\n }\n }\n\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @protected\n */\n preRender(context, frameState) {\n this.frameState = frameState;\n if (frameState.declutter) {\n return;\n }\n this.dispatchRenderEvent_(RenderEventType.PRERENDER, context, frameState);\n }\n\n /**\n * @param {CanvasRenderingContext2D} context Context.\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @protected\n */\n postRender(context, frameState) {\n if (frameState.declutter) {\n return;\n }\n this.dispatchRenderEvent_(RenderEventType.POSTRENDER, context, frameState);\n }\n\n /**\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n */\n renderDeferredInternal(frameState) {}\n\n /**\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @return {import('../../render/canvas/ZIndexContext.js').ZIndexContextProxy} Context.\n */\n getRenderContext(frameState) {\n if (frameState.declutter && !this.deferredContext_) {\n this.deferredContext_ = new ZIndexContext();\n }\n return frameState.declutter\n ? this.deferredContext_.getContext()\n : this.context;\n }\n\n /**\n * @param {import(\"../../Map.js\").FrameState} frameState Frame state.\n * @override\n */\n renderDeferred(frameState) {\n if (!frameState.declutter) {\n return;\n }\n this.dispatchRenderEvent_(\n RenderEventType.PRERENDER,\n this.context,\n frameState,\n );\n if (frameState.declutter && this.deferredContext_) {\n this.deferredContext_.draw(this.context);\n this.deferredContext_.clear();\n }\n this.renderDeferredInternal(frameState);\n this.dispatchRenderEvent_(\n RenderEventType.POSTRENDER,\n this.context,\n frameState,\n );\n }\n\n /**\n * Creates a transform for rendering to an element that will be rotated after rendering.\n * @param {import(\"../../coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} rotation Rotation.\n * @param {number} pixelRatio Pixel ratio.\n * @param {number} width Width of the rendered element (in pixels).\n * @param {number} height Height of the rendered element (in pixels).\n * @param {number} offsetX Offset on the x-axis in view coordinates.\n * @protected\n * @return {!import(\"../../transform.js\").Transform} Transform.\n */\n getRenderTransform(\n center,\n resolution,\n rotation,\n pixelRatio,\n width,\n height,\n offsetX,\n ) {\n const dx1 = width / 2;\n const dy1 = height / 2;\n const sx = pixelRatio / resolution;\n const sy = -sx;\n const dx2 = -center[0] + offsetX;\n const dy2 = -center[1];\n return composeTransform(\n this.tempTransform,\n dx1,\n dy1,\n sx,\n sy,\n -rotation,\n dx2,\n dy2,\n );\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n delete this.frameState;\n super.disposeInternal();\n }\n}\n\nexport default CanvasLayerRenderer;\n", "/**\n * @module ol/layer/Property\n */\n\n/**\n * @enum {string}\n */\nexport default {\n OPACITY: 'opacity',\n VISIBLE: 'visible',\n EXTENT: 'extent',\n Z_INDEX: 'zIndex',\n MAX_RESOLUTION: 'maxResolution',\n MIN_RESOLUTION: 'minResolution',\n MAX_ZOOM: 'maxZoom',\n MIN_ZOOM: 'minZoom',\n SOURCE: 'source',\n MAP: 'map',\n};\n", "/**\n * @module ol/layer/Base\n */\nimport BaseObject from '../Object.js';\nimport {assert} from '../asserts.js';\nimport {clamp} from '../math.js';\nimport {abstract} from '../util.js';\nimport LayerProperty from './Property.js';\n\n/**\n * A css color, or a function called with a view resolution returning a css color.\n *\n * @typedef {string|function(number):string} BackgroundColor\n * @api\n */\n\n/**\n * @typedef {import(\"../ObjectEventType\").Types|'change:extent'|'change:maxResolution'|'change:maxZoom'|\n * 'change:minResolution'|'change:minZoom'|'change:opacity'|'change:visible'|'change:zIndex'} BaseLayerObjectEventTypes\n */\n\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature &\n * import(\"../Observable\").OnSignature &\n * import(\"../Observable\").CombinedOnSignature} BaseLayerOnSignature\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number | undefined} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {BackgroundColor} [background] Background color for the layer. If not specified, no background\n * will be rendered.\n * @property {Object} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n\n/**\n * @classdesc\n * Abstract base class; normally only used for creating subclasses and not\n * instantiated in apps.\n * Note that with {@link module:ol/layer/Base~BaseLayer} and all its subclasses, any property set in\n * the options is set as a {@link module:ol/Object~BaseObject} property on the layer object, so\n * is observable, and has get/set accessors.\n *\n * @api\n */\nclass BaseLayer extends BaseObject {\n /**\n * @param {Options} options Layer options.\n */\n constructor(options) {\n super();\n\n /***\n * @type {BaseLayerOnSignature}\n */\n this.on;\n\n /***\n * @type {BaseLayerOnSignature}\n */\n this.once;\n\n /***\n * @type {BaseLayerOnSignature}\n */\n this.un;\n\n /**\n * @type {BackgroundColor|false}\n * @private\n */\n this.background_ = options.background;\n\n /**\n * @type {Object}\n */\n const properties = Object.assign({}, options);\n if (typeof options.properties === 'object') {\n delete properties.properties;\n Object.assign(properties, options.properties);\n }\n\n properties[LayerProperty.OPACITY] =\n options.opacity !== undefined ? options.opacity : 1;\n assert(\n typeof properties[LayerProperty.OPACITY] === 'number',\n 'Layer opacity must be a number',\n );\n\n properties[LayerProperty.VISIBLE] =\n options.visible !== undefined ? options.visible : true;\n properties[LayerProperty.Z_INDEX] = options.zIndex;\n properties[LayerProperty.MAX_RESOLUTION] =\n options.maxResolution !== undefined ? options.maxResolution : Infinity;\n properties[LayerProperty.MIN_RESOLUTION] =\n options.minResolution !== undefined ? options.minResolution : 0;\n properties[LayerProperty.MIN_ZOOM] =\n options.minZoom !== undefined ? options.minZoom : -Infinity;\n properties[LayerProperty.MAX_ZOOM] =\n options.maxZoom !== undefined ? options.maxZoom : Infinity;\n\n /**\n * @type {string}\n * @private\n */\n this.className_ =\n properties.className !== undefined ? properties.className : 'ol-layer';\n delete properties.className;\n\n this.setProperties(properties);\n\n /**\n * @type {import(\"./Layer.js\").State}\n * @private\n */\n this.state_ = null;\n }\n\n /**\n * Get the background for this layer.\n * @return {BackgroundColor|false} Layer background.\n */\n getBackground() {\n return this.background_;\n }\n\n /**\n * @return {string} CSS class name.\n */\n getClassName() {\n return this.className_;\n }\n\n /**\n * This method is not meant to be called by layers or layer renderers because the state\n * is incorrect if the layer is included in a layer group.\n *\n * @param {boolean} [managed] Layer is managed.\n * @return {import(\"./Layer.js\").State} Layer state.\n */\n getLayerState(managed) {\n /** @type {import(\"./Layer.js\").State} */\n const state =\n this.state_ ||\n /** @type {?} */ ({\n layer: this,\n managed: managed === undefined ? true : managed,\n });\n const zIndex = this.getZIndex();\n state.opacity = clamp(Math.round(this.getOpacity() * 100) / 100, 0, 1);\n state.visible = this.getVisible();\n state.extent = this.getExtent();\n state.zIndex = zIndex === undefined && !state.managed ? Infinity : zIndex;\n state.maxResolution = this.getMaxResolution();\n state.minResolution = Math.max(this.getMinResolution(), 0);\n state.minZoom = this.getMinZoom();\n state.maxZoom = this.getMaxZoom();\n this.state_ = state;\n\n return state;\n }\n\n /**\n * @abstract\n * @param {Array} [array] Array of layers (to be\n * modified in place).\n * @return {Array} Array of layers.\n */\n getLayersArray(array) {\n return abstract();\n }\n\n /**\n * @abstract\n * @param {Array} [states] Optional list of layer\n * states (to be modified in place).\n * @return {Array} List of layer states.\n */\n getLayerStatesArray(states) {\n return abstract();\n }\n\n /**\n * Return the {@link module:ol/extent~Extent extent} of the layer or `undefined` if it\n * will be visible regardless of extent.\n * @return {import(\"../extent.js\").Extent|undefined} The layer extent.\n * @observable\n * @api\n */\n getExtent() {\n return /** @type {import(\"../extent.js\").Extent|undefined} */ (\n this.get(LayerProperty.EXTENT)\n );\n }\n\n /**\n * Return the maximum resolution of the layer. Returns Infinity if\n * the layer has no maximum resolution set.\n * @return {number} The maximum resolution of the layer.\n * @observable\n * @api\n */\n getMaxResolution() {\n return /** @type {number} */ (this.get(LayerProperty.MAX_RESOLUTION));\n }\n\n /**\n * Return the minimum resolution of the layer. Returns 0 if\n * the layer has no minimum resolution set.\n * @return {number} The minimum resolution of the layer.\n * @observable\n * @api\n */\n getMinResolution() {\n return /** @type {number} */ (this.get(LayerProperty.MIN_RESOLUTION));\n }\n\n /**\n * Return the minimum zoom level of the layer. Returns -Infinity if\n * the layer has no minimum zoom set.\n * @return {number} The minimum zoom level of the layer.\n * @observable\n * @api\n */\n getMinZoom() {\n return /** @type {number} */ (this.get(LayerProperty.MIN_ZOOM));\n }\n\n /**\n * Return the maximum zoom level of the layer. Returns Infinity if\n * the layer has no maximum zoom set.\n * @return {number} The maximum zoom level of the layer.\n * @observable\n * @api\n */\n getMaxZoom() {\n return /** @type {number} */ (this.get(LayerProperty.MAX_ZOOM));\n }\n\n /**\n * Return the opacity of the layer (between 0 and 1).\n * @return {number} The opacity of the layer.\n * @observable\n * @api\n */\n getOpacity() {\n return /** @type {number} */ (this.get(LayerProperty.OPACITY));\n }\n\n /**\n * @abstract\n * @return {import(\"../source/Source.js\").State} Source state.\n */\n getSourceState() {\n return abstract();\n }\n\n /**\n * Return the value of this layer's `visible` property. To find out whether the layer\n * is visible on a map, use `isVisible()` instead.\n * @return {boolean} The value of the `visible` property of the layer.\n * @observable\n * @api\n */\n getVisible() {\n return /** @type {boolean} */ (this.get(LayerProperty.VISIBLE));\n }\n\n /**\n * Return the Z-index of the layer, which is used to order layers before\n * rendering. Returns undefined if the layer is unmanaged.\n * @return {number|undefined} The Z-index of the layer.\n * @observable\n * @api\n */\n getZIndex() {\n return /** @type {number|undefined} */ (this.get(LayerProperty.Z_INDEX));\n }\n\n /**\n * Sets the background color.\n * @param {BackgroundColor} [background] Background color.\n */\n setBackground(background) {\n this.background_ = background;\n this.changed();\n }\n\n /**\n * Set the extent at which the layer is visible. If `undefined`, the layer\n * will be visible at all extents.\n * @param {import(\"../extent.js\").Extent|undefined} extent The extent of the layer.\n * @observable\n * @api\n */\n setExtent(extent) {\n this.set(LayerProperty.EXTENT, extent);\n }\n\n /**\n * Set the maximum resolution at which the layer is visible.\n * @param {number} maxResolution The maximum resolution of the layer.\n * @observable\n * @api\n */\n setMaxResolution(maxResolution) {\n this.set(LayerProperty.MAX_RESOLUTION, maxResolution);\n }\n\n /**\n * Set the minimum resolution at which the layer is visible.\n * @param {number} minResolution The minimum resolution of the layer.\n * @observable\n * @api\n */\n setMinResolution(minResolution) {\n this.set(LayerProperty.MIN_RESOLUTION, minResolution);\n }\n\n /**\n * Set the maximum zoom (exclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} maxZoom The maximum zoom of the layer.\n * @observable\n * @api\n */\n setMaxZoom(maxZoom) {\n this.set(LayerProperty.MAX_ZOOM, maxZoom);\n }\n\n /**\n * Set the minimum zoom (inclusive) at which the layer is visible.\n * Note that the zoom levels for layer visibility are based on the\n * view zoom level, which may be different from a tile source zoom level.\n * @param {number} minZoom The minimum zoom of the layer.\n * @observable\n * @api\n */\n setMinZoom(minZoom) {\n this.set(LayerProperty.MIN_ZOOM, minZoom);\n }\n\n /**\n * Set the opacity of the layer, allowed values range from 0 to 1.\n * @param {number} opacity The opacity of the layer.\n * @observable\n * @api\n */\n setOpacity(opacity) {\n assert(typeof opacity === 'number', 'Layer opacity must be a number');\n this.set(LayerProperty.OPACITY, opacity);\n }\n\n /**\n * Set the visibility of the layer (`true` or `false`).\n * @param {boolean} visible The visibility of the layer.\n * @observable\n * @api\n */\n setVisible(visible) {\n this.set(LayerProperty.VISIBLE, visible);\n }\n\n /**\n * Set Z-index of the layer, which is used to order layers before rendering.\n * The default Z-index is 0.\n * @param {number} zindex The z-index of the layer.\n * @observable\n * @api\n */\n setZIndex(zindex) {\n this.set(LayerProperty.Z_INDEX, zindex);\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n if (this.state_) {\n this.state_.layer = null;\n this.state_ = null;\n }\n super.disposeInternal();\n }\n}\n\nexport default BaseLayer;\n", "/**\n * @module ol/layer/Layer\n */\nimport View from '../View.js';\nimport {assert} from '../asserts.js';\nimport EventType from '../events/EventType.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport {intersects} from '../extent.js';\nimport RenderEventType from '../render/EventType.js';\nimport BaseLayer from './Base.js';\nimport LayerProperty from './Property.js';\n\n/**\n * @typedef {function(import(\"../Map.js\").FrameState):HTMLElement} RenderFunction\n */\n\n/**\n * @typedef {'sourceready'|'change:source'} LayerEventType\n */\n\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature &\n * import(\"../Observable\").OnSignature &\n * import(\"../Observable\").OnSignature &\n * import(\"../Observable\").CombinedOnSignature} LayerOnSignature\n */\n\n/**\n * @template {import(\"../source/Source.js\").default} [SourceType=import(\"../source/Source.js\").default]\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {SourceType} [source] Source for this layer. If not provided to the constructor,\n * the source can be set by calling {@link module:ol/layer/Layer~Layer#setSource layer.setSource(source)} after\n * construction.\n * @property {import(\"../Map.js\").default|null} [map] Map.\n * @property {RenderFunction} [render] Render function. Takes the frame state as input and is expected to return an\n * HTML element. Will overwrite the default rendering for the layer.\n * @property {Object} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n\n/**\n * @typedef {Object} State\n * @property {import(\"./Layer.js\").default} layer Layer.\n * @property {number} opacity Opacity, the value is rounded to two digits to appear after the decimal point.\n * @property {boolean} visible Visible.\n * @property {boolean} managed Managed.\n * @property {import(\"../extent.js\").Extent} [extent] Extent.\n * @property {number} zIndex ZIndex.\n * @property {number} maxResolution Maximum resolution.\n * @property {number} minResolution Minimum resolution.\n * @property {number} minZoom Minimum zoom.\n * @property {number} maxZoom Maximum zoom.\n */\n\n/**\n * @classdesc\n * Base class from which all layer types are derived. This should only be instantiated\n * in the case where a custom layer is added to the map with a custom `render` function.\n * Such a function can be specified in the `options` object, and is expected to return an HTML element.\n *\n * A visual representation of raster or vector map data.\n * Layers group together those properties that pertain to how the data is to be\n * displayed, irrespective of the source of that data.\n *\n * Layers are usually added to a map with [map.addLayer()]{@link import(\"../Map.js\").default#addLayer}.\n * Components like {@link module:ol/interaction/Draw~Draw} use unmanaged layers\n * internally. These unmanaged layers are associated with the map using\n * [layer.setMap()]{@link module:ol/layer/Layer~Layer#setMap} instead.\n *\n * A generic `change` event is fired when the state of the source changes.\n * A `sourceready` event is fired when the layer's source is ready.\n *\n * @fires import(\"../render/Event.js\").RenderEvent#prerender\n * @fires import(\"../render/Event.js\").RenderEvent#postrender\n * @fires import(\"../events/Event.js\").BaseEvent#sourceready\n *\n * @template {import(\"../source/Source.js\").default} [SourceType=import(\"../source/Source.js\").default]\n * @template {import(\"../renderer/Layer.js\").default} [RendererType=import(\"../renderer/Layer.js\").default]\n * @api\n */\nclass Layer extends BaseLayer {\n /**\n * @param {Options} options Layer options.\n */\n constructor(options) {\n const baseOptions = Object.assign({}, options);\n delete baseOptions.source;\n\n super(baseOptions);\n\n /***\n * @type {LayerOnSignature}\n */\n this.on;\n\n /***\n * @type {LayerOnSignature}\n */\n this.once;\n\n /***\n * @type {LayerOnSignature}\n */\n this.un;\n\n /**\n * @private\n * @type {?import(\"../events.js\").EventsKey}\n */\n this.mapPrecomposeKey_ = null;\n\n /**\n * @private\n * @type {?import(\"../events.js\").EventsKey}\n */\n this.mapRenderKey_ = null;\n\n /**\n * @private\n * @type {?import(\"../events.js\").EventsKey}\n */\n this.sourceChangeKey_ = null;\n\n /**\n * @private\n * @type {RendererType}\n */\n this.renderer_ = null;\n\n /**\n * @private\n * @type {boolean}\n */\n this.sourceReady_ = false;\n\n /**\n * @protected\n * @type {boolean}\n */\n this.rendered = false;\n\n // Overwrite default render method with a custom one\n if (options.render) {\n this.render = options.render;\n }\n\n if (options.map) {\n this.setMap(options.map);\n }\n\n this.addChangeListener(\n LayerProperty.SOURCE,\n this.handleSourcePropertyChange_,\n );\n\n const source = options.source\n ? /** @type {SourceType} */ (options.source)\n : null;\n this.setSource(source);\n }\n\n /**\n * @param {Array} [array] Array of layers (to be modified in place).\n * @return {Array} Array of layers.\n * @override\n */\n getLayersArray(array) {\n array = array ? array : [];\n array.push(this);\n return array;\n }\n\n /**\n * @param {Array} [states] Optional list of layer states (to be modified in place).\n * @return {Array} List of layer states.\n * @override\n */\n getLayerStatesArray(states) {\n states = states ? states : [];\n states.push(this.getLayerState());\n return states;\n }\n\n /**\n * Get the layer source.\n * @return {SourceType|null} The layer source (or `null` if not yet set).\n * @observable\n * @api\n */\n getSource() {\n return /** @type {SourceType} */ (this.get(LayerProperty.SOURCE)) || null;\n }\n\n /**\n * @return {SourceType|null} The source being rendered.\n */\n getRenderSource() {\n return this.getSource();\n }\n\n /**\n * @return {import(\"../source/Source.js\").State} Source state.\n * @override\n */\n getSourceState() {\n const source = this.getSource();\n return !source ? 'undefined' : source.getState();\n }\n\n /**\n * @private\n */\n handleSourceChange_() {\n this.changed();\n if (this.sourceReady_ || this.getSource().getState() !== 'ready') {\n return;\n }\n this.sourceReady_ = true;\n this.dispatchEvent('sourceready');\n }\n\n /**\n * @private\n */\n handleSourcePropertyChange_() {\n if (this.sourceChangeKey_) {\n unlistenByKey(this.sourceChangeKey_);\n this.sourceChangeKey_ = null;\n }\n this.sourceReady_ = false;\n const source = this.getSource();\n if (source) {\n this.sourceChangeKey_ = listen(\n source,\n EventType.CHANGE,\n this.handleSourceChange_,\n this,\n );\n if (source.getState() === 'ready') {\n this.sourceReady_ = true;\n setTimeout(() => {\n this.dispatchEvent('sourceready');\n }, 0);\n }\n this.clearRenderer();\n }\n this.changed();\n }\n\n /**\n * @param {import(\"../pixel\").Pixel} pixel Pixel.\n * @return {Promise>} Promise that resolves with\n * an array of features.\n */\n getFeatures(pixel) {\n if (!this.renderer_) {\n return Promise.resolve([]);\n }\n return this.renderer_.getFeatures(pixel);\n }\n\n /**\n * @param {import(\"../pixel\").Pixel} pixel Pixel.\n * @return {Uint8ClampedArray|Uint8Array|Float32Array|DataView|null} Pixel data.\n */\n getData(pixel) {\n if (!this.renderer_ || !this.rendered) {\n return null;\n }\n return this.renderer_.getData(pixel);\n }\n\n /**\n * The layer is visible on the map view, i.e. within its min/max resolution or zoom and\n * extent, not set to `visible: false`, and not inside a layer group that is set\n * to `visible: false`.\n * @param {View|import(\"../View.js\").ViewStateLayerStateExtent} [view] View or {@link import(\"../Map.js\").FrameState}.\n * Only required when the layer is not added to a map.\n * @return {boolean} The layer is visible in the map view.\n * @api\n */\n isVisible(view) {\n let frameState;\n const map = this.getMapInternal();\n if (!view && map) {\n view = map.getView();\n }\n if (view instanceof View) {\n frameState = {\n viewState: view.getState(),\n extent: view.calculateExtent(),\n };\n } else {\n frameState = view;\n }\n if (!frameState.layerStatesArray && map) {\n frameState.layerStatesArray = map.getLayerGroup().getLayerStatesArray();\n }\n let layerState;\n if (frameState.layerStatesArray) {\n layerState = frameState.layerStatesArray.find(\n (layerState) => layerState.layer === this,\n );\n if (!layerState) {\n return false;\n }\n } else {\n layerState = this.getLayerState();\n }\n\n const layerExtent = this.getExtent();\n\n return (\n inView(layerState, frameState.viewState) &&\n (!layerExtent || intersects(layerExtent, frameState.extent))\n );\n }\n\n /**\n * Get the attributions of the source of this layer for the given view.\n * @param {View|import(\"../View.js\").ViewStateLayerStateExtent} [view] View or {@link import(\"../Map.js\").FrameState}.\n * Only required when the layer is not added to a map.\n * @return {Array} Attributions for this layer at the given view.\n * @api\n */\n getAttributions(view) {\n if (!this.isVisible(view)) {\n return [];\n }\n const getAttributions = this.getSource()?.getAttributions();\n if (!getAttributions) {\n return [];\n }\n const frameState =\n view instanceof View ? view.getViewStateAndExtent() : view;\n let attributions = getAttributions(frameState);\n if (!Array.isArray(attributions)) {\n attributions = [attributions];\n }\n return attributions;\n }\n\n /**\n * In charge to manage the rendering of the layer. One layer type is\n * bounded with one layer renderer.\n * @param {?import(\"../Map.js\").FrameState} frameState Frame state.\n * @param {HTMLElement} target Target which the renderer may (but need not) use\n * for rendering its content.\n * @return {HTMLElement|null} The rendered element.\n */\n render(frameState, target) {\n const layerRenderer = this.getRenderer();\n\n if (layerRenderer.prepareFrame(frameState)) {\n this.rendered = true;\n return layerRenderer.renderFrame(frameState, target);\n }\n return null;\n }\n\n /**\n * Called when a layer is not visible during a map render.\n */\n unrender() {\n this.rendered = false;\n }\n\n /** @return {string} Declutter */\n getDeclutter() {\n return undefined;\n }\n\n /**\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @param {import(\"../layer/Layer.js\").State} layerState Layer state.\n */\n renderDeclutter(frameState, layerState) {}\n\n /**\n * When the renderer follows a layout -> render approach, do the final rendering here.\n * @param {import('../Map.js').FrameState} frameState Frame state\n */\n renderDeferred(frameState) {\n const layerRenderer = this.getRenderer();\n if (!layerRenderer) {\n return;\n }\n layerRenderer.renderDeferred(frameState);\n }\n\n /**\n * For use inside the library only.\n * @param {import(\"../Map.js\").default|null} map Map.\n */\n setMapInternal(map) {\n if (!map) {\n this.unrender();\n }\n this.set(LayerProperty.MAP, map);\n }\n\n /**\n * For use inside the library only.\n * @return {import(\"../Map.js\").default|null} Map.\n */\n getMapInternal() {\n return this.get(LayerProperty.MAP);\n }\n\n /**\n * Sets the layer to be rendered on top of other layers on a map. The map will\n * not manage this layer in its layers collection. This\n * is useful for temporary layers. To remove an unmanaged layer from the map,\n * use `#setMap(null)`.\n *\n * To add the layer to a map and have it managed by the map, use\n * {@link module:ol/Map~Map#addLayer} instead.\n * @param {import(\"../Map.js\").default|null} map Map.\n * @api\n */\n setMap(map) {\n if (this.mapPrecomposeKey_) {\n unlistenByKey(this.mapPrecomposeKey_);\n this.mapPrecomposeKey_ = null;\n }\n if (!map) {\n this.changed();\n }\n if (this.mapRenderKey_) {\n unlistenByKey(this.mapRenderKey_);\n this.mapRenderKey_ = null;\n }\n if (map) {\n this.mapPrecomposeKey_ = listen(\n map,\n RenderEventType.PRECOMPOSE,\n this.handlePrecompose_,\n this,\n );\n this.mapRenderKey_ = listen(this, EventType.CHANGE, map.render, map);\n this.changed();\n }\n }\n\n /**\n * @param {import(\"../events/Event.js\").default} renderEvent Render event\n * @private\n */\n handlePrecompose_(renderEvent) {\n const layerStatesArray =\n /** @type {import(\"../render/Event.js\").default} */ (renderEvent)\n .frameState.layerStatesArray;\n const layerState = this.getLayerState(false);\n assert(\n !layerStatesArray.some(\n (arrayLayerState) => arrayLayerState.layer === layerState.layer,\n ),\n 'A layer can only be added to the map once. Use either `layer.setMap()` or `map.addLayer()`, not both.',\n );\n layerStatesArray.push(layerState);\n }\n\n /**\n * Set the layer source.\n * @param {SourceType|null} source The layer source.\n * @observable\n * @api\n */\n setSource(source) {\n this.set(LayerProperty.SOURCE, source);\n }\n\n /**\n * Get the renderer for this layer.\n * @return {RendererType|null} The layer renderer.\n */\n getRenderer() {\n if (!this.renderer_) {\n this.renderer_ = this.createRenderer();\n }\n return this.renderer_;\n }\n\n /**\n * @return {boolean} The layer has a renderer.\n */\n hasRenderer() {\n return !!this.renderer_;\n }\n\n /**\n * Create a renderer for this layer.\n * @return {RendererType} A layer renderer.\n * @protected\n */\n createRenderer() {\n return null;\n }\n\n /**\n * This will clear the renderer so that a new one can be created next time it is needed\n */\n clearRenderer() {\n if (this.renderer_) {\n this.renderer_.dispose();\n delete this.renderer_;\n }\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n this.clearRenderer();\n this.setSource(null);\n super.disposeInternal();\n }\n}\n\n/**\n * Return `true` if the layer is visible and if the provided view state\n * has resolution and zoom levels that are in range of the layer's min/max.\n * @param {State} layerState Layer state.\n * @param {import(\"../View.js\").State} viewState View state.\n * @return {boolean} The layer is visible at the given view state.\n */\nexport function inView(layerState, viewState) {\n if (!layerState.visible) {\n return false;\n }\n const resolution = viewState.resolution;\n if (\n resolution < layerState.minResolution ||\n resolution >= layerState.maxResolution\n ) {\n return false;\n }\n const zoom = viewState.zoom;\n return zoom > layerState.minZoom && zoom <= layerState.maxZoom;\n}\n\nexport default Layer;\n"],
+ "mappings": "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",
+ "names": ["none", "equals", "none", "EventType_default", "Event_default", "Event_default", "EventType_default", "Layer_default", "layerState", "EventType_default", "Layer_default"]
+}
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/ol.js b/VentusFlowWebGUI/node_modules/.vite/deps/ol.js
index 304c75e..f5eeb6d 100644
--- a/VentusFlowWebGUI/node_modules/.vite/deps/ol.js
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/ol.js
@@ -1,23 +1,23 @@
-import {
- ImageTile_default,
- TileRange_default,
- TileState_default,
- Tile_default
-} from "./chunk-V7I37XKR.js";
import {
MapBrowserEvent_default,
MapEvent_default
} from "./chunk-LKL2NEMT.js";
import {
- Pointer_default,
- centroid
-} from "./chunk-UWCYJJIT.js";
+ Vector_default
+} from "./chunk-JOMDBGKW.js";
+import "./chunk-6OUHCICN.js";
+import {
+ LineString_default
+} from "./chunk-NER2BJ37.js";
+import {
+ Feature_default
+} from "./chunk-ATTNMDTG.js";
import {
BaseVector_default,
Immediate_default,
Vector_default as Vector_default2,
getSquaredTolerance
-} from "./chunk-VQAOIZZU.js";
+} from "./chunk-HFPY7EDW.js";
import {
CLASS_COLLAPSED,
CLASS_CONTROL,
@@ -30,7 +30,9 @@ import {
Text_default,
checkedFonts,
shared
-} from "./chunk-LKGRVZZI.js";
+} from "./chunk-GKDSB34V.js";
+import "./chunk-RW3V7S4F.js";
+import "./chunk-JFXZSSOM.js";
import {
Base_default,
EventType_default as EventType_default2,
@@ -38,11 +40,15 @@ import {
Layer_default2 as Layer_default,
ViewHint_default,
View_default,
- disable,
inView
-} from "./chunk-6SP66AVH.js";
-import "./chunk-S7HK3S7W.js";
-import "./chunk-33EAEVLP.js";
+} from "./chunk-VWBYIKLE.js";
+import "./chunk-DYKFAHI6.js";
+import {
+ ImageTile_default,
+ TileRange_default,
+ TileState_default,
+ Tile_default
+} from "./chunk-V7I37XKR.js";
import "./chunk-FM44FOIC.js";
import {
ImageState_default,
@@ -56,62 +62,41 @@ import {
replaceNode
} from "./chunk-WEQYAO4O.js";
import {
- hasArea
-} from "./chunk-PPP4FLHO.js";
+ Kinetic_default,
+ defaults
+} from "./chunk-7RGUNZVN.js";
+import "./chunk-RMGZ5HGX.js";
import {
- Interaction_default,
- pan,
- zoomByDelta
-} from "./chunk-F2HSAX6I.js";
+ circular
+} from "./chunk-47JK3GLV.js";
+import "./chunk-TRW2RYAI.js";
+import "./chunk-QIVUQU5K.js";
+import "./chunk-LKZG5HMW.js";
+import "./chunk-F2HSAX6I.js";
import {
easeOut
} from "./chunk-LMC3RO5P.js";
import {
- Vector_default
-} from "./chunk-2R5MNV34.js";
-import "./chunk-DYKFAHI6.js";
-import "./chunk-RW3V7S4F.js";
-import {
- Feature_default
-} from "./chunk-GAPTD7YR.js";
+ CollectionEventType_default,
+ Collection_default
+} from "./chunk-4E4H2AGX.js";
+import "./chunk-S7HK3S7W.js";
+import "./chunk-33EAEVLP.js";
import {
- MapBrowserEventType_default,
- all,
- altShiftKeysOnly,
- always,
- focusWithTabindex,
- mouseActionButton,
- mouseOnly,
- noModifierKeys,
- platformModifierKey,
- primaryAction,
- shiftKeyOnly,
- targetNotEditable
-} from "./chunk-OOF5364O.js";
+ hasArea
+} from "./chunk-PPP4FLHO.js";
+import "./chunk-VAUZYTLA.js";
import {
DEVICE_PIXEL_RATIO,
- FIREFOX,
PASSIVE_EVENT_LISTENERS
} from "./chunk-ZPDML4Q3.js";
-import "./chunk-2NX2FDVC.js";
-import {
- Polygon_default,
- circular
-} from "./chunk-5CPSJRE2.js";
-import {
- CollectionEventType_default,
- Collection_default
-} from "./chunk-4E4H2AGX.js";
import {
- LineString_default
-} from "./chunk-7MYDC76J.js";
-import "./chunk-JFXZSSOM.js";
-import "./chunk-TRW2RYAI.js";
-import "./chunk-QIVUQU5K.js";
+ MapBrowserEventType_default
+} from "./chunk-POVGKIBQ.js";
import {
Point_default
-} from "./chunk-QJJYQF6H.js";
-import "./chunk-W2FV6P6N.js";
+} from "./chunk-G3HPQ3BH.js";
+import "./chunk-6GRRGW6V.js";
import {
apply,
compose,
@@ -131,8 +116,23 @@ import {
warn
} from "./chunk-5ACH5F45.js";
import {
- assert
-} from "./chunk-QFCIXVZ3.js";
+ applyTransform,
+ approximatelyEquals,
+ clone,
+ containsCoordinate,
+ containsExtent,
+ createOrUpdateEmpty,
+ degreesToStringHDMS,
+ equals as equals2,
+ getCenter,
+ getForViewAndSize,
+ getIntersection,
+ getWidth,
+ intersects,
+ isEmpty,
+ wrapX,
+ wrapX2
+} from "./chunk-WXT7AISE.js";
import {
Disposable_default,
Event_default,
@@ -147,9 +147,16 @@ import {
listen,
unlistenByKey
} from "./chunk-V2VQBN44.js";
+import {
+ clamp,
+ squaredSegmentDistance,
+ toRadians
+} from "./chunk-V7KTD4MH.js";
+import {
+ assert
+} from "./chunk-QFCIXVZ3.js";
import {
EventType_default,
- FALSE,
TRUE,
VOID,
toPromise
@@ -157,31 +164,6 @@ import {
import {
equals
} from "./chunk-FQY6EMA7.js";
-import {
- applyTransform,
- approximatelyEquals,
- clone,
- containsCoordinate,
- containsExtent,
- createOrUpdateEmpty,
- degreesToStringHDMS,
- equals as equals2,
- getCenter,
- getForViewAndSize,
- getIntersection,
- getWidth,
- intersects,
- isEmpty,
- rotate,
- scale,
- wrapX,
- wrapX2
-} from "./chunk-WXT7AISE.js";
-import {
- clamp,
- squaredSegmentDistance,
- toRadians
-} from "./chunk-V7KTD4MH.js";
import "./chunk-V6TY7KAL.js";
// node_modules/ol/Geolocation.js
@@ -1400,78 +1382,6 @@ var ImageCanvas = class extends Image_default {
};
var ImageCanvas_default = ImageCanvas;
-// node_modules/ol/Kinetic.js
-var Kinetic = class {
- /**
- * @param {number} decay Rate of decay (must be negative).
- * @param {number} minVelocity Minimum velocity (pixels/millisecond).
- * @param {number} delay Delay to consider to calculate the kinetic
- * initial values (milliseconds).
- */
- constructor(decay, minVelocity, delay) {
- this.decay_ = decay;
- this.minVelocity_ = minVelocity;
- this.delay_ = delay;
- this.points_ = [];
- this.angle_ = 0;
- this.initialVelocity_ = 0;
- }
- /**
- * FIXME empty description for jsdoc
- */
- begin() {
- this.points_.length = 0;
- this.angle_ = 0;
- this.initialVelocity_ = 0;
- }
- /**
- * @param {number} x X.
- * @param {number} y Y.
- */
- update(x, y) {
- this.points_.push(x, y, Date.now());
- }
- /**
- * @return {boolean} Whether we should do kinetic animation.
- */
- end() {
- if (this.points_.length < 6) {
- return false;
- }
- const delay = Date.now() - this.delay_;
- const lastIndex = this.points_.length - 3;
- if (this.points_[lastIndex + 2] < delay) {
- return false;
- }
- let firstIndex = lastIndex - 3;
- while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {
- firstIndex -= 3;
- }
- const duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];
- if (duration < 1e3 / 60) {
- return false;
- }
- const dx = this.points_[lastIndex] - this.points_[firstIndex];
- const dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];
- this.angle_ = Math.atan2(dy, dx);
- this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;
- return this.initialVelocity_ > this.minVelocity_;
- }
- /**
- * @return {number} Total distance travelled (pixels).
- */
- getDistance() {
- return (this.minVelocity_ - this.initialVelocity_) / this.decay_;
- }
- /**
- * @return {number} Angle of the kinetic panning animation (radians).
- */
- getAngle() {
- return this.angle_;
- }
-};
-var Kinetic_default = Kinetic;
-
// node_modules/ol/pointer/EventType.js
var EventType_default3 = {
POINTERMOVE: "pointermove",
@@ -2584,7 +2494,7 @@ var Zoom = class extends Control_default {
var Zoom_default = Zoom;
// node_modules/ol/control/defaults.js
-function defaults(options) {
+function defaults2(options) {
options = options ? options : {};
const controls = new Collection_default();
const zoomControl = options.zoom !== void 0 ? options.zoom : true;
@@ -2602,1088 +2512,6 @@ function defaults(options) {
return controls;
}
-// node_modules/ol/interaction/DoubleClickZoom.js
-var DoubleClickZoom = class extends Interaction_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- super();
- options = options ? options : {};
- this.delta_ = options.delta ? options.delta : 1;
- this.duration_ = options.duration !== void 0 ? options.duration : 250;
- }
- /**
- * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a
- * doubleclick) and eventually zooms the map.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @override
- */
- handleEvent(mapBrowserEvent) {
- let stopEvent = false;
- if (mapBrowserEvent.type == MapBrowserEventType_default.DBLCLICK) {
- const browserEvent = (
- /** @type {MouseEvent} */
- mapBrowserEvent.originalEvent
- );
- const map = mapBrowserEvent.map;
- const anchor = mapBrowserEvent.coordinate;
- const delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;
- const view = map.getView();
- zoomByDelta(view, delta, anchor, this.duration_);
- browserEvent.preventDefault();
- stopEvent = true;
- }
- return !stopEvent;
- }
-};
-var DoubleClickZoom_default = DoubleClickZoom;
-
-// node_modules/ol/interaction/DragPan.js
-var DragPan = class extends Pointer_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- super({
- stopDown: FALSE
- });
- options = options ? options : {};
- this.kinetic_ = options.kinetic;
- this.lastCentroid = null;
- this.lastPointersCount_;
- this.panning_ = false;
- const condition = options.condition ? options.condition : all(noModifierKeys, primaryAction);
- this.condition_ = options.onFocusOnly ? all(focusWithTabindex, condition) : condition;
- this.noKinetic_ = false;
- }
- /**
- * Handle pointer drag events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @override
- */
- handleDragEvent(mapBrowserEvent) {
- const map = mapBrowserEvent.map;
- if (!this.panning_) {
- this.panning_ = true;
- map.getView().beginInteraction();
- }
- const targetPointers = this.targetPointers;
- const centroid2 = map.getEventPixel(centroid(targetPointers));
- if (targetPointers.length == this.lastPointersCount_) {
- if (this.kinetic_) {
- this.kinetic_.update(centroid2[0], centroid2[1]);
- }
- if (this.lastCentroid) {
- const delta = [
- this.lastCentroid[0] - centroid2[0],
- centroid2[1] - this.lastCentroid[1]
- ];
- const map2 = mapBrowserEvent.map;
- const view = map2.getView();
- scale(delta, view.getResolution());
- rotate(delta, view.getRotation());
- view.adjustCenterInternal(delta);
- }
- } else if (this.kinetic_) {
- this.kinetic_.begin();
- }
- this.lastCentroid = centroid2;
- this.lastPointersCount_ = targetPointers.length;
- mapBrowserEvent.originalEvent.preventDefault();
- }
- /**
- * Handle pointer up events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleUpEvent(mapBrowserEvent) {
- const map = mapBrowserEvent.map;
- const view = map.getView();
- if (this.targetPointers.length === 0) {
- if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {
- const distance = this.kinetic_.getDistance();
- const angle = this.kinetic_.getAngle();
- const center = view.getCenterInternal();
- const centerpx = map.getPixelFromCoordinateInternal(center);
- const dest = map.getCoordinateFromPixelInternal([
- centerpx[0] - distance * Math.cos(angle),
- centerpx[1] - distance * Math.sin(angle)
- ]);
- view.animateInternal({
- center: view.getConstrainedCenter(dest),
- duration: 500,
- easing: easeOut
- });
- }
- if (this.panning_) {
- this.panning_ = false;
- view.endInteraction();
- }
- return false;
- }
- if (this.kinetic_) {
- this.kinetic_.begin();
- }
- this.lastCentroid = null;
- return true;
- }
- /**
- * Handle pointer down events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleDownEvent(mapBrowserEvent) {
- if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {
- const map = mapBrowserEvent.map;
- const view = map.getView();
- this.lastCentroid = null;
- if (view.getAnimating()) {
- view.cancelAnimations();
- }
- if (this.kinetic_) {
- this.kinetic_.begin();
- }
- this.noKinetic_ = this.targetPointers.length > 1;
- return true;
- }
- return false;
- }
-};
-var DragPan_default = DragPan;
-
-// node_modules/ol/interaction/DragRotate.js
-var DragRotate = class extends Pointer_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- options = options ? options : {};
- super({
- stopDown: FALSE
- });
- this.condition_ = options.condition ? options.condition : altShiftKeysOnly;
- this.lastAngle_ = void 0;
- this.duration_ = options.duration !== void 0 ? options.duration : 250;
- }
- /**
- * Handle pointer drag events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @override
- */
- handleDragEvent(mapBrowserEvent) {
- if (!mouseOnly(mapBrowserEvent)) {
- return;
- }
- const map = mapBrowserEvent.map;
- const view = map.getView();
- if (view.getConstraints().rotation === disable) {
- return;
- }
- const size = map.getSize();
- const offset = mapBrowserEvent.pixel;
- const theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);
- if (this.lastAngle_ !== void 0) {
- const delta = theta - this.lastAngle_;
- view.adjustRotationInternal(-delta);
- }
- this.lastAngle_ = theta;
- }
- /**
- * Handle pointer up events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleUpEvent(mapBrowserEvent) {
- if (!mouseOnly(mapBrowserEvent)) {
- return true;
- }
- const map = mapBrowserEvent.map;
- const view = map.getView();
- view.endInteraction(this.duration_);
- return false;
- }
- /**
- * Handle pointer down events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleDownEvent(mapBrowserEvent) {
- if (!mouseOnly(mapBrowserEvent)) {
- return false;
- }
- if (mouseActionButton(mapBrowserEvent) && this.condition_(mapBrowserEvent)) {
- const map = mapBrowserEvent.map;
- map.getView().beginInteraction();
- this.lastAngle_ = void 0;
- return true;
- }
- return false;
- }
-};
-var DragRotate_default = DragRotate;
-
-// node_modules/ol/render/Box.js
-var RenderBox = class extends Disposable_default {
- /**
- * @param {string} className CSS class name.
- */
- constructor(className) {
- super();
- this.geometry_ = null;
- this.element_ = document.createElement("div");
- this.element_.style.position = "absolute";
- this.element_.style.pointerEvents = "auto";
- this.element_.className = "ol-box " + className;
- this.map_ = null;
- this.startPixel_ = null;
- this.endPixel_ = null;
- }
- /**
- * Clean up.
- * @override
- */
- disposeInternal() {
- this.setMap(null);
- }
- /**
- * @private
- */
- render_() {
- const startPixel = this.startPixel_;
- const endPixel = this.endPixel_;
- const px = "px";
- const style = this.element_.style;
- style.left = Math.min(startPixel[0], endPixel[0]) + px;
- style.top = Math.min(startPixel[1], endPixel[1]) + px;
- style.width = Math.abs(endPixel[0] - startPixel[0]) + px;
- style.height = Math.abs(endPixel[1] - startPixel[1]) + px;
- }
- /**
- * @param {import("../Map.js").default|null} map Map.
- */
- setMap(map) {
- if (this.map_) {
- this.map_.getOverlayContainer().removeChild(this.element_);
- const style = this.element_.style;
- style.left = "inherit";
- style.top = "inherit";
- style.width = "inherit";
- style.height = "inherit";
- }
- this.map_ = map;
- if (this.map_) {
- this.map_.getOverlayContainer().appendChild(this.element_);
- }
- }
- /**
- * @param {import("../pixel.js").Pixel} startPixel Start pixel.
- * @param {import("../pixel.js").Pixel} endPixel End pixel.
- */
- setPixels(startPixel, endPixel) {
- this.startPixel_ = startPixel;
- this.endPixel_ = endPixel;
- this.createOrUpdateGeometry();
- this.render_();
- }
- /**
- * Creates or updates the cached geometry.
- */
- createOrUpdateGeometry() {
- if (!this.map_) {
- return;
- }
- const startPixel = this.startPixel_;
- const endPixel = this.endPixel_;
- const pixels = [
- startPixel,
- [startPixel[0], endPixel[1]],
- endPixel,
- [endPixel[0], startPixel[1]]
- ];
- const coordinates = pixels.map(
- this.map_.getCoordinateFromPixelInternal,
- this.map_
- );
- coordinates[4] = coordinates[0].slice();
- if (!this.geometry_) {
- this.geometry_ = new Polygon_default([coordinates]);
- } else {
- this.geometry_.setCoordinates([coordinates]);
- }
- }
- /**
- * @return {import("../geom/Polygon.js").default} Geometry.
- */
- getGeometry() {
- return this.geometry_;
- }
-};
-var Box_default = RenderBox;
-
-// node_modules/ol/interaction/DragBox.js
-var DragBoxEventType = {
- /**
- * Triggered upon drag box start.
- * @event DragBoxEvent#boxstart
- * @api
- */
- BOXSTART: "boxstart",
- /**
- * Triggered on drag when box is active.
- * @event DragBoxEvent#boxdrag
- * @api
- */
- BOXDRAG: "boxdrag",
- /**
- * Triggered upon drag box end.
- * @event DragBoxEvent#boxend
- * @api
- */
- BOXEND: "boxend",
- /**
- * Triggered upon drag box canceled.
- * @event DragBoxEvent#boxcancel
- * @api
- */
- BOXCANCEL: "boxcancel"
-};
-var DragBoxEvent = class extends Event_default {
- /**
- * @param {string} type The event type.
- * @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Originating event.
- */
- constructor(type, coordinate, mapBrowserEvent) {
- super(type);
- this.coordinate = coordinate;
- this.mapBrowserEvent = mapBrowserEvent;
- }
-};
-var DragBox = class extends Pointer_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- super();
- this.on;
- this.once;
- this.un;
- options = options ?? {};
- this.box_ = new Box_default(options.className || "ol-dragbox");
- this.minArea_ = options.minArea ?? 64;
- if (options.onBoxEnd) {
- this.onBoxEnd = options.onBoxEnd;
- }
- this.startPixel_ = null;
- this.condition_ = options.condition ?? mouseActionButton;
- this.boxEndCondition_ = options.boxEndCondition ?? this.defaultBoxEndCondition;
- }
- /**
- * The default condition for determining whether the boxend event
- * should fire.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent The originating MapBrowserEvent
- * leading to the box end.
- * @param {import("../pixel.js").Pixel} startPixel The starting pixel of the box.
- * @param {import("../pixel.js").Pixel} endPixel The end pixel of the box.
- * @return {boolean} Whether or not the boxend condition should be fired.
- */
- defaultBoxEndCondition(mapBrowserEvent, startPixel, endPixel) {
- const width = endPixel[0] - startPixel[0];
- const height = endPixel[1] - startPixel[1];
- return width * width + height * height >= this.minArea_;
- }
- /**
- * Returns geometry of last drawn box.
- * @return {import("../geom/Polygon.js").default} Geometry.
- * @api
- */
- getGeometry() {
- return this.box_.getGeometry();
- }
- /**
- * Handle pointer drag events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @override
- */
- handleDragEvent(mapBrowserEvent) {
- if (!this.startPixel_) {
- return;
- }
- this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);
- this.dispatchEvent(
- new DragBoxEvent(
- DragBoxEventType.BOXDRAG,
- mapBrowserEvent.coordinate,
- mapBrowserEvent
- )
- );
- }
- /**
- * Handle pointer up events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleUpEvent(mapBrowserEvent) {
- if (!this.startPixel_) {
- return false;
- }
- const completeBox = this.boxEndCondition_(
- mapBrowserEvent,
- this.startPixel_,
- mapBrowserEvent.pixel
- );
- if (completeBox) {
- this.onBoxEnd(mapBrowserEvent);
- }
- this.dispatchEvent(
- new DragBoxEvent(
- completeBox ? DragBoxEventType.BOXEND : DragBoxEventType.BOXCANCEL,
- mapBrowserEvent.coordinate,
- mapBrowserEvent
- )
- );
- this.box_.setMap(null);
- this.startPixel_ = null;
- return false;
- }
- /**
- * Handle pointer down events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleDownEvent(mapBrowserEvent) {
- if (this.condition_(mapBrowserEvent)) {
- this.startPixel_ = mapBrowserEvent.pixel;
- this.box_.setMap(mapBrowserEvent.map);
- this.box_.setPixels(this.startPixel_, this.startPixel_);
- this.dispatchEvent(
- new DragBoxEvent(
- DragBoxEventType.BOXSTART,
- mapBrowserEvent.coordinate,
- mapBrowserEvent
- )
- );
- return true;
- }
- return false;
- }
- /**
- * Function to execute just before `onboxend` is fired
- * @param {import("../MapBrowserEvent.js").default} event Event.
- */
- onBoxEnd(event) {
- }
- /**
- * Activate or deactivate the interaction.
- * @param {boolean} active Active.
- * @observable
- * @api
- * @override
- */
- setActive(active) {
- if (!active) {
- this.box_.setMap(null);
- if (this.startPixel_) {
- this.dispatchEvent(
- new DragBoxEvent(DragBoxEventType.BOXCANCEL, this.startPixel_, null)
- );
- this.startPixel_ = null;
- }
- }
- super.setActive(active);
- }
- /**
- * @param {import("../Map.js").default|null} map Map.
- * @override
- */
- setMap(map) {
- const oldMap = this.getMap();
- if (oldMap) {
- this.box_.setMap(null);
- if (this.startPixel_) {
- this.dispatchEvent(
- new DragBoxEvent(DragBoxEventType.BOXCANCEL, this.startPixel_, null)
- );
- this.startPixel_ = null;
- }
- }
- super.setMap(map);
- }
-};
-var DragBox_default = DragBox;
-
-// node_modules/ol/interaction/DragZoom.js
-var DragZoom = class extends DragBox_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- options = options ? options : {};
- const condition = options.condition ? options.condition : shiftKeyOnly;
- super({
- condition,
- className: options.className || "ol-dragzoom",
- minArea: options.minArea
- });
- this.duration_ = options.duration !== void 0 ? options.duration : 200;
- this.out_ = options.out !== void 0 ? options.out : false;
- }
- /**
- * Function to execute just before `onboxend` is fired
- * @param {import("../MapBrowserEvent.js").default} event Event.
- * @override
- */
- onBoxEnd(event) {
- const map = this.getMap();
- const view = (
- /** @type {!import("../View.js").default} */
- map.getView()
- );
- let geometry = this.getGeometry();
- if (this.out_) {
- const rotatedExtent = view.rotatedExtentForGeometry(geometry);
- const resolution = view.getResolutionForExtentInternal(rotatedExtent);
- const factor = view.getResolution() / resolution;
- geometry = geometry.clone();
- geometry.scale(factor * factor);
- }
- view.fitInternal(geometry, {
- duration: this.duration_,
- easing: easeOut
- });
- }
-};
-var DragZoom_default = DragZoom;
-
-// node_modules/ol/events/Key.js
-var Key_default = {
- LEFT: "ArrowLeft",
- UP: "ArrowUp",
- RIGHT: "ArrowRight",
- DOWN: "ArrowDown"
-};
-
-// node_modules/ol/interaction/KeyboardPan.js
-var KeyboardPan = class extends Interaction_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- super();
- options = options || {};
- this.defaultCondition_ = function(mapBrowserEvent) {
- return noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent);
- };
- this.condition_ = options.condition !== void 0 ? options.condition : this.defaultCondition_;
- this.duration_ = options.duration !== void 0 ? options.duration : 100;
- this.pixelDelta_ = options.pixelDelta !== void 0 ? options.pixelDelta : 128;
- }
- /**
- * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a
- * `KeyEvent`, and decides the direction to pan to (if an arrow key was
- * pressed).
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @override
- */
- handleEvent(mapBrowserEvent) {
- let stopEvent = false;
- if (mapBrowserEvent.type == EventType_default.KEYDOWN) {
- const keyEvent = (
- /** @type {KeyboardEvent} */
- mapBrowserEvent.originalEvent
- );
- const key = keyEvent.key;
- if (this.condition_(mapBrowserEvent) && (key == Key_default.DOWN || key == Key_default.LEFT || key == Key_default.RIGHT || key == Key_default.UP)) {
- const map = mapBrowserEvent.map;
- const view = map.getView();
- const mapUnitsDelta = view.getResolution() * this.pixelDelta_;
- let deltaX = 0, deltaY = 0;
- if (key == Key_default.DOWN) {
- deltaY = -mapUnitsDelta;
- } else if (key == Key_default.LEFT) {
- deltaX = -mapUnitsDelta;
- } else if (key == Key_default.RIGHT) {
- deltaX = mapUnitsDelta;
- } else {
- deltaY = mapUnitsDelta;
- }
- const delta = [deltaX, deltaY];
- rotate(delta, view.getRotation());
- pan(view, delta, this.duration_);
- keyEvent.preventDefault();
- stopEvent = true;
- }
- }
- return !stopEvent;
- }
-};
-var KeyboardPan_default = KeyboardPan;
-
-// node_modules/ol/interaction/KeyboardZoom.js
-var KeyboardZoom = class extends Interaction_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- super();
- options = options ? options : {};
- this.condition_ = options.condition ? options.condition : function(mapBrowserEvent) {
- return !platformModifierKey(mapBrowserEvent) && targetNotEditable(mapBrowserEvent);
- };
- this.delta_ = options.delta ? options.delta : 1;
- this.duration_ = options.duration !== void 0 ? options.duration : 100;
- }
- /**
- * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a
- * `KeyEvent`, and decides whether to zoom in or out (depending on whether the
- * key pressed was '+' or '-').
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @override
- */
- handleEvent(mapBrowserEvent) {
- let stopEvent = false;
- if (mapBrowserEvent.type == EventType_default.KEYDOWN || mapBrowserEvent.type == EventType_default.KEYPRESS) {
- const keyEvent = (
- /** @type {KeyboardEvent} */
- mapBrowserEvent.originalEvent
- );
- const key = keyEvent.key;
- if (this.condition_(mapBrowserEvent) && (key === "+" || key === "-")) {
- const map = mapBrowserEvent.map;
- const delta = key === "+" ? this.delta_ : -this.delta_;
- const view = map.getView();
- zoomByDelta(view, delta, void 0, this.duration_);
- keyEvent.preventDefault();
- stopEvent = true;
- }
- }
- return !stopEvent;
- }
-};
-var KeyboardZoom_default = KeyboardZoom;
-
-// node_modules/ol/interaction/MouseWheelZoom.js
-var MouseWheelZoom = class extends Interaction_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- options = options ? options : {};
- super(
- /** @type {import("./Interaction.js").InteractionOptions} */
- options
- );
- this.totalDelta_ = 0;
- this.lastDelta_ = 0;
- this.maxDelta_ = options.maxDelta !== void 0 ? options.maxDelta : 1;
- this.duration_ = options.duration !== void 0 ? options.duration : 250;
- this.timeout_ = options.timeout !== void 0 ? options.timeout : 80;
- this.useAnchor_ = options.useAnchor !== void 0 ? options.useAnchor : true;
- this.constrainResolution_ = options.constrainResolution !== void 0 ? options.constrainResolution : false;
- const condition = options.condition ? options.condition : always;
- this.condition_ = options.onFocusOnly ? all(focusWithTabindex, condition) : condition;
- this.lastAnchor_ = null;
- this.startTime_ = void 0;
- this.timeoutId_;
- this.mode_ = void 0;
- this.trackpadEventGap_ = 400;
- this.trackpadTimeoutId_;
- this.deltaPerZoom_ = 300;
- }
- /**
- * @private
- */
- endInteraction_() {
- this.trackpadTimeoutId_ = void 0;
- const map = this.getMap();
- if (!map) {
- return;
- }
- const view = map.getView();
- view.endInteraction(
- void 0,
- this.lastDelta_ ? this.lastDelta_ > 0 ? 1 : -1 : 0,
- this.lastAnchor_ ? map.getCoordinateFromPixel(this.lastAnchor_) : null
- );
- }
- /**
- * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually
- * zooms the map.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
- * @return {boolean} `false` to stop event propagation.
- * @override
- */
- handleEvent(mapBrowserEvent) {
- if (!this.condition_(mapBrowserEvent)) {
- return true;
- }
- const type = mapBrowserEvent.type;
- if (type !== EventType_default.WHEEL) {
- return true;
- }
- const map = mapBrowserEvent.map;
- const wheelEvent = (
- /** @type {WheelEvent} */
- mapBrowserEvent.originalEvent
- );
- wheelEvent.preventDefault();
- if (this.useAnchor_) {
- this.lastAnchor_ = mapBrowserEvent.pixel;
- }
- let delta;
- if (mapBrowserEvent.type == EventType_default.WHEEL) {
- delta = wheelEvent.deltaY;
- if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
- delta /= DEVICE_PIXEL_RATIO;
- }
- if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {
- delta *= 40;
- }
- }
- if (delta === 0) {
- return false;
- }
- this.lastDelta_ = delta;
- const now = Date.now();
- if (this.startTime_ === void 0) {
- this.startTime_ = now;
- }
- if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {
- this.mode_ = Math.abs(delta) < 4 ? "trackpad" : "wheel";
- }
- const view = map.getView();
- if (this.mode_ === "trackpad" && !(view.getConstrainResolution() || this.constrainResolution_)) {
- if (this.trackpadTimeoutId_) {
- clearTimeout(this.trackpadTimeoutId_);
- } else {
- if (view.getAnimating()) {
- view.cancelAnimations();
- }
- view.beginInteraction();
- }
- this.trackpadTimeoutId_ = setTimeout(
- this.endInteraction_.bind(this),
- this.timeout_
- );
- view.adjustZoom(
- -delta / this.deltaPerZoom_,
- this.lastAnchor_ ? map.getCoordinateFromPixel(this.lastAnchor_) : null
- );
- this.startTime_ = now;
- return false;
- }
- this.totalDelta_ += delta;
- const timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);
- clearTimeout(this.timeoutId_);
- this.timeoutId_ = setTimeout(
- this.handleWheelZoom_.bind(this, map),
- timeLeft
- );
- return false;
- }
- /**
- * @private
- * @param {import("../Map.js").default} map Map.
- */
- handleWheelZoom_(map) {
- const view = map.getView();
- if (view.getAnimating()) {
- view.cancelAnimations();
- }
- let delta = -clamp(
- this.totalDelta_,
- -this.maxDelta_ * this.deltaPerZoom_,
- this.maxDelta_ * this.deltaPerZoom_
- ) / this.deltaPerZoom_;
- if (view.getConstrainResolution() || this.constrainResolution_) {
- delta = delta ? delta > 0 ? 1 : -1 : 0;
- }
- zoomByDelta(
- view,
- delta,
- this.lastAnchor_ ? map.getCoordinateFromPixel(this.lastAnchor_) : null,
- this.duration_
- );
- this.mode_ = void 0;
- this.totalDelta_ = 0;
- this.lastAnchor_ = null;
- this.startTime_ = void 0;
- this.timeoutId_ = void 0;
- }
- /**
- * Enable or disable using the mouse's location as an anchor when zooming
- * @param {boolean} useAnchor true to zoom to the mouse's location, false
- * to zoom to the center of the map
- * @api
- */
- setMouseAnchor(useAnchor) {
- this.useAnchor_ = useAnchor;
- if (!useAnchor) {
- this.lastAnchor_ = null;
- }
- }
-};
-var MouseWheelZoom_default = MouseWheelZoom;
-
-// node_modules/ol/interaction/PinchRotate.js
-var PinchRotate = class extends Pointer_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- options = options ? options : {};
- const pointerOptions = (
- /** @type {import("./Pointer.js").Options} */
- options
- );
- if (!pointerOptions.stopDown) {
- pointerOptions.stopDown = FALSE;
- }
- super(pointerOptions);
- this.anchor_ = null;
- this.lastAngle_ = void 0;
- this.rotating_ = false;
- this.rotationDelta_ = 0;
- this.threshold_ = options.threshold !== void 0 ? options.threshold : 0.3;
- this.duration_ = options.duration !== void 0 ? options.duration : 250;
- }
- /**
- * Handle pointer drag events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @override
- */
- handleDragEvent(mapBrowserEvent) {
- let rotationDelta = 0;
- const touch0 = this.targetPointers[0];
- const touch1 = this.targetPointers[1];
- const angle = Math.atan2(
- touch1.clientY - touch0.clientY,
- touch1.clientX - touch0.clientX
- );
- if (this.lastAngle_ !== void 0) {
- const delta = angle - this.lastAngle_;
- this.rotationDelta_ += delta;
- if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {
- this.rotating_ = true;
- }
- rotationDelta = delta;
- }
- this.lastAngle_ = angle;
- const map = mapBrowserEvent.map;
- const view = map.getView();
- if (view.getConstraints().rotation === disable) {
- return;
- }
- this.anchor_ = map.getCoordinateFromPixelInternal(
- map.getEventPixel(centroid(this.targetPointers))
- );
- if (this.rotating_) {
- map.render();
- view.adjustRotationInternal(rotationDelta, this.anchor_);
- }
- }
- /**
- * Handle pointer up events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleUpEvent(mapBrowserEvent) {
- if (this.targetPointers.length < 2) {
- const map = mapBrowserEvent.map;
- const view = map.getView();
- view.endInteraction(this.duration_);
- return false;
- }
- return true;
- }
- /**
- * Handle pointer down events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleDownEvent(mapBrowserEvent) {
- if (this.targetPointers.length >= 2) {
- const map = mapBrowserEvent.map;
- this.anchor_ = null;
- this.lastAngle_ = void 0;
- this.rotating_ = false;
- this.rotationDelta_ = 0;
- if (!this.handlingDownUpSequence) {
- map.getView().beginInteraction();
- }
- return true;
- }
- return false;
- }
-};
-var PinchRotate_default = PinchRotate;
-
-// node_modules/ol/interaction/PinchZoom.js
-var PinchZoom = class extends Pointer_default {
- /**
- * @param {Options} [options] Options.
- */
- constructor(options) {
- options = options ? options : {};
- const pointerOptions = (
- /** @type {import("./Pointer.js").Options} */
- options
- );
- if (!pointerOptions.stopDown) {
- pointerOptions.stopDown = FALSE;
- }
- super(pointerOptions);
- this.anchor_ = null;
- this.duration_ = options.duration !== void 0 ? options.duration : 400;
- this.lastDistance_ = void 0;
- this.lastScaleDelta_ = 1;
- }
- /**
- * Handle pointer drag events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @override
- */
- handleDragEvent(mapBrowserEvent) {
- let scaleDelta = 1;
- const touch0 = this.targetPointers[0];
- const touch1 = this.targetPointers[1];
- const dx = touch0.clientX - touch1.clientX;
- const dy = touch0.clientY - touch1.clientY;
- const distance = Math.sqrt(dx * dx + dy * dy);
- if (this.lastDistance_ !== void 0) {
- scaleDelta = this.lastDistance_ / distance;
- }
- this.lastDistance_ = distance;
- const map = mapBrowserEvent.map;
- const view = map.getView();
- if (scaleDelta != 1) {
- this.lastScaleDelta_ = scaleDelta;
- }
- this.anchor_ = map.getCoordinateFromPixelInternal(
- map.getEventPixel(centroid(this.targetPointers))
- );
- map.render();
- view.adjustResolutionInternal(scaleDelta, this.anchor_);
- }
- /**
- * Handle pointer up events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleUpEvent(mapBrowserEvent) {
- if (this.targetPointers.length < 2) {
- const map = mapBrowserEvent.map;
- const view = map.getView();
- const direction = this.lastScaleDelta_ > 1 ? 1 : -1;
- view.endInteraction(this.duration_, direction);
- return false;
- }
- return true;
- }
- /**
- * Handle pointer down events.
- * @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Event.
- * @return {boolean} If the event was consumed.
- * @override
- */
- handleDownEvent(mapBrowserEvent) {
- if (this.targetPointers.length >= 2) {
- const map = mapBrowserEvent.map;
- this.anchor_ = null;
- this.lastDistance_ = void 0;
- this.lastScaleDelta_ = 1;
- if (!this.handlingDownUpSequence) {
- map.getView().beginInteraction();
- }
- return true;
- }
- return false;
- }
-};
-var PinchZoom_default = PinchZoom;
-
-// node_modules/ol/interaction/defaults.js
-function defaults2(options) {
- options = options ? options : {};
- const interactions = new Collection_default();
- const kinetic = new Kinetic_default(-5e-3, 0.05, 100);
- const altShiftDragRotate = options.altShiftDragRotate !== void 0 ? options.altShiftDragRotate : true;
- if (altShiftDragRotate) {
- interactions.push(new DragRotate_default());
- }
- const doubleClickZoom = options.doubleClickZoom !== void 0 ? options.doubleClickZoom : true;
- if (doubleClickZoom) {
- interactions.push(
- new DoubleClickZoom_default({
- delta: options.zoomDelta,
- duration: options.zoomDuration
- })
- );
- }
- const dragPan = options.dragPan !== void 0 ? options.dragPan : true;
- if (dragPan) {
- interactions.push(
- new DragPan_default({
- onFocusOnly: options.onFocusOnly,
- kinetic
- })
- );
- }
- const pinchRotate = options.pinchRotate !== void 0 ? options.pinchRotate : true;
- if (pinchRotate) {
- interactions.push(new PinchRotate_default());
- }
- const pinchZoom = options.pinchZoom !== void 0 ? options.pinchZoom : true;
- if (pinchZoom) {
- interactions.push(
- new PinchZoom_default({
- duration: options.zoomDuration
- })
- );
- }
- const keyboard = options.keyboard !== void 0 ? options.keyboard : true;
- if (keyboard) {
- interactions.push(new KeyboardPan_default());
- interactions.push(
- new KeyboardZoom_default({
- delta: options.zoomDelta,
- duration: options.zoomDuration
- })
- );
- }
- const mouseWheelZoom = options.mouseWheelZoom !== void 0 ? options.mouseWheelZoom : true;
- if (mouseWheelZoom) {
- interactions.push(
- new MouseWheelZoom_default({
- onFocusOnly: options.onFocusOnly,
- duration: options.zoomDuration
- })
- );
- }
- const shiftDragZoom = options.shiftDragZoom !== void 0 ? options.shiftDragZoom : true;
- if (shiftDragZoom) {
- interactions.push(
- new DragZoom_default({
- duration: options.zoomDuration
- })
- );
- }
- return interactions;
-}
-
// node_modules/ol/layer/Group.js
var GroupEvent = class extends Event_default {
/**
@@ -4294,8 +3122,8 @@ var Map = class extends Object_default {
this.targetChangeHandlerKeys_ = null;
this.targetElement_ = null;
this.resizeObserver_ = new ResizeObserver(() => this.updateSize());
- this.controls = optionsInternal.controls || defaults();
- this.interactions = optionsInternal.interactions || defaults2({
+ this.controls = optionsInternal.controls || defaults2();
+ this.interactions = optionsInternal.interactions || defaults({
onFocusOnly: true
});
this.overlays_ = optionsInternal.overlays;
diff --git a/VentusFlowWebGUI/node_modules/.vite/deps/ol.js.map b/VentusFlowWebGUI/node_modules/.vite/deps/ol.js.map
index ca947cf..f82b205 100644
--- a/VentusFlowWebGUI/node_modules/.vite/deps/ol.js.map
+++ b/VentusFlowWebGUI/node_modules/.vite/deps/ol.js.map
@@ -1,7 +1,7 @@
{
"version": 3,
- "sources": ["../../ol/Geolocation.js", "../../ol/geom/flat/geodesic.js", "../../ol/render.js", "../../ol/layer/Graticule.js", "../../ol/ImageCanvas.js", "../../ol/Kinetic.js", "../../ol/pointer/EventType.js", "../../ol/MapBrowserEventHandler.js", "../../ol/MapEventType.js", "../../ol/MapProperty.js", "../../ol/structs/PriorityQueue.js", "../../ol/TileQueue.js", "../../ol/control/Control.js", "../../ol/control/Attribution.js", "../../ol/control/Rotate.js", "../../ol/control/Zoom.js", "../../ol/control/defaults.js", "../../ol/interaction/DoubleClickZoom.js", "../../ol/interaction/DragPan.js", "../../ol/interaction/DragRotate.js", "../../ol/render/Box.js", "../../ol/interaction/DragBox.js", "../../ol/interaction/DragZoom.js", "../../ol/events/Key.js", "../../ol/interaction/KeyboardPan.js", "../../ol/interaction/KeyboardZoom.js", "../../ol/interaction/MouseWheelZoom.js", "../../ol/interaction/PinchRotate.js", "../../ol/interaction/PinchZoom.js", "../../ol/interaction/defaults.js", "../../ol/layer/Group.js", "../../ol/renderer/Map.js", "../../ol/renderer/Composite.js", "../../ol/Map.js", "../../ol/Overlay.js", "../../ol/VectorRenderTile.js", "../../ol/VectorTile.js"],
- "sourcesContent": ["/**\n * @module ol/Geolocation\n */\nimport BaseObject from './Object.js';\nimport BaseEvent from './events/Event.js';\nimport {circular as circularPolygon} from './geom/Polygon.js';\nimport {toRadians} from './math.js';\nimport {\n get as getProjection,\n getTransformFromProjections,\n identityTransform,\n} from './proj.js';\n\n/**\n * @enum {string}\n */\nconst Property = {\n ACCURACY: 'accuracy',\n ACCURACY_GEOMETRY: 'accuracyGeometry',\n ALTITUDE: 'altitude',\n ALTITUDE_ACCURACY: 'altitudeAccuracy',\n HEADING: 'heading',\n POSITION: 'position',\n PROJECTION: 'projection',\n SPEED: 'speed',\n TRACKING: 'tracking',\n TRACKING_OPTIONS: 'trackingOptions',\n};\n\n/**\n * @enum string\n */\nconst GeolocationErrorType = {\n /**\n * Triggered when a `GeolocationPositionError` occurs.\n * @event module:ol/Geolocation.GeolocationError#error\n * @api\n */\n ERROR: 'error',\n};\n\n/**\n * @classdesc\n * Events emitted on [GeolocationPositionError](https://developer.mozilla.org/en-US/docs/Web/API/GeolocationPositionError).\n */\nexport class GeolocationError extends BaseEvent {\n /**\n * @param {GeolocationPositionError} error error object.\n */\n constructor(error) {\n super(GeolocationErrorType.ERROR);\n\n /**\n * Code of the underlying `GeolocationPositionError`.\n * @type {number}\n * @api\n */\n this.code = error.code;\n\n /**\n * Message of the underlying `GeolocationPositionError`.\n * @type {string}\n * @api\n */\n this.message = error.message;\n }\n}\n\n/**\n * @typedef {Object} Options\n * @property {boolean} [tracking=false] Start Tracking right after\n * instantiation.\n * @property {PositionOptions} [trackingOptions] Tracking options.\n * See https://www.w3.org/TR/geolocation-API/#position_options_interface.\n * @property {import(\"./proj.js\").ProjectionLike} [projection] The projection the position\n * is reported in.\n */\n\n/**\n * @typedef {import(\"./ObjectEventType\").Types|'change:accuracy'|'change:accuracyGeometry'|'change:altitude'|\n * 'change:altitudeAccuracy'|'change:heading'|'change:position'|'change:projection'|'change:speed'|'change:tracking'|\n * 'change:trackingOptions'} GeolocationObjectEventTypes\n */\n\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature &\n * import(\"./Observable\").OnSignature<'error', GeolocationError, Return> &\n * import(\"./Observable\").CombinedOnSignature &\n * import(\"./Observable\").OnSignature} GeolocationOnSignature\n */\n\n/**\n * @classdesc\n * Helper class for providing HTML5 Geolocation capabilities.\n * The [Geolocation API](https://www.w3.org/TR/geolocation-API/)\n * is used to locate a user's position.\n *\n * To get notified of position changes and errors, register listeners for the generic\n * `change` event and the `error` event on your instance of {@link module:ol/Geolocation~Geolocation}.\n *\n * Example:\n *\n * const geolocation = new Geolocation({\n * // take the projection to use from the map's view\n * projection: view.getProjection()\n * });\n * // listen to changes in position\n * geolocation.on('change', function(evt) {\n * console.log(geolocation.getPosition());\n * });\n * // listen to error\n * geolocation.on('error', function(evt) {\n * window.console.log(evt.message);\n * });\n *\n * @fires GeolocationError\n * @api\n */\nclass Geolocation extends BaseObject {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n super();\n\n /***\n * @type {GeolocationOnSignature}\n */\n this.on;\n\n /***\n * @type {GeolocationOnSignature}\n */\n this.once;\n\n /***\n * @type {GeolocationOnSignature}\n */\n this.un;\n\n options = options || {};\n\n /**\n * The unprojected (EPSG:4326) device position.\n * @private\n * @type {?import(\"./coordinate.js\").Coordinate}\n */\n this.position_ = null;\n\n /**\n * @private\n * @type {import(\"./proj.js\").TransformFunction}\n */\n this.transform_ = identityTransform;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.watchId_ = undefined;\n\n this.addChangeListener(Property.PROJECTION, this.handleProjectionChanged_);\n this.addChangeListener(Property.TRACKING, this.handleTrackingChanged_);\n\n if (options.projection !== undefined) {\n this.setProjection(options.projection);\n }\n if (options.trackingOptions !== undefined) {\n this.setTrackingOptions(options.trackingOptions);\n }\n\n this.setTracking(options.tracking !== undefined ? options.tracking : false);\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n this.setTracking(false);\n super.disposeInternal();\n }\n\n /**\n * @private\n */\n handleProjectionChanged_() {\n const projection = this.getProjection();\n if (projection) {\n this.transform_ = getTransformFromProjections(\n getProjection('EPSG:4326'),\n projection,\n );\n if (this.position_) {\n this.set(Property.POSITION, this.transform_(this.position_));\n }\n }\n }\n\n /**\n * @private\n */\n handleTrackingChanged_() {\n if ('geolocation' in navigator) {\n const tracking = this.getTracking();\n if (tracking && this.watchId_ === undefined) {\n this.watchId_ = navigator.geolocation.watchPosition(\n this.positionChange_.bind(this),\n this.positionError_.bind(this),\n this.getTrackingOptions(),\n );\n } else if (!tracking && this.watchId_ !== undefined) {\n navigator.geolocation.clearWatch(this.watchId_);\n this.watchId_ = undefined;\n }\n }\n }\n\n /**\n * @private\n * @param {GeolocationPosition} position position event.\n */\n positionChange_(position) {\n const coords = position.coords;\n this.set(Property.ACCURACY, coords.accuracy);\n this.set(\n Property.ALTITUDE,\n coords.altitude === null ? undefined : coords.altitude,\n );\n this.set(\n Property.ALTITUDE_ACCURACY,\n coords.altitudeAccuracy === null ? undefined : coords.altitudeAccuracy,\n );\n this.set(\n Property.HEADING,\n coords.heading === null ? undefined : toRadians(coords.heading),\n );\n if (!this.position_) {\n this.position_ = [coords.longitude, coords.latitude];\n } else {\n this.position_[0] = coords.longitude;\n this.position_[1] = coords.latitude;\n }\n const projectedPosition = this.transform_(this.position_);\n this.set(Property.POSITION, projectedPosition.slice());\n this.set(Property.SPEED, coords.speed === null ? undefined : coords.speed);\n const geometry = circularPolygon(this.position_, coords.accuracy);\n geometry.applyTransform(this.transform_);\n this.set(Property.ACCURACY_GEOMETRY, geometry);\n this.changed();\n }\n\n /**\n * @private\n * @param {GeolocationPositionError} error error object.\n */\n positionError_(error) {\n this.dispatchEvent(new GeolocationError(error));\n }\n\n /**\n * Get the accuracy of the position in meters.\n * @return {number|undefined} The accuracy of the position measurement in\n * meters.\n * @observable\n * @api\n */\n getAccuracy() {\n return /** @type {number|undefined} */ (this.get(Property.ACCURACY));\n }\n\n /**\n * Get a geometry of the position accuracy.\n * @return {?import(\"./geom/Polygon.js\").default} A geometry of the position accuracy.\n * @observable\n * @api\n */\n getAccuracyGeometry() {\n return /** @type {?import(\"./geom/Polygon.js\").default} */ (\n this.get(Property.ACCURACY_GEOMETRY) || null\n );\n }\n\n /**\n * Get the altitude associated with the position.\n * @return {number|undefined} The altitude of the position in meters above mean\n * sea level.\n * @observable\n * @api\n */\n getAltitude() {\n return /** @type {number|undefined} */ (this.get(Property.ALTITUDE));\n }\n\n /**\n * Get the altitude accuracy of the position.\n * @return {number|undefined} The accuracy of the altitude measurement in\n * meters.\n * @observable\n * @api\n */\n getAltitudeAccuracy() {\n return /** @type {number|undefined} */ (\n this.get(Property.ALTITUDE_ACCURACY)\n );\n }\n\n /**\n * Get the heading as radians clockwise from North.\n * Note: depending on the browser, the heading is only defined if the `enableHighAccuracy`\n * is set to `true` in the tracking options.\n * @return {number|undefined} The heading of the device in radians from north.\n * @observable\n * @api\n */\n getHeading() {\n return /** @type {number|undefined} */ (this.get(Property.HEADING));\n }\n\n /**\n * Get the position of the device.\n * @return {import(\"./coordinate.js\").Coordinate|undefined} The current position of the device reported\n * in the current projection.\n * @observable\n * @api\n */\n getPosition() {\n return /** @type {import(\"./coordinate.js\").Coordinate|undefined} */ (\n this.get(Property.POSITION)\n );\n }\n\n /**\n * Get the projection associated with the position.\n * @return {import(\"./proj/Projection.js\").default|undefined} The projection the position is\n * reported in.\n * @observable\n * @api\n */\n getProjection() {\n return /** @type {import(\"./proj/Projection.js\").default|undefined} */ (\n this.get(Property.PROJECTION)\n );\n }\n\n /**\n * Get the speed in meters per second.\n * @return {number|undefined} The instantaneous speed of the device in meters\n * per second.\n * @observable\n * @api\n */\n getSpeed() {\n return /** @type {number|undefined} */ (this.get(Property.SPEED));\n }\n\n /**\n * Determine if the device location is being tracked.\n * @return {boolean} The device location is being tracked.\n * @observable\n * @api\n */\n getTracking() {\n return /** @type {boolean} */ (this.get(Property.TRACKING));\n }\n\n /**\n * Get the tracking options.\n * See https://www.w3.org/TR/geolocation-API/#position-options.\n * @return {PositionOptions|undefined} PositionOptions as defined by\n * the [HTML5 Geolocation spec\n * ](https://www.w3.org/TR/geolocation-API/#position_options_interface).\n * @observable\n * @api\n */\n getTrackingOptions() {\n return /** @type {PositionOptions|undefined} */ (\n this.get(Property.TRACKING_OPTIONS)\n );\n }\n\n /**\n * Set the projection to use for transforming the coordinates.\n * @param {import(\"./proj.js\").ProjectionLike} projection The projection the position is\n * reported in.\n * @observable\n * @api\n */\n setProjection(projection) {\n this.set(Property.PROJECTION, getProjection(projection));\n }\n\n /**\n * Enable or disable tracking.\n * @param {boolean} tracking Enable tracking.\n * @observable\n * @api\n */\n setTracking(tracking) {\n this.set(Property.TRACKING, tracking);\n }\n\n /**\n * Set the tracking options.\n * See http://www.w3.org/TR/geolocation-API/#position-options.\n * @param {PositionOptions} options PositionOptions as defined by the\n * [HTML5 Geolocation spec\n * ](http://www.w3.org/TR/geolocation-API/#position_options_interface).\n * @observable\n * @api\n */\n setTrackingOptions(options) {\n this.set(Property.TRACKING_OPTIONS, options);\n }\n}\n\nexport default Geolocation;\n", "/**\n * @module ol/geom/flat/geodesic\n */\nimport {squaredSegmentDistance, toDegrees, toRadians} from '../../math.js';\nimport {get as getProjection, getTransform} from '../../proj.js';\n\n/**\n * @param {function(number): import(\"../../coordinate.js\").Coordinate} interpolate Interpolate function.\n * @param {import(\"../../proj.js\").TransformFunction} transform Transform from longitude/latitude to\n * projected coordinates.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array} Flat coordinates.\n */\nfunction line(interpolate, transform, squaredTolerance) {\n // FIXME reduce garbage generation\n // FIXME optimize stack operations\n\n /** @type {Array} */\n const flatCoordinates = [];\n\n let geoA = interpolate(0);\n let geoB = interpolate(1);\n\n let a = transform(geoA);\n let b = transform(geoB);\n\n /** @type {Array} */\n const geoStack = [geoB, geoA];\n /** @type {Array} */\n const stack = [b, a];\n /** @type {Array} */\n const fractionStack = [1, 0];\n\n /** @type {!Object} */\n const fractions = {};\n\n let maxIterations = 1e5;\n let geoM, m, fracA, fracB, fracM, key;\n\n while (--maxIterations > 0 && fractionStack.length > 0) {\n // Pop the a coordinate off the stack\n fracA = fractionStack.pop();\n geoA = geoStack.pop();\n a = stack.pop();\n // Add the a coordinate if it has not been added yet\n key = fracA.toString();\n if (!(key in fractions)) {\n flatCoordinates.push(a[0], a[1]);\n fractions[key] = true;\n }\n // Pop the b coordinate off the stack\n fracB = fractionStack.pop();\n geoB = geoStack.pop();\n b = stack.pop();\n // Find the m point between the a and b coordinates\n fracM = (fracA + fracB) / 2;\n geoM = interpolate(fracM);\n m = transform(geoM);\n if (\n squaredSegmentDistance(m[0], m[1], a[0], a[1], b[0], b[1]) <\n squaredTolerance\n ) {\n // If the m point is sufficiently close to the straight line, then we\n // discard it. Just use the b coordinate and move on to the next line\n // segment.\n flatCoordinates.push(b[0], b[1]);\n key = fracB.toString();\n fractions[key] = true;\n } else {\n // Otherwise, we need to subdivide the current line segment. Split it\n // into two and push the two line segments onto the stack.\n fractionStack.push(fracB, fracM, fracM, fracA);\n stack.push(b, m, m, a);\n geoStack.push(geoB, geoM, geoM, geoA);\n }\n }\n\n return flatCoordinates;\n}\n\n/**\n * Generate a great-circle arcs between two lat/lon points.\n * @param {number} lon1 Longitude 1 in degrees.\n * @param {number} lat1 Latitude 1 in degrees.\n * @param {number} lon2 Longitude 2 in degrees.\n * @param {number} lat2 Latitude 2 in degrees.\n * @param {import(\"../../proj/Projection.js\").default} projection Projection.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array} Flat coordinates.\n */\nexport function greatCircleArc(\n lon1,\n lat1,\n lon2,\n lat2,\n projection,\n squaredTolerance,\n) {\n const geoProjection = getProjection('EPSG:4326');\n\n const cosLat1 = Math.cos(toRadians(lat1));\n const sinLat1 = Math.sin(toRadians(lat1));\n const cosLat2 = Math.cos(toRadians(lat2));\n const sinLat2 = Math.sin(toRadians(lat2));\n const cosDeltaLon = Math.cos(toRadians(lon2 - lon1));\n const sinDeltaLon = Math.sin(toRadians(lon2 - lon1));\n const d = sinLat1 * sinLat2 + cosLat1 * cosLat2 * cosDeltaLon;\n\n return line(\n /**\n * @param {number} frac Fraction.\n * @return {import(\"../../coordinate.js\").Coordinate} Coordinate.\n */\n function (frac) {\n if (1 <= d) {\n return [lon2, lat2];\n }\n const D = frac * Math.acos(d);\n const cosD = Math.cos(D);\n const sinD = Math.sin(D);\n const y = sinDeltaLon * cosLat2;\n const x = cosLat1 * sinLat2 - sinLat1 * cosLat2 * cosDeltaLon;\n const theta = Math.atan2(y, x);\n const lat = Math.asin(sinLat1 * cosD + cosLat1 * sinD * Math.cos(theta));\n const lon =\n toRadians(lon1) +\n Math.atan2(\n Math.sin(theta) * sinD * cosLat1,\n cosD - sinLat1 * Math.sin(lat),\n );\n return [toDegrees(lon), toDegrees(lat)];\n },\n getTransform(geoProjection, projection),\n squaredTolerance,\n );\n}\n\n/**\n * Generate a meridian (line at constant longitude).\n * @param {number} lon Longitude.\n * @param {number} lat1 Latitude 1.\n * @param {number} lat2 Latitude 2.\n * @param {import(\"../../proj/Projection.js\").default} projection Projection.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array} Flat coordinates.\n */\nexport function meridian(lon, lat1, lat2, projection, squaredTolerance) {\n const epsg4326Projection = getProjection('EPSG:4326');\n return line(\n /**\n * @param {number} frac Fraction.\n * @return {import(\"../../coordinate.js\").Coordinate} Coordinate.\n */\n function (frac) {\n return [lon, lat1 + (lat2 - lat1) * frac];\n },\n getTransform(epsg4326Projection, projection),\n squaredTolerance,\n );\n}\n\n/**\n * Generate a parallel (line at constant latitude).\n * @param {number} lat Latitude.\n * @param {number} lon1 Longitude 1.\n * @param {number} lon2 Longitude 2.\n * @param {import(\"../../proj/Projection.js\").default} projection Projection.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {Array} Flat coordinates.\n */\nexport function parallel(lat, lon1, lon2, projection, squaredTolerance) {\n const epsg4326Projection = getProjection('EPSG:4326');\n return line(\n /**\n * @param {number} frac Fraction.\n * @return {import(\"../../coordinate.js\").Coordinate} Coordinate.\n */\n function (frac) {\n return [lon1 + (lon2 - lon1) * frac, lat];\n },\n getTransform(epsg4326Projection, projection),\n squaredTolerance,\n );\n}\n", "/**\n * @module ol/render\n */\nimport {DEVICE_PIXEL_RATIO} from './has.js';\nimport {getTransformFromProjections, getUserProjection} from './proj.js';\nimport CanvasImmediateRenderer from './render/canvas/Immediate.js';\nimport {getSquaredTolerance} from './renderer/vector.js';\nimport {\n apply as applyTransform,\n create as createTransform,\n multiply as multiplyTransform,\n scale as scaleTransform,\n} from './transform.js';\n\n/**\n * @typedef {Object} State\n * @property {CanvasRenderingContext2D} context Canvas context that the layer is being rendered to.\n * @property {import(\"./Feature.js\").FeatureLike} feature Feature.\n * @property {import(\"./geom/SimpleGeometry.js\").default} geometry Geometry.\n * @property {number} pixelRatio Pixel ratio used by the layer renderer.\n * @property {number} resolution Resolution that the render batch was created and optimized for.\n * This is not the view's resolution that is being rendered.\n * @property {number} rotation Rotation of the rendered layer in radians.\n */\n\n/**\n * A function to be used when sorting features before rendering.\n * It takes two instances of {@link module:ol/Feature~Feature} or\n * {@link module:ol/render/Feature~RenderFeature} and returns a `{number}`.\n *\n * @typedef {function(import(\"./Feature.js\").FeatureLike, import(\"./Feature.js\").FeatureLike):number} OrderFunction\n */\n\n/**\n * @typedef {Object} ToContextOptions\n * @property {import(\"./size.js\").Size} [size] Desired size of the canvas in css\n * pixels. When provided, both canvas and css size will be set according to the\n * `pixelRatio`. If not provided, the current canvas and css sizes will not be\n * altered.\n * @property {number} [pixelRatio=window.devicePixelRatio] Pixel ratio (canvas\n * pixel to css pixel ratio) for the canvas.\n */\n\n/**\n * Binds a Canvas Immediate API to a canvas context, to allow drawing geometries\n * to the context's canvas.\n *\n * The units for geometry coordinates are css pixels relative to the top left\n * corner of the canvas element.\n * ```js\n * import {toContext} from 'ol/render.js';\n * import Fill from 'ol/style/Fill.js';\n * import Polygon from 'ol/geom/Polygon.js';\n *\n * const canvas = document.createElement('canvas');\n * const render = toContext(\n * canvas.getContext('2d'),\n * {size: [100, 100]}\n * );\n * render.setFillStrokeStyle(new Fill({ color: blue }));\n * render.drawPolygon(\n * new Polygon([[[0, 0], [100, 100], [100, 0], [0, 0]]])\n * );\n * ```\n *\n * @param {CanvasRenderingContext2D} context Canvas context.\n * @param {ToContextOptions} [options] Options.\n * @return {CanvasImmediateRenderer} Canvas Immediate.\n * @api\n */\nexport function toContext(context, options) {\n const canvas = context.canvas;\n options = options ? options : {};\n const pixelRatio = options.pixelRatio || DEVICE_PIXEL_RATIO;\n const size = options.size;\n if (size) {\n canvas.width = size[0] * pixelRatio;\n canvas.height = size[1] * pixelRatio;\n canvas.style.width = size[0] + 'px';\n canvas.style.height = size[1] + 'px';\n }\n const extent = [0, 0, canvas.width, canvas.height];\n const transform = scaleTransform(createTransform(), pixelRatio, pixelRatio);\n return new CanvasImmediateRenderer(context, pixelRatio, extent, transform, 0);\n}\n\n/**\n * Gets a vector context for drawing to the event's canvas.\n * @param {import(\"./render/Event.js\").default} event Render event.\n * @return {CanvasImmediateRenderer} Vector context.\n * @api\n */\nexport function getVectorContext(event) {\n if (!(event.context instanceof CanvasRenderingContext2D)) {\n throw new Error('Only works for render events from Canvas 2D layers');\n }\n\n // canvas may be at a different pixel ratio than frameState.pixelRatio\n const a = event.inversePixelTransform[0];\n const b = event.inversePixelTransform[1];\n const canvasPixelRatio = Math.sqrt(a * a + b * b);\n const frameState = event.frameState;\n const transform = multiplyTransform(\n event.inversePixelTransform.slice(),\n frameState.coordinateToPixelTransform,\n );\n const squaredTolerance = getSquaredTolerance(\n frameState.viewState.resolution,\n canvasPixelRatio,\n );\n let userTransform;\n const userProjection = getUserProjection();\n if (userProjection) {\n userTransform = getTransformFromProjections(\n userProjection,\n frameState.viewState.projection,\n );\n }\n\n return new CanvasImmediateRenderer(\n event.context,\n canvasPixelRatio,\n frameState.extent,\n transform,\n frameState.viewState.rotation,\n squaredTolerance,\n userTransform,\n );\n}\n\n/**\n * Gets the pixel of the event's canvas context from the map viewport's CSS pixel.\n * @param {import(\"./render/Event.js\").default} event Render event.\n * @param {import(\"./pixel.js\").Pixel} pixel CSS pixel relative to the top-left\n * corner of the map viewport.\n * @return {import(\"./pixel.js\").Pixel} Pixel on the event's canvas context.\n * @api\n */\nexport function getRenderPixel(event, pixel) {\n return applyTransform(event.inversePixelTransform, pixel.slice(0));\n}\n", "/**\n * @module ol/layer/Graticule\n */\nimport Collection from '../Collection.js';\nimport Feature from '../Feature.js';\nimport {degreesToStringHDMS} from '../coordinate.js';\nimport {\n applyTransform,\n approximatelyEquals,\n containsCoordinate,\n containsExtent,\n equals,\n getCenter,\n getIntersection,\n getWidth,\n intersects,\n isEmpty,\n wrapX as wrapExtentX,\n} from '../extent.js';\nimport LineString from '../geom/LineString.js';\nimport Point from '../geom/Point.js';\nimport {meridian, parallel} from '../geom/flat/geodesic.js';\nimport {clamp} from '../math.js';\nimport {\n equivalent as equivalentProjection,\n get as getProjection,\n getTransform,\n} from '../proj.js';\nimport EventType from '../render/EventType.js';\nimport {getVectorContext} from '../render.js';\nimport VectorSource from '../source/Vector.js';\nimport Fill from '../style/Fill.js';\nimport Stroke from '../style/Stroke.js';\nimport Style from '../style/Style.js';\nimport Text from '../style/Text.js';\nimport VectorLayer from './Vector.js';\n\n/**\n * @type {Stroke}\n * @private\n * @const\n */\nconst DEFAULT_STROKE_STYLE = new Stroke({\n color: 'rgba(0,0,0,0.2)',\n});\n\n/**\n * @type {Array}\n * @private\n */\nconst INTERVALS = [\n 90,\n 45,\n 30,\n 20,\n 10,\n 5,\n 2,\n 1,\n 30 / 60,\n 20 / 60,\n 10 / 60,\n 5 / 60,\n 2 / 60,\n 1 / 60,\n 30 / 3600,\n 20 / 3600,\n 10 / 3600,\n 5 / 3600,\n 2 / 3600,\n 1 / 3600,\n];\n\n/**\n * @typedef {Object} GraticuleLabelDataType\n * @property {Point} geom Geometry.\n * @property {string} text Text.\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-layer'] A CSS class name to set to the layer element.\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {number} [maxLines=100] The maximum number of meridians and\n * parallels from the center of the map. The default value of 100 means that at\n * most 200 meridians and 200 parallels will be displayed. The default value is\n * appropriate for conformal projections like Spherical Mercator. If you\n * increase the value, more lines will be drawn and the drawing performance will\n * decrease.\n * @property {Stroke} [strokeStyle] The\n * stroke style to use for drawing the graticule. If not provided, the following stroke will be used:\n * ```js\n * new Stroke({\n * color: 'rgba(0, 0, 0, 0.2)' // a not fully opaque black\n * });\n * ```\n * @property {number} [targetSize=100] The target size of the graticule cells,\n * in pixels.\n * @property {boolean} [showLabels=false] Render a label with the respective\n * latitude/longitude for each graticule line.\n * @property {function(number):string} [lonLabelFormatter] Label formatter for\n * longitudes. This function is called with the longitude as argument, and\n * should return a formatted string representing the longitude. By default,\n * labels are formatted as degrees, minutes, seconds and hemisphere.\n * @property {function(number):string} [latLabelFormatter] Label formatter for\n * latitudes. This function is called with the latitude as argument, and\n * should return a formatted string representing the latitude. By default,\n * labels are formatted as degrees, minutes, seconds and hemisphere.\n * @property {number} [lonLabelPosition=0] Longitude label position in fractions\n * (0..1) of view extent. 0 means at the bottom of the viewport, 1 means at the\n * top.\n * @property {number} [latLabelPosition=1] Latitude label position in fractions\n * (0..1) of view extent. 0 means at the left of the viewport, 1 means at the\n * right.\n * @property {Text} [lonLabelStyle] Longitude label text\n * style. If not provided, the following style will be used:\n * ```js\n * new Text({\n * font: '12px Calibri,sans-serif',\n * textBaseline: 'bottom',\n * fill: new Fill({\n * color: 'rgba(0,0,0,1)'\n * }),\n * stroke: new Stroke({\n * color: 'rgba(255,255,255,1)',\n * width: 3\n * })\n * });\n * ```\n * Note that the default's `textBaseline` configuration will not work well for\n * `lonLabelPosition` configurations that position labels close to the top of\n * the viewport.\n * @property {Text} [latLabelStyle] Latitude label text style.\n * If not provided, the following style will be used:\n * ```js\n * new Text({\n * font: '12px Calibri,sans-serif',\n * textAlign: 'end',\n * fill: new Fill({\n * color: 'rgba(0,0,0,1)'\n * }),\n * stroke: Stroke({\n * color: 'rgba(255,255,255,1)',\n * width: 3\n * })\n * });\n * ```\n * Note that the default's `textAlign` configuration will not work well for\n * `latLabelPosition` configurations that position labels close to the left of\n * the viewport.\n * @property {Array} [intervals=[90, 45, 30, 20, 10, 5, 2, 1, 30/60, 20/60, 10/60, 5/60, 2/60, 1/60, 30/3600, 20/3600, 10/3600, 5/3600, 2/3600, 1/3600]]\n * Intervals (in degrees) for the graticule. Example to limit graticules to 30 and 10 degrees intervals:\n * ```js\n * [30, 10]\n * ```\n * @property {boolean} [wrapX=true] Whether to repeat the graticule horizontally.\n * @property {Object} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n\n/**\n * @classdesc\n * Layer that renders a grid for a coordinate system (currently only EPSG:4326 is supported).\n * Note that the view projection must define both extent and worldExtent.\n *\n * @fires import(\"../render/Event.js\").RenderEvent#prerender\n * @fires import(\"../render/Event.js\").RenderEvent#postrender\n * @extends {VectorLayer>}\n * @api\n */\nclass Graticule extends VectorLayer {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {};\n\n const baseOptions = Object.assign(\n {\n updateWhileAnimating: true,\n updateWhileInteracting: true,\n renderBuffer: 0,\n },\n options,\n );\n\n delete baseOptions.maxLines;\n delete baseOptions.strokeStyle;\n delete baseOptions.targetSize;\n delete baseOptions.showLabels;\n delete baseOptions.lonLabelFormatter;\n delete baseOptions.latLabelFormatter;\n delete baseOptions.lonLabelPosition;\n delete baseOptions.latLabelPosition;\n delete baseOptions.lonLabelStyle;\n delete baseOptions.latLabelStyle;\n delete baseOptions.intervals;\n super(baseOptions);\n\n /**\n * @type {import(\"../proj/Projection.js\").default}\n * @private\n */\n this.projection_ = null;\n\n /**\n * @type {number}\n * @private\n */\n this.maxLat_ = Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.maxLon_ = Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.minLat_ = -Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.minLon_ = -Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.maxX_ = Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.maxY_ = Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.minX_ = -Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.minY_ = -Infinity;\n\n /**\n * @type {number}\n * @private\n */\n this.targetSize_ =\n options.targetSize !== undefined ? options.targetSize : 100;\n\n /**\n * @type {number}\n * @private\n */\n this.maxLines_ = options.maxLines !== undefined ? options.maxLines : 100;\n\n /**\n * @type {Array}\n * @private\n */\n this.meridians_ = [];\n\n /**\n * @type {Array}\n * @private\n */\n this.parallels_ = [];\n\n /**\n * @type {Stroke}\n * @private\n */\n this.strokeStyle_ =\n options.strokeStyle !== undefined\n ? options.strokeStyle\n : DEFAULT_STROKE_STYLE;\n\n /**\n * @type {import(\"../proj.js\").TransformFunction|undefined}\n * @private\n */\n this.fromLonLatTransform_ = undefined;\n\n /**\n * @type {import(\"../proj.js\").TransformFunction|undefined}\n * @private\n */\n this.toLonLatTransform_ = undefined;\n\n /**\n * @type {import(\"../coordinate.js\").Coordinate}\n * @private\n */\n this.projectionCenterLonLat_ = null;\n\n /**\n * @type {import(\"../coordinate.js\").Coordinate}\n * @private\n */\n this.bottomLeft_ = null;\n\n /**\n * @type {import(\"../coordinate.js\").Coordinate}\n * @private\n */\n this.bottomRight_ = null;\n\n /**\n * @type {import(\"../coordinate.js\").Coordinate}\n * @private\n */\n this.topLeft_ = null;\n\n /**\n * @type {import(\"../coordinate.js\").Coordinate}\n * @private\n */\n this.topRight_ = null;\n\n /**\n * @type {Array}\n * @private\n */\n this.meridiansLabels_ = null;\n\n /**\n * @type {Array}\n * @private\n */\n this.parallelsLabels_ = null;\n\n if (options.showLabels) {\n /**\n * @type {null|function(number):string}\n * @private\n */\n this.lonLabelFormatter_ =\n options.lonLabelFormatter == undefined\n ? degreesToStringHDMS.bind(this, 'EW')\n : options.lonLabelFormatter;\n\n /**\n * @type {function(number):string}\n * @private\n */\n this.latLabelFormatter_ =\n options.latLabelFormatter == undefined\n ? degreesToStringHDMS.bind(this, 'NS')\n : options.latLabelFormatter;\n\n /**\n * Longitude label position in fractions (0..1) of view extent. 0 means\n * bottom, 1 means top.\n * @type {number}\n * @private\n */\n this.lonLabelPosition_ =\n options.lonLabelPosition == undefined ? 0 : options.lonLabelPosition;\n\n /**\n * Latitude Label position in fractions (0..1) of view extent. 0 means left, 1\n * means right.\n * @type {number}\n * @private\n */\n this.latLabelPosition_ =\n options.latLabelPosition == undefined ? 1 : options.latLabelPosition;\n\n /**\n * @type {Style}\n * @private\n */\n this.lonLabelStyleBase_ = new Style({\n text:\n options.lonLabelStyle !== undefined\n ? options.lonLabelStyle.clone()\n : new Text({\n font: '12px Calibri,sans-serif',\n textBaseline: 'bottom',\n fill: new Fill({\n color: 'rgba(0,0,0,1)',\n }),\n stroke: new Stroke({\n color: 'rgba(255,255,255,1)',\n width: 3,\n }),\n }),\n });\n\n /**\n * @private\n * @param {import(\"../Feature\").default} feature Feature\n * @return {Style} style\n */\n this.lonLabelStyle_ = (feature) => {\n const label = feature.get('graticule_label');\n this.lonLabelStyleBase_.getText().setText(label);\n return this.lonLabelStyleBase_;\n };\n\n /**\n * @type {Style}\n * @private\n */\n this.latLabelStyleBase_ = new Style({\n text:\n options.latLabelStyle !== undefined\n ? options.latLabelStyle.clone()\n : new Text({\n font: '12px Calibri,sans-serif',\n textAlign: 'right',\n fill: new Fill({\n color: 'rgba(0,0,0,1)',\n }),\n stroke: new Stroke({\n color: 'rgba(255,255,255,1)',\n width: 3,\n }),\n }),\n });\n\n /**\n * @private\n * @param {import(\"../Feature\").default} feature Feature\n * @return {Style} style\n */\n this.latLabelStyle_ = (feature) => {\n const label = feature.get('graticule_label');\n this.latLabelStyleBase_.getText().setText(label);\n return this.latLabelStyleBase_;\n };\n\n this.meridiansLabels_ = [];\n this.parallelsLabels_ = [];\n\n this.addEventListener(EventType.POSTRENDER, this.drawLabels_.bind(this));\n }\n\n /**\n * @type {Array}\n * @private\n */\n this.intervals_ =\n options.intervals !== undefined ? options.intervals : INTERVALS;\n\n // use a source with a custom loader for lines & text\n this.setSource(\n new VectorSource({\n loader: this.loaderFunction.bind(this),\n strategy: this.strategyFunction.bind(this),\n features: new Collection(),\n overlaps: false,\n useSpatialIndex: false,\n wrapX: options.wrapX,\n }),\n );\n\n /**\n * feature pool to use when updating graticule\n * @type {Array}\n * @private\n */\n this.featurePool_ = [];\n\n /**\n * @type {Style}\n * @private\n */\n this.lineStyle_ = new Style({\n stroke: this.strokeStyle_,\n });\n\n /**\n * @type {?import(\"../extent.js\").Extent}\n * @private\n */\n this.loadedExtent_ = null;\n\n /**\n * @type {?import(\"../extent.js\").Extent}\n * @private\n */\n this.renderedExtent_ = null;\n\n /**\n * @type {?number}\n * @private\n */\n this.renderedResolution_ = null;\n\n this.setRenderOrder(null);\n }\n\n /**\n * Strategy function for loading features based on the view's extent and\n * resolution.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @return {Array} Extents.\n */\n strategyFunction(extent, resolution) {\n // extents may be passed in different worlds, to avoid endless loop we use only one\n let realWorldExtent = extent.slice();\n if (this.projection_ && this.getSource().getWrapX()) {\n wrapExtentX(realWorldExtent, this.projection_);\n }\n if (this.loadedExtent_) {\n if (\n approximatelyEquals(this.loadedExtent_, realWorldExtent, resolution)\n ) {\n // make sure result is exactly equal to previous extent\n realWorldExtent = this.loadedExtent_.slice();\n } else {\n // we should not keep track of loaded extents\n this.getSource().removeLoadedExtent(this.loadedExtent_);\n }\n }\n return [realWorldExtent];\n }\n\n /**\n * Update geometries in the source based on current view\n * @param {import(\"../extent\").Extent} extent Extent\n * @param {number} resolution Resolution\n * @param {import(\"../proj/Projection.js\").default} projection Projection\n */\n loaderFunction(extent, resolution, projection) {\n this.loadedExtent_ = extent;\n const source = this.getSource();\n\n // only consider the intersection between our own extent & the requested one\n const layerExtent = this.getExtent() || [\n -Infinity,\n -Infinity,\n Infinity,\n Infinity,\n ];\n const renderExtent = getIntersection(layerExtent, extent);\n\n if (\n this.renderedExtent_ &&\n equals(this.renderedExtent_, renderExtent) &&\n this.renderedResolution_ === resolution\n ) {\n return;\n }\n this.renderedExtent_ = renderExtent;\n this.renderedResolution_ = resolution;\n\n // bail out if nothing to render\n if (isEmpty(renderExtent)) {\n return;\n }\n\n // update projection info\n const center = getCenter(renderExtent);\n const squaredTolerance = (resolution * resolution) / 4;\n\n const updateProjectionInfo =\n !this.projection_ || !equivalentProjection(this.projection_, projection);\n\n if (updateProjectionInfo) {\n this.updateProjectionInfo_(projection);\n }\n\n this.createGraticule_(renderExtent, center, resolution, squaredTolerance);\n\n // first make sure we have enough features in the pool\n let featureCount = this.meridians_.length + this.parallels_.length;\n if (this.meridiansLabels_) {\n featureCount += this.meridians_.length;\n }\n if (this.parallelsLabels_) {\n featureCount += this.parallels_.length;\n }\n\n let feature;\n while (featureCount > this.featurePool_.length) {\n feature = new Feature();\n this.featurePool_.push(feature);\n }\n\n const featuresColl = source.getFeaturesCollection();\n featuresColl.clear();\n let poolIndex = 0;\n\n // add features for the lines & labels\n let i, l;\n for (i = 0, l = this.meridians_.length; i < l; ++i) {\n feature = this.featurePool_[poolIndex++];\n feature.setGeometry(this.meridians_[i]);\n feature.setStyle(this.lineStyle_);\n featuresColl.push(feature);\n }\n for (i = 0, l = this.parallels_.length; i < l; ++i) {\n feature = this.featurePool_[poolIndex++];\n feature.setGeometry(this.parallels_[i]);\n feature.setStyle(this.lineStyle_);\n featuresColl.push(feature);\n }\n }\n\n /**\n * @param {number} lon Longitude.\n * @param {number} minLat Minimal latitude.\n * @param {number} maxLat Maximal latitude.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} index Index.\n * @return {number} Index.\n * @private\n */\n addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, index) {\n const lineString = this.getMeridian_(\n lon,\n minLat,\n maxLat,\n squaredTolerance,\n index,\n );\n if (intersects(lineString.getExtent(), extent)) {\n if (this.meridiansLabels_) {\n const text = this.lonLabelFormatter_(lon);\n if (index in this.meridiansLabels_) {\n this.meridiansLabels_[index].text = text;\n } else {\n this.meridiansLabels_[index] = {\n geom: new Point([]),\n text: text,\n };\n }\n }\n this.meridians_[index++] = lineString;\n }\n return index;\n }\n\n /**\n * @param {number} lat Latitude.\n * @param {number} minLon Minimal longitude.\n * @param {number} maxLon Maximal longitude.\n * @param {number} squaredTolerance Squared tolerance.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} index Index.\n * @return {number} Index.\n * @private\n */\n addParallel_(lat, minLon, maxLon, squaredTolerance, extent, index) {\n const lineString = this.getParallel_(\n lat,\n minLon,\n maxLon,\n squaredTolerance,\n index,\n );\n if (intersects(lineString.getExtent(), extent)) {\n if (this.parallelsLabels_) {\n const text = this.latLabelFormatter_(lat);\n if (index in this.parallelsLabels_) {\n this.parallelsLabels_[index].text = text;\n } else {\n this.parallelsLabels_[index] = {\n geom: new Point([]),\n text: text,\n };\n }\n }\n this.parallels_[index++] = lineString;\n }\n return index;\n }\n\n /**\n * @param {import(\"../render/Event.js\").default} event Render event.\n * @private\n */\n drawLabels_(event) {\n const rotation = event.frameState.viewState.rotation;\n const resolution = event.frameState.viewState.resolution;\n const size = event.frameState.size;\n const extent = event.frameState.extent;\n const rotationCenter = getCenter(extent);\n let rotationExtent = extent;\n if (rotation) {\n const unrotatedWidth = size[0] * resolution;\n const unrotatedHeight = size[1] * resolution;\n rotationExtent = [\n rotationCenter[0] - unrotatedWidth / 2,\n rotationCenter[1] - unrotatedHeight / 2,\n rotationCenter[0] + unrotatedWidth / 2,\n rotationCenter[1] + unrotatedHeight / 2,\n ];\n }\n\n let startWorld = 0;\n let endWorld = 0;\n let labelsAtStart = this.latLabelPosition_ < 0.5;\n const projectionExtent = this.projection_.getExtent();\n const worldWidth = getWidth(projectionExtent);\n if (\n this.getSource().getWrapX() &&\n this.projection_.canWrapX() &&\n !containsExtent(projectionExtent, extent)\n ) {\n startWorld = Math.floor((extent[0] - projectionExtent[0]) / worldWidth);\n endWorld = Math.ceil((extent[2] - projectionExtent[2]) / worldWidth);\n const inverted = Math.abs(rotation) > Math.PI / 2;\n labelsAtStart = labelsAtStart !== inverted;\n }\n const vectorContext = getVectorContext(event);\n\n for (let world = startWorld; world <= endWorld; ++world) {\n let poolIndex = this.meridians_.length + this.parallels_.length;\n let feature, index, l, textPoint;\n\n if (this.meridiansLabels_) {\n for (index = 0, l = this.meridiansLabels_.length; index < l; ++index) {\n const lineString = this.meridians_[index];\n if (!rotation && world === 0) {\n textPoint = this.getMeridianPoint_(lineString, extent, index);\n } else {\n const clone = lineString.clone();\n clone.translate(world * worldWidth, 0);\n clone.rotate(-rotation, rotationCenter);\n textPoint = this.getMeridianPoint_(clone, rotationExtent, index);\n textPoint.rotate(rotation, rotationCenter);\n }\n feature = this.featurePool_[poolIndex++];\n feature.setGeometry(textPoint);\n feature.set('graticule_label', this.meridiansLabels_[index].text);\n vectorContext.drawFeature(feature, this.lonLabelStyle_(feature));\n }\n }\n if (this.parallelsLabels_) {\n if (\n (world === startWorld && labelsAtStart) ||\n (world === endWorld && !labelsAtStart)\n ) {\n for (index = 0, l = this.parallels_.length; index < l; ++index) {\n const lineString = this.parallels_[index];\n if (!rotation && world === 0) {\n textPoint = this.getParallelPoint_(lineString, extent, index);\n } else {\n const clone = lineString.clone();\n clone.translate(world * worldWidth, 0);\n clone.rotate(-rotation, rotationCenter);\n textPoint = this.getParallelPoint_(clone, rotationExtent, index);\n textPoint.rotate(rotation, rotationCenter);\n }\n feature = this.featurePool_[poolIndex++];\n feature.setGeometry(textPoint);\n feature.set('graticule_label', this.parallelsLabels_[index].text);\n vectorContext.drawFeature(feature, this.latLabelStyle_(feature));\n }\n }\n }\n }\n }\n\n /**\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {import(\"../coordinate.js\").Coordinate} center Center.\n * @param {number} resolution Resolution.\n * @param {number} squaredTolerance Squared tolerance.\n * @private\n */\n createGraticule_(extent, center, resolution, squaredTolerance) {\n const interval = this.getInterval_(resolution);\n if (interval == -1) {\n this.meridians_.length = 0;\n this.parallels_.length = 0;\n if (this.meridiansLabels_) {\n this.meridiansLabels_.length = 0;\n }\n if (this.parallelsLabels_) {\n this.parallelsLabels_.length = 0;\n }\n return;\n }\n\n let wrapX = false;\n const projectionExtent = this.projection_.getExtent();\n const worldWidth = getWidth(projectionExtent);\n if (\n this.getSource().getWrapX() &&\n this.projection_.canWrapX() &&\n !containsExtent(projectionExtent, extent)\n ) {\n if (getWidth(extent) >= worldWidth) {\n extent[0] = projectionExtent[0];\n extent[2] = projectionExtent[2];\n } else {\n wrapX = true;\n }\n }\n\n // Constrain the center to fit into the extent available to the graticule\n\n const validCenterP = [\n clamp(center[0], this.minX_, this.maxX_),\n clamp(center[1], this.minY_, this.maxY_),\n ];\n\n // Transform the center to lon lat\n // Some projections may have a void area at the poles\n // so replace any NaN latitudes with the min or max value closest to a pole\n\n const centerLonLat = this.toLonLatTransform_(validCenterP);\n if (isNaN(centerLonLat[1])) {\n centerLonLat[1] =\n Math.abs(this.maxLat_) >= Math.abs(this.minLat_)\n ? this.maxLat_\n : this.minLat_;\n }\n let centerLon = clamp(centerLonLat[0], this.minLon_, this.maxLon_);\n let centerLat = clamp(centerLonLat[1], this.minLat_, this.maxLat_);\n const maxLines = this.maxLines_;\n let cnt, idx, lat, lon;\n\n // Limit the extent to fit into the extent available to the graticule\n\n let validExtentP = extent;\n if (!wrapX) {\n validExtentP = [\n clamp(extent[0], this.minX_, this.maxX_),\n clamp(extent[1], this.minY_, this.maxY_),\n clamp(extent[2], this.minX_, this.maxX_),\n clamp(extent[3], this.minY_, this.maxY_),\n ];\n }\n\n // Transform the extent to get the lon lat ranges for the edges of the extent\n\n const validExtent = applyTransform(\n validExtentP,\n this.toLonLatTransform_,\n undefined,\n 8,\n );\n\n let maxLat = validExtent[3];\n let maxLon = validExtent[2];\n let minLat = validExtent[1];\n let minLon = validExtent[0];\n\n if (!wrapX) {\n // Check if extremities of the world extent lie inside the extent\n // (for example the pole in a polar projection)\n // and extend the extent as appropriate\n\n if (containsCoordinate(validExtentP, this.bottomLeft_)) {\n minLon = this.minLon_;\n minLat = this.minLat_;\n }\n if (containsCoordinate(validExtentP, this.bottomRight_)) {\n maxLon = this.maxLon_;\n minLat = this.minLat_;\n }\n if (containsCoordinate(validExtentP, this.topLeft_)) {\n minLon = this.minLon_;\n maxLat = this.maxLat_;\n }\n if (containsCoordinate(validExtentP, this.topRight_)) {\n maxLon = this.maxLon_;\n maxLat = this.maxLat_;\n }\n\n // The transformed center may also extend the lon lat ranges used for rendering\n\n maxLat = clamp(maxLat, centerLat, this.maxLat_);\n maxLon = clamp(maxLon, centerLon, this.maxLon_);\n minLat = clamp(minLat, this.minLat_, centerLat);\n minLon = clamp(minLon, this.minLon_, centerLon);\n }\n\n // Create meridians\n\n centerLon = Math.floor(centerLon / interval) * interval;\n lon = clamp(centerLon, this.minLon_, this.maxLon_);\n\n idx = this.addMeridian_(lon, minLat, maxLat, squaredTolerance, extent, 0);\n\n cnt = 0;\n if (wrapX) {\n while ((lon -= interval) >= minLon && cnt++ < maxLines) {\n idx = this.addMeridian_(\n lon,\n minLat,\n maxLat,\n squaredTolerance,\n extent,\n idx,\n );\n }\n } else {\n while (lon != this.minLon_ && cnt++ < maxLines) {\n lon = Math.max(lon - interval, this.minLon_);\n idx = this.addMeridian_(\n lon,\n minLat,\n maxLat,\n squaredTolerance,\n extent,\n idx,\n );\n }\n }\n\n lon = clamp(centerLon, this.minLon_, this.maxLon_);\n\n cnt = 0;\n if (wrapX) {\n while ((lon += interval) <= maxLon && cnt++ < maxLines) {\n idx = this.addMeridian_(\n lon,\n minLat,\n maxLat,\n squaredTolerance,\n extent,\n idx,\n );\n }\n } else {\n while (lon != this.maxLon_ && cnt++ < maxLines) {\n lon = Math.min(lon + interval, this.maxLon_);\n idx = this.addMeridian_(\n lon,\n minLat,\n maxLat,\n squaredTolerance,\n extent,\n idx,\n );\n }\n }\n\n this.meridians_.length = idx;\n if (this.meridiansLabels_) {\n this.meridiansLabels_.length = idx;\n }\n\n // Create parallels\n\n centerLat = Math.floor(centerLat / interval) * interval;\n lat = clamp(centerLat, this.minLat_, this.maxLat_);\n\n idx = this.addParallel_(lat, minLon, maxLon, squaredTolerance, extent, 0);\n\n cnt = 0;\n while (lat != this.minLat_ && cnt++ < maxLines) {\n lat = Math.max(lat - interval, this.minLat_);\n idx = this.addParallel_(\n lat,\n minLon,\n maxLon,\n squaredTolerance,\n extent,\n idx,\n );\n }\n\n lat = clamp(centerLat, this.minLat_, this.maxLat_);\n\n cnt = 0;\n while (lat != this.maxLat_ && cnt++ < maxLines) {\n lat = Math.min(lat + interval, this.maxLat_);\n idx = this.addParallel_(\n lat,\n minLon,\n maxLon,\n squaredTolerance,\n extent,\n idx,\n );\n }\n\n this.parallels_.length = idx;\n if (this.parallelsLabels_) {\n this.parallelsLabels_.length = idx;\n }\n }\n\n /**\n * @param {number} resolution Resolution.\n * @return {number} The interval in degrees.\n * @private\n */\n getInterval_(resolution) {\n const centerLon = this.projectionCenterLonLat_[0];\n const centerLat = this.projectionCenterLonLat_[1];\n let interval = -1;\n const target = Math.pow(this.targetSize_ * resolution, 2);\n /** @type {Array} **/\n const p1 = [];\n /** @type {Array} **/\n const p2 = [];\n for (let i = 0, ii = this.intervals_.length; i < ii; ++i) {\n const delta = clamp(this.intervals_[i] / 2, 0, 90);\n // Don't attempt to transform latitudes beyond the poles!\n const clampedLat = clamp(centerLat, -90 + delta, 90 - delta);\n p1[0] = centerLon - delta;\n p1[1] = clampedLat - delta;\n p2[0] = centerLon + delta;\n p2[1] = clampedLat + delta;\n this.fromLonLatTransform_(p1, p1);\n this.fromLonLatTransform_(p2, p2);\n const dist = Math.pow(p2[0] - p1[0], 2) + Math.pow(p2[1] - p1[1], 2);\n if (dist <= target) {\n break;\n }\n interval = this.intervals_[i];\n }\n return interval;\n }\n\n /**\n * @param {number} lon Longitude.\n * @param {number} minLat Minimal latitude.\n * @param {number} maxLat Maximal latitude.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LineString} The meridian line string.\n * @param {number} index Index.\n * @private\n */\n getMeridian_(lon, minLat, maxLat, squaredTolerance, index) {\n const flatCoordinates = meridian(\n lon,\n minLat,\n maxLat,\n this.projection_,\n squaredTolerance,\n );\n let lineString = this.meridians_[index];\n if (!lineString) {\n lineString = new LineString(flatCoordinates, 'XY');\n this.meridians_[index] = lineString;\n } else {\n lineString.setFlatCoordinates('XY', flatCoordinates);\n lineString.changed();\n }\n return lineString;\n }\n\n /**\n * @param {LineString} lineString Meridian\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} index Index.\n * @return {Point} Meridian point.\n * @private\n */\n getMeridianPoint_(lineString, extent, index) {\n const flatCoordinates = lineString.getFlatCoordinates();\n let bottom = 1;\n let top = flatCoordinates.length - 1;\n if (flatCoordinates[bottom] > flatCoordinates[top]) {\n bottom = top;\n top = 1;\n }\n const clampedBottom = Math.max(extent[1], flatCoordinates[bottom]);\n const clampedTop = Math.min(extent[3], flatCoordinates[top]);\n const lat = clamp(\n extent[1] + Math.abs(extent[1] - extent[3]) * this.lonLabelPosition_,\n clampedBottom,\n clampedTop,\n );\n const coordinate0 =\n flatCoordinates[bottom - 1] +\n ((flatCoordinates[top - 1] - flatCoordinates[bottom - 1]) *\n (lat - flatCoordinates[bottom])) /\n (flatCoordinates[top] - flatCoordinates[bottom]);\n const coordinate = [coordinate0, lat];\n const point = this.meridiansLabels_[index].geom;\n point.setCoordinates(coordinate);\n return point;\n }\n\n /**\n * Get the list of meridians. Meridians are lines of equal longitude.\n * @return {Array} The meridians.\n * @api\n */\n getMeridians() {\n return this.meridians_;\n }\n\n /**\n * @param {number} lat Latitude.\n * @param {number} minLon Minimal longitude.\n * @param {number} maxLon Maximal longitude.\n * @param {number} squaredTolerance Squared tolerance.\n * @return {LineString} The parallel line string.\n * @param {number} index Index.\n * @private\n */\n getParallel_(lat, minLon, maxLon, squaredTolerance, index) {\n const flatCoordinates = parallel(\n lat,\n minLon,\n maxLon,\n this.projection_,\n squaredTolerance,\n );\n let lineString = this.parallels_[index];\n if (!lineString) {\n lineString = new LineString(flatCoordinates, 'XY');\n } else {\n lineString.setFlatCoordinates('XY', flatCoordinates);\n lineString.changed();\n }\n return lineString;\n }\n\n /**\n * @param {LineString} lineString Parallels.\n * @param {import(\"../extent.js\").Extent} extent Extent.\n * @param {number} index Index.\n * @return {Point} Parallel point.\n * @private\n */\n getParallelPoint_(lineString, extent, index) {\n const flatCoordinates = lineString.getFlatCoordinates();\n let left = 0;\n let right = flatCoordinates.length - 2;\n if (flatCoordinates[left] > flatCoordinates[right]) {\n left = right;\n right = 0;\n }\n const clampedLeft = Math.max(extent[0], flatCoordinates[left]);\n const clampedRight = Math.min(extent[2], flatCoordinates[right]);\n const lon = clamp(\n extent[0] + Math.abs(extent[0] - extent[2]) * this.latLabelPosition_,\n clampedLeft,\n clampedRight,\n );\n const coordinate1 =\n flatCoordinates[left + 1] +\n ((flatCoordinates[right + 1] - flatCoordinates[left + 1]) *\n (lon - flatCoordinates[left])) /\n (flatCoordinates[right] - flatCoordinates[left]);\n const coordinate = [lon, coordinate1];\n const point = this.parallelsLabels_[index].geom;\n point.setCoordinates(coordinate);\n return point;\n }\n\n /**\n * Get the list of parallels. Parallels are lines of equal latitude.\n * @return {Array} The parallels.\n * @api\n */\n getParallels() {\n return this.parallels_;\n }\n\n /**\n * @param {import(\"../proj/Projection.js\").default} projection Projection.\n * @private\n */\n updateProjectionInfo_(projection) {\n const epsg4326Projection = getProjection('EPSG:4326');\n\n const worldExtent = projection.getWorldExtent();\n\n this.maxLat_ = worldExtent[3];\n this.maxLon_ = worldExtent[2];\n this.minLat_ = worldExtent[1];\n this.minLon_ = worldExtent[0];\n\n // If the world extent crosses the dateline define a custom transform to\n // return longitudes which wrap the dateline\n\n const toLonLatTransform = getTransform(projection, epsg4326Projection);\n if (this.minLon_ < this.maxLon_) {\n this.toLonLatTransform_ = toLonLatTransform;\n } else {\n const split = this.minLon_ + this.maxLon_ / 2;\n this.maxLon_ += 360;\n this.toLonLatTransform_ = function (coordinates, output, dimension) {\n dimension = dimension || 2;\n const lonLatCoordinates = toLonLatTransform(\n coordinates,\n output,\n dimension,\n );\n for (let i = 0, l = lonLatCoordinates.length; i < l; i += dimension) {\n if (lonLatCoordinates[i] < split) {\n lonLatCoordinates[i] += 360;\n }\n }\n return lonLatCoordinates;\n };\n }\n\n // Transform the extent to get the limits of the view projection extent\n // which should be available to the graticule\n\n this.fromLonLatTransform_ = getTransform(epsg4326Projection, projection);\n const worldExtentP = applyTransform(\n [this.minLon_, this.minLat_, this.maxLon_, this.maxLat_],\n this.fromLonLatTransform_,\n undefined,\n 8,\n );\n\n this.minX_ = worldExtentP[0];\n this.maxX_ = worldExtentP[2];\n this.minY_ = worldExtentP[1];\n this.maxY_ = worldExtentP[3];\n\n // Determine the view projection coordinates of the extremities of the world extent\n // as these may lie inside a view extent (for example the pole in a polar projection)\n\n this.bottomLeft_ = this.fromLonLatTransform_([this.minLon_, this.minLat_]);\n this.bottomRight_ = this.fromLonLatTransform_([this.maxLon_, this.minLat_]);\n this.topLeft_ = this.fromLonLatTransform_([this.minLon_, this.maxLat_]);\n this.topRight_ = this.fromLonLatTransform_([this.maxLon_, this.maxLat_]);\n\n // Transform the projection center to lon lat\n // Some projections may have a void area at the poles\n // so replace any NaN latitudes with the min or max value closest to a pole\n\n this.projectionCenterLonLat_ = this.toLonLatTransform_(\n getCenter(projection.getExtent()),\n );\n if (isNaN(this.projectionCenterLonLat_[1])) {\n this.projectionCenterLonLat_[1] =\n Math.abs(this.maxLat_) >= Math.abs(this.minLat_)\n ? this.maxLat_\n : this.minLat_;\n }\n\n this.projection_ = projection;\n }\n}\n\nexport default Graticule;\n", "/**\n * @module ol/ImageCanvas\n */\nimport ImageWrapper from './Image.js';\nimport ImageState from './ImageState.js';\n\n/**\n * A function that is called to trigger asynchronous canvas drawing. It is\n * called with a \"done\" callback that should be called when drawing is done.\n * If any error occurs during drawing, the \"done\" callback should be called with\n * that error.\n *\n * @typedef {function(function(Error=): void): void} Loader\n */\n\nclass ImageCanvas extends ImageWrapper {\n /**\n * @param {import(\"./extent.js\").Extent} extent Extent.\n * @param {number} resolution Resolution.\n * @param {number} pixelRatio Pixel ratio.\n * @param {HTMLCanvasElement} canvas Canvas.\n * @param {Loader} [loader] Optional loader function to\n * support asynchronous canvas drawing.\n */\n constructor(extent, resolution, pixelRatio, canvas, loader) {\n const state = loader !== undefined ? ImageState.IDLE : ImageState.LOADED;\n\n super(extent, resolution, pixelRatio, state);\n\n /**\n * Optional canvas loader function.\n * @type {?Loader}\n * @private\n */\n this.loader_ = loader !== undefined ? loader : null;\n\n /**\n * @private\n * @type {HTMLCanvasElement}\n */\n this.canvas_ = canvas;\n\n /**\n * @private\n * @type {?Error}\n */\n this.error_ = null;\n }\n\n /**\n * Get any error associated with asynchronous rendering.\n * @return {?Error} Any error that occurred during rendering.\n */\n getError() {\n return this.error_;\n }\n\n /**\n * Handle async drawing complete.\n * @param {Error} [err] Any error during drawing.\n * @private\n */\n handleLoad_(err) {\n if (err) {\n this.error_ = err;\n this.state = ImageState.ERROR;\n } else {\n this.state = ImageState.LOADED;\n }\n this.changed();\n }\n\n /**\n * Load not yet loaded URI.\n * @override\n */\n load() {\n if (this.state == ImageState.IDLE) {\n this.state = ImageState.LOADING;\n this.changed();\n this.loader_(this.handleLoad_.bind(this));\n }\n }\n\n /**\n * @return {HTMLCanvasElement} Canvas element.\n * @override\n */\n getImage() {\n return this.canvas_;\n }\n}\n\nexport default ImageCanvas;\n", "/**\n * @module ol/Kinetic\n */\n\n/**\n * @classdesc\n * Implementation of inertial deceleration for map movement.\n *\n * @api\n */\nclass Kinetic {\n /**\n * @param {number} decay Rate of decay (must be negative).\n * @param {number} minVelocity Minimum velocity (pixels/millisecond).\n * @param {number} delay Delay to consider to calculate the kinetic\n * initial values (milliseconds).\n */\n constructor(decay, minVelocity, delay) {\n /**\n * @private\n * @type {number}\n */\n this.decay_ = decay;\n\n /**\n * @private\n * @type {number}\n */\n this.minVelocity_ = minVelocity;\n\n /**\n * @private\n * @type {number}\n */\n this.delay_ = delay;\n\n /**\n * @private\n * @type {Array}\n */\n this.points_ = [];\n\n /**\n * @private\n * @type {number}\n */\n this.angle_ = 0;\n\n /**\n * @private\n * @type {number}\n */\n this.initialVelocity_ = 0;\n }\n\n /**\n * FIXME empty description for jsdoc\n */\n begin() {\n this.points_.length = 0;\n this.angle_ = 0;\n this.initialVelocity_ = 0;\n }\n\n /**\n * @param {number} x X.\n * @param {number} y Y.\n */\n update(x, y) {\n this.points_.push(x, y, Date.now());\n }\n\n /**\n * @return {boolean} Whether we should do kinetic animation.\n */\n end() {\n if (this.points_.length < 6) {\n // at least 2 points are required (i.e. there must be at least 6 elements\n // in the array)\n return false;\n }\n const delay = Date.now() - this.delay_;\n const lastIndex = this.points_.length - 3;\n if (this.points_[lastIndex + 2] < delay) {\n // the last tracked point is too old, which means that the user stopped\n // panning before releasing the map\n return false;\n }\n\n // get the first point which still falls into the delay time\n let firstIndex = lastIndex - 3;\n while (firstIndex > 0 && this.points_[firstIndex + 2] > delay) {\n firstIndex -= 3;\n }\n\n const duration = this.points_[lastIndex + 2] - this.points_[firstIndex + 2];\n // we don't want a duration of 0 (divide by zero)\n // we also make sure the user panned for a duration of at least one frame\n // (1/60s) to compute sane displacement values\n if (duration < 1000 / 60) {\n return false;\n }\n\n const dx = this.points_[lastIndex] - this.points_[firstIndex];\n const dy = this.points_[lastIndex + 1] - this.points_[firstIndex + 1];\n this.angle_ = Math.atan2(dy, dx);\n this.initialVelocity_ = Math.sqrt(dx * dx + dy * dy) / duration;\n return this.initialVelocity_ > this.minVelocity_;\n }\n\n /**\n * @return {number} Total distance travelled (pixels).\n */\n getDistance() {\n return (this.minVelocity_ - this.initialVelocity_) / this.decay_;\n }\n\n /**\n * @return {number} Angle of the kinetic panning animation (radians).\n */\n getAngle() {\n return this.angle_;\n }\n}\n\nexport default Kinetic;\n", "/**\n * @module ol/pointer/EventType\n */\n\n/**\n * Constants for event names.\n * @enum {string}\n */\nexport default {\n POINTERMOVE: 'pointermove',\n POINTERDOWN: 'pointerdown',\n POINTERUP: 'pointerup',\n POINTEROVER: 'pointerover',\n POINTEROUT: 'pointerout',\n POINTERENTER: 'pointerenter',\n POINTERLEAVE: 'pointerleave',\n POINTERCANCEL: 'pointercancel',\n};\n", "/**\n * @module ol/MapBrowserEventHandler\n */\n\nimport MapBrowserEvent from './MapBrowserEvent.js';\nimport MapBrowserEventType from './MapBrowserEventType.js';\nimport EventType from './events/EventType.js';\nimport Target from './events/Target.js';\nimport {listen, unlistenByKey} from './events.js';\nimport {PASSIVE_EVENT_LISTENERS} from './has.js';\nimport PointerEventType from './pointer/EventType.js';\n\nclass MapBrowserEventHandler extends Target {\n /**\n * @param {import(\"./Map.js\").default} map The map with the viewport to listen to events on.\n * @param {number} [moveTolerance] The minimal distance the pointer must travel to trigger a move.\n */\n constructor(map, moveTolerance) {\n super(map);\n\n /**\n * This is the element that we will listen to the real events on.\n * @type {import(\"./Map.js\").default}\n * @private\n */\n this.map_ = map;\n\n /**\n * @type {ReturnType}\n * @private\n */\n this.clickTimeoutId_;\n\n /**\n * Emulate dblclick and singleclick. Will be true when only one pointer is active.\n * @type {boolean}\n */\n this.emulateClicks_ = false;\n\n /**\n * @type {boolean}\n * @private\n */\n this.dragging_ = false;\n\n /**\n * @type {!Array}\n * @private\n */\n this.dragListenerKeys_ = [];\n\n /**\n * @type {number}\n * @private\n */\n this.moveTolerance_ = moveTolerance === undefined ? 1 : moveTolerance;\n\n /**\n * The most recent \"down\" type event (or null if none have occurred).\n * Set on pointerdown.\n * @type {PointerEvent|null}\n * @private\n */\n this.down_ = null;\n\n const element = this.map_.getViewport();\n\n /**\n * @type {Array}\n * @private\n */\n this.activePointers_ = [];\n\n /**\n * @type {!Object}\n * @private\n */\n this.trackedTouches_ = {};\n\n /**\n * @private\n */\n this.element_ = element;\n\n /**\n * @type {?import(\"./events.js\").EventsKey}\n * @private\n */\n this.pointerdownListenerKey_ = listen(\n element,\n PointerEventType.POINTERDOWN,\n this.handlePointerDown_,\n this,\n );\n\n /**\n * @type {PointerEvent}\n * @private\n */\n this.originalPointerMoveEvent_;\n\n /**\n * @type {?import(\"./events.js\").EventsKey}\n * @private\n */\n this.relayedListenerKey_ = listen(\n element,\n PointerEventType.POINTERMOVE,\n this.relayMoveEvent_,\n this,\n );\n\n /**\n * @private\n */\n this.boundHandleTouchMove_ = this.handleTouchMove_.bind(this);\n\n this.element_.addEventListener(\n EventType.TOUCHMOVE,\n this.boundHandleTouchMove_,\n PASSIVE_EVENT_LISTENERS ? {passive: false} : false,\n );\n }\n\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n emulateClick_(pointerEvent) {\n let newEvent = new MapBrowserEvent(\n MapBrowserEventType.CLICK,\n this.map_,\n pointerEvent,\n );\n this.dispatchEvent(newEvent);\n if (this.clickTimeoutId_ !== undefined) {\n // double-click\n clearTimeout(this.clickTimeoutId_);\n this.clickTimeoutId_ = undefined;\n newEvent = new MapBrowserEvent(\n MapBrowserEventType.DBLCLICK,\n this.map_,\n pointerEvent,\n );\n this.dispatchEvent(newEvent);\n } else {\n // click\n this.clickTimeoutId_ = setTimeout(() => {\n this.clickTimeoutId_ = undefined;\n const newEvent = new MapBrowserEvent(\n MapBrowserEventType.SINGLECLICK,\n this.map_,\n pointerEvent,\n );\n this.dispatchEvent(newEvent);\n }, 250);\n }\n }\n\n /**\n * Keeps track on how many pointers are currently active.\n *\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n updateActivePointers_(pointerEvent) {\n const event = pointerEvent;\n const id = event.pointerId;\n\n if (\n event.type == MapBrowserEventType.POINTERUP ||\n event.type == MapBrowserEventType.POINTERCANCEL\n ) {\n delete this.trackedTouches_[id];\n for (const pointerId in this.trackedTouches_) {\n if (this.trackedTouches_[pointerId].target !== event.target) {\n // Some platforms assign a new pointerId when the target changes.\n // If this happens, delete one tracked pointer. If there is more\n // than one tracked pointer for the old target, it will be cleared\n // by subsequent POINTERUP events from other pointers.\n delete this.trackedTouches_[pointerId];\n break;\n }\n }\n } else if (\n event.type == MapBrowserEventType.POINTERDOWN ||\n event.type == MapBrowserEventType.POINTERMOVE\n ) {\n this.trackedTouches_[id] = event;\n }\n this.activePointers_ = Object.values(this.trackedTouches_);\n }\n\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n handlePointerUp_(pointerEvent) {\n this.updateActivePointers_(pointerEvent);\n const newEvent = new MapBrowserEvent(\n MapBrowserEventType.POINTERUP,\n this.map_,\n pointerEvent,\n undefined,\n undefined,\n this.activePointers_,\n );\n this.dispatchEvent(newEvent);\n\n // We emulate click events on left mouse button click, touch contact, and pen\n // contact. isMouseActionButton returns true in these cases (evt.button is set\n // to 0).\n // See http://www.w3.org/TR/pointerevents/#button-states\n // We only fire click, singleclick, and doubleclick if nobody has called\n // event.preventDefault().\n if (\n this.emulateClicks_ &&\n !newEvent.defaultPrevented &&\n !this.dragging_ &&\n this.isMouseActionButton_(pointerEvent)\n ) {\n this.emulateClick_(this.down_);\n }\n\n if (this.activePointers_.length === 0) {\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n this.dragging_ = false;\n this.down_ = null;\n }\n }\n\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} If the left mouse button was pressed.\n * @private\n */\n isMouseActionButton_(pointerEvent) {\n return pointerEvent.button === 0;\n }\n\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n handlePointerDown_(pointerEvent) {\n this.emulateClicks_ = this.activePointers_.length === 0;\n this.updateActivePointers_(pointerEvent);\n const newEvent = new MapBrowserEvent(\n MapBrowserEventType.POINTERDOWN,\n this.map_,\n pointerEvent,\n undefined,\n undefined,\n this.activePointers_,\n );\n this.dispatchEvent(newEvent);\n\n this.down_ = new PointerEvent(pointerEvent.type, pointerEvent);\n Object.defineProperty(this.down_, 'target', {\n writable: false,\n value: pointerEvent.target,\n });\n\n if (this.dragListenerKeys_.length === 0) {\n const doc = this.map_.getOwnerDocument();\n this.dragListenerKeys_.push(\n listen(\n doc,\n MapBrowserEventType.POINTERMOVE,\n this.handlePointerMove_,\n this,\n ),\n listen(doc, MapBrowserEventType.POINTERUP, this.handlePointerUp_, this),\n /* Note that the listener for `pointercancel is set up on\n * `pointerEventHandler_` and not `documentPointerEventHandler_` like\n * the `pointerup` and `pointermove` listeners.\n *\n * The reason for this is the following: `TouchSource.vacuumTouches_()`\n * issues `pointercancel` events, when there was no `touchend` for a\n * `touchstart`. Now, let's say a first `touchstart` is registered on\n * `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.\n * But `documentPointerEventHandler_` doesn't know about the first\n * `touchstart`. If there is no `touchend` for the `touchstart`, we can\n * only receive a `touchcancel` from `pointerEventHandler_`, because it is\n * only registered there.\n */\n listen(\n this.element_,\n MapBrowserEventType.POINTERCANCEL,\n this.handlePointerUp_,\n this,\n ),\n );\n if (this.element_.getRootNode && this.element_.getRootNode() !== doc) {\n this.dragListenerKeys_.push(\n listen(\n this.element_.getRootNode(),\n MapBrowserEventType.POINTERUP,\n this.handlePointerUp_,\n this,\n ),\n );\n }\n }\n }\n\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n handlePointerMove_(pointerEvent) {\n // Between pointerdown and pointerup, pointermove events are triggered.\n // To avoid a 'false' touchmove event to be dispatched, we test if the pointer\n // moved a significant distance.\n if (this.isMoving_(pointerEvent)) {\n this.updateActivePointers_(pointerEvent);\n this.dragging_ = true;\n const newEvent = new MapBrowserEvent(\n MapBrowserEventType.POINTERDRAG,\n this.map_,\n pointerEvent,\n this.dragging_,\n undefined,\n this.activePointers_,\n );\n this.dispatchEvent(newEvent);\n }\n }\n\n /**\n * Wrap and relay a pointermove event.\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @private\n */\n relayMoveEvent_(pointerEvent) {\n this.originalPointerMoveEvent_ = pointerEvent;\n const dragging = !!(this.down_ && this.isMoving_(pointerEvent));\n this.dispatchEvent(\n new MapBrowserEvent(\n MapBrowserEventType.POINTERMOVE,\n this.map_,\n pointerEvent,\n dragging,\n ),\n );\n }\n\n /**\n * Flexible handling of a `touch-action: none` css equivalent: because calling\n * `preventDefault()` on a `pointermove` event does not stop native page scrolling\n * and zooming, we also listen for `touchmove` and call `preventDefault()` on it\n * when an interaction (currently `DragPan` handles the event.\n * @param {TouchEvent} event Event.\n * @private\n */\n handleTouchMove_(event) {\n // Due to https://github.com/mpizenberg/elm-pep/issues/2, `this.originalPointerMoveEvent_`\n // may not be initialized yet when we get here on a platform without native pointer events,\n // when elm-pep is used as pointer events polyfill.\n const originalEvent = this.originalPointerMoveEvent_;\n if (\n (!originalEvent || originalEvent.defaultPrevented) &&\n (typeof event.cancelable !== 'boolean' || event.cancelable === true)\n ) {\n event.preventDefault();\n }\n }\n\n /**\n * @param {PointerEvent} pointerEvent Pointer\n * event.\n * @return {boolean} Is moving.\n * @private\n */\n isMoving_(pointerEvent) {\n return (\n this.dragging_ ||\n Math.abs(pointerEvent.clientX - this.down_.clientX) >\n this.moveTolerance_ ||\n Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_\n );\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n if (this.relayedListenerKey_) {\n unlistenByKey(this.relayedListenerKey_);\n this.relayedListenerKey_ = null;\n }\n this.element_.removeEventListener(\n EventType.TOUCHMOVE,\n this.boundHandleTouchMove_,\n );\n\n if (this.pointerdownListenerKey_) {\n unlistenByKey(this.pointerdownListenerKey_);\n this.pointerdownListenerKey_ = null;\n }\n\n this.dragListenerKeys_.forEach(unlistenByKey);\n this.dragListenerKeys_.length = 0;\n\n this.element_ = null;\n super.disposeInternal();\n }\n}\n\nexport default MapBrowserEventHandler;\n", "/**\n * @module ol/MapEventType\n */\n\n/**\n * @enum {string}\n */\nexport default {\n /**\n * Triggered after a map frame is rendered.\n * @event module:ol/MapEvent~MapEvent#postrender\n * @api\n */\n POSTRENDER: 'postrender',\n\n /**\n * Triggered when the map starts moving.\n * @event module:ol/MapEvent~MapEvent#movestart\n * @api\n */\n MOVESTART: 'movestart',\n\n /**\n * Triggered after the map is moved.\n * @event module:ol/MapEvent~MapEvent#moveend\n * @api\n */\n MOVEEND: 'moveend',\n\n /**\n * Triggered when loading of additional map data (tiles, images, features) starts.\n * @event module:ol/MapEvent~MapEvent#loadstart\n * @api\n */\n LOADSTART: 'loadstart',\n\n /**\n * Triggered when loading of additional map data has completed.\n * @event module:ol/MapEvent~MapEvent#loadend\n * @api\n */\n LOADEND: 'loadend',\n};\n\n/***\n * @typedef {'postrender'|'movestart'|'moveend'|'loadstart'|'loadend'} Types\n */\n", "/**\n * @module ol/MapProperty\n */\n\n/**\n * @enum {string}\n */\nexport default {\n LAYERGROUP: 'layergroup',\n SIZE: 'size',\n TARGET: 'target',\n VIEW: 'view',\n};\n", "/**\n * @module ol/structs/PriorityQueue\n */\nimport {assert} from '../asserts.js';\nimport {clear} from '../obj.js';\n\n/**\n * @type {number}\n */\nexport const DROP = Infinity;\n\n/**\n * @classdesc\n * Priority queue.\n *\n * The implementation is inspired from the Closure Library's Heap class and\n * Python's heapq module.\n *\n * See https://github.com/google/closure-library/blob/master/closure/goog/structs/heap.js\n * and https://hg.python.org/cpython/file/2.7/Lib/heapq.py.\n *\n * @template T\n */\nclass PriorityQueue {\n /**\n * @param {function(T): number} priorityFunction Priority function.\n * @param {function(T): string} keyFunction Key function.\n */\n constructor(priorityFunction, keyFunction) {\n /**\n * @type {function(T): number}\n * @private\n */\n this.priorityFunction_ = priorityFunction;\n\n /**\n * @type {function(T): string}\n * @private\n */\n this.keyFunction_ = keyFunction;\n\n /**\n * @type {Array}\n * @private\n */\n this.elements_ = [];\n\n /**\n * @type {Array}\n * @private\n */\n this.priorities_ = [];\n\n /**\n * @type {!Object}\n * @private\n */\n this.queuedElements_ = {};\n }\n\n /**\n * FIXME empty description for jsdoc\n */\n clear() {\n this.elements_.length = 0;\n this.priorities_.length = 0;\n clear(this.queuedElements_);\n }\n\n /**\n * Remove and return the highest-priority element. O(log N).\n * @return {T} Element.\n */\n dequeue() {\n const elements = this.elements_;\n const priorities = this.priorities_;\n const element = elements[0];\n if (elements.length == 1) {\n elements.length = 0;\n priorities.length = 0;\n } else {\n elements[0] = /** @type {T} */ (elements.pop());\n priorities[0] = /** @type {number} */ (priorities.pop());\n this.siftUp_(0);\n }\n const elementKey = this.keyFunction_(element);\n delete this.queuedElements_[elementKey];\n return element;\n }\n\n /**\n * Enqueue an element. O(log N).\n * @param {T} element Element.\n * @return {boolean} The element was added to the queue.\n */\n enqueue(element) {\n assert(\n !(this.keyFunction_(element) in this.queuedElements_),\n 'Tried to enqueue an `element` that was already added to the queue',\n );\n const priority = this.priorityFunction_(element);\n if (priority != DROP) {\n this.elements_.push(element);\n this.priorities_.push(priority);\n this.queuedElements_[this.keyFunction_(element)] = true;\n this.siftDown_(0, this.elements_.length - 1);\n return true;\n }\n return false;\n }\n\n /**\n * @return {number} Count.\n */\n getCount() {\n return this.elements_.length;\n }\n\n /**\n * Gets the index of the left child of the node at the given index.\n * @param {number} index The index of the node to get the left child for.\n * @return {number} The index of the left child.\n * @private\n */\n getLeftChildIndex_(index) {\n return index * 2 + 1;\n }\n\n /**\n * Gets the index of the right child of the node at the given index.\n * @param {number} index The index of the node to get the right child for.\n * @return {number} The index of the right child.\n * @private\n */\n getRightChildIndex_(index) {\n return index * 2 + 2;\n }\n\n /**\n * Gets the index of the parent of the node at the given index.\n * @param {number} index The index of the node to get the parent for.\n * @return {number} The index of the parent.\n * @private\n */\n getParentIndex_(index) {\n return (index - 1) >> 1;\n }\n\n /**\n * Make this a heap. O(N).\n * @private\n */\n heapify_() {\n let i;\n for (i = (this.elements_.length >> 1) - 1; i >= 0; i--) {\n this.siftUp_(i);\n }\n }\n\n /**\n * @return {boolean} Is empty.\n */\n isEmpty() {\n return this.elements_.length === 0;\n }\n\n /**\n * @param {string} key Key.\n * @return {boolean} Is key queued.\n */\n isKeyQueued(key) {\n return key in this.queuedElements_;\n }\n\n /**\n * @param {T} element Element.\n * @return {boolean} Is queued.\n */\n isQueued(element) {\n return this.isKeyQueued(this.keyFunction_(element));\n }\n\n /**\n * @param {number} index The index of the node to move down.\n * @private\n */\n siftUp_(index) {\n const elements = this.elements_;\n const priorities = this.priorities_;\n const count = elements.length;\n const element = elements[index];\n const priority = priorities[index];\n const startIndex = index;\n\n while (index < count >> 1) {\n const lIndex = this.getLeftChildIndex_(index);\n const rIndex = this.getRightChildIndex_(index);\n\n const smallerChildIndex =\n rIndex < count && priorities[rIndex] < priorities[lIndex]\n ? rIndex\n : lIndex;\n\n elements[index] = elements[smallerChildIndex];\n priorities[index] = priorities[smallerChildIndex];\n index = smallerChildIndex;\n }\n\n elements[index] = element;\n priorities[index] = priority;\n this.siftDown_(startIndex, index);\n }\n\n /**\n * @param {number} startIndex The index of the root.\n * @param {number} index The index of the node to move up.\n * @private\n */\n siftDown_(startIndex, index) {\n const elements = this.elements_;\n const priorities = this.priorities_;\n const element = elements[index];\n const priority = priorities[index];\n\n while (index > startIndex) {\n const parentIndex = this.getParentIndex_(index);\n if (priorities[parentIndex] > priority) {\n elements[index] = elements[parentIndex];\n priorities[index] = priorities[parentIndex];\n index = parentIndex;\n } else {\n break;\n }\n }\n elements[index] = element;\n priorities[index] = priority;\n }\n\n /**\n * FIXME empty description for jsdoc\n */\n reprioritize() {\n const priorityFunction = this.priorityFunction_;\n const elements = this.elements_;\n const priorities = this.priorities_;\n let index = 0;\n const n = elements.length;\n let element, i, priority;\n for (i = 0; i < n; ++i) {\n element = elements[i];\n priority = priorityFunction(element);\n if (priority == DROP) {\n delete this.queuedElements_[this.keyFunction_(element)];\n } else {\n priorities[index] = priority;\n elements[index++] = element;\n }\n }\n elements.length = index;\n priorities.length = index;\n this.heapify_();\n }\n}\n\nexport default PriorityQueue;\n", "/**\n * @module ol/TileQueue\n */\nimport TileState from './TileState.js';\nimport EventType from './events/EventType.js';\nimport PriorityQueue, {DROP} from './structs/PriorityQueue.js';\n\n/**\n * @typedef {function(import(\"./Tile.js\").default, string, import('./tilecoord.js').TileCoord, number): number} PriorityFunction\n */\n\n/**\n * @typedef {[import('./Tile.js').default, string, import('./tilecoord.js').TileCoord, number]} TileQueueElement\n */\n\n/**\n * @extends PriorityQueue}\n */\nclass TileQueue extends PriorityQueue {\n /**\n * @param {PriorityFunction} tilePriorityFunction Tile priority function.\n * @param {function(): ?} tileChangeCallback Function called on each tile change event.\n */\n constructor(tilePriorityFunction, tileChangeCallback) {\n super(\n (element) => tilePriorityFunction.apply(null, element),\n (element) => element[0].getKey(),\n );\n\n /** @private */\n this.boundHandleTileChange_ = this.handleTileChange.bind(this);\n\n /**\n * @private\n * @type {function(): ?}\n */\n this.tileChangeCallback_ = tileChangeCallback;\n\n /**\n * @private\n * @type {number}\n */\n this.tilesLoading_ = 0;\n\n /**\n * @private\n * @type {!Object}\n */\n this.tilesLoadingKeys_ = {};\n }\n\n /**\n * @param {TileQueueElement} element Element.\n * @return {boolean} The element was added to the queue.\n * @override\n */\n enqueue(element) {\n const added = super.enqueue(element);\n if (added) {\n const tile = element[0];\n tile.addEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n }\n return added;\n }\n\n /**\n * @return {number} Number of tiles loading.\n */\n getTilesLoading() {\n return this.tilesLoading_;\n }\n\n /**\n * @param {import(\"./events/Event.js\").default} event Event.\n * @protected\n */\n handleTileChange(event) {\n const tile = /** @type {import(\"./Tile.js\").default} */ (event.target);\n const state = tile.getState();\n if (\n state === TileState.LOADED ||\n state === TileState.ERROR ||\n state === TileState.EMPTY\n ) {\n if (state !== TileState.ERROR) {\n tile.removeEventListener(EventType.CHANGE, this.boundHandleTileChange_);\n }\n const tileKey = tile.getKey();\n if (tileKey in this.tilesLoadingKeys_) {\n delete this.tilesLoadingKeys_[tileKey];\n --this.tilesLoading_;\n }\n this.tileChangeCallback_();\n }\n }\n\n /**\n * @param {number} maxTotalLoading Maximum number tiles to load simultaneously.\n * @param {number} maxNewLoads Maximum number of new tiles to load.\n */\n loadMoreTiles(maxTotalLoading, maxNewLoads) {\n let newLoads = 0;\n while (\n this.tilesLoading_ < maxTotalLoading &&\n newLoads < maxNewLoads &&\n this.getCount() > 0\n ) {\n const tile = this.dequeue()[0];\n const tileKey = tile.getKey();\n const state = tile.getState();\n if (state === TileState.IDLE && !(tileKey in this.tilesLoadingKeys_)) {\n this.tilesLoadingKeys_[tileKey] = true;\n ++this.tilesLoading_;\n ++newLoads;\n tile.load();\n }\n }\n }\n}\n\nexport default TileQueue;\n\n/**\n * @param {import('./Map.js').FrameState} frameState Frame state.\n * @param {import(\"./Tile.js\").default} tile Tile.\n * @param {string} tileSourceKey Tile source key.\n * @param {import(\"./coordinate.js\").Coordinate} tileCenter Tile center.\n * @param {number} tileResolution Tile resolution.\n * @return {number} Tile priority.\n */\nexport function getTilePriority(\n frameState,\n tile,\n tileSourceKey,\n tileCenter,\n tileResolution,\n) {\n // Filter out tiles at higher zoom levels than the current zoom level, or that\n // are outside the visible extent.\n if (!frameState || !(tileSourceKey in frameState.wantedTiles)) {\n return DROP;\n }\n if (!frameState.wantedTiles[tileSourceKey][tile.getKey()]) {\n return DROP;\n }\n // Prioritize the highest zoom level tiles closest to the focus.\n // Tiles at higher zoom levels are prioritized using Math.log(tileResolution).\n // Within a zoom level, tiles are prioritized by the distance in pixels between\n // the center of the tile and the center of the viewport. The factor of 65536\n // means that the prioritization should behave as desired for tiles up to\n // 65536 * Math.log(2) = 45426 pixels from the focus.\n const center = frameState.viewState.center;\n const deltaX = tileCenter[0] - center[0];\n const deltaY = tileCenter[1] - center[1];\n return (\n 65536 * Math.log(tileResolution) +\n Math.sqrt(deltaX * deltaX + deltaY * deltaY) / tileResolution\n );\n}\n", "/**\n * @module ol/control/Control\n */\nimport MapEventType from '../MapEventType.js';\nimport BaseObject from '../Object.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport {VOID} from '../functions.js';\n\n/**\n * @typedef {Object} Options\n * @property {HTMLElement} [element] The element is the control's\n * container element. This only needs to be specified if you're developing\n * a custom control.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {HTMLElement|string} [target] Specify a target if you want\n * the control to be rendered outside of the map's viewport.\n */\n\n/**\n * @classdesc\n * A control is a visible widget with a DOM element in a fixed position on the\n * screen. They can involve user input (buttons), or be informational only;\n * the position is determined using CSS. By default these are placed in the\n * container with CSS class name `ol-overlaycontainer-stopevent`, but can use\n * any outside DOM element.\n *\n * This is the base class for controls. You can use it for simple custom\n * controls by creating the element with listeners, creating an instance:\n * ```js\n * const myControl = new Control({element: myElement});\n * ```\n * and then adding this to the map.\n *\n * The main advantage of having this as a control rather than a simple separate\n * DOM element is that preventing propagation is handled for you. Controls\n * will also be objects in a {@link module:ol/Collection~Collection}, so you can use their methods.\n *\n * You can also extend this base for your own control class. See\n * examples/custom-controls for an example of how to do this.\n *\n * @api\n */\nclass Control extends BaseObject {\n /**\n * @param {Options} options Control options.\n */\n constructor(options) {\n super();\n\n const element = options.element;\n if (element && !options.target && !element.style.pointerEvents) {\n element.style.pointerEvents = 'auto';\n }\n\n /**\n * @protected\n * @type {HTMLElement}\n */\n this.element = element ? element : null;\n\n /**\n * @private\n * @type {HTMLElement}\n */\n this.target_ = null;\n\n /**\n * @private\n * @type {import(\"../Map.js\").default|null}\n */\n this.map_ = null;\n\n /**\n * @protected\n * @type {!Array}\n */\n this.listenerKeys = [];\n\n if (options.render) {\n this.render = options.render;\n }\n\n if (options.target) {\n this.setTarget(options.target);\n }\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n this.element?.remove();\n super.disposeInternal();\n }\n\n /**\n * Get the map associated with this control.\n * @return {import(\"../Map.js\").default|null} Map.\n * @api\n */\n getMap() {\n return this.map_;\n }\n\n /**\n * Remove the control from its current map and attach it to the new map.\n * Pass `null` to just remove the control from the current map.\n * Subclasses may set up event handlers to get notified about changes to\n * the map here.\n * @param {import(\"../Map.js\").default|null} map Map.\n * @api\n */\n setMap(map) {\n if (this.map_) {\n this.element?.remove();\n }\n for (let i = 0, ii = this.listenerKeys.length; i < ii; ++i) {\n unlistenByKey(this.listenerKeys[i]);\n }\n this.listenerKeys.length = 0;\n this.map_ = map;\n if (map) {\n const target = this.target_ ?? map.getOverlayContainerStopEvent();\n if (this.element) {\n target.appendChild(this.element);\n }\n if (this.render !== VOID) {\n this.listenerKeys.push(\n listen(map, MapEventType.POSTRENDER, this.render, this),\n );\n }\n map.render();\n }\n }\n\n /**\n * Renders the control.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @api\n */\n render(mapEvent) {}\n\n /**\n * This function is used to set a target element for the control. It has no\n * effect if it is called after the control has been added to the map (i.e.\n * after `setMap` is called on the control). If no `target` is set in the\n * options passed to the control constructor and if `setTarget` is not called\n * then the control is added to the map's overlay container.\n * @param {HTMLElement|string} target Target.\n * @api\n */\n setTarget(target) {\n this.target_ =\n typeof target === 'string' ? document.getElementById(target) : target;\n }\n}\n\nexport default Control;\n", "/**\n * @module ol/control/Attribution\n */\nimport {equals} from '../array.js';\nimport {CLASS_COLLAPSED, CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';\nimport {removeChildren, replaceNode} from '../dom.js';\nimport EventType from '../events/EventType.js';\nimport {toPromise} from '../functions.js';\nimport Control from './Control.js';\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-attribution'] CSS class name.\n * @property {HTMLElement|string} [target] Specify a target if you\n * want the control to be rendered outside of the map's\n * viewport.\n * @property {boolean} [collapsible] Specify if attributions can\n * be collapsed. If not specified, sources control this behavior with their\n * `attributionsCollapsible` setting.\n * @property {boolean} [collapsed=true] Specify if attributions should\n * be collapsed at startup.\n * @property {string} [tipLabel='Attributions'] Text label to use for the button tip.\n * @property {string|HTMLElement} [label='i'] Text label to use for the\n * collapsed attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [expandClassName=className + '-expand'] CSS class name for the\n * collapsed attributions button.\n * @property {string|HTMLElement} [collapseLabel='›'] Text label to use\n * for the expanded attributions button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [collapseClassName=className + '-collapse'] CSS class name for the\n * expanded attributions button.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when\n * the control should be re-rendered. This is called in a `requestAnimationFrame`\n * callback.\n * @property {string|Array|undefined} [attributions] Optional attribution(s) that will always be\n * displayed regardless of the layers rendered\n */\n\n/**\n * @classdesc\n * Control to show all the attributions associated with the layer sources\n * in the map. This control is one of the default controls included in maps.\n * By default it will show in the bottom right portion of the map, but this can\n * be changed by using a css selector for `.ol-attribution`.\n *\n * @api\n */\nclass Attribution extends Control {\n /**\n * @param {Options} [options] Attribution options.\n */\n constructor(options) {\n options = options ? options : {};\n\n super({\n element: document.createElement('div'),\n render: options.render,\n target: options.target,\n });\n\n /**\n * @private\n * @type {HTMLElement}\n */\n this.ulElement_ = document.createElement('ul');\n\n /**\n * @private\n * @type {boolean}\n */\n this.collapsed_ =\n options.collapsed !== undefined ? options.collapsed : true;\n\n /**\n * @private\n * @type {boolean}\n */\n this.userCollapsed_ = this.collapsed_;\n\n /**\n * @private\n * @type {boolean}\n */\n this.overrideCollapsible_ = options.collapsible !== undefined;\n\n /**\n * @private\n * @type {boolean}\n */\n this.collapsible_ =\n options.collapsible !== undefined ? options.collapsible : true;\n\n if (!this.collapsible_) {\n this.collapsed_ = false;\n }\n\n /**\n * @private\n * @type {string | Array | undefined}\n */\n this.attributions_ = options.attributions;\n\n const className =\n options.className !== undefined ? options.className : 'ol-attribution';\n\n const tipLabel =\n options.tipLabel !== undefined ? options.tipLabel : 'Attributions';\n\n const expandClassName =\n options.expandClassName !== undefined\n ? options.expandClassName\n : className + '-expand';\n\n const collapseLabel =\n options.collapseLabel !== undefined ? options.collapseLabel : '\\u203A';\n\n const collapseClassName =\n options.collapseClassName !== undefined\n ? options.collapseClassName\n : className + '-collapse';\n\n if (typeof collapseLabel === 'string') {\n /**\n * @private\n * @type {HTMLElement}\n */\n this.collapseLabel_ = document.createElement('span');\n this.collapseLabel_.textContent = collapseLabel;\n this.collapseLabel_.className = collapseClassName;\n } else {\n this.collapseLabel_ = collapseLabel;\n }\n\n const label = options.label !== undefined ? options.label : 'i';\n\n if (typeof label === 'string') {\n /**\n * @private\n * @type {HTMLElement}\n */\n this.label_ = document.createElement('span');\n this.label_.textContent = label;\n this.label_.className = expandClassName;\n } else {\n this.label_ = label;\n }\n\n const activeLabel =\n this.collapsible_ && !this.collapsed_ ? this.collapseLabel_ : this.label_;\n\n /**\n * @private\n * @type {HTMLElement}\n */\n this.toggleButton_ = document.createElement('button');\n this.toggleButton_.setAttribute('type', 'button');\n this.toggleButton_.setAttribute('aria-expanded', String(!this.collapsed_));\n this.toggleButton_.title = tipLabel;\n this.toggleButton_.appendChild(activeLabel);\n\n this.toggleButton_.addEventListener(\n EventType.CLICK,\n this.handleClick_.bind(this),\n false,\n );\n\n const cssClasses =\n className +\n ' ' +\n CLASS_UNSELECTABLE +\n ' ' +\n CLASS_CONTROL +\n (this.collapsed_ && this.collapsible_ ? ' ' + CLASS_COLLAPSED : '') +\n (this.collapsible_ ? '' : ' ol-uncollapsible');\n const element = this.element;\n element.className = cssClasses;\n element.appendChild(this.toggleButton_);\n element.appendChild(this.ulElement_);\n\n /**\n * A list of currently rendered resolutions.\n * @type {Array}\n * @private\n */\n this.renderedAttributions_ = [];\n\n /**\n * @private\n * @type {boolean}\n */\n this.renderedVisible_ = true;\n }\n\n /**\n * Collect a list of visible attributions and set the collapsible state.\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @return {Array} Attributions.\n * @private\n */\n collectSourceAttributions_(frameState) {\n const layers = this.getMap().getAllLayers();\n const visibleAttributions = new Set(\n layers.flatMap((layer) => layer.getAttributions(frameState)),\n );\n if (this.attributions_ !== undefined) {\n Array.isArray(this.attributions_)\n ? this.attributions_.forEach((item) => visibleAttributions.add(item))\n : visibleAttributions.add(this.attributions_);\n }\n\n if (!this.overrideCollapsible_) {\n const collapsible = !layers.some(\n (layer) => layer.getSource()?.getAttributionsCollapsible() === false,\n );\n this.setCollapsible(collapsible);\n }\n return Array.from(visibleAttributions);\n }\n\n /**\n * @private\n * @param {?import(\"../Map.js\").FrameState} frameState Frame state.\n */\n async updateElement_(frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element.style.display = 'none';\n this.renderedVisible_ = false;\n }\n return;\n }\n\n const attributions = await Promise.all(\n this.collectSourceAttributions_(frameState).map((attribution) =>\n toPromise(() => attribution),\n ),\n );\n\n const visible = attributions.length > 0;\n if (this.renderedVisible_ != visible) {\n this.element.style.display = visible ? '' : 'none';\n this.renderedVisible_ = visible;\n }\n\n if (equals(attributions, this.renderedAttributions_)) {\n return;\n }\n\n removeChildren(this.ulElement_);\n\n // append the attributions\n for (let i = 0, ii = attributions.length; i < ii; ++i) {\n const element = document.createElement('li');\n element.innerHTML = attributions[i];\n this.ulElement_.appendChild(element);\n }\n\n this.renderedAttributions_ = attributions;\n }\n\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n handleClick_(event) {\n event.preventDefault();\n this.handleToggle_();\n this.userCollapsed_ = this.collapsed_;\n }\n\n /**\n * @private\n */\n handleToggle_() {\n this.element.classList.toggle(CLASS_COLLAPSED);\n if (this.collapsed_) {\n replaceNode(this.collapseLabel_, this.label_);\n } else {\n replaceNode(this.label_, this.collapseLabel_);\n }\n this.collapsed_ = !this.collapsed_;\n this.toggleButton_.setAttribute('aria-expanded', String(!this.collapsed_));\n }\n\n /**\n * Return `true` if the attribution is collapsible, `false` otherwise.\n * @return {boolean} True if the widget is collapsible.\n * @api\n */\n getCollapsible() {\n return this.collapsible_;\n }\n\n /**\n * Set whether the attribution should be collapsible.\n * @param {boolean} collapsible True if the widget is collapsible.\n * @api\n */\n setCollapsible(collapsible) {\n if (this.collapsible_ === collapsible) {\n return;\n }\n this.collapsible_ = collapsible;\n this.element.classList.toggle('ol-uncollapsible');\n if (this.userCollapsed_) {\n this.handleToggle_();\n }\n }\n\n /**\n * Collapse or expand the attribution according to the passed parameter. Will\n * not do anything if the attribution isn't collapsible or if the current\n * collapsed state is already the one requested.\n * @param {boolean} collapsed True if the widget is collapsed.\n * @api\n */\n setCollapsed(collapsed) {\n this.userCollapsed_ = collapsed;\n if (!this.collapsible_ || this.collapsed_ === collapsed) {\n return;\n }\n this.handleToggle_();\n }\n\n /**\n * Return `true` when the attribution is currently collapsed or `false`\n * otherwise.\n * @return {boolean} True if the widget is collapsed.\n * @api\n */\n getCollapsed() {\n return this.collapsed_;\n }\n\n /**\n * Update the attribution element.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @override\n */\n render(mapEvent) {\n this.updateElement_(mapEvent.frameState);\n }\n}\n\nexport default Attribution;\n", "/**\n * @module ol/control/Rotate\n */\nimport {CLASS_CONTROL, CLASS_HIDDEN, CLASS_UNSELECTABLE} from '../css.js';\nimport {easeOut} from '../easing.js';\nimport EventType from '../events/EventType.js';\nimport Control from './Control.js';\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-rotate'] CSS class name.\n * @property {string|HTMLElement} [label='⇧'] Text label to use for the rotate button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [tipLabel='Reset rotation'] Text label to use for the rotate tip.\n * @property {string} [compassClassName='ol-compass'] CSS class name for the compass.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {boolean} [autoHide=true] Hide the control when rotation is 0.\n * @property {function(import(\"../MapEvent.js\").default):void} [render] Function called when the control should\n * be re-rendered. This is called in a `requestAnimationFrame` callback.\n * @property {function():void} [resetNorth] Function called when the control is clicked.\n * This will override the default `resetNorth`.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map's viewport.\n */\n\n/**\n * @classdesc\n * A button control to reset rotation to 0.\n * To style this control use css selector `.ol-rotate`. A `.ol-hidden` css\n * selector is added to the button when the rotation is 0.\n *\n * @api\n */\nclass Rotate extends Control {\n /**\n * @param {Options} [options] Rotate options.\n */\n constructor(options) {\n options = options ? options : {};\n\n super({\n element: document.createElement('div'),\n render: options.render,\n target: options.target,\n });\n\n const className =\n options.className !== undefined ? options.className : 'ol-rotate';\n\n const label = options.label !== undefined ? options.label : '\\u21E7';\n\n const compassClassName =\n options.compassClassName !== undefined\n ? options.compassClassName\n : 'ol-compass';\n\n /**\n * @type {HTMLElement}\n * @private\n */\n this.label_ = null;\n\n if (typeof label === 'string') {\n this.label_ = document.createElement('span');\n this.label_.className = compassClassName;\n this.label_.textContent = label;\n } else {\n this.label_ = label;\n this.label_.classList.add(compassClassName);\n }\n\n const tipLabel = options.tipLabel ? options.tipLabel : 'Reset rotation';\n\n const button = document.createElement('button');\n button.className = className + '-reset';\n button.setAttribute('type', 'button');\n button.title = tipLabel;\n button.appendChild(this.label_);\n\n button.addEventListener(\n EventType.CLICK,\n this.handleClick_.bind(this),\n false,\n );\n\n const cssClasses =\n className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n const element = this.element;\n element.className = cssClasses;\n element.appendChild(button);\n\n /**\n * @private\n */\n this.callResetNorth_ = options.resetNorth ? options.resetNorth : undefined;\n\n /**\n * @type {number}\n * @private\n */\n this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n /**\n * @type {boolean}\n * @private\n */\n this.autoHide_ = options.autoHide !== undefined ? options.autoHide : true;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.rotation_ = undefined;\n\n if (this.autoHide_) {\n this.element.classList.add(CLASS_HIDDEN);\n }\n }\n\n /**\n * @param {MouseEvent} event The event to handle\n * @private\n */\n handleClick_(event) {\n event.preventDefault();\n if (this.callResetNorth_ !== undefined) {\n this.callResetNorth_();\n } else {\n this.resetNorth_();\n }\n }\n\n /**\n * @private\n */\n resetNorth_() {\n const map = this.getMap();\n const view = map.getView();\n if (!view) {\n // the map does not have a view, so we can't act\n // upon it\n return;\n }\n const rotation = view.getRotation();\n if (rotation !== undefined) {\n if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {\n view.animate({\n rotation: 0,\n duration: this.duration_,\n easing: easeOut,\n });\n } else {\n view.setRotation(0);\n }\n }\n }\n\n /**\n * Update the rotate control element.\n * @param {import(\"../MapEvent.js\").default} mapEvent Map event.\n * @override\n */\n render(mapEvent) {\n const frameState = mapEvent.frameState;\n if (!frameState) {\n return;\n }\n const rotation = frameState.viewState.rotation;\n if (rotation != this.rotation_) {\n const transform = 'rotate(' + rotation + 'rad)';\n if (this.autoHide_) {\n const contains = this.element.classList.contains(CLASS_HIDDEN);\n if (!contains && rotation === 0) {\n this.element.classList.add(CLASS_HIDDEN);\n } else if (contains && rotation !== 0) {\n this.element.classList.remove(CLASS_HIDDEN);\n }\n }\n this.label_.style.transform = transform;\n }\n this.rotation_ = rotation;\n }\n}\n\nexport default Rotate;\n", "/**\n * @module ol/control/Zoom\n */\nimport {CLASS_CONTROL, CLASS_UNSELECTABLE} from '../css.js';\nimport {easeOut} from '../easing.js';\nimport EventType from '../events/EventType.js';\nimport Control from './Control.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {string} [className='ol-zoom'] CSS class name.\n * @property {string} [zoomInClassName=className + '-in'] CSS class name for the zoom-in button.\n * @property {string} [zoomOutClassName=className + '-out'] CSS class name for the zoom-out button.\n * @property {string|HTMLElement} [zoomInLabel='+'] Text label to use for the zoom-in\n * button. Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string|HTMLElement} [zoomOutLabel='–'] Text label to use for the zoom-out button.\n * Instead of text, also an element (e.g. a `span` element) can be used.\n * @property {string} [zoomInTipLabel='Zoom in'] Text label to use for the button tip.\n * @property {string} [zoomOutTipLabel='Zoom out'] Text label to use for the button tip.\n * @property {number} [delta=1] The zoom delta applied on each click.\n * @property {HTMLElement|string} [target] Specify a target if you want the control to be\n * rendered outside of the map's viewport.\n */\n\n/**\n * @classdesc\n * A control with 2 buttons, one for zoom in and one for zoom out.\n * This control is one of the default controls of a map. To style this control\n * use css selectors `.ol-zoom-in` and `.ol-zoom-out`.\n *\n * @api\n */\nclass Zoom extends Control {\n /**\n * @param {Options} [options] Zoom options.\n */\n constructor(options) {\n options = options ? options : {};\n\n super({\n element: document.createElement('div'),\n target: options.target,\n });\n\n const className =\n options.className !== undefined ? options.className : 'ol-zoom';\n\n const delta = options.delta !== undefined ? options.delta : 1;\n\n const zoomInClassName =\n options.zoomInClassName !== undefined\n ? options.zoomInClassName\n : className + '-in';\n\n const zoomOutClassName =\n options.zoomOutClassName !== undefined\n ? options.zoomOutClassName\n : className + '-out';\n\n const zoomInLabel =\n options.zoomInLabel !== undefined ? options.zoomInLabel : '+';\n const zoomOutLabel =\n options.zoomOutLabel !== undefined ? options.zoomOutLabel : '\\u2013';\n\n const zoomInTipLabel =\n options.zoomInTipLabel !== undefined ? options.zoomInTipLabel : 'Zoom in';\n const zoomOutTipLabel =\n options.zoomOutTipLabel !== undefined\n ? options.zoomOutTipLabel\n : 'Zoom out';\n\n const inElement = document.createElement('button');\n inElement.className = zoomInClassName;\n inElement.setAttribute('type', 'button');\n inElement.title = zoomInTipLabel;\n inElement.appendChild(\n typeof zoomInLabel === 'string'\n ? document.createTextNode(zoomInLabel)\n : zoomInLabel,\n );\n\n inElement.addEventListener(\n EventType.CLICK,\n this.handleClick_.bind(this, delta),\n false,\n );\n\n const outElement = document.createElement('button');\n outElement.className = zoomOutClassName;\n outElement.setAttribute('type', 'button');\n outElement.title = zoomOutTipLabel;\n outElement.appendChild(\n typeof zoomOutLabel === 'string'\n ? document.createTextNode(zoomOutLabel)\n : zoomOutLabel,\n );\n\n outElement.addEventListener(\n EventType.CLICK,\n this.handleClick_.bind(this, -delta),\n false,\n );\n\n const cssClasses =\n className + ' ' + CLASS_UNSELECTABLE + ' ' + CLASS_CONTROL;\n const element = this.element;\n element.className = cssClasses;\n element.appendChild(inElement);\n element.appendChild(outElement);\n\n /**\n * @type {number}\n * @private\n */\n this.duration_ = options.duration !== undefined ? options.duration : 250;\n }\n\n /**\n * @param {number} delta Zoom delta.\n * @param {MouseEvent} event The event to handle\n * @private\n */\n handleClick_(delta, event) {\n event.preventDefault();\n this.zoomByDelta_(delta);\n }\n\n /**\n * @param {number} delta Zoom delta.\n * @private\n */\n zoomByDelta_(delta) {\n const map = this.getMap();\n const view = map.getView();\n if (!view) {\n // the map does not have a view, so we can't act\n // upon it\n return;\n }\n const currentZoom = view.getZoom();\n if (currentZoom !== undefined) {\n const newZoom = view.getConstrainedZoom(currentZoom + delta);\n if (this.duration_ > 0) {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n view.animate({\n zoom: newZoom,\n duration: this.duration_,\n easing: easeOut,\n });\n } else {\n view.setZoom(newZoom);\n }\n }\n }\n}\n\nexport default Zoom;\n", "/**\n * @module ol/control/defaults\n */\nimport Collection from '../Collection.js';\nimport Attribution from './Attribution.js';\nimport Rotate from './Rotate.js';\nimport Zoom from './Zoom.js';\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [attribution=true] Include\n * {@link module:ol/control/Attribution~Attribution}.\n * @property {import(\"./Attribution.js\").Options} [attributionOptions]\n * Options for {@link module:ol/control/Attribution~Attribution}.\n * @property {boolean} [rotate=true] Include\n * {@link module:ol/control/Rotate~Rotate}.\n * @property {import(\"./Rotate.js\").Options} [rotateOptions] Options\n * for {@link module:ol/control/Rotate~Rotate}.\n * @property {boolean} [zoom] Include {@link module:ol/control/Zoom~Zoom}.\n * @property {import(\"./Zoom.js\").Options} [zoomOptions] Options for\n * {@link module:ol/control/Zoom~Zoom}.\n */\n\n/**\n * Set of controls included in maps by default. Unless configured otherwise,\n * this returns a collection containing an instance of each of the following\n * controls:\n * {@link module:ol/control/Zoom~Zoom}\n * {@link module:ol/control/Rotate~Rotate}\n * {@link module:ol/control/Attribution~Attribution}\n *\n * @param {DefaultsOptions} [options] Options for the default controls.\n * @return {Collection} A collection of controls\n * to be used with the {@link module:ol/Map~Map} constructor's `controls` option.\n * @api\n */\nexport function defaults(options) {\n options = options ? options : {};\n\n /** @type {Collection} */\n const controls = new Collection();\n\n const zoomControl = options.zoom !== undefined ? options.zoom : true;\n if (zoomControl) {\n controls.push(new Zoom(options.zoomOptions));\n }\n\n const rotateControl = options.rotate !== undefined ? options.rotate : true;\n if (rotateControl) {\n controls.push(new Rotate(options.rotateOptions));\n }\n\n const attributionControl =\n options.attribution !== undefined ? options.attribution : true;\n if (attributionControl) {\n controls.push(new Attribution(options.attributionOptions));\n }\n\n return controls;\n}\n", "/**\n * @module ol/interaction/DoubleClickZoom\n */\nimport MapBrowserEventType from '../MapBrowserEventType.js';\nimport Interaction, {zoomByDelta} from './Interaction.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [delta=1] The zoom delta applied on each double click.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom by double-clicking on the map.\n * @api\n */\nclass DoubleClickZoom extends Interaction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n super();\n\n options = options ? options : {};\n\n /**\n * @private\n * @type {number}\n */\n this.delta_ = options.delta ? options.delta : 1;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 250;\n }\n\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a\n * doubleclick) and eventually zooms the map.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @override\n */\n handleEvent(mapBrowserEvent) {\n let stopEvent = false;\n if (mapBrowserEvent.type == MapBrowserEventType.DBLCLICK) {\n const browserEvent = /** @type {MouseEvent} */ (\n mapBrowserEvent.originalEvent\n );\n const map = mapBrowserEvent.map;\n const anchor = mapBrowserEvent.coordinate;\n const delta = browserEvent.shiftKey ? -this.delta_ : this.delta_;\n const view = map.getView();\n zoomByDelta(view, delta, anchor, this.duration_);\n browserEvent.preventDefault();\n stopEvent = true;\n }\n return !stopEvent;\n }\n}\n\nexport default DoubleClickZoom;\n", "/**\n * @module ol/interaction/DragPan\n */\nimport {\n rotate as rotateCoordinate,\n scale as scaleCoordinate,\n} from '../coordinate.js';\nimport {easeOut} from '../easing.js';\nimport {\n all,\n focusWithTabindex,\n noModifierKeys,\n primaryAction,\n} from '../events/condition.js';\nimport {FALSE} from '../functions.js';\nimport PointerInteraction, {\n centroid as centroidFromPointers,\n} from './Pointer.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition.noModifierKeys} and {@link module:ol/events/condition.primaryAction}.\n * @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {import(\"../Kinetic.js\").default} [kinetic] Kinetic inertia to apply to the pan.\n */\n\n/**\n * @classdesc\n * Allows the user to pan the map by dragging the map.\n * @api\n */\nclass DragPan extends PointerInteraction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n super({\n stopDown: FALSE,\n });\n\n options = options ? options : {};\n\n /**\n * @private\n * @type {import(\"../Kinetic.js\").default|undefined}\n */\n this.kinetic_ = options.kinetic;\n\n /**\n * @type {import(\"../pixel.js\").Pixel}\n */\n this.lastCentroid = null;\n\n /**\n * @type {number}\n * @private\n */\n this.lastPointersCount_;\n\n /**\n * @type {boolean}\n * @private\n */\n this.panning_ = false;\n\n const condition = options.condition\n ? options.condition\n : all(noModifierKeys, primaryAction);\n\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n this.condition_ = options.onFocusOnly\n ? all(focusWithTabindex, condition)\n : condition;\n\n /**\n * @private\n * @type {boolean}\n */\n this.noKinetic_ = false;\n }\n\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @override\n */\n handleDragEvent(mapBrowserEvent) {\n const map = mapBrowserEvent.map;\n if (!this.panning_) {\n this.panning_ = true;\n map.getView().beginInteraction();\n }\n const targetPointers = this.targetPointers;\n const centroid = map.getEventPixel(centroidFromPointers(targetPointers));\n if (targetPointers.length == this.lastPointersCount_) {\n if (this.kinetic_) {\n this.kinetic_.update(centroid[0], centroid[1]);\n }\n if (this.lastCentroid) {\n const delta = [\n this.lastCentroid[0] - centroid[0],\n centroid[1] - this.lastCentroid[1],\n ];\n const map = mapBrowserEvent.map;\n const view = map.getView();\n scaleCoordinate(delta, view.getResolution());\n rotateCoordinate(delta, view.getRotation());\n view.adjustCenterInternal(delta);\n }\n } else if (this.kinetic_) {\n // reset so we don't overestimate the kinetic energy after\n // after one finger down, tiny drag, second finger down\n this.kinetic_.begin();\n }\n this.lastCentroid = centroid;\n this.lastPointersCount_ = targetPointers.length;\n mapBrowserEvent.originalEvent.preventDefault();\n }\n\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleUpEvent(mapBrowserEvent) {\n const map = mapBrowserEvent.map;\n const view = map.getView();\n if (this.targetPointers.length === 0) {\n if (!this.noKinetic_ && this.kinetic_ && this.kinetic_.end()) {\n const distance = this.kinetic_.getDistance();\n const angle = this.kinetic_.getAngle();\n const center = view.getCenterInternal();\n const centerpx = map.getPixelFromCoordinateInternal(center);\n const dest = map.getCoordinateFromPixelInternal([\n centerpx[0] - distance * Math.cos(angle),\n centerpx[1] - distance * Math.sin(angle),\n ]);\n view.animateInternal({\n center: view.getConstrainedCenter(dest),\n duration: 500,\n easing: easeOut,\n });\n }\n if (this.panning_) {\n this.panning_ = false;\n view.endInteraction();\n }\n return false;\n }\n if (this.kinetic_) {\n // reset so we don't overestimate the kinetic energy after\n // after one finger up, tiny drag, second finger up\n this.kinetic_.begin();\n }\n this.lastCentroid = null;\n return true;\n }\n\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleDownEvent(mapBrowserEvent) {\n if (this.targetPointers.length > 0 && this.condition_(mapBrowserEvent)) {\n const map = mapBrowserEvent.map;\n const view = map.getView();\n this.lastCentroid = null;\n // stop any current animation\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n if (this.kinetic_) {\n this.kinetic_.begin();\n }\n // No kinetic as soon as more than one pointer on the screen is\n // detected. This is to prevent nasty pans after pinch.\n this.noKinetic_ = this.targetPointers.length > 1;\n return true;\n }\n return false;\n }\n}\n\nexport default DragPan;\n", "/**\n * @module ol/interaction/DragRotate\n */\nimport {\n altShiftKeysOnly,\n mouseActionButton,\n mouseOnly,\n} from '../events/condition.js';\nimport {FALSE} from '../functions.js';\nimport {disable} from '../rotationconstraint.js';\nimport PointerInteraction from './Pointer.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that takes a\n * {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition.altShiftKeysOnly}.\n * @property {number} [duration=250] Animation duration in milliseconds.\n */\n\n/**\n * @classdesc\n * Allows the user to rotate the map by clicking and dragging on the map,\n * normally combined with a {@link module:ol/events/condition} that limits\n * it to when the alt and shift keys are held down.\n *\n * This interaction is only supported for mouse devices.\n * @api\n */\nclass DragRotate extends PointerInteraction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {};\n\n super({\n stopDown: FALSE,\n });\n\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n this.condition_ = options.condition ? options.condition : altShiftKeysOnly;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.lastAngle_ = undefined;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 250;\n }\n\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @override\n */\n handleDragEvent(mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return;\n }\n\n const map = mapBrowserEvent.map;\n const view = map.getView();\n if (view.getConstraints().rotation === disable) {\n return;\n }\n const size = map.getSize();\n const offset = mapBrowserEvent.pixel;\n const theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);\n if (this.lastAngle_ !== undefined) {\n const delta = theta - this.lastAngle_;\n view.adjustRotationInternal(-delta);\n }\n this.lastAngle_ = theta;\n }\n\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleUpEvent(mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return true;\n }\n\n const map = mapBrowserEvent.map;\n const view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n }\n\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleDownEvent(mapBrowserEvent) {\n if (!mouseOnly(mapBrowserEvent)) {\n return false;\n }\n\n if (\n mouseActionButton(mapBrowserEvent) &&\n this.condition_(mapBrowserEvent)\n ) {\n const map = mapBrowserEvent.map;\n map.getView().beginInteraction();\n this.lastAngle_ = undefined;\n return true;\n }\n return false;\n }\n}\n\nexport default DragRotate;\n", "/**\n * @module ol/render/Box\n */\n\nimport Disposable from '../Disposable.js';\nimport Polygon from '../geom/Polygon.js';\n\nclass RenderBox extends Disposable {\n /**\n * @param {string} className CSS class name.\n */\n constructor(className) {\n super();\n\n /**\n * @type {import(\"../geom/Polygon.js\").default}\n * @private\n */\n this.geometry_ = null;\n\n /**\n * @type {HTMLDivElement}\n * @private\n */\n this.element_ = document.createElement('div');\n this.element_.style.position = 'absolute';\n this.element_.style.pointerEvents = 'auto';\n this.element_.className = 'ol-box ' + className;\n\n /**\n * @private\n * @type {import(\"../Map.js\").default|null}\n */\n this.map_ = null;\n\n /**\n * @private\n * @type {import(\"../pixel.js\").Pixel}\n */\n this.startPixel_ = null;\n\n /**\n * @private\n * @type {import(\"../pixel.js\").Pixel}\n */\n this.endPixel_ = null;\n }\n\n /**\n * Clean up.\n * @override\n */\n disposeInternal() {\n this.setMap(null);\n }\n\n /**\n * @private\n */\n render_() {\n const startPixel = this.startPixel_;\n const endPixel = this.endPixel_;\n const px = 'px';\n const style = this.element_.style;\n style.left = Math.min(startPixel[0], endPixel[0]) + px;\n style.top = Math.min(startPixel[1], endPixel[1]) + px;\n style.width = Math.abs(endPixel[0] - startPixel[0]) + px;\n style.height = Math.abs(endPixel[1] - startPixel[1]) + px;\n }\n\n /**\n * @param {import(\"../Map.js\").default|null} map Map.\n */\n setMap(map) {\n if (this.map_) {\n this.map_.getOverlayContainer().removeChild(this.element_);\n const style = this.element_.style;\n style.left = 'inherit';\n style.top = 'inherit';\n style.width = 'inherit';\n style.height = 'inherit';\n }\n this.map_ = map;\n if (this.map_) {\n this.map_.getOverlayContainer().appendChild(this.element_);\n }\n }\n\n /**\n * @param {import(\"../pixel.js\").Pixel} startPixel Start pixel.\n * @param {import(\"../pixel.js\").Pixel} endPixel End pixel.\n */\n setPixels(startPixel, endPixel) {\n this.startPixel_ = startPixel;\n this.endPixel_ = endPixel;\n this.createOrUpdateGeometry();\n this.render_();\n }\n\n /**\n * Creates or updates the cached geometry.\n */\n createOrUpdateGeometry() {\n if (!this.map_) {\n return;\n }\n\n const startPixel = this.startPixel_;\n const endPixel = this.endPixel_;\n const pixels = [\n startPixel,\n [startPixel[0], endPixel[1]],\n endPixel,\n [endPixel[0], startPixel[1]],\n ];\n const coordinates = pixels.map(\n this.map_.getCoordinateFromPixelInternal,\n this.map_,\n );\n // close the polygon\n coordinates[4] = coordinates[0].slice();\n if (!this.geometry_) {\n this.geometry_ = new Polygon([coordinates]);\n } else {\n this.geometry_.setCoordinates([coordinates]);\n }\n }\n\n /**\n * @return {import(\"../geom/Polygon.js\").default} Geometry.\n */\n getGeometry() {\n return this.geometry_;\n }\n}\n\nexport default RenderBox;\n", "/**\n * @module ol/interaction/DragBox\n */\n// FIXME draw drag box\nimport Event from '../events/Event.js';\nimport {mouseActionButton} from '../events/condition.js';\nimport RenderBox from '../render/Box.js';\nimport PointerInteraction from './Pointer.js';\n\n/**\n * A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s and returns a `{boolean}`. If the condition is met,\n * true should be returned.\n * @typedef {function(this: ?, import(\"../MapBrowserEvent.js\").default, import(\"../pixel.js\").Pixel, import(\"../pixel.js\").Pixel):boolean} EndCondition\n */\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-dragbox'] CSS class name for styling the box.\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a boolean\n * to indicate whether that event should be handled.\n * Default is {@link ol/events/condition~mouseActionButton}.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the default\n * `boxEndCondition` function.\n * @property {EndCondition} [boxEndCondition] A function that takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and two\n * {@link module:ol/pixel~Pixel}s to indicate whether a `boxend` event should be fired.\n * Default is `true` if the area of the box is bigger than the `minArea` option.\n * @property {function(this:DragBox, import(\"../MapBrowserEvent.js\").default):void} [onBoxEnd] Code to execute just\n * before `boxend` is fired.\n */\n\n/**\n * @enum {string}\n */\nconst DragBoxEventType = {\n /**\n * Triggered upon drag box start.\n * @event DragBoxEvent#boxstart\n * @api\n */\n BOXSTART: 'boxstart',\n\n /**\n * Triggered on drag when box is active.\n * @event DragBoxEvent#boxdrag\n * @api\n */\n BOXDRAG: 'boxdrag',\n\n /**\n * Triggered upon drag box end.\n * @event DragBoxEvent#boxend\n * @api\n */\n BOXEND: 'boxend',\n\n /**\n * Triggered upon drag box canceled.\n * @event DragBoxEvent#boxcancel\n * @api\n */\n BOXCANCEL: 'boxcancel',\n};\n\n/**\n * @classdesc\n * Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of\n * this type.\n */\nexport class DragBoxEvent extends Event {\n /**\n * @param {string} type The event type.\n * @param {import(\"../coordinate.js\").Coordinate} coordinate The event coordinate.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Originating event.\n */\n constructor(type, coordinate, mapBrowserEvent) {\n super(type);\n\n /**\n * The coordinate of the drag event.\n * @const\n * @type {import(\"../coordinate.js\").Coordinate}\n * @api\n */\n this.coordinate = coordinate;\n\n /**\n * @const\n * @type {import(\"../MapBrowserEvent.js\").default}\n * @api\n */\n this.mapBrowserEvent = mapBrowserEvent;\n }\n}\n\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature &\n * import(\"../Observable\").OnSignature &\n * import(\"../Observable\").OnSignature<'boxcancel'|'boxdrag'|'boxend'|'boxstart', DragBoxEvent, Return> &\n * import(\"../Observable\").CombinedOnSignature} DragBoxOnSignature\n */\n\n/**\n * @classdesc\n * Allows the user to draw a vector box by clicking and dragging on the map,\n * normally combined with a {@link module:ol/events/condition} that limits\n * it to when the shift or other key is held down. This is used, for example,\n * for zooming to a specific area of the map\n * (see {@link module:ol/interaction/DragZoom~DragZoom} and\n * {@link module:ol/interaction/DragRotateAndZoom~DragRotateAndZoom}).\n *\n * @fires DragBoxEvent\n * @api\n */\nclass DragBox extends PointerInteraction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n super();\n\n /***\n * @type {DragBoxOnSignature}\n */\n this.on;\n\n /***\n * @type {DragBoxOnSignature}\n */\n this.once;\n\n /***\n * @type {DragBoxOnSignature}\n */\n this.un;\n\n options = options ?? {};\n\n /**\n * @type {import(\"../render/Box.js\").default}\n * @private\n */\n this.box_ = new RenderBox(options.className || 'ol-dragbox');\n\n /**\n * @type {number}\n * @private\n */\n this.minArea_ = options.minArea ?? 64;\n\n if (options.onBoxEnd) {\n this.onBoxEnd = options.onBoxEnd;\n }\n\n /**\n * @type {import(\"../pixel.js\").Pixel}\n * @private\n */\n this.startPixel_ = null;\n\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n this.condition_ = options.condition ?? mouseActionButton;\n\n /**\n * @private\n * @type {EndCondition}\n */\n this.boxEndCondition_ =\n options.boxEndCondition ?? this.defaultBoxEndCondition;\n }\n\n /**\n * The default condition for determining whether the boxend event\n * should fire.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent The originating MapBrowserEvent\n * leading to the box end.\n * @param {import(\"../pixel.js\").Pixel} startPixel The starting pixel of the box.\n * @param {import(\"../pixel.js\").Pixel} endPixel The end pixel of the box.\n * @return {boolean} Whether or not the boxend condition should be fired.\n */\n defaultBoxEndCondition(mapBrowserEvent, startPixel, endPixel) {\n const width = endPixel[0] - startPixel[0];\n const height = endPixel[1] - startPixel[1];\n return width * width + height * height >= this.minArea_;\n }\n\n /**\n * Returns geometry of last drawn box.\n * @return {import(\"../geom/Polygon.js\").default} Geometry.\n * @api\n */\n getGeometry() {\n return this.box_.getGeometry();\n }\n\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @override\n */\n handleDragEvent(mapBrowserEvent) {\n if (!this.startPixel_) {\n return;\n }\n\n this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);\n\n this.dispatchEvent(\n new DragBoxEvent(\n DragBoxEventType.BOXDRAG,\n mapBrowserEvent.coordinate,\n mapBrowserEvent,\n ),\n );\n }\n\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleUpEvent(mapBrowserEvent) {\n if (!this.startPixel_) {\n return false;\n }\n\n const completeBox = this.boxEndCondition_(\n mapBrowserEvent,\n this.startPixel_,\n mapBrowserEvent.pixel,\n );\n if (completeBox) {\n this.onBoxEnd(mapBrowserEvent);\n }\n this.dispatchEvent(\n new DragBoxEvent(\n completeBox ? DragBoxEventType.BOXEND : DragBoxEventType.BOXCANCEL,\n mapBrowserEvent.coordinate,\n mapBrowserEvent,\n ),\n );\n\n this.box_.setMap(null);\n this.startPixel_ = null;\n\n return false;\n }\n\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleDownEvent(mapBrowserEvent) {\n if (this.condition_(mapBrowserEvent)) {\n this.startPixel_ = mapBrowserEvent.pixel;\n this.box_.setMap(mapBrowserEvent.map);\n this.box_.setPixels(this.startPixel_, this.startPixel_);\n this.dispatchEvent(\n new DragBoxEvent(\n DragBoxEventType.BOXSTART,\n mapBrowserEvent.coordinate,\n mapBrowserEvent,\n ),\n );\n return true;\n }\n return false;\n }\n\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import(\"../MapBrowserEvent.js\").default} event Event.\n */\n onBoxEnd(event) {}\n\n /**\n * Activate or deactivate the interaction.\n * @param {boolean} active Active.\n * @observable\n * @api\n * @override\n */\n setActive(active) {\n if (!active) {\n this.box_.setMap(null);\n if (this.startPixel_) {\n this.dispatchEvent(\n new DragBoxEvent(DragBoxEventType.BOXCANCEL, this.startPixel_, null),\n );\n this.startPixel_ = null;\n }\n }\n\n super.setActive(active);\n }\n\n /**\n * @param {import(\"../Map.js\").default|null} map Map.\n * @override\n */\n setMap(map) {\n const oldMap = this.getMap();\n\n if (oldMap) {\n this.box_.setMap(null);\n\n if (this.startPixel_) {\n this.dispatchEvent(\n new DragBoxEvent(DragBoxEventType.BOXCANCEL, this.startPixel_, null),\n );\n this.startPixel_ = null;\n }\n }\n\n super.setMap(map);\n }\n}\n\nexport default DragBox;\n", "/**\n * @module ol/interaction/DragZoom\n */\nimport {easeOut} from '../easing.js';\nimport {shiftKeyOnly} from '../events/condition.js';\nimport DragBox from './DragBox.js';\n\n/**\n * @typedef {Object} Options\n * @property {string} [className='ol-dragzoom'] CSS class name for styling the\n * box.\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled.\n * Default is {@link module:ol/events/condition.shiftKeyOnly}.\n * @property {number} [duration=200] Animation duration in milliseconds.\n * @property {boolean} [out=false] Use interaction for zooming out.\n * @property {number} [minArea=64] The minimum area of the box in pixel, this value is used by the parent default\n * `boxEndCondition` function.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by clicking and dragging on the map,\n * normally combined with a {@link module:ol/events/condition} that limits\n * it to when a key, shift by default, is held down.\n *\n * To change the style of the box, use CSS and the `.ol-dragzoom` selector, or\n * your custom one configured with `className`.\n * @api\n */\nclass DragZoom extends DragBox {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {};\n\n const condition = options.condition ? options.condition : shiftKeyOnly;\n\n super({\n condition: condition,\n className: options.className || 'ol-dragzoom',\n minArea: options.minArea,\n });\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 200;\n\n /**\n * @private\n * @type {boolean}\n */\n this.out_ = options.out !== undefined ? options.out : false;\n }\n\n /**\n * Function to execute just before `onboxend` is fired\n * @param {import(\"../MapBrowserEvent.js\").default} event Event.\n * @override\n */\n onBoxEnd(event) {\n const map = this.getMap();\n const view = /** @type {!import(\"../View.js\").default} */ (map.getView());\n let geometry = this.getGeometry();\n\n if (this.out_) {\n const rotatedExtent = view.rotatedExtentForGeometry(geometry);\n const resolution = view.getResolutionForExtentInternal(rotatedExtent);\n const factor = view.getResolution() / resolution;\n geometry = geometry.clone();\n geometry.scale(factor * factor);\n }\n\n view.fitInternal(geometry, {\n duration: this.duration_,\n easing: easeOut,\n });\n }\n}\n\nexport default DragZoom;\n", "/**\n * @module ol/events/Key\n */\n\n/**\n * @enum {string}\n * @const\n */\nexport default {\n LEFT: 'ArrowLeft',\n UP: 'ArrowUp',\n RIGHT: 'ArrowRight',\n DOWN: 'ArrowDown',\n};\n", "/**\n * @module ol/interaction/KeyboardPan\n */\nimport {rotate as rotateCoordinate} from '../coordinate.js';\nimport EventType from '../events/EventType.js';\nimport Key from '../events/Key.js';\nimport {noModifierKeys, targetNotEditable} from '../events/condition.js';\nimport Interaction, {pan} from './Interaction.js';\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition.noModifierKeys} and\n * {@link module:ol/events/condition.targetNotEditable}.\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {number} [pixelDelta=128] The amount of pixels to pan on each key\n * press.\n */\n\n/**\n * @classdesc\n * Allows the user to pan the map using keyboard arrows.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}.\n * @api\n */\nclass KeyboardPan extends Interaction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n super();\n\n options = options || {};\n\n /**\n * @private\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Browser event.\n * @return {boolean} Combined condition result.\n */\n this.defaultCondition_ = function (mapBrowserEvent) {\n return (\n noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent)\n );\n };\n\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n this.condition_ =\n options.condition !== undefined\n ? options.condition\n : this.defaultCondition_;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 100;\n\n /**\n * @private\n * @type {number}\n */\n this.pixelDelta_ =\n options.pixelDelta !== undefined ? options.pixelDelta : 128;\n }\n\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides the direction to pan to (if an arrow key was\n * pressed).\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @override\n */\n handleEvent(mapBrowserEvent) {\n let stopEvent = false;\n if (mapBrowserEvent.type == EventType.KEYDOWN) {\n const keyEvent = /** @type {KeyboardEvent} */ (\n mapBrowserEvent.originalEvent\n );\n const key = keyEvent.key;\n if (\n this.condition_(mapBrowserEvent) &&\n (key == Key.DOWN ||\n key == Key.LEFT ||\n key == Key.RIGHT ||\n key == Key.UP)\n ) {\n const map = mapBrowserEvent.map;\n const view = map.getView();\n const mapUnitsDelta = view.getResolution() * this.pixelDelta_;\n let deltaX = 0,\n deltaY = 0;\n if (key == Key.DOWN) {\n deltaY = -mapUnitsDelta;\n } else if (key == Key.LEFT) {\n deltaX = -mapUnitsDelta;\n } else if (key == Key.RIGHT) {\n deltaX = mapUnitsDelta;\n } else {\n deltaY = mapUnitsDelta;\n }\n const delta = [deltaX, deltaY];\n rotateCoordinate(delta, view.getRotation());\n pan(view, delta, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n return !stopEvent;\n }\n}\n\nexport default KeyboardPan;\n", "/**\n * @module ol/interaction/KeyboardZoom\n */\nimport EventType from '../events/EventType.js';\nimport {platformModifierKey, targetNotEditable} from '../events/condition.js';\nimport Interaction, {zoomByDelta} from './Interaction.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=100] Animation duration in milliseconds.\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. The default condition is\n * that {@link module:ol/events/condition.targetNotEditable} is fulfilled and that\n * the platform modifier key isn't pressed\n * (!{@link module:ol/events/condition.platformModifierKey}).\n * @property {number} [delta=1] The zoom level delta on each key press.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map using keyboard + and -.\n * Note that, although this interaction is by default included in maps,\n * the keys can only be used when browser focus is on the element to which\n * the keyboard events are attached. By default, this is the map div,\n * though you can change this with the `keyboardEventTarget` in\n * {@link module:ol/Map~Map}. `document` never loses focus but, for any other\n * element, focus will have to be on, and returned to, this element if the keys\n * are to function.\n * See also {@link module:ol/interaction/KeyboardPan~KeyboardPan}.\n * @api\n */\nclass KeyboardZoom extends Interaction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n super();\n\n options = options ? options : {};\n\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n this.condition_ = options.condition\n ? options.condition\n : function (mapBrowserEvent) {\n return (\n !platformModifierKey(mapBrowserEvent) &&\n targetNotEditable(mapBrowserEvent)\n );\n };\n\n /**\n * @private\n * @type {number}\n */\n this.delta_ = options.delta ? options.delta : 1;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 100;\n }\n\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} if it was a\n * `KeyEvent`, and decides whether to zoom in or out (depending on whether the\n * key pressed was '+' or '-').\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @override\n */\n handleEvent(mapBrowserEvent) {\n let stopEvent = false;\n if (\n mapBrowserEvent.type == EventType.KEYDOWN ||\n mapBrowserEvent.type == EventType.KEYPRESS\n ) {\n const keyEvent = /** @type {KeyboardEvent} */ (\n mapBrowserEvent.originalEvent\n );\n const key = keyEvent.key;\n if (this.condition_(mapBrowserEvent) && (key === '+' || key === '-')) {\n const map = mapBrowserEvent.map;\n const delta = key === '+' ? this.delta_ : -this.delta_;\n const view = map.getView();\n zoomByDelta(view, delta, undefined, this.duration_);\n keyEvent.preventDefault();\n stopEvent = true;\n }\n }\n return !stopEvent;\n }\n}\n\nexport default KeyboardZoom;\n", "/**\n * @module ol/interaction/MouseWheelZoom\n */\nimport EventType from '../events/EventType.js';\nimport {all, always, focusWithTabindex} from '../events/condition.js';\nimport {DEVICE_PIXEL_RATIO, FIREFOX} from '../has.js';\nimport {clamp} from '../math.js';\nimport Interaction, {zoomByDelta} from './Interaction.js';\n\n/**\n * @typedef {'trackpad' | 'wheel'} Mode\n */\n\n/**\n * @typedef {Object} Options\n * @property {import(\"../events/condition.js\").Condition} [condition] A function that\n * takes a {@link module:ol/MapBrowserEvent~MapBrowserEvent} and returns a\n * boolean to indicate whether that event should be handled. Default is\n * {@link module:ol/events/condition.always}.\n * @property {boolean} [onFocusOnly=false] When the map's target has a `tabindex` attribute set,\n * the interaction will only handle events when the map has the focus.\n * @property {number} [maxDelta=1] Maximum mouse wheel delta.\n * @property {number} [duration=250] Animation duration in milliseconds.\n * @property {number} [timeout=80] Mouse wheel timeout duration in milliseconds.\n * @property {boolean} [useAnchor=true] Enable zooming using the mouse's\n * location as the anchor. When set to `false`, zooming in and out will zoom to\n * the center of the screen instead of zooming on the mouse's location.\n * @property {boolean} [constrainResolution=false] If true, the mouse wheel zoom\n * event will always animate to the closest zoom level after an interaction;\n * false means intermediary zoom levels are allowed.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by scrolling the mouse wheel.\n * @api\n */\nclass MouseWheelZoom extends Interaction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {};\n\n super(\n /** @type {import(\"./Interaction.js\").InteractionOptions} */ (options),\n );\n\n /**\n * @private\n * @type {number}\n */\n this.totalDelta_ = 0;\n\n /**\n * @private\n * @type {number}\n */\n this.lastDelta_ = 0;\n\n /**\n * @private\n * @type {number}\n */\n this.maxDelta_ = options.maxDelta !== undefined ? options.maxDelta : 1;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 250;\n\n /**\n * @private\n * @type {number}\n */\n this.timeout_ = options.timeout !== undefined ? options.timeout : 80;\n\n /**\n * @private\n * @type {boolean}\n */\n this.useAnchor_ =\n options.useAnchor !== undefined ? options.useAnchor : true;\n\n /**\n * @private\n * @type {boolean}\n */\n this.constrainResolution_ =\n options.constrainResolution !== undefined\n ? options.constrainResolution\n : false;\n\n const condition = options.condition ? options.condition : always;\n\n /**\n * @private\n * @type {import(\"../events/condition.js\").Condition}\n */\n this.condition_ = options.onFocusOnly\n ? all(focusWithTabindex, condition)\n : condition;\n\n /**\n * @private\n * @type {?import(\"../pixel.js\").Pixel}\n */\n this.lastAnchor_ = null;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.startTime_ = undefined;\n\n /**\n * @private\n * @type {ReturnType}\n */\n this.timeoutId_;\n\n /**\n * @private\n * @type {Mode|undefined}\n */\n this.mode_ = undefined;\n\n /**\n * Trackpad events separated by this delay will be considered separate\n * interactions.\n * @private\n * @type {number}\n */\n this.trackpadEventGap_ = 400;\n\n /**\n * @private\n * @type {ReturnType}\n */\n this.trackpadTimeoutId_;\n\n /**\n * The number of delta values per zoom level\n * @private\n * @type {number}\n */\n this.deltaPerZoom_ = 300;\n }\n\n /**\n * @private\n */\n endInteraction_() {\n this.trackpadTimeoutId_ = undefined;\n const map = this.getMap();\n if (!map) {\n return;\n }\n const view = map.getView();\n view.endInteraction(\n undefined,\n this.lastDelta_ ? (this.lastDelta_ > 0 ? 1 : -1) : 0,\n this.lastAnchor_ ? map.getCoordinateFromPixel(this.lastAnchor_) : null,\n );\n }\n\n /**\n * Handles the {@link module:ol/MapBrowserEvent~MapBrowserEvent map browser event} (if it was a mousewheel-event) and eventually\n * zooms the map.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Map browser event.\n * @return {boolean} `false` to stop event propagation.\n * @override\n */\n handleEvent(mapBrowserEvent) {\n if (!this.condition_(mapBrowserEvent)) {\n return true;\n }\n const type = mapBrowserEvent.type;\n if (type !== EventType.WHEEL) {\n return true;\n }\n\n const map = mapBrowserEvent.map;\n const wheelEvent = /** @type {WheelEvent} */ (\n mapBrowserEvent.originalEvent\n );\n wheelEvent.preventDefault();\n\n if (this.useAnchor_) {\n this.lastAnchor_ = mapBrowserEvent.pixel;\n }\n\n // Delta normalisation inspired by\n // https://github.com/mapbox/mapbox-gl-js/blob/001c7b9/js/ui/handler/scroll_zoom.js\n let delta;\n if (mapBrowserEvent.type == EventType.WHEEL) {\n delta = wheelEvent.deltaY;\n if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {\n delta /= DEVICE_PIXEL_RATIO;\n }\n if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {\n delta *= 40;\n }\n }\n\n if (delta === 0) {\n return false;\n }\n this.lastDelta_ = delta;\n\n const now = Date.now();\n\n if (this.startTime_ === undefined) {\n this.startTime_ = now;\n }\n\n if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {\n this.mode_ = Math.abs(delta) < 4 ? 'trackpad' : 'wheel';\n }\n\n const view = map.getView();\n if (\n this.mode_ === 'trackpad' &&\n !(view.getConstrainResolution() || this.constrainResolution_)\n ) {\n if (this.trackpadTimeoutId_) {\n clearTimeout(this.trackpadTimeoutId_);\n } else {\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n view.beginInteraction();\n }\n this.trackpadTimeoutId_ = setTimeout(\n this.endInteraction_.bind(this),\n this.timeout_,\n );\n view.adjustZoom(\n -delta / this.deltaPerZoom_,\n this.lastAnchor_ ? map.getCoordinateFromPixel(this.lastAnchor_) : null,\n );\n this.startTime_ = now;\n return false;\n }\n\n this.totalDelta_ += delta;\n\n const timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);\n\n clearTimeout(this.timeoutId_);\n this.timeoutId_ = setTimeout(\n this.handleWheelZoom_.bind(this, map),\n timeLeft,\n );\n\n return false;\n }\n\n /**\n * @private\n * @param {import(\"../Map.js\").default} map Map.\n */\n handleWheelZoom_(map) {\n const view = map.getView();\n if (view.getAnimating()) {\n view.cancelAnimations();\n }\n let delta =\n -clamp(\n this.totalDelta_,\n -this.maxDelta_ * this.deltaPerZoom_,\n this.maxDelta_ * this.deltaPerZoom_,\n ) / this.deltaPerZoom_;\n if (view.getConstrainResolution() || this.constrainResolution_) {\n // view has a zoom constraint, zoom by 1\n delta = delta ? (delta > 0 ? 1 : -1) : 0;\n }\n zoomByDelta(\n view,\n delta,\n this.lastAnchor_ ? map.getCoordinateFromPixel(this.lastAnchor_) : null,\n this.duration_,\n );\n\n this.mode_ = undefined;\n this.totalDelta_ = 0;\n this.lastAnchor_ = null;\n this.startTime_ = undefined;\n this.timeoutId_ = undefined;\n }\n\n /**\n * Enable or disable using the mouse's location as an anchor when zooming\n * @param {boolean} useAnchor true to zoom to the mouse's location, false\n * to zoom to the center of the map\n * @api\n */\n setMouseAnchor(useAnchor) {\n this.useAnchor_ = useAnchor;\n if (!useAnchor) {\n this.lastAnchor_ = null;\n }\n }\n}\n\nexport default MouseWheelZoom;\n", "/**\n * @module ol/interaction/PinchRotate\n */\nimport {FALSE} from '../functions.js';\nimport {disable} from '../rotationconstraint.js';\nimport PointerInteraction, {\n centroid as centroidFromPointers,\n} from './Pointer.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=250] The duration of the animation in\n * milliseconds.\n * @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.\n */\n\n/**\n * @classdesc\n * Allows the user to rotate the map by twisting with two fingers\n * on a touch screen.\n * @api\n */\nclass PinchRotate extends PointerInteraction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {};\n\n const pointerOptions = /** @type {import(\"./Pointer.js\").Options} */ (\n options\n );\n\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = FALSE;\n }\n\n super(pointerOptions);\n\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate}\n */\n this.anchor_ = null;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.lastAngle_ = undefined;\n\n /**\n * @private\n * @type {boolean}\n */\n this.rotating_ = false;\n\n /**\n * @private\n * @type {number}\n */\n this.rotationDelta_ = 0.0;\n\n /**\n * @private\n * @type {number}\n */\n this.threshold_ = options.threshold !== undefined ? options.threshold : 0.3;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 250;\n }\n\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @override\n */\n handleDragEvent(mapBrowserEvent) {\n let rotationDelta = 0.0;\n\n const touch0 = this.targetPointers[0];\n const touch1 = this.targetPointers[1];\n\n // angle between touches\n const angle = Math.atan2(\n touch1.clientY - touch0.clientY,\n touch1.clientX - touch0.clientX,\n );\n\n if (this.lastAngle_ !== undefined) {\n const delta = angle - this.lastAngle_;\n this.rotationDelta_ += delta;\n if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {\n this.rotating_ = true;\n }\n rotationDelta = delta;\n }\n this.lastAngle_ = angle;\n\n const map = mapBrowserEvent.map;\n const view = map.getView();\n if (view.getConstraints().rotation === disable) {\n return;\n }\n\n // rotate anchor point.\n // FIXME: should be the intersection point between the lines:\n // touch0,touch1 and previousTouch0,previousTouch1\n this.anchor_ = map.getCoordinateFromPixelInternal(\n map.getEventPixel(centroidFromPointers(this.targetPointers)),\n );\n\n // rotate\n if (this.rotating_) {\n map.render();\n view.adjustRotationInternal(rotationDelta, this.anchor_);\n }\n }\n\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleUpEvent(mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n const map = mapBrowserEvent.map;\n const view = map.getView();\n view.endInteraction(this.duration_);\n return false;\n }\n return true;\n }\n\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleDownEvent(mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n const map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastAngle_ = undefined;\n this.rotating_ = false;\n this.rotationDelta_ = 0.0;\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n return true;\n }\n return false;\n }\n}\n\nexport default PinchRotate;\n", "/**\n * @module ol/interaction/PinchZoom\n */\nimport {FALSE} from '../functions.js';\nimport PointerInteraction, {\n centroid as centroidFromPointers,\n} from './Pointer.js';\n\n/**\n * @typedef {Object} Options\n * @property {number} [duration=400] Animation duration in milliseconds.\n */\n\n/**\n * @classdesc\n * Allows the user to zoom the map by pinching with two fingers\n * on a touch screen.\n * @api\n */\nclass PinchZoom extends PointerInteraction {\n /**\n * @param {Options} [options] Options.\n */\n constructor(options) {\n options = options ? options : {};\n\n const pointerOptions = /** @type {import(\"./Pointer.js\").Options} */ (\n options\n );\n\n if (!pointerOptions.stopDown) {\n pointerOptions.stopDown = FALSE;\n }\n\n super(pointerOptions);\n\n /**\n * @private\n * @type {import(\"../coordinate.js\").Coordinate}\n */\n this.anchor_ = null;\n\n /**\n * @private\n * @type {number}\n */\n this.duration_ = options.duration !== undefined ? options.duration : 400;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.lastDistance_ = undefined;\n\n /**\n * @private\n * @type {number}\n */\n this.lastScaleDelta_ = 1;\n }\n\n /**\n * Handle pointer drag events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @override\n */\n handleDragEvent(mapBrowserEvent) {\n let scaleDelta = 1.0;\n\n const touch0 = this.targetPointers[0];\n const touch1 = this.targetPointers[1];\n const dx = touch0.clientX - touch1.clientX;\n const dy = touch0.clientY - touch1.clientY;\n\n // distance between touches\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (this.lastDistance_ !== undefined) {\n scaleDelta = this.lastDistance_ / distance;\n }\n this.lastDistance_ = distance;\n\n const map = mapBrowserEvent.map;\n const view = map.getView();\n\n if (scaleDelta != 1.0) {\n this.lastScaleDelta_ = scaleDelta;\n }\n\n // scale anchor point.\n this.anchor_ = map.getCoordinateFromPixelInternal(\n map.getEventPixel(centroidFromPointers(this.targetPointers)),\n );\n\n // scale, bypass the resolution constraint\n map.render();\n view.adjustResolutionInternal(scaleDelta, this.anchor_);\n }\n\n /**\n * Handle pointer up events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleUpEvent(mapBrowserEvent) {\n if (this.targetPointers.length < 2) {\n const map = mapBrowserEvent.map;\n const view = map.getView();\n const direction = this.lastScaleDelta_ > 1 ? 1 : -1;\n view.endInteraction(this.duration_, direction);\n return false;\n }\n return true;\n }\n\n /**\n * Handle pointer down events.\n * @param {import(\"../MapBrowserEvent.js\").default} mapBrowserEvent Event.\n * @return {boolean} If the event was consumed.\n * @override\n */\n handleDownEvent(mapBrowserEvent) {\n if (this.targetPointers.length >= 2) {\n const map = mapBrowserEvent.map;\n this.anchor_ = null;\n this.lastDistance_ = undefined;\n this.lastScaleDelta_ = 1;\n if (!this.handlingDownUpSequence) {\n map.getView().beginInteraction();\n }\n return true;\n }\n return false;\n }\n}\n\nexport default PinchZoom;\n", "/**\n * @module ol/interaction/defaults\n */\nimport Collection from '../Collection.js';\nimport Kinetic from '../Kinetic.js';\nimport DoubleClickZoom from './DoubleClickZoom.js';\nimport DragPan from './DragPan.js';\nimport DragRotate from './DragRotate.js';\nimport DragZoom from './DragZoom.js';\nimport KeyboardPan from './KeyboardPan.js';\nimport KeyboardZoom from './KeyboardZoom.js';\nimport MouseWheelZoom from './MouseWheelZoom.js';\nimport PinchRotate from './PinchRotate.js';\nimport PinchZoom from './PinchZoom.js';\n\n/**\n * @typedef {Object} DefaultsOptions\n * @property {boolean} [altShiftDragRotate=true] Whether Alt-Shift-drag rotate is\n * desired.\n * @property {boolean} [onFocusOnly=false] Interact only when the map has the\n * focus. This affects the `MouseWheelZoom` and `DragPan` interactions and is\n * useful when page scroll is desired for maps that do not have the browser's\n * focus.\n * @property {boolean} [doubleClickZoom=true] Whether double click zoom is\n * desired.\n * @property {boolean} [keyboard=true] Whether keyboard interaction is desired.\n * @property {boolean} [mouseWheelZoom=true] Whether mousewheel zoom is desired.\n * @property {boolean} [shiftDragZoom=true] Whether Shift-drag zoom is desired.\n * @property {boolean} [dragPan=true] Whether drag pan is desired.\n * @property {boolean} [pinchRotate=true] Whether pinch rotate is desired.\n * @property {boolean} [pinchZoom=true] Whether pinch zoom is desired.\n * @property {number} [zoomDelta] Zoom level delta when using keyboard or double click zoom.\n * @property {number} [zoomDuration] Duration of the zoom animation in\n * milliseconds.\n */\n\n/**\n * Set of interactions included in maps by default. Specific interactions can be\n * excluded by setting the appropriate option to false in the constructor\n * options, but the order of the interactions is fixed. If you want to specify\n * a different order for interactions, you will need to create your own\n * {@link module:ol/interaction/Interaction~Interaction} instances and insert\n * them into a {@link module:ol/Collection~Collection} in the order you want\n * before creating your {@link module:ol/Map~Map} instance. Changing the order can\n * be of interest if the event propagation needs to be stopped at a point.\n * The default set of interactions, in sequence, is:\n * {@link module:ol/interaction/DragRotate~DragRotate}\n * {@link module:ol/interaction/DoubleClickZoom~DoubleClickZoom}\n * {@link module:ol/interaction/DragPan~DragPan}\n * {@link module:ol/interaction/PinchRotate~PinchRotate}\n * {@link module:ol/interaction/PinchZoom~PinchZoom}\n * {@link module:ol/interaction/KeyboardPan~KeyboardPan}\n * {@link module:ol/interaction/KeyboardZoom~KeyboardZoom}\n * {@link module:ol/interaction/MouseWheelZoom~MouseWheelZoom}\n * {@link module:ol/interaction/DragZoom~DragZoom}\n *\n * @param {DefaultsOptions} [options] Defaults options.\n * @return {Collection}\n * A collection of interactions to be used with the {@link module:ol/Map~Map}\n * constructor's `interactions` option.\n * @api\n */\nexport function defaults(options) {\n options = options ? options : {};\n\n /** @type {Collection} */\n const interactions = new Collection();\n\n const kinetic = new Kinetic(-0.005, 0.05, 100);\n\n const altShiftDragRotate =\n options.altShiftDragRotate !== undefined\n ? options.altShiftDragRotate\n : true;\n if (altShiftDragRotate) {\n interactions.push(new DragRotate());\n }\n\n const doubleClickZoom =\n options.doubleClickZoom !== undefined ? options.doubleClickZoom : true;\n if (doubleClickZoom) {\n interactions.push(\n new DoubleClickZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration,\n }),\n );\n }\n\n const dragPan = options.dragPan !== undefined ? options.dragPan : true;\n if (dragPan) {\n interactions.push(\n new DragPan({\n onFocusOnly: options.onFocusOnly,\n kinetic: kinetic,\n }),\n );\n }\n\n const pinchRotate =\n options.pinchRotate !== undefined ? options.pinchRotate : true;\n if (pinchRotate) {\n interactions.push(new PinchRotate());\n }\n\n const pinchZoom = options.pinchZoom !== undefined ? options.pinchZoom : true;\n if (pinchZoom) {\n interactions.push(\n new PinchZoom({\n duration: options.zoomDuration,\n }),\n );\n }\n\n const keyboard = options.keyboard !== undefined ? options.keyboard : true;\n if (keyboard) {\n interactions.push(new KeyboardPan());\n interactions.push(\n new KeyboardZoom({\n delta: options.zoomDelta,\n duration: options.zoomDuration,\n }),\n );\n }\n\n const mouseWheelZoom =\n options.mouseWheelZoom !== undefined ? options.mouseWheelZoom : true;\n if (mouseWheelZoom) {\n interactions.push(\n new MouseWheelZoom({\n onFocusOnly: options.onFocusOnly,\n duration: options.zoomDuration,\n }),\n );\n }\n\n const shiftDragZoom =\n options.shiftDragZoom !== undefined ? options.shiftDragZoom : true;\n if (shiftDragZoom) {\n interactions.push(\n new DragZoom({\n duration: options.zoomDuration,\n }),\n );\n }\n\n return interactions;\n}\n", "/**\n * @module ol/layer/Group\n */\nimport Collection from '../Collection.js';\nimport CollectionEventType from '../CollectionEventType.js';\nimport ObjectEventType from '../ObjectEventType.js';\nimport {assert} from '../asserts.js';\nimport Event from '../events/Event.js';\nimport EventType from '../events/EventType.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport {getIntersection} from '../extent.js';\nimport {clear} from '../obj.js';\nimport {getUid} from '../util.js';\nimport BaseLayer from './Base.js';\n\n/**\n * @typedef {'addlayer'|'removelayer'} GroupEventType\n */\n\n/**\n * @classdesc\n * A layer group triggers 'addlayer' and 'removelayer' events when layers are added to or removed from\n * the group or one of its child groups. When a layer group is added to or removed from another layer group,\n * a single event will be triggered (instead of one per layer in the group added or removed).\n */\nexport class GroupEvent extends Event {\n /**\n * @param {GroupEventType} type The event type.\n * @param {BaseLayer} layer The layer.\n */\n constructor(type, layer) {\n super(type);\n\n /**\n * The added or removed layer.\n * @type {BaseLayer}\n * @api\n */\n this.layer = layer;\n }\n}\n\n/***\n * @template Return\n * @typedef {import(\"../Observable\").OnSignature &\n * import(\"../Observable\").OnSignature &\n * import(\"../Observable\").CombinedOnSignature} GroupOnSignature\n */\n\n/**\n * @typedef {Object} Options\n * @property {number} [opacity=1] Opacity (0, 1).\n * @property {boolean} [visible=true] Visibility.\n * @property {import(\"../extent.js\").Extent} [extent] The bounding extent for layer rendering. The layer will not be\n * rendered outside of this extent.\n * @property {number} [zIndex] The z-index for layer rendering. At rendering time, the layers\n * will be ordered, first by Z-index and then by position. When `undefined`, a `zIndex` of 0 is assumed\n * for layers that are added to the map's `layers` collection, or `Infinity` when the layer's `setMap()`\n * method was used.\n * @property {number} [minResolution] The minimum resolution (inclusive) at which this layer will be\n * visible.\n * @property {number} [maxResolution] The maximum resolution (exclusive) below which this layer will\n * be visible.\n * @property {number} [minZoom] The minimum view zoom level (exclusive) above which this layer will be\n * visible.\n * @property {number} [maxZoom] The maximum view zoom level (inclusive) at which this layer will\n * be visible.\n * @property {Array|Collection} [layers] Child layers.\n * @property {Object} [properties] Arbitrary observable properties. Can be accessed with `#get()` and `#set()`.\n */\n\n/**\n * @enum {string}\n * @private\n */\nconst Property = {\n LAYERS: 'layers',\n};\n\n/**\n * @classdesc\n * A {@link module:ol/Collection~Collection} of layers that are handled together.\n *\n * A generic `change` event is triggered when the group/Collection changes.\n *\n * @api\n */\nclass LayerGroup extends BaseLayer {\n /**\n * @param {Options} [options] Layer options.\n */\n constructor(options) {\n options = options || {};\n const baseOptions = /** @type {Options} */ (Object.assign({}, options));\n delete baseOptions.layers;\n\n let layers = options.layers;\n\n super(baseOptions);\n\n /***\n * @type {GroupOnSignature}\n */\n this.on;\n\n /***\n * @type {GroupOnSignature}\n */\n this.once;\n\n /***\n * @type {GroupOnSignature}\n */\n this.un;\n\n /**\n * @private\n * @type {Array}\n */\n this.layersListenerKeys_ = [];\n\n /**\n * @private\n * @type {Object>}\n */\n this.listenerKeys_ = {};\n\n this.addChangeListener(Property.LAYERS, this.handleLayersChanged_);\n\n if (layers) {\n if (Array.isArray(layers)) {\n layers = new Collection(layers.slice(), {unique: true});\n } else {\n assert(\n typeof (/** @type {?} */ (layers).getArray) === 'function',\n 'Expected `layers` to be an array or a `Collection`',\n );\n }\n } else {\n layers = new Collection(undefined, {unique: true});\n }\n\n this.setLayers(layers);\n }\n\n /**\n * @private\n */\n handleLayerChange_() {\n this.changed();\n }\n\n /**\n * @private\n */\n handleLayersChanged_() {\n this.layersListenerKeys_.forEach(unlistenByKey);\n this.layersListenerKeys_.length = 0;\n\n const layers = this.getLayers();\n this.layersListenerKeys_.push(\n listen(layers, CollectionEventType.ADD, this.handleLayersAdd_, this),\n listen(\n layers,\n CollectionEventType.REMOVE,\n this.handleLayersRemove_,\n this,\n ),\n );\n\n for (const id in this.listenerKeys_) {\n this.listenerKeys_[id].forEach(unlistenByKey);\n }\n clear(this.listenerKeys_);\n\n const layersArray = layers.getArray();\n for (let i = 0, ii = layersArray.length; i < ii; i++) {\n const layer = layersArray[i];\n this.registerLayerListeners_(layer);\n this.dispatchEvent(new GroupEvent('addlayer', layer));\n }\n this.changed();\n }\n\n /**\n * @param {BaseLayer} layer The layer.\n */\n registerLayerListeners_(layer) {\n const listenerKeys = [\n listen(\n layer,\n ObjectEventType.PROPERTYCHANGE,\n this.handleLayerChange_,\n this,\n ),\n listen(layer, EventType.CHANGE, this.handleLayerChange_, this),\n ];\n\n if (layer instanceof LayerGroup) {\n listenerKeys.push(\n listen(layer, 'addlayer', this.handleLayerGroupAdd_, this),\n listen(layer, 'removelayer', this.handleLayerGroupRemove_, this),\n );\n }\n\n this.listenerKeys_[getUid(layer)] = listenerKeys;\n }\n\n /**\n * @param {GroupEvent} event The layer group event.\n */\n handleLayerGroupAdd_(event) {\n this.dispatchEvent(new GroupEvent('addlayer', event.layer));\n }\n\n /**\n * @param {GroupEvent} event The layer group event.\n */\n handleLayerGroupRemove_(event) {\n this.dispatchEvent(new GroupEvent('removelayer', event.layer));\n }\n\n /**\n * @param {import(\"../Collection.js\").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n handleLayersAdd_(collectionEvent) {\n const layer = collectionEvent.element;\n this.registerLayerListeners_(layer);\n this.dispatchEvent(new GroupEvent('addlayer', layer));\n this.changed();\n }\n\n /**\n * @param {import(\"../Collection.js\").CollectionEvent} collectionEvent CollectionEvent.\n * @private\n */\n handleLayersRemove_(collectionEvent) {\n const layer = collectionEvent.element;\n const key = getUid(layer);\n this.listenerKeys_[key].forEach(unlistenByKey);\n delete this.listenerKeys_[key];\n this.dispatchEvent(new GroupEvent('removelayer', layer));\n this.changed();\n }\n\n /**\n * Returns the {@link module:ol/Collection~Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @return {!Collection} Collection of\n * {@link module:ol/layer/Base~BaseLayer layers} that are part of this group.\n * @observable\n * @api\n */\n getLayers() {\n return /** @type {!Collection} */ (\n this.get(Property.LAYERS)\n );\n }\n\n /**\n * Set the {@link module:ol/Collection~Collection collection} of {@link module:ol/layer/Layer~Layer layers}\n * in this group.\n * @param {!Collection} layers Collection of\n * {@link module:ol/layer/Base~BaseLayer layers} that are part of this group.\n * @observable\n * @api\n */\n setLayers(layers) {\n const collection = this.getLayers();\n if (collection) {\n const currentLayers = collection.getArray();\n for (let i = 0, ii = currentLayers.length; i < ii; ++i) {\n this.dispatchEvent(new GroupEvent('removelayer', currentLayers[i]));\n }\n }\n\n this.set(Property.LAYERS, layers);\n }\n\n /**\n * @param {Array} [array] Array of layers (to be modified in place).\n * @return {Array} Array of layers.\n * @override\n */\n getLayersArray(array) {\n array = array !== undefined ? array : [];\n this.getLayers().forEach(function (layer) {\n layer.getLayersArray(array);\n });\n return array;\n }\n\n /**\n * Get the layer states list and use this groups z-index as the default\n * for all layers in this and nested groups, if it is unset at this point.\n * If dest is not provided and this group's z-index is undefined\n * 0 is used a the default z-index.\n * @param {Array} [dest] Optional list\n * of layer states (to be modified in place).\n * @return {Array} List of layer states.\n * @override\n */\n getLayerStatesArray(dest) {\n const states = dest !== undefined ? dest : [];\n const pos = states.length;\n\n this.getLayers().forEach(function (layer) {\n layer.getLayerStatesArray(states);\n });\n\n const ownLayerState = this.getLayerState();\n let defaultZIndex = ownLayerState.zIndex;\n if (!dest && ownLayerState.zIndex === undefined) {\n defaultZIndex = 0;\n }\n for (let i = pos, ii = states.length; i < ii; i++) {\n const layerState = states[i];\n layerState.opacity *= ownLayerState.opacity;\n layerState.visible = layerState.visible && ownLayerState.visible;\n layerState.maxResolution = Math.min(\n layerState.maxResolution,\n ownLayerState.maxResolution,\n );\n layerState.minResolution = Math.max(\n layerState.minResolution,\n ownLayerState.minResolution,\n );\n layerState.minZoom = Math.max(layerState.minZoom, ownLayerState.minZoom);\n layerState.maxZoom = Math.min(layerState.maxZoom, ownLayerState.maxZoom);\n if (ownLayerState.extent !== undefined) {\n if (layerState.extent !== undefined) {\n layerState.extent = getIntersection(\n layerState.extent,\n ownLayerState.extent,\n );\n } else {\n layerState.extent = ownLayerState.extent;\n }\n }\n if (layerState.zIndex === undefined) {\n layerState.zIndex = defaultZIndex;\n }\n }\n\n return states;\n }\n\n /**\n * @return {import(\"../source/Source.js\").State} Source state.\n * @override\n */\n getSourceState() {\n return 'ready';\n }\n}\n\nexport default LayerGroup;\n", "/**\n * @module ol/renderer/Map\n */\nimport Disposable from '../Disposable.js';\nimport {wrapX} from '../coordinate.js';\nimport {getWidth} from '../extent.js';\nimport {TRUE} from '../functions.js';\nimport {inView} from '../layer/Layer.js';\nimport {shared as iconImageCache} from '../style/IconImageCache.js';\nimport {compose as composeTransform, makeInverse} from '../transform.js';\nimport {abstract} from '../util.js';\n\n/**\n * @template T\n * @typedef HitMatch\n * @property {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @property {import(\"../layer/Layer.js\").default} layer Layer.\n * @property {import(\"../geom/SimpleGeometry.js\").default} geometry Geometry.\n * @property {number} distanceSq Squared distance.\n * @property {import(\"./vector.js\").FeatureCallback} callback Callback.\n */\n\n/**\n * @abstract\n */\nclass MapRenderer extends Disposable {\n /**\n * @param {import(\"../Map.js\").default} map Map.\n */\n constructor(map) {\n super();\n\n /**\n * @private\n * @type {import(\"../Map.js\").default}\n */\n this.map_ = map;\n }\n\n /**\n * @abstract\n * @param {import(\"../render/EventType.js\").default} type Event type.\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n */\n dispatchRenderEvent(type, frameState) {\n abstract();\n }\n\n /**\n * @param {import(\"../Map.js\").FrameState} frameState FrameState.\n * @protected\n */\n calculateMatrices2D(frameState) {\n const viewState = frameState.viewState;\n const coordinateToPixelTransform = frameState.coordinateToPixelTransform;\n const pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;\n\n composeTransform(\n coordinateToPixelTransform,\n frameState.size[0] / 2,\n frameState.size[1] / 2,\n 1 / viewState.resolution,\n -1 / viewState.resolution,\n -viewState.rotation,\n -viewState.center[0],\n -viewState.center[1],\n );\n\n makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform);\n }\n\n /**\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../Map.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {import(\"./vector.js\").FeatureCallback} callback Feature callback.\n * @param {S} thisArg Value to use as `this` when executing `callback`.\n * @param {function(this: U, import(\"../layer/Layer.js\").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.\n * @return {T|undefined} Callback result.\n * @template S,T,U\n */\n forEachFeatureAtCoordinate(\n coordinate,\n frameState,\n hitTolerance,\n checkWrapped,\n callback,\n thisArg,\n layerFilter,\n thisArg2,\n ) {\n let result;\n const viewState = frameState.viewState;\n\n /**\n * @param {boolean} managed Managed layer.\n * @param {import(\"../Feature.js\").FeatureLike} feature Feature.\n * @param {import(\"../layer/Layer.js\").default} layer Layer.\n * @param {import(\"../geom/Geometry.js\").default} geometry Geometry.\n * @return {T|undefined} Callback result.\n */\n function forEachFeatureAtCoordinate(managed, feature, layer, geometry) {\n return callback.call(thisArg, feature, managed ? layer : null, geometry);\n }\n\n const projection = viewState.projection;\n\n const translatedCoordinate = wrapX(coordinate.slice(), projection);\n const offsets = [[0, 0]];\n if (projection.canWrapX() && checkWrapped) {\n const projectionExtent = projection.getExtent();\n const worldWidth = getWidth(projectionExtent);\n offsets.push([-worldWidth, 0], [worldWidth, 0]);\n }\n\n const layerStates = frameState.layerStatesArray;\n const numLayers = layerStates.length;\n\n const matches = /** @type {Array>} */ ([]);\n const tmpCoord = [];\n for (let i = 0; i < offsets.length; i++) {\n for (let j = numLayers - 1; j >= 0; --j) {\n const layerState = layerStates[j];\n const layer = layerState.layer;\n if (\n layer.hasRenderer() &&\n inView(layerState, viewState) &&\n layerFilter.call(thisArg2, layer)\n ) {\n const layerRenderer = layer.getRenderer();\n const source = layer.getSource();\n if (layerRenderer && source) {\n const coordinates = source.getWrapX()\n ? translatedCoordinate\n : coordinate;\n const callback = forEachFeatureAtCoordinate.bind(\n null,\n layerState.managed,\n );\n tmpCoord[0] = coordinates[0] + offsets[i][0];\n tmpCoord[1] = coordinates[1] + offsets[i][1];\n result = layerRenderer.forEachFeatureAtCoordinate(\n tmpCoord,\n frameState,\n hitTolerance,\n callback,\n matches,\n );\n }\n if (result) {\n return result;\n }\n }\n }\n }\n if (matches.length === 0) {\n return undefined;\n }\n const order = 1 / matches.length;\n matches.forEach((m, i) => (m.distanceSq += i * order));\n matches.sort((a, b) => a.distanceSq - b.distanceSq);\n matches.some((m) => {\n return (result = m.callback(m.feature, m.layer, m.geometry));\n });\n return result;\n }\n\n /**\n * @param {import(\"../coordinate.js\").Coordinate} coordinate Coordinate.\n * @param {import(\"../Map.js\").FrameState} frameState FrameState.\n * @param {number} hitTolerance Hit tolerance in pixels.\n * @param {boolean} checkWrapped Check for wrapped geometries.\n * @param {function(this: U, import(\"../layer/Layer.js\").default): boolean} layerFilter Layer filter\n * function, only layers which are visible and for which this function\n * returns `true` will be tested for features. By default, all visible\n * layers will be tested.\n * @param {U} thisArg Value to use as `this` when executing `layerFilter`.\n * @return {boolean} Is there a feature at the given coordinate?\n * @template U\n */\n hasFeatureAtCoordinate(\n coordinate,\n frameState,\n hitTolerance,\n checkWrapped,\n layerFilter,\n thisArg,\n ) {\n const hasFeature = this.forEachFeatureAtCoordinate(\n coordinate,\n frameState,\n hitTolerance,\n checkWrapped,\n TRUE,\n this,\n layerFilter,\n thisArg,\n );\n\n return hasFeature !== undefined;\n }\n\n /**\n * @return {import(\"../Map.js\").default} Map.\n */\n getMap() {\n return this.map_;\n }\n\n /**\n * Render.\n * @abstract\n * @param {?import(\"../Map.js\").FrameState} frameState Frame state.\n */\n renderFrame(frameState) {\n abstract();\n }\n\n /**\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @protected\n */\n scheduleExpireIconCache(frameState) {\n if (iconImageCache.canExpireCache()) {\n frameState.postRenderFunctions.push(expireIconCache);\n }\n }\n}\n\n/**\n * @param {import(\"../Map.js\").default} map Map.\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n */\nfunction expireIconCache(map, frameState) {\n iconImageCache.expire();\n}\n\nexport default MapRenderer;\n", "/**\n * @module ol/renderer/Composite\n */\nimport ObjectEventType from '../ObjectEventType.js';\nimport {CLASS_UNSELECTABLE} from '../css.js';\nimport {replaceChildren} from '../dom.js';\nimport {listen, unlistenByKey} from '../events.js';\nimport BaseVectorLayer from '../layer/BaseVector.js';\nimport {inView} from '../layer/Layer.js';\nimport RenderEvent from '../render/Event.js';\nimport RenderEventType from '../render/EventType.js';\nimport {checkedFonts} from '../render/canvas.js';\nimport MapRenderer from './Map.js';\n\n/**\n * @classdesc\n * Canvas map renderer.\n * @api\n */\nclass CompositeMapRenderer extends MapRenderer {\n /**\n * @param {import(\"../Map.js\").default} map Map.\n */\n constructor(map) {\n super(map);\n\n /**\n * @private\n * @type {import(\"../events.js\").EventsKey}\n */\n this.fontChangeListenerKey_ = listen(\n checkedFonts,\n ObjectEventType.PROPERTYCHANGE,\n map.redrawText,\n map,\n );\n\n /**\n * @private\n * @type {HTMLDivElement}\n */\n this.element_ = document.createElement('div');\n const style = this.element_.style;\n style.position = 'absolute';\n style.width = '100%';\n style.height = '100%';\n style.zIndex = '0';\n\n this.element_.className = CLASS_UNSELECTABLE + ' ol-layers';\n\n const container = map.getViewport();\n container.insertBefore(this.element_, container.firstChild || null);\n\n /**\n * @private\n * @type {Array}\n */\n this.children_ = [];\n\n /**\n * @private\n * @type {boolean}\n */\n this.renderedVisible_ = true;\n }\n\n /**\n * @param {import(\"../render/EventType.js\").default} type Event type.\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @override\n */\n dispatchRenderEvent(type, frameState) {\n const map = this.getMap();\n if (map.hasListener(type)) {\n const event = new RenderEvent(type, undefined, frameState);\n map.dispatchEvent(event);\n }\n }\n\n /**\n * @override\n */\n disposeInternal() {\n unlistenByKey(this.fontChangeListenerKey_);\n this.element_.remove();\n super.disposeInternal();\n }\n\n /**\n * Render.\n * @param {?import(\"../Map.js\").FrameState} frameState Frame state.\n * @override\n */\n renderFrame(frameState) {\n if (!frameState) {\n if (this.renderedVisible_) {\n this.element_.style.display = 'none';\n this.renderedVisible_ = false;\n }\n return;\n }\n\n this.calculateMatrices2D(frameState);\n this.dispatchRenderEvent(RenderEventType.PRECOMPOSE, frameState);\n\n const layerStatesArray = frameState.layerStatesArray.sort(\n (a, b) => a.zIndex - b.zIndex,\n );\n const declutter = layerStatesArray.some(\n (layerState) =>\n layerState.layer instanceof BaseVectorLayer &&\n layerState.layer.getDeclutter(),\n );\n if (declutter) {\n // Some layers need decluttering, turn on deferred rendering hint\n frameState.declutter = {};\n }\n const viewState = frameState.viewState;\n\n this.children_.length = 0;\n\n const renderedLayerStates = [];\n let previousElement = null;\n for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {\n const layerState = layerStatesArray[i];\n frameState.layerIndex = i;\n\n const layer = layerState.layer;\n const sourceState = layer.getSourceState();\n if (\n !inView(layerState, viewState) ||\n (sourceState != 'ready' && sourceState != 'undefined')\n ) {\n layer.unrender();\n continue;\n }\n\n const element = layer.render(frameState, previousElement);\n if (!element) {\n continue;\n }\n if (element !== previousElement) {\n this.children_.push(element);\n previousElement = element;\n }\n\n renderedLayerStates.push(layerState);\n }\n\n this.declutter(frameState, renderedLayerStates);\n\n replaceChildren(this.element_, this.children_);\n\n this.dispatchRenderEvent(RenderEventType.POSTCOMPOSE, frameState);\n\n if (!this.renderedVisible_) {\n this.element_.style.display = '';\n this.renderedVisible_ = true;\n }\n\n this.scheduleExpireIconCache(frameState);\n }\n\n /**\n * @param {import(\"../Map.js\").FrameState} frameState Frame state.\n * @param {Array} layerStates Layers.\n */\n declutter(frameState, layerStates) {\n if (!frameState.declutter) {\n return;\n }\n for (let i = layerStates.length - 1; i >= 0; --i) {\n const layerState = layerStates[i];\n const layer = layerState.layer;\n if (layer.getDeclutter()) {\n layer.renderDeclutter(frameState, layerState);\n }\n }\n layerStates.forEach((layerState) =>\n layerState.layer.renderDeferred(frameState),\n );\n }\n}\n\nexport default CompositeMapRenderer;\n", "/**\n * @module ol/Map\n */\nimport Collection from './Collection.js';\nimport CollectionEventType from './CollectionEventType.js';\nimport MapBrowserEvent from './MapBrowserEvent.js';\nimport MapBrowserEventHandler from './MapBrowserEventHandler.js';\nimport MapBrowserEventType from './MapBrowserEventType.js';\nimport MapEvent from './MapEvent.js';\nimport MapEventType from './MapEventType.js';\nimport MapProperty from './MapProperty.js';\nimport BaseObject from './Object.js';\nimport ObjectEventType from './ObjectEventType.js';\nimport TileQueue, {getTilePriority} from './TileQueue.js';\nimport View from './View.js';\nimport ViewHint from './ViewHint.js';\nimport {equals} from './array.js';\nimport {assert} from './asserts.js';\nimport {warn} from './console.js';\nimport {defaults as defaultControls} from './control/defaults.js';\nimport EventType from './events/EventType.js';\nimport {listen, unlistenByKey} from './events.js';\nimport {\n clone,\n createOrUpdateEmpty,\n equals as equalsExtent,\n getForViewAndSize,\n isEmpty,\n} from './extent.js';\nimport {TRUE} from './functions.js';\nimport {DEVICE_PIXEL_RATIO, PASSIVE_EVENT_LISTENERS} from './has.js';\nimport {defaults as defaultInteractions} from './interaction/defaults.js';\nimport LayerGroup, {GroupEvent} from './layer/Group.js';\nimport Layer from './layer/Layer.js';\nimport PointerEventType from './pointer/EventType.js';\nimport {fromUserCoordinate, toUserCoordinate} from './proj.js';\nimport RenderEventType from './render/EventType.js';\nimport CompositeMapRenderer from './renderer/Composite.js';\nimport {hasArea} from './size.js';\nimport {\n apply as applyTransform,\n create as createTransform,\n} from './transform.js';\nimport {getUid} from './util.js';\n\n/**\n * State of the current frame. Only `pixelRatio`, `time` and `viewState` should\n * be used in applications.\n * @typedef {Object} FrameState\n * @property {number} pixelRatio The pixel ratio of the frame.\n * @property {number} time The time when rendering of the frame was requested.\n * @property {import(\"./View.js\").State} viewState The state of the current view.\n * @property {boolean} animate Animate.\n * @property {import(\"./transform.js\").Transform} coordinateToPixelTransform CoordinateToPixelTransform.\n * @property {Object>|null} declutter\n * Declutter trees by declutter group.\n * When null, no decluttering is needed because no layers have decluttering enabled.\n * @property {null|import(\"./extent.js\").Extent} extent Extent (in view projection coordinates).\n * @property {import(\"./extent.js\").Extent} [nextExtent] Next extent during an animation series.\n * @property {number} index Index.\n * @property {Array} layerStatesArray LayerStatesArray.\n * @property {number} layerIndex LayerIndex.\n * @property {import(\"./transform.js\").Transform} pixelToCoordinateTransform PixelToCoordinateTransform.\n * @property {Array} postRenderFunctions PostRenderFunctions.\n * @property {import(\"./size.js\").Size} size Size.\n * @property {TileQueue} tileQueue TileQueue.\n * @property {!Object>} usedTiles UsedTiles.\n * @property {Array} viewHints ViewHints.\n * @property {!Object>} wantedTiles WantedTiles.\n * @property {string} mapId The id of the map.\n * @property {Object} renderTargets Identifiers of previously rendered elements.\n */\n\n/**\n * @typedef {function(Map, FrameState): any} PostRenderFunction\n */\n\n/**\n * @typedef {Object} AtPixelOptions\n * @property {undefined|function(import(\"./layer/Layer.js\").default): boolean} [layerFilter] Layer filter\n * function. The filter function will receive one argument, the\n * {@link module:ol/layer/Layer~Layer layer-candidate} and it should return a boolean value.\n * Only layers which are visible and for which this function returns `true`\n * will be tested for features. By default, all visible layers will be tested.\n * @property {number} [hitTolerance=0] Hit-detection tolerance in css pixels. Pixels\n * inside the radius around the given position will be checked for features.\n * @property {boolean} [checkWrapped=true] Check-Wrapped Will check for wrapped geometries inside the range of\n * +/- 1 world width. Works only if a projection is used that can be wrapped.\n */\n\n/**\n * @typedef {Object} MapOptionsInternal\n * @property {Collection} [controls] Controls.\n * @property {Collection} [interactions] Interactions.\n * @property {HTMLElement|Document} keyboardEventTarget KeyboardEventTarget.\n * @property {Collection} overlays Overlays.\n * @property {Object} values Values.\n */\n\n/**\n * @typedef {import(\"./ObjectEventType\").Types|'change:layergroup'|'change:size'|'change:target'|'change:view'} MapObjectEventTypes\n */\n\n/***\n * @template Return\n * @typedef {import(\"./Observable\").OnSignature &\n * import(\"./Observable\").OnSignature &\n * import(\"./Observable\").OnSignature &\n * import(\"./Observable\").OnSignature &\n * import(\"./Observable\").OnSignature &\n * import(\"./Observable\").CombinedOnSignature} MapEventHandler\n */\n\n/**\n * Object literal with config options for the map.\n * @typedef {Object} MapOptions\n * @property {Collection|Array} [controls]\n * Controls initially added to the map. If not specified,\n * {@link module:ol/control/defaults.defaults} is used.\n * @property {number} [pixelRatio=window.devicePixelRatio] The ratio between\n * physical pixels and device-independent pixels (dips) on the device.\n * @property {Collection|Array} [interactions]\n * Interactions that are initially added to the map. If not specified,\n * {@link module:ol/interaction/defaults.defaults} is used.\n * @property {HTMLElement|Document|string} [keyboardEventTarget] The element to\n * listen to keyboard events on. This determines when the `KeyboardPan` and\n * `KeyboardZoom` interactions trigger. For example, if this option is set to\n * `document` the keyboard interactions will always trigger. If this option is\n * not specified, the element the library listens to keyboard events on is the\n * map target (i.e. the user-provided div for the map). If this is not\n * `document`, the target element needs to be focused for key events to be\n * emitted, requiring that the target element has a `tabindex` attribute.\n * @property {Array|Collection|LayerGroup} [layers]\n * Layers. If this is not defined, a map with no layers will be rendered. Note\n * that layers are rendered in the order supplied, so if you want, for example,\n * a vector layer to appear on top of a tile layer, it must come after the tile\n * layer.\n * @property {number} [maxTilesLoading=16] Maximum number tiles to load\n * simultaneously.\n * @property {number} [moveTolerance=1] The minimum distance in pixels the\n * cursor must move to be detected as a map move event instead of a click.\n * Increasing this value can make it easier to click on the map.\n * @property {Collection|Array} [overlays]\n * Overlays initially added to the map. By default, no overlays are added.\n * @property {HTMLElement|string} [target] The container for the map, either the\n * element itself or the `id` of the element. If not specified at construction\n * time, {@link module:ol/Map~Map#setTarget} must be called for the map to be\n * rendered. If passed by element, the container can be in a secondary document.\n * For accessibility (focus and keyboard events for map navigation), the `target` element must have a\n * properly configured `tabindex` attribute. If the `target` element is inside a Shadow DOM, the\n * `tabindex` atribute must be set on the custom element's host element.\n * **Note:** CSS `transform` support for the target element is limited to `scale`.\n * @property {View|Promise} [view] The map's view. No layer sources will be\n * fetched unless this is specified at construction time or through\n * {@link module:ol/Map~Map#setView}.\n */\n\n/**\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n */\nfunction removeLayerMapProperty(layer) {\n if (layer instanceof Layer) {\n layer.setMapInternal(null);\n return;\n }\n if (layer instanceof LayerGroup) {\n layer.getLayers().forEach(removeLayerMapProperty);\n }\n}\n\n/**\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n * @param {Map} map Map.\n */\nfunction setLayerMapProperty(layer, map) {\n if (layer instanceof Layer) {\n layer.setMapInternal(map);\n return;\n }\n if (layer instanceof LayerGroup) {\n const layers = layer.getLayers().getArray();\n for (let i = 0, ii = layers.length; i < ii; ++i) {\n setLayerMapProperty(layers[i], map);\n }\n }\n}\n\n/**\n * @classdesc\n * The map is the core component of OpenLayers. For a map to render, a view,\n * one or more layers, and a target container are needed:\n *\n * import Map from 'ol/Map.js';\n * import View from 'ol/View.js';\n * import TileLayer from 'ol/layer/Tile.js';\n * import OSM from 'ol/source/OSM.js';\n *\n * const map = new Map({\n * view: new View({\n * center: [0, 0],\n * zoom: 1,\n * }),\n * layers: [\n * new TileLayer({\n * source: new OSM(),\n * }),\n * ],\n * target: 'map',\n * });\n *\n * The above snippet creates a map using a {@link module:ol/layer/Tile~TileLayer} to\n * display {@link module:ol/source/OSM~OSM} OSM data and render it to a DOM\n * element with the id `map`.\n *\n * The constructor places a viewport container (with CSS class name\n * `ol-viewport`) in the target element (see `getViewport()`), and then two\n * further elements within the viewport: one with CSS class name\n * `ol-overlaycontainer-stopevent` for controls and some overlays, and one with\n * CSS class name `ol-overlaycontainer` for other overlays (see the `stopEvent`\n * option of {@link module:ol/Overlay~Overlay} for the difference). The map\n * itself is placed in a further element within the viewport.\n *\n * Layers are stored as a {@link module:ol/Collection~Collection} in\n * layerGroups. A top-level group is provided by the library. This is what is\n * accessed by `getLayerGroup` and `setLayerGroup`. Layers entered in the\n * options are added to this group, and `addLayer` and `removeLayer` change the\n * layer collection in the group. `getLayers` is a convenience function for\n * `getLayerGroup().getLayers()`. Note that {@link module:ol/layer/Group~LayerGroup}\n * is a subclass of {@link module:ol/layer/Base~BaseLayer}, so layers entered in the\n * options or added with `addLayer` can be groups, which can contain further\n * groups, and so on.\n *\n * @fires import(\"./MapBrowserEvent.js\").MapBrowserEvent\n * @fires import(\"./MapEvent.js\").MapEvent\n * @fires import(\"./render/Event.js\").default#precompose\n * @fires import(\"./render/Event.js\").default#postcompose\n * @fires import(\"./render/Event.js\").default#rendercomplete\n * @api\n */\nclass Map extends BaseObject {\n /**\n * @param {MapOptions} [options] Map options.\n */\n constructor(options) {\n super();\n\n options = options || {};\n\n /***\n * @type {MapEventHandler}\n */\n this.on;\n\n /***\n * @type {MapEventHandler}\n */\n this.once;\n\n /***\n * @type {MapEventHandler}\n */\n this.un;\n\n const optionsInternal = createOptionsInternal(options);\n\n /**\n * @private\n * @type {boolean}\n */\n this.renderComplete_ = false;\n\n /**\n * @private\n * @type {boolean}\n */\n this.loaded_ = true;\n\n /** @private */\n this.boundHandleBrowserEvent_ = this.handleBrowserEvent.bind(this);\n\n /**\n * @type {number}\n * @private\n */\n this.maxTilesLoading_ =\n options.maxTilesLoading !== undefined ? options.maxTilesLoading : 16;\n\n /**\n * @private\n * @type {number}\n */\n this.pixelRatio_ =\n options.pixelRatio !== undefined\n ? options.pixelRatio\n : DEVICE_PIXEL_RATIO;\n\n /**\n * @private\n * @type {ReturnType}\n */\n this.postRenderTimeoutHandle_;\n\n /**\n * @private\n * @type {number|undefined}\n */\n this.animationDelayKey_;\n\n /**\n * @private\n */\n this.animationDelay_ = this.animationDelay_.bind(this);\n\n /**\n * @private\n * @type {import(\"./transform.js\").Transform}\n */\n this.coordinateToPixelTransform_ = createTransform();\n\n /**\n * @private\n * @type {import(\"./transform.js\").Transform}\n */\n this.pixelToCoordinateTransform_ = createTransform();\n\n /**\n * @private\n * @type {number}\n */\n this.frameIndex_ = 0;\n\n /**\n * @private\n * @type {?FrameState}\n */\n this.frameState_ = null;\n\n /**\n * The extent at the previous 'moveend' event.\n * @private\n * @type {import(\"./extent.js\").Extent}\n */\n this.previousExtent_ = null;\n\n /**\n * @private\n * @type {?import(\"./events.js\").EventsKey}\n */\n this.viewPropertyListenerKey_ = null;\n\n /**\n * @private\n * @type {?import(\"./events.js\").EventsKey}\n */\n this.viewChangeListenerKey_ = null;\n\n /**\n * @private\n * @type {?Array}\n */\n this.layerGroupPropertyListenerKeys_ = null;\n\n /**\n * @private\n * @type {!HTMLElement}\n */\n this.viewport_ = document.createElement('div');\n this.viewport_.className =\n 'ol-viewport' + ('ontouchstart' in window ? ' ol-touch' : '');\n this.viewport_.style.position = 'relative';\n this.viewport_.style.overflow = 'hidden';\n this.viewport_.style.width = '100%';\n this.viewport_.style.height = '100%';\n\n /**\n * @private\n * @type {!HTMLElement}\n */\n this.overlayContainer_ = document.createElement('div');\n this.overlayContainer_.style.position = 'absolute';\n this.overlayContainer_.style.zIndex = '0';\n this.overlayContainer_.style.width = '100%';\n this.overlayContainer_.style.height = '100%';\n this.overlayContainer_.style.pointerEvents = 'none';\n this.overlayContainer_.className = 'ol-overlaycontainer';\n this.viewport_.appendChild(this.overlayContainer_);\n\n /**\n * @private\n * @type {!HTMLElement}\n */\n this.overlayContainerStopEvent_ = document.createElement('div');\n this.overlayContainerStopEvent_.style.position = 'absolute';\n this.overlayContainerStopEvent_.style.zIndex = '0';\n this.overlayContainerStopEvent_.style.width = '100%';\n this.overlayContainerStopEvent_.style.height = '100%';\n this.overlayContainerStopEvent_.style.pointerEvents = 'none';\n this.overlayContainerStopEvent_.className = 'ol-overlaycontainer-stopevent';\n this.viewport_.appendChild(this.overlayContainerStopEvent_);\n\n /**\n * @private\n * @type {MapBrowserEventHandler}\n */\n this.mapBrowserEventHandler_ = null;\n\n /**\n * @private\n * @type {number}\n */\n this.moveTolerance_ = options.moveTolerance;\n\n /**\n * @private\n * @type {HTMLElement|Document}\n */\n this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;\n\n /**\n * @private\n * @type {?Array}\n */\n this.targetChangeHandlerKeys_ = null;\n\n /**\n * @private\n * @type {HTMLElement|null}\n */\n this.targetElement_ = null;\n\n /**\n * @private\n * @type {ResizeObserver}\n */\n this.resizeObserver_ = new ResizeObserver(() => this.updateSize());\n\n /**\n * @type {Collection}\n * @protected\n */\n this.controls = optionsInternal.controls || defaultControls();\n\n /**\n * @type {Collection}\n * @protected\n */\n this.interactions =\n optionsInternal.interactions ||\n defaultInteractions({\n onFocusOnly: true,\n });\n\n /**\n * @type {Collection}\n * @private\n */\n this.overlays_ = optionsInternal.overlays;\n\n /**\n * A lookup of overlays by id.\n * @private\n * @type {Object}\n */\n this.overlayIdIndex_ = {};\n\n /**\n * @type {import(\"./renderer/Map.js\").default|null}\n * @private\n */\n this.renderer_ = null;\n\n /**\n * @private\n * @type {!Array}\n */\n this.postRenderFunctions_ = [];\n\n /**\n * @private\n * @type {TileQueue}\n */\n this.tileQueue_ = new TileQueue(\n this.getTilePriority.bind(this),\n this.handleTileChange_.bind(this),\n );\n\n this.addChangeListener(\n MapProperty.LAYERGROUP,\n this.handleLayerGroupChanged_,\n );\n this.addChangeListener(MapProperty.VIEW, this.handleViewChanged_);\n this.addChangeListener(MapProperty.SIZE, this.handleSizeChanged_);\n this.addChangeListener(MapProperty.TARGET, this.handleTargetChanged_);\n\n // setProperties will trigger the rendering of the map if the map\n // is \"defined\" already.\n this.setProperties(optionsInternal.values);\n\n const map = this;\n if (options.view && !(options.view instanceof View)) {\n options.view.then(function (viewOptions) {\n map.setView(new View(viewOptions));\n });\n }\n\n this.controls.addEventListener(\n CollectionEventType.ADD,\n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent\n */\n (event) => {\n event.element.setMap(this);\n },\n );\n\n this.controls.addEventListener(\n CollectionEventType.REMOVE,\n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n (event) => {\n event.element.setMap(null);\n },\n );\n\n this.interactions.addEventListener(\n CollectionEventType.ADD,\n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n (event) => {\n event.element.setMap(this);\n },\n );\n\n this.interactions.addEventListener(\n CollectionEventType.REMOVE,\n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n (event) => {\n event.element.setMap(null);\n },\n );\n\n this.overlays_.addEventListener(\n CollectionEventType.ADD,\n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n (event) => {\n this.addOverlayInternal_(event.element);\n },\n );\n\n this.overlays_.addEventListener(\n CollectionEventType.REMOVE,\n /**\n * @param {import(\"./Collection.js\").CollectionEvent} event CollectionEvent.\n */\n (event) => {\n const id = event.element.getId();\n if (id !== undefined) {\n delete this.overlayIdIndex_[id.toString()];\n }\n event.element.setMap(null);\n },\n );\n\n this.controls.forEach(\n /**\n * @param {import(\"./control/Control.js\").default} control Control.\n */\n (control) => {\n control.setMap(this);\n },\n );\n\n this.interactions.forEach(\n /**\n * @param {import(\"./interaction/Interaction.js\").default} interaction Interaction.\n */\n (interaction) => {\n interaction.setMap(this);\n },\n );\n\n this.overlays_.forEach(this.addOverlayInternal_.bind(this));\n }\n\n /**\n * Add the given control to the map.\n * @param {import(\"./control/Control.js\").default} control Control.\n * @api\n */\n addControl(control) {\n this.getControls().push(control);\n }\n\n /**\n * Add the given interaction to the map. If you want to add an interaction\n * at another point of the collection use `getInteractions()` and the methods\n * available on {@link module:ol/Collection~Collection}. This can be used to\n * stop the event propagation from the handleEvent function. The interactions\n * get to handle the events in the reverse order of this collection.\n * @param {import(\"./interaction/Interaction.js\").default} interaction Interaction to add.\n * @api\n */\n addInteraction(interaction) {\n this.getInteractions().push(interaction);\n }\n\n /**\n * Adds the given layer to the top of this map. If you want to add a layer\n * elsewhere in the stack, use `getLayers()` and the methods available on\n * {@link module:ol/Collection~Collection}.\n * @param {import(\"./layer/Base.js\").default} layer Layer.\n * @api\n */\n addLayer(layer) {\n const layers = this.getLayerGroup().getLayers();\n layers.push(layer);\n }\n\n /**\n * @param {import(\"./layer/Group.js\").GroupEvent} event The layer add event.\n * @private\n */\n handleLayerAdd_(event) {\n setLayerMapProperty(event.layer, this);\n }\n\n /**\n * Add the given overlay to the map.\n * @param {import(\"./Overlay.js\").default} overlay Overlay.\n * @api\n */\n addOverlay(overlay) {\n this.getOverlays().push(overlay);\n }\n\n /**\n * This deals with map's overlay collection changes.\n * @param {import(\"./Overlay.js\").default} overlay Overlay.\n * @private\n */\n addOverlayInternal_(overlay) {\n const id = overlay.getId();\n if (id !== undefined) {\n this.overlayIdIndex_[id.toString()] = overlay;\n }\n overlay.setMap(this);\n }\n\n /**\n *\n * Clean up.\n * @override\n */\n disposeInternal() {\n this.controls.clear();\n this.interactions.clear();\n this.overlays_.clear();\n this.resizeObserver_.disconnect();\n this.setTarget(null);\n super.disposeInternal();\n }\n\n /**\n * Detect features that intersect a pixel on the viewport, and execute a\n * callback with each intersecting feature. Layers included in the detection can\n * be configured through the `layerFilter` option in `options`.\n * @param {import(\"./pixel.js\").Pixel} pixel Pixel.\n * @param {function(import(\"./Feature.js\").FeatureLike, import(\"./layer/Layer.js\").default