3579 lines
112 KiB
JavaScript
3579 lines
112 KiB
JavaScript
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
|