SourceTermAnalysisSystem_vue/node_modules/.vite/deps/chunk-EW2Q4UMF.js
2026-05-15 10:22:44 +08:00

3579 lines
112 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import {
TileQueue_default,
getTilePriority
} from "./chunk-RLY4OFPK.js";
import {
Interaction_default,
MapBrowserEventType_default,
MapBrowserEvent_default,
MapEvent_default,
Pointer_default,
all,
altShiftKeysOnly,
always,
centroid,
focusWithTabindex,
mouseActionButton,
mouseOnly,
noModifierKeys,
pan,
platformModifierKey,
primaryAction,
shiftKeyOnly,
targetNotEditable,
zoomByDelta
} from "./chunk-Z7GUXWJ4.js";
import {
Control_default,
EventType_default as EventType_default3
} from "./chunk-LXWL6YOU.js";
import {
MapEventType_default
} from "./chunk-BHVDQB66.js";
import {
GroupEvent,
Group_default
} from "./chunk-POHYZJBN.js";
import {
CollectionEventType_default,
Collection_default
} from "./chunk-F6XZ22ZQ.js";
import {
BaseVector_default
} from "./chunk-OVJRLVXU.js";
import {
checkedFonts,
shared
} from "./chunk-EMRMEHGR.js";
import {
CLASS_COLLAPSED,
CLASS_CONTROL,
CLASS_HIDDEN,
CLASS_UNSELECTABLE
} from "./chunk-GNM7L5BH.js";
import {
EventType_default as EventType_default2,
Event_default as Event_default2,
Layer_default,
ViewHint_default,
View_default,
disable,
inView
} from "./chunk-S5OMZ56B.js";
import {
easeOut
} from "./chunk-LMC3RO5P.js";
import {
hasArea
} from "./chunk-PPP4FLHO.js";
import {
removeChildren,
replaceChildren,
replaceNode
} from "./chunk-YWIWRQT2.js";
import {
DEVICE_PIXEL_RATIO,
PASSIVE_EVENT_LISTENERS
} from "./chunk-5XHD7RSF.js";
import {
Polygon_default
} from "./chunk-RBA5LKAR.js";
import {
apply,
compose,
create,
makeInverse
} from "./chunk-JFONEOYG.js";
import {
fromUserCoordinate,
toUserCoordinate,
warn
} from "./chunk-XZU4LSFD.js";
import {
rotate,
scale,
wrapX
} from "./chunk-3JZANJYE.js";
import {
clamp
} from "./chunk-54BTDBAD.js";
import {
clone,
createOrUpdateEmpty,
equals as equals2,
getForViewAndSize,
getWidth,
isEmpty
} from "./chunk-CKDBVGKM.js";
import {
assert
} from "./chunk-QFCIXVZ3.js";
import {
ObjectEventType_default,
Object_default,
abstract,
getUid
} from "./chunk-H47PV7W6.js";
import {
Disposable_default,
EventType_default,
Event_default,
FALSE,
TRUE,
Target_default,
listen,
toPromise,
unlistenByKey
} from "./chunk-KJXIHBKT.js";
import {
equals
} from "./chunk-FQY6EMA7.js";
// 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/MapBrowserEventHandler.js
var MapBrowserEventHandler = class extends Target_default {
/**
* @param {import("./Map.js").default} map The map with the viewport to listen to events on.
* @param {number} [moveTolerance] The minimal distance the pointer must travel to trigger a move.
*/
constructor(map, moveTolerance) {
super(map);
this.map_ = map;
this.clickTimeoutId_;
this.emulateClicks_ = false;
this.dragging_ = false;
this.dragListenerKeys_ = [];
this.moveTolerance_ = moveTolerance === void 0 ? 1 : moveTolerance;
this.down_ = null;
const element = this.map_.getViewport();
this.activePointers_ = [];
this.trackedTouches_ = {};
this.element_ = element;
this.pointerdownListenerKey_ = listen(
element,
EventType_default3.POINTERDOWN,
this.handlePointerDown_,
this
);
this.originalPointerMoveEvent_;
this.relayedListenerKey_ = listen(
element,
EventType_default3.POINTERMOVE,
this.relayMoveEvent_,
this
);
this.boundHandleTouchMove_ = this.handleTouchMove_.bind(this);
this.element_.addEventListener(
EventType_default.TOUCHMOVE,
this.boundHandleTouchMove_,
PASSIVE_EVENT_LISTENERS ? { passive: false } : false
);
}
/**
* @param {PointerEvent} pointerEvent Pointer
* event.
* @private
*/
emulateClick_(pointerEvent) {
let newEvent = new MapBrowserEvent_default(
MapBrowserEventType_default.CLICK,
this.map_,
pointerEvent
);
this.dispatchEvent(newEvent);
if (this.clickTimeoutId_ !== void 0) {
clearTimeout(this.clickTimeoutId_);
this.clickTimeoutId_ = void 0;
newEvent = new MapBrowserEvent_default(
MapBrowserEventType_default.DBLCLICK,
this.map_,
pointerEvent
);
this.dispatchEvent(newEvent);
} else {
this.clickTimeoutId_ = setTimeout(() => {
this.clickTimeoutId_ = void 0;
const newEvent2 = new MapBrowserEvent_default(
MapBrowserEventType_default.SINGLECLICK,
this.map_,
pointerEvent
);
this.dispatchEvent(newEvent2);
}, 250);
}
}
/**
* Keeps track on how many pointers are currently active.
*
* @param {PointerEvent} pointerEvent Pointer
* event.
* @private
*/
updateActivePointers_(pointerEvent) {
const event = pointerEvent;
const id = event.pointerId;
if (event.type == MapBrowserEventType_default.POINTERUP || event.type == MapBrowserEventType_default.POINTERCANCEL) {
delete this.trackedTouches_[id];
for (const pointerId in this.trackedTouches_) {
if (this.trackedTouches_[pointerId].target !== event.target) {
delete this.trackedTouches_[pointerId];
break;
}
}
} else if (event.type == MapBrowserEventType_default.POINTERDOWN || event.type == MapBrowserEventType_default.POINTERMOVE) {
this.trackedTouches_[id] = event;
}
this.activePointers_ = Object.values(this.trackedTouches_);
}
/**
* @param {PointerEvent} pointerEvent Pointer
* event.
* @private
*/
handlePointerUp_(pointerEvent) {
this.updateActivePointers_(pointerEvent);
const newEvent = new MapBrowserEvent_default(
MapBrowserEventType_default.POINTERUP,
this.map_,
pointerEvent,
void 0,
void 0,
this.activePointers_
);
this.dispatchEvent(newEvent);
if (this.emulateClicks_ && !newEvent.defaultPrevented && !this.dragging_ && this.isMouseActionButton_(pointerEvent)) {
this.emulateClick_(this.down_);
}
if (this.activePointers_.length === 0) {
this.dragListenerKeys_.forEach(unlistenByKey);
this.dragListenerKeys_.length = 0;
this.dragging_ = false;
this.down_ = null;
}
}
/**
* @param {PointerEvent} pointerEvent Pointer
* event.
* @return {boolean} If the left mouse button was pressed.
* @private
*/
isMouseActionButton_(pointerEvent) {
return pointerEvent.button === 0;
}
/**
* @param {PointerEvent} pointerEvent Pointer
* event.
* @private
*/
handlePointerDown_(pointerEvent) {
this.emulateClicks_ = this.activePointers_.length === 0;
this.updateActivePointers_(pointerEvent);
const newEvent = new MapBrowserEvent_default(
MapBrowserEventType_default.POINTERDOWN,
this.map_,
pointerEvent,
void 0,
void 0,
this.activePointers_
);
this.dispatchEvent(newEvent);
this.down_ = new PointerEvent(pointerEvent.type, pointerEvent);
Object.defineProperty(this.down_, "target", {
writable: false,
value: pointerEvent.target
});
if (this.dragListenerKeys_.length === 0) {
const doc = this.map_.getOwnerDocument();
this.dragListenerKeys_.push(
listen(
doc,
MapBrowserEventType_default.POINTERMOVE,
this.handlePointerMove_,
this
),
listen(doc, MapBrowserEventType_default.POINTERUP, this.handlePointerUp_, this),
/* Note that the listener for `pointercancel is set up on
* `pointerEventHandler_` and not `documentPointerEventHandler_` like
* the `pointerup` and `pointermove` listeners.
*
* The reason for this is the following: `TouchSource.vacuumTouches_()`
* issues `pointercancel` events, when there was no `touchend` for a
* `touchstart`. Now, let's say a first `touchstart` is registered on
* `pointerEventHandler_`. The `documentPointerEventHandler_` is set up.
* But `documentPointerEventHandler_` doesn't know about the first
* `touchstart`. If there is no `touchend` for the `touchstart`, we can
* only receive a `touchcancel` from `pointerEventHandler_`, because it is
* only registered there.
*/
listen(
this.element_,
MapBrowserEventType_default.POINTERCANCEL,
this.handlePointerUp_,
this
)
);
if (this.element_.getRootNode && this.element_.getRootNode() !== doc) {
this.dragListenerKeys_.push(
listen(
this.element_.getRootNode(),
MapBrowserEventType_default.POINTERUP,
this.handlePointerUp_,
this
)
);
}
}
}
/**
* @param {PointerEvent} pointerEvent Pointer
* event.
* @private
*/
handlePointerMove_(pointerEvent) {
if (this.isMoving_(pointerEvent)) {
this.updateActivePointers_(pointerEvent);
this.dragging_ = true;
const newEvent = new MapBrowserEvent_default(
MapBrowserEventType_default.POINTERDRAG,
this.map_,
pointerEvent,
this.dragging_,
void 0,
this.activePointers_
);
this.dispatchEvent(newEvent);
}
}
/**
* Wrap and relay a pointermove event.
* @param {PointerEvent} pointerEvent Pointer
* event.
* @private
*/
relayMoveEvent_(pointerEvent) {
this.originalPointerMoveEvent_ = pointerEvent;
const dragging = !!(this.down_ && this.isMoving_(pointerEvent));
this.dispatchEvent(
new MapBrowserEvent_default(
MapBrowserEventType_default.POINTERMOVE,
this.map_,
pointerEvent,
dragging
)
);
}
/**
* Flexible handling of a `touch-action: none` css equivalent: because calling
* `preventDefault()` on a `pointermove` event does not stop native page scrolling
* and zooming, we also listen for `touchmove` and call `preventDefault()` on it
* when an interaction (currently `DragPan` handles the event.
* @param {TouchEvent} event Event.
* @private
*/
handleTouchMove_(event) {
const originalEvent = this.originalPointerMoveEvent_;
if ((!originalEvent || originalEvent.defaultPrevented) && (typeof event.cancelable !== "boolean" || event.cancelable === true)) {
event.preventDefault();
}
}
/**
* @param {PointerEvent} pointerEvent Pointer
* event.
* @return {boolean} Is moving.
* @private
*/
isMoving_(pointerEvent) {
return this.dragging_ || Math.abs(pointerEvent.clientX - this.down_.clientX) > this.moveTolerance_ || Math.abs(pointerEvent.clientY - this.down_.clientY) > this.moveTolerance_;
}
/**
* Clean up.
* @override
*/
disposeInternal() {
if (this.relayedListenerKey_) {
unlistenByKey(this.relayedListenerKey_);
this.relayedListenerKey_ = null;
}
this.element_.removeEventListener(
EventType_default.TOUCHMOVE,
this.boundHandleTouchMove_
);
if (this.pointerdownListenerKey_) {
unlistenByKey(this.pointerdownListenerKey_);
this.pointerdownListenerKey_ = null;
}
this.dragListenerKeys_.forEach(unlistenByKey);
this.dragListenerKeys_.length = 0;
this.element_ = null;
super.disposeInternal();
}
};
var MapBrowserEventHandler_default = MapBrowserEventHandler;
// node_modules/ol/control/Attribution.js
var Attribution = class extends Control_default {
/**
* @param {Options} [options] Attribution options.
*/
constructor(options) {
options = options ? options : {};
super({
element: document.createElement("div"),
render: options.render,
target: options.target
});
this.ulElement_ = document.createElement("ul");
this.collapsed_ = options.collapsed !== void 0 ? options.collapsed : true;
this.userCollapsed_ = this.collapsed_;
this.overrideCollapsible_ = options.collapsible !== void 0;
this.collapsible_ = options.collapsible !== void 0 ? options.collapsible : true;
if (!this.collapsible_) {
this.collapsed_ = false;
}
this.attributions_ = options.attributions;
const className = options.className !== void 0 ? options.className : "ol-attribution";
const tipLabel = options.tipLabel !== void 0 ? options.tipLabel : "Attributions";
const expandClassName = options.expandClassName !== void 0 ? options.expandClassName : className + "-expand";
const collapseLabel = options.collapseLabel !== void 0 ? options.collapseLabel : "";
const collapseClassName = options.collapseClassName !== void 0 ? options.collapseClassName : className + "-collapse";
if (typeof collapseLabel === "string") {
this.collapseLabel_ = document.createElement("span");
this.collapseLabel_.textContent = collapseLabel;
this.collapseLabel_.className = collapseClassName;
} else {
this.collapseLabel_ = collapseLabel;
}
const label = options.label !== void 0 ? options.label : "i";
if (typeof label === "string") {
this.label_ = document.createElement("span");
this.label_.textContent = label;
this.label_.className = expandClassName;
} else {
this.label_ = label;
}
const activeLabel = this.collapsible_ && !this.collapsed_ ? this.collapseLabel_ : this.label_;
this.toggleButton_ = document.createElement("button");
this.toggleButton_.setAttribute("type", "button");
this.toggleButton_.setAttribute("aria-expanded", String(!this.collapsed_));
this.toggleButton_.title = tipLabel;
this.toggleButton_.appendChild(activeLabel);
this.toggleButton_.addEventListener(
EventType_default.CLICK,
this.handleClick_.bind(this),
false
);
const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL + (this.collapsed_ && this.collapsible_ ? " " + CLASS_COLLAPSED : "") + (this.collapsible_ ? "" : " ol-uncollapsible");
const element = this.element;
element.className = cssClasses;
element.appendChild(this.toggleButton_);
element.appendChild(this.ulElement_);
this.renderedAttributions_ = [];
this.renderedVisible_ = true;
}
/**
* Collect a list of visible attributions and set the collapsible state.
* @param {import("../Map.js").FrameState} frameState Frame state.
* @return {Array<string>} Attributions.
* @private
*/
collectSourceAttributions_(frameState) {
const layers = this.getMap().getAllLayers();
const visibleAttributions = new Set(
layers.flatMap((layer) => layer.getAttributions(frameState))
);
if (this.attributions_ !== void 0) {
Array.isArray(this.attributions_) ? this.attributions_.forEach((item) => visibleAttributions.add(item)) : visibleAttributions.add(this.attributions_);
}
if (!this.overrideCollapsible_) {
const collapsible = !layers.some(
(layer) => {
var _a;
return ((_a = layer.getSource()) == null ? void 0 : _a.getAttributionsCollapsible()) === false;
}
);
this.setCollapsible(collapsible);
}
return Array.from(visibleAttributions);
}
/**
* @private
* @param {?import("../Map.js").FrameState} frameState Frame state.
*/
async updateElement_(frameState) {
if (!frameState) {
if (this.renderedVisible_) {
this.element.style.display = "none";
this.renderedVisible_ = false;
}
return;
}
const attributions = await Promise.all(
this.collectSourceAttributions_(frameState).map(
(attribution) => toPromise(() => attribution)
)
);
const visible = attributions.length > 0;
if (this.renderedVisible_ != visible) {
this.element.style.display = visible ? "" : "none";
this.renderedVisible_ = visible;
}
if (equals(attributions, this.renderedAttributions_)) {
return;
}
removeChildren(this.ulElement_);
for (let i = 0, ii = attributions.length; i < ii; ++i) {
const element = document.createElement("li");
element.innerHTML = attributions[i];
this.ulElement_.appendChild(element);
}
this.renderedAttributions_ = attributions;
}
/**
* @param {MouseEvent} event The event to handle
* @private
*/
handleClick_(event) {
event.preventDefault();
this.handleToggle_();
this.userCollapsed_ = this.collapsed_;
}
/**
* @private
*/
handleToggle_() {
this.element.classList.toggle(CLASS_COLLAPSED);
if (this.collapsed_) {
replaceNode(this.collapseLabel_, this.label_);
} else {
replaceNode(this.label_, this.collapseLabel_);
}
this.collapsed_ = !this.collapsed_;
this.toggleButton_.setAttribute("aria-expanded", String(!this.collapsed_));
}
/**
* Return `true` if the attribution is collapsible, `false` otherwise.
* @return {boolean} True if the widget is collapsible.
* @api
*/
getCollapsible() {
return this.collapsible_;
}
/**
* Set whether the attribution should be collapsible.
* @param {boolean} collapsible True if the widget is collapsible.
* @api
*/
setCollapsible(collapsible) {
if (this.collapsible_ === collapsible) {
return;
}
this.collapsible_ = collapsible;
this.element.classList.toggle("ol-uncollapsible");
if (this.userCollapsed_) {
this.handleToggle_();
}
}
/**
* Collapse or expand the attribution according to the passed parameter. Will
* not do anything if the attribution isn't collapsible or if the current
* collapsed state is already the one requested.
* @param {boolean} collapsed True if the widget is collapsed.
* @api
*/
setCollapsed(collapsed) {
this.userCollapsed_ = collapsed;
if (!this.collapsible_ || this.collapsed_ === collapsed) {
return;
}
this.handleToggle_();
}
/**
* Return `true` when the attribution is currently collapsed or `false`
* otherwise.
* @return {boolean} True if the widget is collapsed.
* @api
*/
getCollapsed() {
return this.collapsed_;
}
/**
* Update the attribution element.
* @param {import("../MapEvent.js").default} mapEvent Map event.
* @override
*/
render(mapEvent) {
this.updateElement_(mapEvent.frameState);
}
};
var Attribution_default = Attribution;
// node_modules/ol/control/Rotate.js
var Rotate = class extends Control_default {
/**
* @param {Options} [options] Rotate options.
*/
constructor(options) {
options = options ? options : {};
super({
element: document.createElement("div"),
render: options.render,
target: options.target
});
const className = options.className !== void 0 ? options.className : "ol-rotate";
const label = options.label !== void 0 ? options.label : "⇧";
const compassClassName = options.compassClassName !== void 0 ? options.compassClassName : "ol-compass";
this.label_ = null;
if (typeof label === "string") {
this.label_ = document.createElement("span");
this.label_.className = compassClassName;
this.label_.textContent = label;
} else {
this.label_ = label;
this.label_.classList.add(compassClassName);
}
const tipLabel = options.tipLabel ? options.tipLabel : "Reset rotation";
const button = document.createElement("button");
button.className = className + "-reset";
button.setAttribute("type", "button");
button.title = tipLabel;
button.appendChild(this.label_);
button.addEventListener(
EventType_default.CLICK,
this.handleClick_.bind(this),
false
);
const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;
const element = this.element;
element.className = cssClasses;
element.appendChild(button);
this.callResetNorth_ = options.resetNorth ? options.resetNorth : void 0;
this.duration_ = options.duration !== void 0 ? options.duration : 250;
this.autoHide_ = options.autoHide !== void 0 ? options.autoHide : true;
this.rotation_ = void 0;
if (this.autoHide_) {
this.element.classList.add(CLASS_HIDDEN);
}
}
/**
* @param {MouseEvent} event The event to handle
* @private
*/
handleClick_(event) {
event.preventDefault();
if (this.callResetNorth_ !== void 0) {
this.callResetNorth_();
} else {
this.resetNorth_();
}
}
/**
* @private
*/
resetNorth_() {
const map = this.getMap();
const view = map.getView();
if (!view) {
return;
}
const rotation = view.getRotation();
if (rotation !== void 0) {
if (this.duration_ > 0 && rotation % (2 * Math.PI) !== 0) {
view.animate({
rotation: 0,
duration: this.duration_,
easing: easeOut
});
} else {
view.setRotation(0);
}
}
}
/**
* Update the rotate control element.
* @param {import("../MapEvent.js").default} mapEvent Map event.
* @override
*/
render(mapEvent) {
const frameState = mapEvent.frameState;
if (!frameState) {
return;
}
const rotation = frameState.viewState.rotation;
if (rotation != this.rotation_) {
const transform = "rotate(" + rotation + "rad)";
if (this.autoHide_) {
const contains = this.element.classList.contains(CLASS_HIDDEN);
if (!contains && rotation === 0) {
this.element.classList.add(CLASS_HIDDEN);
} else if (contains && rotation !== 0) {
this.element.classList.remove(CLASS_HIDDEN);
}
}
this.label_.style.transform = transform;
}
this.rotation_ = rotation;
}
};
var Rotate_default = Rotate;
// node_modules/ol/control/Zoom.js
var Zoom = class extends Control_default {
/**
* @param {Options} [options] Zoom options.
*/
constructor(options) {
options = options ? options : {};
super({
element: document.createElement("div"),
target: options.target
});
const className = options.className !== void 0 ? options.className : "ol-zoom";
const delta = options.delta !== void 0 ? options.delta : 1;
const zoomInClassName = options.zoomInClassName !== void 0 ? options.zoomInClassName : className + "-in";
const zoomOutClassName = options.zoomOutClassName !== void 0 ? options.zoomOutClassName : className + "-out";
const zoomInLabel = options.zoomInLabel !== void 0 ? options.zoomInLabel : "+";
const zoomOutLabel = options.zoomOutLabel !== void 0 ? options.zoomOutLabel : "";
const zoomInTipLabel = options.zoomInTipLabel !== void 0 ? options.zoomInTipLabel : "Zoom in";
const zoomOutTipLabel = options.zoomOutTipLabel !== void 0 ? options.zoomOutTipLabel : "Zoom out";
const inElement = document.createElement("button");
inElement.className = zoomInClassName;
inElement.setAttribute("type", "button");
inElement.title = zoomInTipLabel;
inElement.appendChild(
typeof zoomInLabel === "string" ? document.createTextNode(zoomInLabel) : zoomInLabel
);
inElement.addEventListener(
EventType_default.CLICK,
this.handleClick_.bind(this, delta),
false
);
const outElement = document.createElement("button");
outElement.className = zoomOutClassName;
outElement.setAttribute("type", "button");
outElement.title = zoomOutTipLabel;
outElement.appendChild(
typeof zoomOutLabel === "string" ? document.createTextNode(zoomOutLabel) : zoomOutLabel
);
outElement.addEventListener(
EventType_default.CLICK,
this.handleClick_.bind(this, -delta),
false
);
const cssClasses = className + " " + CLASS_UNSELECTABLE + " " + CLASS_CONTROL;
const element = this.element;
element.className = cssClasses;
element.appendChild(inElement);
element.appendChild(outElement);
this.duration_ = options.duration !== void 0 ? options.duration : 250;
}
/**
* @param {number} delta Zoom delta.
* @param {MouseEvent} event The event to handle
* @private
*/
handleClick_(delta, event) {
event.preventDefault();
this.zoomByDelta_(delta);
}
/**
* @param {number} delta Zoom delta.
* @private
*/
zoomByDelta_(delta) {
const map = this.getMap();
const view = map.getView();
if (!view) {
return;
}
const currentZoom = view.getZoom();
if (currentZoom !== void 0) {
const newZoom = view.getConstrainedZoom(currentZoom + delta);
if (this.duration_ > 0) {
if (view.getAnimating()) {
view.cancelAnimations();
}
view.animate({
zoom: newZoom,
duration: this.duration_,
easing: easeOut
});
} else {
view.setZoom(newZoom);
}
}
}
};
var Zoom_default = Zoom;
// node_modules/ol/control/defaults.js
function defaults(options) {
options = options ? options : {};
const controls = new Collection_default();
const zoomControl = options.zoom !== void 0 ? options.zoom : true;
if (zoomControl) {
controls.push(new Zoom_default(options.zoomOptions));
}
const rotateControl = options.rotate !== void 0 ? options.rotate : true;
if (rotateControl) {
controls.push(new Rotate_default(options.rotateOptions));
}
const attributionControl = options.attribution !== void 0 ? options.attribution : true;
if (attributionControl) {
controls.push(new Attribution_default(options.attributionOptions));
}
return controls;
}
// node_modules/ol/MapProperty.js
var MapProperty_default = {
LAYERGROUP: "layergroup",
SIZE: "size",
TARGET: "target",
VIEW: "view"
};
// 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 DELTA_LINE_MULTIPLIER = 40;
var DELTA_PAGE_MULTIPLIER = 300;
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 = wheelEvent.deltaY;
switch (wheelEvent.deltaMode) {
case WheelEvent.DOM_DELTA_LINE:
delta *= DELTA_LINE_MULTIPLIER;
break;
case WheelEvent.DOM_DELTA_PAGE:
delta *= DELTA_PAGE_MULTIPLIER;
break;
default:
}
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/renderer/Map.js
var MapRenderer = class extends Disposable_default {
/**
* @param {import("../Map.js").default} map Map.
*/
constructor(map) {
super();
this.map_ = map;
}
/**
* @abstract
* @param {import("../render/EventType.js").default} type Event type.
* @param {import("../Map.js").FrameState} frameState Frame state.
*/
dispatchRenderEvent(type, frameState) {
abstract();
}
/**
* @param {import("../Map.js").FrameState} frameState FrameState.
* @protected
*/
calculateMatrices2D(frameState) {
const viewState = frameState.viewState;
const coordinateToPixelTransform = frameState.coordinateToPixelTransform;
const pixelToCoordinateTransform = frameState.pixelToCoordinateTransform;
compose(
coordinateToPixelTransform,
frameState.size[0] / 2,
frameState.size[1] / 2,
1 / viewState.resolution,
-1 / viewState.resolution,
-viewState.rotation,
-viewState.center[0],
-viewState.center[1]
);
makeInverse(pixelToCoordinateTransform, coordinateToPixelTransform);
}
/**
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {import("../Map.js").FrameState} frameState FrameState.
* @param {number} hitTolerance Hit tolerance in pixels.
* @param {boolean} checkWrapped Check for wrapped geometries.
* @param {import("./vector.js").FeatureCallback<T>} callback Feature callback.
* @param {S} thisArg Value to use as `this` when executing `callback`.
* @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter
* function, only layers which are visible and for which this function
* returns `true` will be tested for features. By default, all visible
* layers will be tested.
* @param {U} thisArg2 Value to use as `this` when executing `layerFilter`.
* @return {T|undefined} Callback result.
* @template S,T,U
*/
forEachFeatureAtCoordinate(coordinate, frameState, hitTolerance, checkWrapped, callback, thisArg, layerFilter, thisArg2) {
let result;
const viewState = frameState.viewState;
function forEachFeatureAtCoordinate(managed, feature, layer, geometry) {
return callback.call(thisArg, feature, managed ? layer : null, geometry);
}
const projection = viewState.projection;
const translatedCoordinate = wrapX(coordinate.slice(), projection);
const offsets = [[0, 0]];
if (projection.canWrapX() && checkWrapped) {
const projectionExtent = projection.getExtent();
const worldWidth = getWidth(projectionExtent);
offsets.push([-worldWidth, 0], [worldWidth, 0]);
}
const layerStates = frameState.layerStatesArray;
const numLayers = layerStates.length;
const matches = (
/** @type {Array<HitMatch<T>>} */
[]
);
const tmpCoord = [];
for (let i = 0; i < offsets.length; i++) {
for (let j = numLayers - 1; j >= 0; --j) {
const layerState = layerStates[j];
const layer = layerState.layer;
if (layer.hasRenderer() && inView(layerState, viewState) && layerFilter.call(thisArg2, layer)) {
const layerRenderer = layer.getRenderer();
const source = layer.getSource();
if (layerRenderer && source) {
const coordinates = source.getWrapX() ? translatedCoordinate : coordinate;
const callback2 = forEachFeatureAtCoordinate.bind(
null,
layerState.managed
);
tmpCoord[0] = coordinates[0] + offsets[i][0];
tmpCoord[1] = coordinates[1] + offsets[i][1];
result = layerRenderer.forEachFeatureAtCoordinate(
tmpCoord,
frameState,
hitTolerance,
callback2,
matches
);
}
if (result) {
return result;
}
}
}
}
if (matches.length === 0) {
return void 0;
}
const order = 1 / matches.length;
matches.forEach((m, i) => m.distanceSq += i * order);
matches.sort((a, b) => a.distanceSq - b.distanceSq);
matches.some((m) => {
return result = m.callback(m.feature, m.layer, m.geometry);
});
return result;
}
/**
* @param {import("../coordinate.js").Coordinate} coordinate Coordinate.
* @param {import("../Map.js").FrameState} frameState FrameState.
* @param {number} hitTolerance Hit tolerance in pixels.
* @param {boolean} checkWrapped Check for wrapped geometries.
* @param {function(this: U, import("../layer/Layer.js").default): boolean} layerFilter Layer filter
* function, only layers which are visible and for which this function
* returns `true` will be tested for features. By default, all visible
* layers will be tested.
* @param {U} thisArg Value to use as `this` when executing `layerFilter`.
* @return {boolean} Is there a feature at the given coordinate?
* @template U
*/
hasFeatureAtCoordinate(coordinate, frameState, hitTolerance, checkWrapped, layerFilter, thisArg) {
const hasFeature = this.forEachFeatureAtCoordinate(
coordinate,
frameState,
hitTolerance,
checkWrapped,
TRUE,
this,
layerFilter,
thisArg
);
return hasFeature !== void 0;
}
/**
* @return {import("../Map.js").default} Map.
*/
getMap() {
return this.map_;
}
/**
* Render.
* @abstract
* @param {?import("../Map.js").FrameState} frameState Frame state.
*/
renderFrame(frameState) {
abstract();
}
/**
* @param {import("../Map.js").FrameState} frameState Frame state.
* @protected
*/
scheduleExpireIconCache(frameState) {
if (shared.canExpireCache()) {
frameState.postRenderFunctions.push(expireIconCache);
}
}
};
function expireIconCache(map, frameState) {
shared.expire();
}
var Map_default = MapRenderer;
// node_modules/ol/renderer/Composite.js
var CompositeMapRenderer = class extends Map_default {
/**
* @param {import("../Map.js").default} map Map.
*/
constructor(map) {
super(map);
this.fontChangeListenerKey_ = listen(
checkedFonts,
ObjectEventType_default.PROPERTYCHANGE,
map.redrawText,
map
);
this.element_ = document.createElement("div");
const style = this.element_.style;
style.position = "absolute";
style.width = "100%";
style.height = "100%";
style.zIndex = "0";
this.element_.className = CLASS_UNSELECTABLE + " ol-layers";
const container = map.getViewport();
container.insertBefore(this.element_, container.firstChild || null);
this.children_ = [];
this.renderedVisible_ = true;
}
/**
* @param {import("../render/EventType.js").default} type Event type.
* @param {import("../Map.js").FrameState} frameState Frame state.
* @override
*/
dispatchRenderEvent(type, frameState) {
const map = this.getMap();
if (map.hasListener(type)) {
const event = new Event_default2(type, void 0, frameState);
map.dispatchEvent(event);
}
}
/**
* @override
*/
disposeInternal() {
unlistenByKey(this.fontChangeListenerKey_);
this.element_.remove();
super.disposeInternal();
}
/**
* Render.
* @param {?import("../Map.js").FrameState} frameState Frame state.
* @override
*/
renderFrame(frameState) {
if (!frameState) {
if (this.renderedVisible_) {
this.element_.style.display = "none";
this.renderedVisible_ = false;
}
return;
}
this.calculateMatrices2D(frameState);
this.dispatchRenderEvent(EventType_default2.PRECOMPOSE, frameState);
const layerStatesArray = frameState.layerStatesArray.sort(
(a, b) => a.zIndex - b.zIndex
);
const declutter = layerStatesArray.some(
(layerState) => layerState.layer instanceof BaseVector_default && layerState.layer.getDeclutter()
);
if (declutter) {
frameState.declutter = {};
}
const viewState = frameState.viewState;
this.children_.length = 0;
const renderedLayerStates = [];
let previousElement = null;
for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
const layerState = layerStatesArray[i];
frameState.layerIndex = i;
const layer = layerState.layer;
const sourceState = layer.getSourceState();
if (!inView(layerState, viewState) || sourceState != "ready" && sourceState != "undefined") {
layer.unrender();
continue;
}
const element = layer.render(frameState, previousElement);
if (!element) {
continue;
}
if (element !== previousElement) {
this.children_.push(element);
previousElement = element;
}
renderedLayerStates.push(layerState);
}
this.declutter(frameState, renderedLayerStates);
replaceChildren(this.element_, this.children_);
this.dispatchRenderEvent(EventType_default2.POSTCOMPOSE, frameState);
if (!this.renderedVisible_) {
this.element_.style.display = "";
this.renderedVisible_ = true;
}
this.scheduleExpireIconCache(frameState);
}
/**
* @param {import("../Map.js").FrameState} frameState Frame state.
* @param {Array<import('../layer/Layer.js').State>} layerStates Layers.
*/
declutter(frameState, layerStates) {
if (!frameState.declutter) {
return;
}
for (let i = layerStates.length - 1; i >= 0; --i) {
const layerState = layerStates[i];
const layer = layerState.layer;
if (layer.getDeclutter()) {
layer.renderDeclutter(frameState, layerState);
}
}
layerStates.forEach(
(layerState) => layerState.layer.renderDeferred(frameState)
);
}
};
var Composite_default = CompositeMapRenderer;
// node_modules/ol/Map.js
function removeLayerMapProperty(layer) {
if (layer instanceof Layer_default) {
layer.setMapInternal(null);
return;
}
if (layer instanceof Group_default) {
layer.getLayers().forEach(removeLayerMapProperty);
}
}
function setLayerMapProperty(layer, map) {
if (layer instanceof Layer_default) {
layer.setMapInternal(map);
return;
}
if (layer instanceof Group_default) {
const layers = layer.getLayers().getArray();
for (let i = 0, ii = layers.length; i < ii; ++i) {
setLayerMapProperty(layers[i], map);
}
}
}
var Map = class extends Object_default {
/**
* @param {MapOptions} [options] Map options.
*/
constructor(options) {
super();
options = options || {};
this.on;
this.once;
this.un;
const optionsInternal = createOptionsInternal(options);
this.renderComplete_ = false;
this.loaded_ = true;
this.boundHandleBrowserEvent_ = this.handleBrowserEvent.bind(this);
this.maxTilesLoading_ = options.maxTilesLoading !== void 0 ? options.maxTilesLoading : 16;
this.pixelRatio_ = options.pixelRatio !== void 0 ? options.pixelRatio : DEVICE_PIXEL_RATIO;
this.postRenderTimeoutHandle_;
this.animationDelayKey_;
this.animationDelay_ = this.animationDelay_.bind(this);
this.coordinateToPixelTransform_ = create();
this.pixelToCoordinateTransform_ = create();
this.frameIndex_ = 0;
this.frameState_ = null;
this.previousExtent_ = null;
this.viewPropertyListenerKey_ = null;
this.viewChangeListenerKey_ = null;
this.layerGroupPropertyListenerKeys_ = null;
this.viewport_ = document.createElement("div");
this.viewport_.className = "ol-viewport" + ("ontouchstart" in window ? " ol-touch" : "");
this.viewport_.style.position = "relative";
this.viewport_.style.overflow = "hidden";
this.viewport_.style.width = "100%";
this.viewport_.style.height = "100%";
this.overlayContainer_ = document.createElement("div");
this.overlayContainer_.style.position = "absolute";
this.overlayContainer_.style.zIndex = "0";
this.overlayContainer_.style.width = "100%";
this.overlayContainer_.style.height = "100%";
this.overlayContainer_.style.pointerEvents = "none";
this.overlayContainer_.className = "ol-overlaycontainer";
this.viewport_.appendChild(this.overlayContainer_);
this.overlayContainerStopEvent_ = document.createElement("div");
this.overlayContainerStopEvent_.style.position = "absolute";
this.overlayContainerStopEvent_.style.zIndex = "0";
this.overlayContainerStopEvent_.style.width = "100%";
this.overlayContainerStopEvent_.style.height = "100%";
this.overlayContainerStopEvent_.style.pointerEvents = "none";
this.overlayContainerStopEvent_.className = "ol-overlaycontainer-stopevent";
this.viewport_.appendChild(this.overlayContainerStopEvent_);
this.mapBrowserEventHandler_ = null;
this.moveTolerance_ = options.moveTolerance;
this.keyboardEventTarget_ = optionsInternal.keyboardEventTarget;
this.targetChangeHandlerKeys_ = null;
this.targetElement_ = null;
this.resizeObserver_ = new ResizeObserver(() => this.updateSize());
this.controls = optionsInternal.controls || defaults();
this.interactions = optionsInternal.interactions || defaults2({
onFocusOnly: true
});
this.overlays_ = optionsInternal.overlays;
this.overlayIdIndex_ = {};
this.renderer_ = null;
this.postRenderFunctions_ = [];
this.tileQueue_ = new TileQueue_default(
this.getTilePriority.bind(this),
this.handleTileChange_.bind(this)
);
this.addChangeListener(
MapProperty_default.LAYERGROUP,
this.handleLayerGroupChanged_
);
this.addChangeListener(MapProperty_default.VIEW, this.handleViewChanged_);
this.addChangeListener(MapProperty_default.SIZE, this.handleSizeChanged_);
this.addChangeListener(MapProperty_default.TARGET, this.handleTargetChanged_);
this.setProperties(optionsInternal.values);
const map = this;
if (options.view && !(options.view instanceof View_default)) {
options.view.then(function(viewOptions) {
map.setView(new View_default(viewOptions));
});
}
this.controls.addEventListener(
CollectionEventType_default.ADD,
/**
* @param {import("./Collection.js").CollectionEvent<import("./control/Control.js").default>} event CollectionEvent
*/
(event) => {
event.element.setMap(this);
}
);
this.controls.addEventListener(
CollectionEventType_default.REMOVE,
/**
* @param {import("./Collection.js").CollectionEvent<import("./control/Control.js").default>} event CollectionEvent.
*/
(event) => {
event.element.setMap(null);
}
);
this.interactions.addEventListener(
CollectionEventType_default.ADD,
/**
* @param {import("./Collection.js").CollectionEvent<import("./interaction/Interaction.js").default>} event CollectionEvent.
*/
(event) => {
event.element.setMap(this);
}
);
this.interactions.addEventListener(
CollectionEventType_default.REMOVE,
/**
* @param {import("./Collection.js").CollectionEvent<import("./interaction/Interaction.js").default>} event CollectionEvent.
*/
(event) => {
event.element.setMap(null);
}
);
this.overlays_.addEventListener(
CollectionEventType_default.ADD,
/**
* @param {import("./Collection.js").CollectionEvent<import("./Overlay.js").default>} event CollectionEvent.
*/
(event) => {
this.addOverlayInternal_(event.element);
}
);
this.overlays_.addEventListener(
CollectionEventType_default.REMOVE,
/**
* @param {import("./Collection.js").CollectionEvent<import("./Overlay.js").default>} event CollectionEvent.
*/
(event) => {
const id = event.element.getId();
if (id !== void 0) {
delete this.overlayIdIndex_[id.toString()];
}
event.element.setMap(null);
}
);
this.controls.forEach(
/**
* @param {import("./control/Control.js").default} control Control.
*/
(control) => {
control.setMap(this);
}
);
this.interactions.forEach(
/**
* @param {import("./interaction/Interaction.js").default} interaction Interaction.
*/
(interaction) => {
interaction.setMap(this);
}
);
this.overlays_.forEach(this.addOverlayInternal_.bind(this));
}
/**
* Add the given control to the map.
* @param {import("./control/Control.js").default} control Control.
* @api
*/
addControl(control) {
this.getControls().push(control);
}
/**
* Add the given interaction to the map. If you want to add an interaction
* at another point of the collection use `getInteractions()` and the methods
* available on {@link module:ol/Collection~Collection}. This can be used to
* stop the event propagation from the handleEvent function. The interactions
* get to handle the events in the reverse order of this collection.
* @param {import("./interaction/Interaction.js").default} interaction Interaction to add.
* @api
*/
addInteraction(interaction) {
this.getInteractions().push(interaction);
}
/**
* Adds the given layer to the top of this map. If you want to add a layer
* elsewhere in the stack, use `getLayers()` and the methods available on
* {@link module:ol/Collection~Collection}.
* @param {import("./layer/Base.js").default} layer Layer.
* @api
*/
addLayer(layer) {
const layers = this.getLayerGroup().getLayers();
layers.push(layer);
}
/**
* @param {import("./layer/Group.js").GroupEvent} event The layer add event.
* @private
*/
handleLayerAdd_(event) {
setLayerMapProperty(event.layer, this);
}
/**
* Add the given overlay to the map.
* @param {import("./Overlay.js").default} overlay Overlay.
* @api
*/
addOverlay(overlay) {
this.getOverlays().push(overlay);
}
/**
* This deals with map's overlay collection changes.
* @param {import("./Overlay.js").default} overlay Overlay.
* @private
*/
addOverlayInternal_(overlay) {
const id = overlay.getId();
if (id !== void 0) {
this.overlayIdIndex_[id.toString()] = overlay;
}
overlay.setMap(this);
}
/**
*
* Clean up.
* @override
*/
disposeInternal() {
this.controls.clear();
this.interactions.clear();
this.overlays_.clear();
this.resizeObserver_.disconnect();
this.setTarget(null);
super.disposeInternal();
}
/**
* Detect features that intersect a pixel on the viewport, and execute a
* callback with each intersecting feature. Layers included in the detection can
* be configured through the `layerFilter` option in `options`.
* For polygons without a fill, only the stroke will be used for hit detection.
* Polygons must have a fill style applied to ensure that pixels inside a polygon are detected.
* The fill can be transparent.
* @param {import("./pixel.js").Pixel} pixel Pixel.
* @param {function(import("./Feature.js").FeatureLike, import("./layer/Layer.js").default<import("./source/Source").default>, import("./geom/SimpleGeometry.js").default): T} callback Feature callback. The callback will be
* called with two arguments. The first argument is one
* {@link module:ol/Feature~Feature feature} or
* {@link module:ol/render/Feature~RenderFeature render feature} at the pixel, the second is
* the {@link module:ol/layer/Layer~Layer layer} of the feature and will be null for
* unmanaged layers. To stop detection, callback functions can return a
* truthy value.
* @param {AtPixelOptions} [options] Optional options.
* @return {T|undefined} Callback result, i.e. the return value of last
* callback execution, or the first truthy callback return value.
* @template T
* @api
*/
forEachFeatureAtPixel(pixel, callback, options) {
if (!this.frameState_ || !this.renderer_) {
return;
}
const coordinate = this.getCoordinateFromPixelInternal(pixel);
options = options !== void 0 ? options : {};
const hitTolerance = options.hitTolerance !== void 0 ? options.hitTolerance : 0;
const layerFilter = options.layerFilter !== void 0 ? options.layerFilter : TRUE;
const checkWrapped = options.checkWrapped !== false;
return this.renderer_.forEachFeatureAtCoordinate(
coordinate,
this.frameState_,
hitTolerance,
checkWrapped,
callback,
null,
layerFilter,
null
);
}
/**
* Get all features that intersect a pixel on the viewport.
* For polygons without a fill, only the stroke will be used for hit detection.
* Polygons must have a fill style applied to ensure that pixels inside a polygon are detected.
* The fill can be transparent.
* @param {import("./pixel.js").Pixel} pixel Pixel.
* @param {AtPixelOptions} [options] Optional options.
* @return {Array<import("./Feature.js").FeatureLike>} The detected features or
* an empty array if none were found.
* @api
*/
getFeaturesAtPixel(pixel, options) {
const features = [];
this.forEachFeatureAtPixel(
pixel,
function(feature) {
features.push(feature);
},
options
);
return features;
}
/**
* Get all layers from all layer groups.
* @return {Array<import("./layer/Layer.js").default>} Layers.
* @api
*/
getAllLayers() {
const layers = [];
function addLayersFrom(layerGroup) {
layerGroup.forEach(function(layer) {
if (layer instanceof Group_default) {
addLayersFrom(layer.getLayers());
} else {
layers.push(layer);
}
});
}
addLayersFrom(this.getLayers());
return layers;
}
/**
* Detect if features intersect a pixel on the viewport. Layers included in the
* detection can be configured through the `layerFilter` option.
* For polygons without a fill, only the stroke will be used for hit detection.
* Polygons must have a fill style applied to ensure that pixels inside a polygon are detected.
* The fill can be transparent.
* @param {import("./pixel.js").Pixel} pixel Pixel.
* @param {AtPixelOptions} [options] Optional options.
* @return {boolean} Is there a feature at the given pixel?
* @api
*/
hasFeatureAtPixel(pixel, options) {
if (!this.frameState_ || !this.renderer_) {
return false;
}
const coordinate = this.getCoordinateFromPixelInternal(pixel);
options = options !== void 0 ? options : {};
const layerFilter = options.layerFilter !== void 0 ? options.layerFilter : TRUE;
const hitTolerance = options.hitTolerance !== void 0 ? options.hitTolerance : 0;
const checkWrapped = options.checkWrapped !== false;
return this.renderer_.hasFeatureAtCoordinate(
coordinate,
this.frameState_,
hitTolerance,
checkWrapped,
layerFilter,
null
);
}
/**
* Returns the coordinate in user projection for a browser event.
* @param {MouseEvent} event Event.
* @return {import("./coordinate.js").Coordinate} Coordinate.
* @api
*/
getEventCoordinate(event) {
return this.getCoordinateFromPixel(this.getEventPixel(event));
}
/**
* Returns the coordinate in view projection for a browser event.
* @param {MouseEvent} event Event.
* @return {import("./coordinate.js").Coordinate} Coordinate.
*/
getEventCoordinateInternal(event) {
return this.getCoordinateFromPixelInternal(this.getEventPixel(event));
}
/**
* Returns the map pixel position for a browser event relative to the viewport.
* @param {UIEvent|{clientX: number, clientY: number}} event Event.
* @return {import("./pixel.js").Pixel} Pixel.
* @api
*/
getEventPixel(event) {
const viewport = this.viewport_;
const viewportPosition = viewport.getBoundingClientRect();
const viewportSize = this.getSize();
const scaleX = viewportPosition.width / viewportSize[0];
const scaleY = viewportPosition.height / viewportSize[1];
const eventPosition = (
//FIXME Are we really calling this with a TouchEvent anywhere?
"changedTouches" in event ? (
/** @type {TouchEvent} */
event.changedTouches[0]
) : (
/** @type {MouseEvent} */
event
)
);
return [
(eventPosition.clientX - viewportPosition.left) / scaleX,
(eventPosition.clientY - viewportPosition.top) / scaleY
];
}
/**
* Get the target in which this map is rendered.
* Note that this returns what is entered as an option or in setTarget:
* if that was an element, it returns an element; if a string, it returns that.
* @return {HTMLElement|string|undefined} The Element or id of the Element that the
* map is rendered in.
* @observable
* @api
*/
getTarget() {
return (
/** @type {HTMLElement|string|undefined} */
this.get(MapProperty_default.TARGET)
);
}
/**
* Get the DOM element into which this map is rendered. In contrast to
* `getTarget` this method always return an `Element`, or `null` if the
* map has no target.
* @return {HTMLElement} The element that the map is rendered in.
* @api
*/
getTargetElement() {
return this.targetElement_;
}
/**
* Get the coordinate for a given pixel. This returns a coordinate in the
* user projection.
* @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.
* @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.
* @api
*/
getCoordinateFromPixel(pixel) {
return toUserCoordinate(
this.getCoordinateFromPixelInternal(pixel),
this.getView().getProjection()
);
}
/**
* Get the coordinate for a given pixel. This returns a coordinate in the
* map view projection.
* @param {import("./pixel.js").Pixel} pixel Pixel position in the map viewport.
* @return {import("./coordinate.js").Coordinate} The coordinate for the pixel position.
*/
getCoordinateFromPixelInternal(pixel) {
const frameState = this.frameState_;
if (!frameState) {
return null;
}
return apply(frameState.pixelToCoordinateTransform, pixel.slice());
}
/**
* Get the map controls. Modifying this collection changes the controls
* associated with the map.
* @return {Collection<import("./control/Control.js").default>} Controls.
* @api
*/
getControls() {
return this.controls;
}
/**
* Get the map overlays. Modifying this collection changes the overlays
* associated with the map.
* @return {Collection<import("./Overlay.js").default>} Overlays.
* @api
*/
getOverlays() {
return this.overlays_;
}
/**
* Get an overlay by its identifier (the value returned by overlay.getId()).
* Note that the index treats string and numeric identifiers as the same. So
* `map.getOverlayById(2)` will return an overlay with id `'2'` or `2`.
* @param {string|number} id Overlay identifier.
* @return {import("./Overlay.js").default|null} Overlay.
* @api
*/
getOverlayById(id) {
const overlay = this.overlayIdIndex_[id.toString()];
return overlay !== void 0 ? overlay : null;
}
/**
* Get the map interactions. Modifying this collection changes the interactions
* associated with the map.
*
* Interactions are used for e.g. pan, zoom and rotate.
* @return {Collection<import("./interaction/Interaction.js").default>} Interactions.
* @api
*/
getInteractions() {
return this.interactions;
}
/**
* Get the layergroup associated with this map.
* @return {LayerGroup} A layer group containing the layers in this map.
* @observable
* @api
*/
getLayerGroup() {
return (
/** @type {LayerGroup} */
this.get(MapProperty_default.LAYERGROUP)
);
}
/**
* Clear any existing layers and add layers to the map.
* @param {Array<import("./layer/Base.js").default>|Collection<import("./layer/Base.js").default>} layers The layers to be added to the map.
* @api
*/
setLayers(layers) {
const group = this.getLayerGroup();
if (layers instanceof Collection_default) {
group.setLayers(layers);
return;
}
const collection = group.getLayers();
collection.clear();
collection.extend(layers);
}
/**
* Get the collection of layers associated with this map.
* @return {!Collection<import("./layer/Base.js").default>} Layers.
* @api
*/
getLayers() {
const layers = this.getLayerGroup().getLayers();
return layers;
}
/**
* @return {boolean} Layers have sources that are still loading.
*/
getLoadingOrNotReady() {
const layerStatesArray = this.getLayerGroup().getLayerStatesArray();
for (let i = 0, ii = layerStatesArray.length; i < ii; ++i) {
const state = layerStatesArray[i];
if (!state.visible) {
continue;
}
const renderer = state.layer.getRenderer();
if (renderer && !renderer.ready) {
return true;
}
const source = state.layer.getSource();
if (source && source.loading) {
return true;
}
}
return false;
}
/**
* Get the pixel for a coordinate. This takes a coordinate in the user
* projection and returns the corresponding pixel.
* @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.
* @return {import("./pixel.js").Pixel} A pixel position in the map viewport.
* @api
*/
getPixelFromCoordinate(coordinate) {
const viewCoordinate = fromUserCoordinate(
coordinate,
this.getView().getProjection()
);
return this.getPixelFromCoordinateInternal(viewCoordinate);
}
/**
* Get the pixel for a coordinate. This takes a coordinate in the map view
* projection and returns the corresponding pixel.
* @param {import("./coordinate.js").Coordinate} coordinate A map coordinate.
* @return {import("./pixel.js").Pixel} A pixel position in the map viewport.
*/
getPixelFromCoordinateInternal(coordinate) {
const frameState = this.frameState_;
if (!frameState) {
return null;
}
return apply(
frameState.coordinateToPixelTransform,
coordinate.slice(0, 2)
);
}
/**
* Get the map renderer.
* @return {import("./renderer/Map.js").default|null} Renderer
*/
getRenderer() {
return this.renderer_;
}
/**
* Get the size of this map.
* @return {import("./size.js").Size|undefined} The size in pixels of the map in the DOM.
* @observable
* @api
*/
getSize() {
return (
/** @type {import("./size.js").Size|undefined} */
this.get(MapProperty_default.SIZE)
);
}
/**
* Get the view associated with this map. A view manages properties such as
* center and resolution.
* @return {View} The view that controls this map.
* @observable
* @api
*/
getView() {
return (
/** @type {View} */
this.get(MapProperty_default.VIEW)
);
}
/**
* Get the element that serves as the map viewport.
* @return {HTMLElement} Viewport.
* @api
*/
getViewport() {
return this.viewport_;
}
/**
* Get the element that serves as the container for overlays. Elements added to
* this container will let mousedown and touchstart events through to the map,
* so clicks and gestures on an overlay will trigger {@link module:ol/MapBrowserEvent~MapBrowserEvent}
* events.
* @return {!HTMLElement} The map's overlay container.
*/
getOverlayContainer() {
return this.overlayContainer_;
}
/**
* Get the element that serves as a container for overlays that don't allow
* event propagation. Elements added to this container won't let mousedown and
* touchstart events through to the map, so clicks and gestures on an overlay
* don't trigger any {@link module:ol/MapBrowserEvent~MapBrowserEvent}.
* @return {!HTMLElement} The map's overlay container that stops events.
*/
getOverlayContainerStopEvent() {
return this.overlayContainerStopEvent_;
}
/**
* @return {!Document} The document where the map is displayed.
*/
getOwnerDocument() {
const targetElement = this.getTargetElement();
return targetElement ? targetElement.ownerDocument : document;
}
/**
* @param {import("./Tile.js").default} tile Tile.
* @param {string} tileSourceKey Tile source key.
* @param {import("./coordinate.js").Coordinate} tileCenter Tile center.
* @param {number} tileResolution Tile resolution.
* @return {number} Tile priority.
*/
getTilePriority(tile, tileSourceKey, tileCenter, tileResolution) {
return getTilePriority(
this.frameState_,
tile,
tileSourceKey,
tileCenter,
tileResolution
);
}
/**
* @param {PointerEvent|KeyboardEvent|WheelEvent} browserEvent Browser event.
* @param {string} [type] Type.
*/
handleBrowserEvent(browserEvent, type) {
type = type || browserEvent.type;
const mapBrowserEvent = new MapBrowserEvent_default(type, this, browserEvent);
this.handleMapBrowserEvent(mapBrowserEvent);
}
/**
* @param {MapBrowserEvent} mapBrowserEvent The event to handle.
*/
handleMapBrowserEvent(mapBrowserEvent) {
if (!this.frameState_) {
return;
}
const originalEvent = mapBrowserEvent.originalEvent;
const eventType = originalEvent.type;
if (eventType === EventType_default3.POINTERDOWN || eventType === EventType_default.WHEEL || eventType === EventType_default.KEYDOWN) {
const doc = this.getOwnerDocument();
const rootNode = this.viewport_.getRootNode ? this.viewport_.getRootNode() : doc;
const target = (
/** @type {Node} */
originalEvent.target
);
const currentDoc = rootNode instanceof ShadowRoot ? rootNode.host === target ? rootNode.host.ownerDocument : rootNode : rootNode === doc ? doc.documentElement : rootNode;
if (
// Abort if the target is a child of the container for elements whose events are not meant
// to be handled by map interactions.
this.overlayContainerStopEvent_.contains(target) || // Abort if the event target is a child of the container that is no longer in the page.
// It's possible for the target to no longer be in the page if it has been removed in an
// event listener, this might happen in a Control that recreates it's content based on
// user interaction either manually or via a render in something like https://reactjs.org/
!currentDoc.contains(target)
) {
return;
}
}
mapBrowserEvent.frameState = this.frameState_;
if (this.dispatchEvent(mapBrowserEvent) !== false) {
const interactionsArray = this.getInteractions().getArray().slice();
for (let i = interactionsArray.length - 1; i >= 0; i--) {
const interaction = interactionsArray[i];
if (interaction.getMap() !== this || !interaction.getActive() || !this.getTargetElement()) {
continue;
}
const cont = interaction.handleEvent(mapBrowserEvent);
if (!cont || mapBrowserEvent.propagationStopped) {
break;
}
}
}
}
/**
* @protected
*/
handlePostRender() {
const frameState = this.frameState_;
const tileQueue = this.tileQueue_;
if (!tileQueue.isEmpty()) {
let maxTotalLoading = this.maxTilesLoading_;
let maxNewLoads = maxTotalLoading;
if (frameState) {
const hints = frameState.viewHints;
if (hints[ViewHint_default.ANIMATING] || hints[ViewHint_default.INTERACTING]) {
const lowOnFrameBudget = Date.now() - frameState.time > 8;
maxTotalLoading = lowOnFrameBudget ? 0 : 8;
maxNewLoads = lowOnFrameBudget ? 0 : 2;
}
}
if (tileQueue.getTilesLoading() < maxTotalLoading) {
tileQueue.reprioritize();
tileQueue.loadMoreTiles(maxTotalLoading, maxNewLoads);
}
}
if (frameState && this.renderer_ && !frameState.animate) {
if (this.renderComplete_) {
if (this.hasListener(EventType_default2.RENDERCOMPLETE)) {
this.renderer_.dispatchRenderEvent(
EventType_default2.RENDERCOMPLETE,
frameState
);
}
if (this.loaded_ === false) {
this.loaded_ = true;
this.dispatchEvent(
new MapEvent_default(MapEventType_default.LOADEND, this, frameState)
);
}
} else if (this.loaded_ === true) {
this.loaded_ = false;
this.dispatchEvent(
new MapEvent_default(MapEventType_default.LOADSTART, this, frameState)
);
}
}
const postRenderFunctions = this.postRenderFunctions_;
if (frameState) {
for (let i = 0, ii = postRenderFunctions.length; i < ii; ++i) {
postRenderFunctions[i](this, frameState);
}
}
postRenderFunctions.length = 0;
}
/**
* @private
*/
handleSizeChanged_() {
if (this.getView() && !this.getView().getAnimating()) {
this.getView().resolveConstraints(0);
}
this.render();
}
/**
* @private
*/
handleTargetChanged_() {
if (this.mapBrowserEventHandler_) {
for (let i = 0, ii = this.targetChangeHandlerKeys_.length; i < ii; ++i) {
unlistenByKey(this.targetChangeHandlerKeys_[i]);
}
this.targetChangeHandlerKeys_ = null;
this.viewport_.removeEventListener(
EventType_default.CONTEXTMENU,
this.boundHandleBrowserEvent_
);
this.viewport_.removeEventListener(
EventType_default.WHEEL,
this.boundHandleBrowserEvent_
);
this.mapBrowserEventHandler_.dispose();
this.mapBrowserEventHandler_ = null;
this.viewport_.remove();
}
if (this.targetElement_) {
this.resizeObserver_.unobserve(this.targetElement_);
const rootNode = this.targetElement_.getRootNode();
if (rootNode instanceof ShadowRoot) {
this.resizeObserver_.unobserve(rootNode.host);
}
this.setSize(void 0);
}
const target = this.getTarget();
const targetElement = typeof target === "string" ? document.getElementById(target) : target;
this.targetElement_ = targetElement;
if (!targetElement) {
if (this.renderer_) {
clearTimeout(this.postRenderTimeoutHandle_);
this.postRenderTimeoutHandle_ = void 0;
this.postRenderFunctions_.length = 0;
this.renderer_.dispose();
this.renderer_ = null;
}
if (this.animationDelayKey_) {
cancelAnimationFrame(this.animationDelayKey_);
this.animationDelayKey_ = void 0;
}
} else {
targetElement.appendChild(this.viewport_);
if (!this.renderer_) {
this.renderer_ = new Composite_default(this);
}
this.mapBrowserEventHandler_ = new MapBrowserEventHandler_default(
this,
this.moveTolerance_
);
for (const key in MapBrowserEventType_default) {
this.mapBrowserEventHandler_.addEventListener(
MapBrowserEventType_default[key],
this.handleMapBrowserEvent.bind(this)
);
}
this.viewport_.addEventListener(
EventType_default.CONTEXTMENU,
this.boundHandleBrowserEvent_,
false
);
this.viewport_.addEventListener(
EventType_default.WHEEL,
this.boundHandleBrowserEvent_,
PASSIVE_EVENT_LISTENERS ? { passive: false } : false
);
let keyboardEventTarget;
if (!this.keyboardEventTarget_) {
const targetRoot = targetElement.getRootNode();
const targetCandidate = targetRoot instanceof ShadowRoot ? targetRoot.host : targetElement;
keyboardEventTarget = targetCandidate;
} else {
keyboardEventTarget = this.keyboardEventTarget_;
}
this.targetChangeHandlerKeys_ = [
listen(
keyboardEventTarget,
EventType_default.KEYDOWN,
this.handleBrowserEvent,
this
),
listen(
keyboardEventTarget,
EventType_default.KEYPRESS,
this.handleBrowserEvent,
this
)
];
const rootNode = targetElement.getRootNode();
if (rootNode instanceof ShadowRoot) {
this.resizeObserver_.observe(rootNode.host);
}
this.resizeObserver_.observe(targetElement);
}
this.updateSize();
}
/**
* @private
*/
handleTileChange_() {
this.render();
}
/**
* @private
*/
handleViewPropertyChanged_() {
this.render();
}
/**
* @private
*/
handleViewChanged_() {
if (this.viewPropertyListenerKey_) {
unlistenByKey(this.viewPropertyListenerKey_);
this.viewPropertyListenerKey_ = null;
}
if (this.viewChangeListenerKey_) {
unlistenByKey(this.viewChangeListenerKey_);
this.viewChangeListenerKey_ = null;
}
const view = this.getView();
if (view) {
this.updateViewportSize_(this.getSize());
this.viewPropertyListenerKey_ = listen(
view,
ObjectEventType_default.PROPERTYCHANGE,
this.handleViewPropertyChanged_,
this
);
this.viewChangeListenerKey_ = listen(
view,
EventType_default.CHANGE,
this.handleViewPropertyChanged_,
this
);
view.resolveConstraints(0);
}
this.render();
}
/**
* @private
*/
handleLayerGroupChanged_() {
if (this.layerGroupPropertyListenerKeys_) {
this.layerGroupPropertyListenerKeys_.forEach(unlistenByKey);
this.layerGroupPropertyListenerKeys_ = null;
}
const layerGroup = this.getLayerGroup();
if (layerGroup) {
this.handleLayerAdd_(new GroupEvent("addlayer", layerGroup));
this.layerGroupPropertyListenerKeys_ = [
listen(layerGroup, ObjectEventType_default.PROPERTYCHANGE, this.render, this),
listen(layerGroup, EventType_default.CHANGE, this.render, this),
listen(layerGroup, "addlayer", this.handleLayerAdd_, this),
listen(layerGroup, "removelayer", this.handleLayerRemove_, this)
];
}
this.render();
}
/**
* @return {boolean} Is rendered.
*/
isRendered() {
return !!this.frameState_;
}
/**
* @private
*/
animationDelay_() {
this.animationDelayKey_ = void 0;
this.renderFrame_(Date.now());
}
/**
* Requests an immediate render in a synchronous manner.
* @api
*/
renderSync() {
if (this.animationDelayKey_) {
cancelAnimationFrame(this.animationDelayKey_);
}
this.animationDelay_();
}
/**
* Redraws all text after new fonts have loaded
*/
redrawText() {
if (!this.frameState_) {
return;
}
const layerStates = this.frameState_.layerStatesArray;
for (let i = 0, ii = layerStates.length; i < ii; ++i) {
const layer = layerStates[i].layer;
if (layer.hasRenderer()) {
layer.getRenderer().handleFontsChanged();
}
}
}
/**
* Request a map rendering (at the next animation frame).
* @api
*/
render() {
if (this.renderer_ && this.animationDelayKey_ === void 0) {
this.animationDelayKey_ = requestAnimationFrame(this.animationDelay_);
}
}
/**
* Remove the given control from the map.
* @param {import("./control/Control.js").default} control Control.
* @return {import("./control/Control.js").default|undefined} The removed control (or undefined
* if the control was not found).
* @api
*/
removeControl(control) {
return this.getControls().remove(control);
}
/**
* Remove the given interaction from the map.
* @param {import("./interaction/Interaction.js").default} interaction Interaction to remove.
* @return {import("./interaction/Interaction.js").default|undefined} The removed interaction (or
* undefined if the interaction was not found).
* @api
*/
removeInteraction(interaction) {
return this.getInteractions().remove(interaction);
}
/**
* Removes the given layer from the map.
* @param {import("./layer/Base.js").default} layer Layer.
* @return {import("./layer/Base.js").default|undefined} The removed layer (or undefined if the
* layer was not found).
* @api
*/
removeLayer(layer) {
const layers = this.getLayerGroup().getLayers();
return layers.remove(layer);
}
/**
* @param {import("./layer/Group.js").GroupEvent} event The layer remove event.
* @private
*/
handleLayerRemove_(event) {
removeLayerMapProperty(event.layer);
}
/**
* Remove the given overlay from the map.
* @param {import("./Overlay.js").default} overlay Overlay.
* @return {import("./Overlay.js").default|undefined} The removed overlay (or undefined
* if the overlay was not found).
* @api
*/
removeOverlay(overlay) {
return this.getOverlays().remove(overlay);
}
/**
* @param {number} time Time.
* @private
*/
renderFrame_(time) {
const size = this.getSize();
const view = this.getView();
const previousFrameState = this.frameState_;
let frameState = null;
if (size !== void 0 && hasArea(size) && view && view.isDef()) {
const viewHints = view.getHints(
this.frameState_ ? this.frameState_.viewHints : void 0
);
const viewState = view.getState();
frameState = {
animate: false,
coordinateToPixelTransform: this.coordinateToPixelTransform_,
declutter: null,
extent: getForViewAndSize(
viewState.center,
viewState.resolution,
viewState.rotation,
size
),
index: this.frameIndex_++,
layerIndex: 0,
layerStatesArray: this.getLayerGroup().getLayerStatesArray(),
pixelRatio: this.pixelRatio_,
pixelToCoordinateTransform: this.pixelToCoordinateTransform_,
postRenderFunctions: [],
size,
tileQueue: this.tileQueue_,
time,
usedTiles: {},
viewState,
viewHints,
wantedTiles: {},
mapId: getUid(this),
renderTargets: {}
};
if (viewState.nextCenter && viewState.nextResolution) {
const rotation = isNaN(viewState.nextRotation) ? viewState.rotation : viewState.nextRotation;
frameState.nextExtent = getForViewAndSize(
viewState.nextCenter,
viewState.nextResolution,
rotation,
size
);
}
}
this.frameState_ = frameState;
this.renderer_.renderFrame(frameState);
if (frameState) {
if (frameState.animate) {
this.render();
}
Array.prototype.push.apply(
this.postRenderFunctions_,
frameState.postRenderFunctions
);
if (previousFrameState) {
const moveStart = !this.previousExtent_ || !isEmpty(this.previousExtent_) && !equals2(frameState.extent, this.previousExtent_);
if (moveStart) {
this.dispatchEvent(
new MapEvent_default(MapEventType_default.MOVESTART, this, previousFrameState)
);
this.previousExtent_ = createOrUpdateEmpty(this.previousExtent_);
}
}
const idle = this.previousExtent_ && !frameState.viewHints[ViewHint_default.ANIMATING] && !frameState.viewHints[ViewHint_default.INTERACTING] && !equals2(frameState.extent, this.previousExtent_);
if (idle) {
this.dispatchEvent(
new MapEvent_default(MapEventType_default.MOVEEND, this, frameState)
);
clone(frameState.extent, this.previousExtent_);
}
}
this.dispatchEvent(new MapEvent_default(MapEventType_default.POSTRENDER, this, frameState));
this.renderComplete_ = (this.hasListener(MapEventType_default.LOADSTART) || this.hasListener(MapEventType_default.LOADEND) || this.hasListener(EventType_default2.RENDERCOMPLETE)) && !this.tileQueue_.getTilesLoading() && !this.tileQueue_.getCount() && !this.getLoadingOrNotReady();
if (!this.postRenderTimeoutHandle_) {
this.postRenderTimeoutHandle_ = setTimeout(() => {
this.postRenderTimeoutHandle_ = void 0;
this.handlePostRender();
}, 0);
}
}
/**
* Sets the layergroup of this map.
* @param {LayerGroup} layerGroup A layer group containing the layers in this map.
* @observable
* @api
*/
setLayerGroup(layerGroup) {
const oldLayerGroup = this.getLayerGroup();
if (oldLayerGroup) {
this.handleLayerRemove_(new GroupEvent("removelayer", oldLayerGroup));
}
this.set(MapProperty_default.LAYERGROUP, layerGroup);
}
/**
* Set the size of this map.
* @param {import("./size.js").Size|undefined} size The size in pixels of the map in the DOM.
* @observable
* @api
*/
setSize(size) {
this.set(MapProperty_default.SIZE, size);
}
/**
* Set the target element to render this map into.
* For accessibility (focus and keyboard events for map navigation), the `target` element must have a
* properly configured `tabindex` attribute. If the `target` element is inside a Shadow DOM, the
* `tabindex` atribute must be set on the custom element's host element.
* @param {HTMLElement|string} [target] The Element or id of the Element
* that the map is rendered in.
* @observable
* @api
*/
setTarget(target) {
this.set(MapProperty_default.TARGET, target);
}
/**
* Set the view for this map.
* @param {View|Promise<import("./View.js").ViewOptions>|null} view The view that controls this map.
* It is also possible to pass a promise that resolves to options for constructing a view. This
* alternative allows view properties to be resolved by sources or other components that load
* view-related metadata.
* @observable
* @api
*/
setView(view) {
if (!view || view instanceof View_default) {
this.set(MapProperty_default.VIEW, view);
return;
}
this.set(MapProperty_default.VIEW, new View_default());
const map = this;
view.then(function(viewOptions) {
map.setView(new View_default(viewOptions));
});
}
/**
* Force a recalculation of the map viewport size. This should be called when
* third-party code changes the size of the map viewport.
* @api
*/
updateSize() {
const targetElement = this.getTargetElement();
let size = void 0;
if (targetElement) {
const computedStyle = getComputedStyle(targetElement);
const width = targetElement.offsetWidth - parseFloat(computedStyle["borderLeftWidth"]) - parseFloat(computedStyle["paddingLeft"]) - parseFloat(computedStyle["paddingRight"]) - parseFloat(computedStyle["borderRightWidth"]);
const height = targetElement.offsetHeight - parseFloat(computedStyle["borderTopWidth"]) - parseFloat(computedStyle["paddingTop"]) - parseFloat(computedStyle["paddingBottom"]) - parseFloat(computedStyle["borderBottomWidth"]);
if (!isNaN(width) && !isNaN(height)) {
size = [Math.max(0, width), Math.max(0, height)];
if (!hasArea(size) && !!(targetElement.offsetWidth || targetElement.offsetHeight || targetElement.getClientRects().length)) {
warn(
"No map visible because the map container's width or height are 0."
);
}
}
}
const oldSize = this.getSize();
if (size && (!oldSize || !equals(size, oldSize))) {
this.setSize(size);
this.updateViewportSize_(size);
}
}
/**
* Recomputes the viewport size and save it on the view object (if any)
* @param {import("./size.js").Size|undefined} size The size.
* @private
*/
updateViewportSize_(size) {
const view = this.getView();
if (view) {
view.setViewportSize(size);
}
}
};
function createOptionsInternal(options) {
let keyboardEventTarget = null;
if (options.keyboardEventTarget !== void 0) {
keyboardEventTarget = typeof options.keyboardEventTarget === "string" ? document.getElementById(options.keyboardEventTarget) : options.keyboardEventTarget;
}
const values = {};
const layerGroup = options.layers && typeof /** @type {?} */
options.layers.getLayers === "function" ? (
/** @type {LayerGroup} */
options.layers
) : new Group_default({
layers: (
/** @type {Collection<import("./layer/Base.js").default>|Array<import("./layer/Base.js").default>} */
options.layers
)
});
values[MapProperty_default.LAYERGROUP] = layerGroup;
values[MapProperty_default.TARGET] = options.target;
values[MapProperty_default.VIEW] = options.view instanceof View_default ? options.view : new View_default();
let controls;
if (options.controls !== void 0) {
if (Array.isArray(options.controls)) {
controls = new Collection_default(options.controls.slice());
} else {
assert(
typeof /** @type {?} */
options.controls.getArray === "function",
"Expected `controls` to be an array or an `ol/Collection.js`"
);
controls = options.controls;
}
}
let interactions;
if (options.interactions !== void 0) {
if (Array.isArray(options.interactions)) {
interactions = new Collection_default(options.interactions.slice());
} else {
assert(
typeof /** @type {?} */
options.interactions.getArray === "function",
"Expected `interactions` to be an array or an `ol/Collection.js`"
);
interactions = options.interactions;
}
}
let overlays;
if (options.overlays !== void 0) {
if (Array.isArray(options.overlays)) {
overlays = new Collection_default(options.overlays.slice());
} else {
assert(
typeof /** @type {?} */
options.overlays.getArray === "function",
"Expected `overlays` to be an array or an `ol/Collection.js`"
);
overlays = options.overlays;
}
} else {
overlays = new Collection_default();
}
return {
controls,
interactions,
keyboardEventTarget,
overlays,
values
};
}
var Map_default2 = Map;
export {
Kinetic_default,
MapBrowserEventHandler_default,
MapProperty_default,
Attribution_default,
Rotate_default,
Zoom_default,
defaults,
Map_default2 as Map_default
};
//# sourceMappingURL=chunk-EW2Q4UMF.js.map