Make code prettier
This updates ESLint and our shared eslint-config-openlayers to use Prettier. Most formatting changes were automatically applied with this:
npm run lint -- --fix
A few manual changes were required:
* In `examples/offscreen-canvas.js`, the `//eslint-disable-line` comment needed to be moved to the appropriate line to disable the error about the `'worker-loader!./offscreen-canvas.worker.js'` import.
* In `examples/webpack/exapmle-builder.js`, spaces could not be added after a couple `function`s for some reason. While editing this, I reworked `ExampleBuilder` to be a class.
* In `src/ol/format/WMSGetFeatureInfo.js`, the `// @ts-ignore` comment needed to be moved down one line so it applied to the `parsersNS` argument.
This commit is contained in:
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* @module ol/interaction/DoubleClickZoom
|
||||
*/
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import Interaction, {zoomByDelta} from './Interaction.js';
|
||||
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -11,20 +10,18 @@ import Interaction, {zoomByDelta} from './Interaction.js';
|
||||
* @property {number} [delta=1] The zoom delta applied on each double click.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to zoom by double-clicking on the map.
|
||||
* @api
|
||||
*/
|
||||
class DoubleClickZoom extends Interaction {
|
||||
|
||||
/**
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
super({
|
||||
handleEvent: handleEvent
|
||||
handleEvent: handleEvent,
|
||||
});
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
@@ -40,12 +37,9 @@ class DoubleClickZoom extends Interaction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the {@link module:ol/MapBrowserEvent map browser event} (if it was a
|
||||
* doubleclick) and eventually zooms the map.
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
*/
|
||||
// FIXME should handle all geo-referenced data, not just vector data
|
||||
|
||||
import {TRUE} from '../functions.js';
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
import Event from '../events/Event.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import Interaction from './Interaction.js';
|
||||
import {TRUE} from '../functions.js';
|
||||
import {get as getProjection} from '../proj.js';
|
||||
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -23,7 +22,6 @@ import {get as getProjection} from '../proj.js';
|
||||
* @property {HTMLElement} [target] The element that is used as the drop target, default is the viewport element.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -33,17 +31,15 @@ const DragAndDropEventType = {
|
||||
* @event DragAndDropEvent#addfeatures
|
||||
* @api
|
||||
*/
|
||||
ADD_FEATURES: 'addfeatures'
|
||||
ADD_FEATURES: 'addfeatures',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/DragAndDrop~DragAndDrop} instances are instances
|
||||
* of this type.
|
||||
*/
|
||||
class DragAndDropEvent extends Event {
|
||||
|
||||
/**
|
||||
* @param {DragAndDropEventType} type Type.
|
||||
* @param {File} file File.
|
||||
@@ -51,7 +47,6 @@ class DragAndDropEvent extends Event {
|
||||
* @param {import("../proj/Projection.js").default=} opt_projection Projection.
|
||||
*/
|
||||
constructor(type, file, opt_features, opt_projection) {
|
||||
|
||||
super(type);
|
||||
|
||||
/**
|
||||
@@ -74,12 +69,9 @@ class DragAndDropEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.projection = opt_projection;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Handles input of vector data by drag and drop.
|
||||
@@ -92,26 +84,27 @@ class DragAndDrop extends Interaction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super({
|
||||
handleEvent: TRUE
|
||||
handleEvent: TRUE,
|
||||
});
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {Array<typeof import("../format/Feature.js").default>}
|
||||
*/
|
||||
this.formatConstructors_ = options.formatConstructors ?
|
||||
options.formatConstructors : [];
|
||||
this.formatConstructors_ = options.formatConstructors
|
||||
? options.formatConstructors
|
||||
: [];
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../proj/Projection.js").default}
|
||||
*/
|
||||
this.projection_ = options.projection ?
|
||||
getProjection(options.projection) : null;
|
||||
this.projection_ = options.projection
|
||||
? getProjection(options.projection)
|
||||
: null;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -130,7 +123,6 @@ class DragAndDrop extends Interaction {
|
||||
* @type {HTMLElement}
|
||||
*/
|
||||
this.target = options.target ? options.target : null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -152,7 +144,7 @@ class DragAndDrop extends Interaction {
|
||||
for (let i = 0, ii = formatConstructors.length; i < ii; ++i) {
|
||||
const format = new formatConstructors[i]();
|
||||
features = this.tryReadFeatures_(format, result, {
|
||||
featureProjection: projection
|
||||
featureProjection: projection,
|
||||
});
|
||||
if (features && features.length > 0) {
|
||||
break;
|
||||
@@ -164,8 +156,12 @@ class DragAndDrop extends Interaction {
|
||||
}
|
||||
this.dispatchEvent(
|
||||
new DragAndDropEvent(
|
||||
DragAndDropEventType.ADD_FEATURES, file,
|
||||
features, projection));
|
||||
DragAndDropEventType.ADD_FEATURES,
|
||||
file,
|
||||
features,
|
||||
projection
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -179,7 +175,7 @@ class DragAndDrop extends Interaction {
|
||||
listen(dropArea, EventType.DROP, handleDrop, this),
|
||||
listen(dropArea, EventType.DRAGENTER, handleStop, this),
|
||||
listen(dropArea, EventType.DRAGOVER, handleStop, this),
|
||||
listen(dropArea, EventType.DROP, handleStop, this)
|
||||
listen(dropArea, EventType.DROP, handleStop, this),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -240,7 +236,6 @@ class DragAndDrop extends Interaction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {DragEvent} event Event.
|
||||
* @this {DragAndDrop}
|
||||
@@ -250,12 +245,14 @@ function handleDrop(event) {
|
||||
for (let i = 0, ii = files.length; i < ii; ++i) {
|
||||
const file = files.item(i);
|
||||
const reader = new FileReader();
|
||||
reader.addEventListener(EventType.LOAD, this.handleResult_.bind(this, file));
|
||||
reader.addEventListener(
|
||||
EventType.LOAD,
|
||||
this.handleResult_.bind(this, file)
|
||||
);
|
||||
reader.readAsText(file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {DragEvent} event Event.
|
||||
*/
|
||||
@@ -265,5 +262,4 @@ function handleStop(event) {
|
||||
event.dataTransfer.dropEffect = 'copy';
|
||||
}
|
||||
|
||||
|
||||
export default DragAndDrop;
|
||||
|
||||
@@ -3,11 +3,10 @@
|
||||
*/
|
||||
// FIXME draw drag box
|
||||
import Event from '../events/Event.js';
|
||||
import {mouseActionButton} from '../events/condition.js';
|
||||
import {VOID} from '../functions.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import RenderBox from '../render/Box.js';
|
||||
|
||||
import {VOID} from '../functions.js';
|
||||
import {mouseActionButton} from '../events/condition.js';
|
||||
|
||||
/**
|
||||
* A function that takes a {@link module:ol/MapBrowserEvent} and two
|
||||
@@ -16,7 +15,6 @@ import RenderBox from '../render/Box.js';
|
||||
* @typedef {function(this: ?, import("../MapBrowserEvent.js").default, import("../pixel.js").Pixel, import("../pixel.js").Pixel):boolean} EndCondition
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {string} [className='ol-dragbox'] CSS class name for styling the box.
|
||||
@@ -32,7 +30,6 @@ import RenderBox from '../render/Box.js';
|
||||
* before `boxend` is fired.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -56,17 +53,15 @@ const DragBoxEventType = {
|
||||
* @event DragBoxEvent#boxend
|
||||
* @api
|
||||
*/
|
||||
BOXEND: 'boxend'
|
||||
BOXEND: 'boxend',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/DragBox~DragBox} instances are instances of
|
||||
* this type.
|
||||
*/
|
||||
class DragBoxEvent extends Event {
|
||||
|
||||
/**
|
||||
* @param {string} type The event type.
|
||||
* @param {import("../coordinate.js").Coordinate} coordinate The event coordinate.
|
||||
@@ -89,12 +84,9 @@ class DragBoxEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to draw a vector box by clicking and dragging on the map,
|
||||
@@ -112,7 +104,6 @@ class DragBox extends PointerInteraction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
super();
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
@@ -152,8 +143,9 @@ class DragBox extends PointerInteraction {
|
||||
* @private
|
||||
* @type {EndCondition}
|
||||
*/
|
||||
this.boxEndCondition_ = options.boxEndCondition ?
|
||||
options.boxEndCondition : this.defaultBoxEndCondition;
|
||||
this.boxEndCondition_ = options.boxEndCondition
|
||||
? options.boxEndCondition
|
||||
: this.defaultBoxEndCondition;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -187,8 +179,13 @@ class DragBox extends PointerInteraction {
|
||||
handleDragEvent(mapBrowserEvent) {
|
||||
this.box_.setPixels(this.startPixel_, mapBrowserEvent.pixel);
|
||||
|
||||
this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXDRAG,
|
||||
mapBrowserEvent.coordinate, mapBrowserEvent));
|
||||
this.dispatchEvent(
|
||||
new DragBoxEvent(
|
||||
DragBoxEventType.BOXDRAG,
|
||||
mapBrowserEvent.coordinate,
|
||||
mapBrowserEvent
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -199,10 +196,21 @@ class DragBox extends PointerInteraction {
|
||||
handleUpEvent(mapBrowserEvent) {
|
||||
this.box_.setMap(null);
|
||||
|
||||
if (this.boxEndCondition_(mapBrowserEvent, this.startPixel_, mapBrowserEvent.pixel)) {
|
||||
if (
|
||||
this.boxEndCondition_(
|
||||
mapBrowserEvent,
|
||||
this.startPixel_,
|
||||
mapBrowserEvent.pixel
|
||||
)
|
||||
) {
|
||||
this.onBoxEnd_(mapBrowserEvent);
|
||||
this.dispatchEvent(new DragBoxEvent(DragBoxEventType.BOXEND,
|
||||
mapBrowserEvent.coordinate, mapBrowserEvent));
|
||||
this.dispatchEvent(
|
||||
new DragBoxEvent(
|
||||
DragBoxEventType.BOXEND,
|
||||
mapBrowserEvent.coordinate,
|
||||
mapBrowserEvent
|
||||
)
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -217,8 +225,13 @@ class DragBox extends PointerInteraction {
|
||||
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));
|
||||
this.dispatchEvent(
|
||||
new DragBoxEvent(
|
||||
DragBoxEventType.BOXSTART,
|
||||
mapBrowserEvent.coordinate,
|
||||
mapBrowserEvent
|
||||
)
|
||||
);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
@@ -226,5 +239,4 @@ class DragBox extends PointerInteraction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default DragBox;
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
/**
|
||||
* @module ol/interaction/DragPan
|
||||
*/
|
||||
import {scale as scaleCoordinate, rotate as rotateCoordinate} from '../coordinate.js';
|
||||
import {easeOut} from '../easing.js';
|
||||
import {noModifierKeys, primaryAction, focus} from '../events/condition.js';
|
||||
import PointerInteraction, {
|
||||
centroid as centroidFromPointers,
|
||||
} from './Pointer.js';
|
||||
import {FALSE} from '../functions.js';
|
||||
import PointerInteraction, {centroid as centroidFromPointers} from './Pointer.js';
|
||||
|
||||
import {easeOut} from '../easing.js';
|
||||
import {focus, noModifierKeys, primaryAction} from '../events/condition.js';
|
||||
import {
|
||||
rotate as rotateCoordinate,
|
||||
scale as scaleCoordinate,
|
||||
} from '../coordinate.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -18,7 +22,6 @@ import PointerInteraction, {centroid as centroidFromPointers} from './Pointer.js
|
||||
* @property {import("../Kinetic.js").default} [kinetic] Kinetic inertia to apply to the pan.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to pan the map by dragging the map.
|
||||
@@ -29,9 +32,8 @@ class DragPan extends PointerInteraction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
super({
|
||||
stopDown: FALSE
|
||||
stopDown: FALSE,
|
||||
});
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
@@ -68,7 +70,6 @@ class DragPan extends PointerInteraction {
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.noKinetic_ = false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -84,7 +85,6 @@ class DragPan extends PointerInteraction {
|
||||
return pass && this.condition_(mapBrowserEvent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle pointer drag events.
|
||||
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
|
||||
@@ -103,7 +103,7 @@ class DragPan extends PointerInteraction {
|
||||
if (this.lastCentroid) {
|
||||
const delta = [
|
||||
this.lastCentroid[0] - centroid[0],
|
||||
centroid[1] - this.lastCentroid[1]
|
||||
centroid[1] - this.lastCentroid[1],
|
||||
];
|
||||
const map = mapBrowserEvent.map;
|
||||
const view = map.getView();
|
||||
@@ -137,12 +137,12 @@ class DragPan extends PointerInteraction {
|
||||
const centerpx = map.getPixelFromCoordinateInternal(center);
|
||||
const dest = map.getCoordinateFromPixelInternal([
|
||||
centerpx[0] - distance * Math.cos(angle),
|
||||
centerpx[1] - distance * Math.sin(angle)
|
||||
centerpx[1] - distance * Math.sin(angle),
|
||||
]);
|
||||
view.animateInternal({
|
||||
center: view.getConstrainedCenter(dest),
|
||||
duration: 500,
|
||||
easing: easeOut
|
||||
easing: easeOut,
|
||||
});
|
||||
}
|
||||
if (this.panning_) {
|
||||
@@ -167,7 +167,10 @@ class DragPan extends PointerInteraction {
|
||||
* @return {boolean} If the event was consumed.
|
||||
*/
|
||||
handleDownEvent(mapBrowserEvent) {
|
||||
if (this.targetPointers.length > 0 && this.conditionInternal_(mapBrowserEvent)) {
|
||||
if (
|
||||
this.targetPointers.length > 0 &&
|
||||
this.conditionInternal_(mapBrowserEvent)
|
||||
) {
|
||||
const map = mapBrowserEvent.map;
|
||||
const view = map.getView();
|
||||
this.lastCentroid = null;
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
/**
|
||||
* @module ol/interaction/DragRotate
|
||||
*/
|
||||
import {disable} from '../rotationconstraint.js';
|
||||
import {altShiftKeysOnly, mouseOnly, mouseActionButton} from '../events/condition.js';
|
||||
import {FALSE} from '../functions.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
|
||||
import {FALSE} from '../functions.js';
|
||||
import {
|
||||
altShiftKeysOnly,
|
||||
mouseActionButton,
|
||||
mouseOnly,
|
||||
} from '../events/condition.js';
|
||||
import {disable} from '../rotationconstraint.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -16,7 +19,6 @@ import PointerInteraction from './Pointer.js';
|
||||
* @property {number} [duration=250] Animation duration in milliseconds.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to rotate the map by clicking and dragging on the map,
|
||||
@@ -27,16 +29,14 @@ import PointerInteraction from './Pointer.js';
|
||||
* @api
|
||||
*/
|
||||
class DragRotate extends PointerInteraction {
|
||||
|
||||
/**
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super({
|
||||
stopDown: FALSE
|
||||
stopDown: FALSE,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -56,7 +56,6 @@ class DragRotate extends PointerInteraction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -75,8 +74,7 @@ class DragRotate extends PointerInteraction {
|
||||
}
|
||||
const size = map.getSize();
|
||||
const offset = mapBrowserEvent.pixel;
|
||||
const theta =
|
||||
Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);
|
||||
const theta = Math.atan2(size[1] / 2 - offset[1], offset[0] - size[0] / 2);
|
||||
if (this.lastAngle_ !== undefined) {
|
||||
const delta = theta - this.lastAngle_;
|
||||
view.adjustRotationInternal(-delta);
|
||||
@@ -84,7 +82,6 @@ class DragRotate extends PointerInteraction {
|
||||
this.lastAngle_ = theta;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle pointer up events.
|
||||
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
|
||||
@@ -101,7 +98,6 @@ class DragRotate extends PointerInteraction {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle pointer down events.
|
||||
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
|
||||
@@ -112,7 +108,10 @@ class DragRotate extends PointerInteraction {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mouseActionButton(mapBrowserEvent) && this.condition_(mapBrowserEvent)) {
|
||||
if (
|
||||
mouseActionButton(mapBrowserEvent) &&
|
||||
this.condition_(mapBrowserEvent)
|
||||
) {
|
||||
const map = mapBrowserEvent.map;
|
||||
map.getView().beginInteraction();
|
||||
this.lastAngle_ = undefined;
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/**
|
||||
* @module ol/interaction/DragRotateAndZoom
|
||||
*/
|
||||
import {shiftKeyOnly, mouseOnly} from '../events/condition.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
|
||||
import {mouseOnly, shiftKeyOnly} from '../events/condition.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -14,7 +13,6 @@ import PointerInteraction from './Pointer.js';
|
||||
* @property {number} [duration=400] Animation duration in milliseconds.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to zoom and rotate the map by clicking and dragging
|
||||
@@ -27,12 +25,10 @@ import PointerInteraction from './Pointer.js';
|
||||
* @api
|
||||
*/
|
||||
class DragRotateAndZoom extends PointerInteraction {
|
||||
|
||||
/**
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super(/** @type {import("./Pointer.js").Options} */ (options));
|
||||
@@ -66,7 +62,6 @@ class DragRotateAndZoom extends PointerInteraction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 400;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
/**
|
||||
* @module ol/interaction/DragZoom
|
||||
*/
|
||||
import DragBox from './DragBox.js';
|
||||
import {
|
||||
createOrUpdateFromCoordinates,
|
||||
getBottomLeft,
|
||||
getCenter,
|
||||
getTopRight,
|
||||
scaleFromCenter,
|
||||
} from '../extent.js';
|
||||
import {easeOut} from '../easing.js';
|
||||
import {shiftKeyOnly} from '../events/condition.js';
|
||||
import {createOrUpdateFromCoordinates, getBottomLeft, getCenter, getTopRight, scaleFromCenter} from '../extent.js';
|
||||
import DragBox from './DragBox.js';
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -21,7 +26,6 @@ import DragBox from './DragBox.js';
|
||||
* `boxEndCondition` function.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to zoom the map by clicking and dragging on the map,
|
||||
@@ -45,7 +49,7 @@ class DragZoom extends DragBox {
|
||||
condition: condition,
|
||||
className: options.className || 'ol-dragzoom',
|
||||
minArea: options.minArea,
|
||||
onBoxEnd: onBoxEnd
|
||||
onBoxEnd: onBoxEnd,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -62,7 +66,6 @@ class DragZoom extends DragBox {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @this {DragZoom}
|
||||
*/
|
||||
@@ -76,23 +79,25 @@ function onBoxEnd() {
|
||||
const mapExtent = view.calculateExtentInternal(size);
|
||||
const boxPixelExtent = createOrUpdateFromCoordinates([
|
||||
map.getPixelFromCoordinateInternal(getBottomLeft(extent)),
|
||||
map.getPixelFromCoordinateInternal(getTopRight(extent))]);
|
||||
map.getPixelFromCoordinateInternal(getTopRight(extent)),
|
||||
]);
|
||||
const factor = view.getResolutionForExtentInternal(boxPixelExtent, size);
|
||||
|
||||
scaleFromCenter(mapExtent, 1 / factor);
|
||||
extent = mapExtent;
|
||||
}
|
||||
|
||||
const resolution = view.getConstrainedResolution(view.getResolutionForExtentInternal(extent, size));
|
||||
const resolution = view.getConstrainedResolution(
|
||||
view.getResolutionForExtentInternal(extent, size)
|
||||
);
|
||||
const center = view.getConstrainedCenter(getCenter(extent), resolution);
|
||||
|
||||
view.animateInternal({
|
||||
resolution: resolution,
|
||||
center: center,
|
||||
duration: this.duration_,
|
||||
easing: easeOut
|
||||
easing: easeOut,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export default DragZoom;
|
||||
|
||||
+185
-122
@@ -1,31 +1,36 @@
|
||||
/**
|
||||
* @module ol/interaction/Draw
|
||||
*/
|
||||
import Circle from '../geom/Circle.js';
|
||||
import Event from '../events/Event.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import Feature from '../Feature.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import InteractionProperty from './Property.js';
|
||||
import LineString from '../geom/LineString.js';
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import MapBrowserPointerEvent from '../MapBrowserPointerEvent.js';
|
||||
import {getChangeEventType} from '../Object.js';
|
||||
import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
|
||||
import Event from '../events/Event.js';
|
||||
import {noModifierKeys, always, shiftKeyOnly} from '../events/condition.js';
|
||||
import {boundingExtent, getBottomLeft, getBottomRight, getTopLeft, getTopRight} from '../extent.js';
|
||||
import {TRUE, FALSE} from '../functions.js';
|
||||
import Circle from '../geom/Circle.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import LineString from '../geom/LineString.js';
|
||||
import MultiLineString from '../geom/MultiLineString.js';
|
||||
import MultiPoint from '../geom/MultiPoint.js';
|
||||
import MultiPolygon from '../geom/MultiPolygon.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import InteractionProperty from './Property.js';
|
||||
import Polygon, {fromCircle, makeRegular} from '../geom/Polygon.js';
|
||||
import VectorLayer from '../layer/Vector.js';
|
||||
import VectorSource from '../source/Vector.js';
|
||||
import {FALSE, TRUE} from '../functions.js';
|
||||
import {always, noModifierKeys, shiftKeyOnly} from '../events/condition.js';
|
||||
import {
|
||||
boundingExtent,
|
||||
getBottomLeft,
|
||||
getBottomRight,
|
||||
getTopLeft,
|
||||
getTopRight,
|
||||
} from '../extent.js';
|
||||
import {createEditingStyle} from '../style/Style.js';
|
||||
import {fromUserCoordinate, getUserProjection} from '../proj.js';
|
||||
|
||||
import {getChangeEventType} from '../Object.js';
|
||||
import {squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -79,31 +84,26 @@ import {fromUserCoordinate, getUserProjection} from '../proj.js';
|
||||
* overlay.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Coordinate type when drawing points.
|
||||
* @typedef {import("../coordinate.js").Coordinate} PointCoordType
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Coordinate type when drawing lines.
|
||||
* @typedef {Array<import("../coordinate.js").Coordinate>} LineCoordType
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Coordinate type when drawing polygons.
|
||||
* @typedef {Array<Array<import("../coordinate.js").Coordinate>>} PolyCoordType
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Types used for drawing coordinates.
|
||||
* @typedef {PointCoordType|LineCoordType|PolyCoordType} SketchCoordType
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Function that takes an array of coordinates and an optional existing geometry
|
||||
* and a projection as arguments, and returns a geometry. The optional existing
|
||||
@@ -114,7 +114,6 @@ import {fromUserCoordinate, getUserProjection} from '../proj.js';
|
||||
* import("../geom/SimpleGeometry.js").default} GeometryFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Draw mode. This collapses multi-part geometry types with their single-part
|
||||
* cousins.
|
||||
@@ -124,10 +123,9 @@ const Mode = {
|
||||
POINT: 'Point',
|
||||
LINE_STRING: 'LineString',
|
||||
POLYGON: 'Polygon',
|
||||
CIRCLE: 'Circle'
|
||||
CIRCLE: 'Circle',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -149,10 +147,9 @@ const DrawEventType = {
|
||||
* @event DrawEvent#drawabort
|
||||
* @api
|
||||
*/
|
||||
DRAWABORT: 'drawabort'
|
||||
DRAWABORT: 'drawabort',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/Draw~Draw} instances are
|
||||
@@ -164,7 +161,6 @@ class DrawEvent extends Event {
|
||||
* @param {Feature} feature The feature drawn.
|
||||
*/
|
||||
constructor(type, feature) {
|
||||
|
||||
super(type);
|
||||
|
||||
/**
|
||||
@@ -173,12 +169,9 @@ class DrawEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.feature = feature;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Interaction for drawing feature geometries.
|
||||
@@ -191,7 +184,6 @@ class Draw extends PointerInteraction {
|
||||
* @param {Options} options Options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
|
||||
if (!pointerOptions.stopDown) {
|
||||
pointerOptions.stopDown = FALSE;
|
||||
@@ -279,9 +271,11 @@ class Draw extends PointerInteraction {
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.minPoints_ = options.minPoints ?
|
||||
options.minPoints :
|
||||
(this.mode_ === Mode.POLYGON ? 3 : 2);
|
||||
this.minPoints_ = options.minPoints
|
||||
? options.minPoints
|
||||
: this.mode_ === Mode.POLYGON
|
||||
? 3
|
||||
: 2;
|
||||
|
||||
/**
|
||||
* The number of points that can be drawn before a polygon ring or line string
|
||||
@@ -296,7 +290,9 @@ class Draw extends PointerInteraction {
|
||||
* @private
|
||||
* @type {import("../events/condition.js").Condition}
|
||||
*/
|
||||
this.finishCondition_ = options.finishCondition ? options.finishCondition : TRUE;
|
||||
this.finishCondition_ = options.finishCondition
|
||||
? options.finishCondition
|
||||
: TRUE;
|
||||
|
||||
let geometryFunction = options.geometryFunction;
|
||||
if (!geometryFunction) {
|
||||
@@ -307,12 +303,15 @@ class Draw extends PointerInteraction {
|
||||
* @param {import("../proj/Projection.js").default} projection The view projection.
|
||||
* @return {import("../geom/SimpleGeometry.js").default} A geometry.
|
||||
*/
|
||||
geometryFunction = function(coordinates, opt_geometry, projection) {
|
||||
const circle = opt_geometry ? /** @type {Circle} */ (opt_geometry) :
|
||||
new Circle([NaN, NaN]);
|
||||
geometryFunction = function (coordinates, opt_geometry, projection) {
|
||||
const circle = opt_geometry
|
||||
? /** @type {Circle} */ (opt_geometry)
|
||||
: new Circle([NaN, NaN]);
|
||||
const center = fromUserCoordinate(coordinates[0], projection);
|
||||
const squaredLength = squaredCoordinateDistance(
|
||||
center, fromUserCoordinate(coordinates[1], projection));
|
||||
center,
|
||||
fromUserCoordinate(coordinates[1], projection)
|
||||
);
|
||||
circle.setCenterAndRadius(center, Math.sqrt(squaredLength));
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
@@ -336,13 +335,15 @@ class Draw extends PointerInteraction {
|
||||
* @param {import("../proj/Projection.js").default} projection The view projection.
|
||||
* @return {import("../geom/SimpleGeometry.js").default} A geometry.
|
||||
*/
|
||||
geometryFunction = function(coordinates, opt_geometry, projection) {
|
||||
geometryFunction = function (coordinates, opt_geometry, projection) {
|
||||
let geometry = opt_geometry;
|
||||
if (geometry) {
|
||||
if (mode === Mode.POLYGON) {
|
||||
if (coordinates[0].length) {
|
||||
// Add a closing coordinate to match the first
|
||||
geometry.setCoordinates([coordinates[0].concat([coordinates[0][0]])]);
|
||||
geometry.setCoordinates([
|
||||
coordinates[0].concat([coordinates[0][0]]),
|
||||
]);
|
||||
} else {
|
||||
geometry.setCoordinates([]);
|
||||
}
|
||||
@@ -367,7 +368,8 @@ class Draw extends PointerInteraction {
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.dragVertexDelay_ = options.dragVertexDelay !== undefined ? options.dragVertexDelay : 500;
|
||||
this.dragVertexDelay_ =
|
||||
options.dragVertexDelay !== undefined ? options.dragVertexDelay : 500;
|
||||
|
||||
/**
|
||||
* Finish coordinate for the feature (first point for polygons, last point for
|
||||
@@ -419,8 +421,9 @@ class Draw extends PointerInteraction {
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.squaredClickTolerance_ = options.clickTolerance ?
|
||||
options.clickTolerance * options.clickTolerance : 36;
|
||||
this.squaredClickTolerance_ = options.clickTolerance
|
||||
? options.clickTolerance * options.clickTolerance
|
||||
: 36;
|
||||
|
||||
/**
|
||||
* Draw overlay where our sketch features are drawn.
|
||||
@@ -430,10 +433,10 @@ class Draw extends PointerInteraction {
|
||||
this.overlay_ = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
useSpatialIndex: false,
|
||||
wrapX: options.wrapX ? options.wrapX : false
|
||||
wrapX: options.wrapX ? options.wrapX : false,
|
||||
}),
|
||||
style: options.style ? options.style : getDefaultStyleFunction(),
|
||||
updateWhileInteracting: true
|
||||
updateWhileInteracting: true,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -457,11 +460,15 @@ class Draw extends PointerInteraction {
|
||||
if (options.freehand) {
|
||||
this.freehandCondition_ = always;
|
||||
} else {
|
||||
this.freehandCondition_ = options.freehandCondition ? options.freehandCondition : shiftKeyOnly;
|
||||
this.freehandCondition_ = options.freehandCondition
|
||||
? options.freehandCondition
|
||||
: shiftKeyOnly;
|
||||
}
|
||||
|
||||
this.addEventListener(getChangeEventType(InteractionProperty.ACTIVE), this.updateState_);
|
||||
|
||||
this.addEventListener(
|
||||
getChangeEventType(InteractionProperty.ACTIVE),
|
||||
this.updateState_
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -495,10 +502,15 @@ class Draw extends PointerInteraction {
|
||||
// Avoid context menu for long taps when drawing on mobile
|
||||
event.preventDefault();
|
||||
}
|
||||
this.freehand_ = this.mode_ !== Mode.POINT && this.freehandCondition_(event);
|
||||
this.freehand_ =
|
||||
this.mode_ !== Mode.POINT && this.freehandCondition_(event);
|
||||
let move = event.type === MapBrowserEventType.POINTERMOVE;
|
||||
let pass = true;
|
||||
if (!this.freehand_ && this.lastDragTime_ && event.type === MapBrowserEventType.POINTERDRAG) {
|
||||
if (
|
||||
!this.freehand_ &&
|
||||
this.lastDragTime_ &&
|
||||
event.type === MapBrowserEventType.POINTERDRAG
|
||||
) {
|
||||
const now = Date.now();
|
||||
if (now - this.lastDragTime_ >= this.dragVertexDelay_) {
|
||||
this.downPx_ = event.pixel;
|
||||
@@ -512,13 +524,17 @@ class Draw extends PointerInteraction {
|
||||
this.downTimeout_ = undefined;
|
||||
}
|
||||
}
|
||||
if (this.freehand_ &&
|
||||
event.type === MapBrowserEventType.POINTERDRAG &&
|
||||
this.sketchFeature_ !== null) {
|
||||
if (
|
||||
this.freehand_ &&
|
||||
event.type === MapBrowserEventType.POINTERDRAG &&
|
||||
this.sketchFeature_ !== null
|
||||
) {
|
||||
this.addToDrawing_(event.coordinate);
|
||||
pass = false;
|
||||
} else if (this.freehand_ &&
|
||||
event.type === MapBrowserEventType.POINTERDOWN) {
|
||||
} else if (
|
||||
this.freehand_ &&
|
||||
event.type === MapBrowserEventType.POINTERDOWN
|
||||
) {
|
||||
pass = false;
|
||||
} else if (move) {
|
||||
pass = event.type === MapBrowserEventType.POINTERMOVE;
|
||||
@@ -528,8 +544,11 @@ class Draw extends PointerInteraction {
|
||||
// Avoid page scrolling when freehand drawing on mobile
|
||||
event.preventDefault();
|
||||
}
|
||||
} else if (event.pointerEvent.pointerType == 'mouse' ||
|
||||
(event.type === MapBrowserEventType.POINTERDRAG && this.downTimeout_ === undefined)) {
|
||||
} else if (
|
||||
event.pointerEvent.pointerType == 'mouse' ||
|
||||
(event.type === MapBrowserEventType.POINTERDRAG &&
|
||||
this.downTimeout_ === undefined)
|
||||
) {
|
||||
this.handlePointerMove_(event);
|
||||
}
|
||||
} else if (event.type === MapBrowserEventType.DBLCLICK) {
|
||||
@@ -555,10 +574,20 @@ class Draw extends PointerInteraction {
|
||||
return true;
|
||||
} else if (this.condition_(event)) {
|
||||
this.lastDragTime_ = Date.now();
|
||||
this.downTimeout_ = setTimeout(function() {
|
||||
this.handlePointerMove_(new MapBrowserPointerEvent(
|
||||
MapBrowserEventType.POINTERMOVE, event.map, event.pointerEvent, false, event.frameState));
|
||||
}.bind(this), this.dragVertexDelay_);
|
||||
this.downTimeout_ = setTimeout(
|
||||
function () {
|
||||
this.handlePointerMove_(
|
||||
new MapBrowserPointerEvent(
|
||||
MapBrowserEventType.POINTERMOVE,
|
||||
event.map,
|
||||
event.pointerEvent,
|
||||
false,
|
||||
event.frameState
|
||||
)
|
||||
);
|
||||
}.bind(this),
|
||||
this.dragVertexDelay_
|
||||
);
|
||||
this.downPx_ = event.pixel;
|
||||
return true;
|
||||
} else {
|
||||
@@ -567,7 +596,6 @@ class Draw extends PointerInteraction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle pointer up events.
|
||||
* @param {import("../MapBrowserPointerEvent.js").default} event Event.
|
||||
@@ -616,17 +644,19 @@ class Draw extends PointerInteraction {
|
||||
* @private
|
||||
*/
|
||||
handlePointerMove_(event) {
|
||||
if (this.downPx_ &&
|
||||
((!this.freehand_ && this.shouldHandle_) ||
|
||||
(this.freehand_ && !this.shouldHandle_))) {
|
||||
if (
|
||||
this.downPx_ &&
|
||||
((!this.freehand_ && this.shouldHandle_) ||
|
||||
(this.freehand_ && !this.shouldHandle_))
|
||||
) {
|
||||
const downPx = this.downPx_;
|
||||
const clickPx = event.pixel;
|
||||
const dx = downPx[0] - clickPx[0];
|
||||
const dy = downPx[1] - clickPx[1];
|
||||
const squaredDistance = dx * dx + dy * dy;
|
||||
this.shouldHandle_ = this.freehand_ ?
|
||||
squaredDistance > this.squaredClickTolerance_ :
|
||||
squaredDistance <= this.squaredClickTolerance_;
|
||||
this.shouldHandle_ = this.freehand_
|
||||
? squaredDistance > this.squaredClickTolerance_
|
||||
: squaredDistance <= this.squaredClickTolerance_;
|
||||
if (!this.shouldHandle_) {
|
||||
return;
|
||||
}
|
||||
@@ -655,7 +685,10 @@ class Draw extends PointerInteraction {
|
||||
} else if (this.mode_ === Mode.POLYGON) {
|
||||
const sketchCoords = /** @type {PolyCoordType} */ (this.sketchCoords_);
|
||||
potentiallyDone = sketchCoords[0].length > this.minPoints_;
|
||||
potentiallyFinishCoordinates = [sketchCoords[0][0], sketchCoords[0][sketchCoords[0].length - 2]];
|
||||
potentiallyFinishCoordinates = [
|
||||
sketchCoords[0][0],
|
||||
sketchCoords[0][sketchCoords[0].length - 2],
|
||||
];
|
||||
}
|
||||
if (potentiallyDone) {
|
||||
const map = event.map;
|
||||
@@ -710,17 +743,22 @@ class Draw extends PointerInteraction {
|
||||
this.sketchCoords_ = [start.slice(), start.slice()];
|
||||
}
|
||||
if (this.sketchLineCoords_) {
|
||||
this.sketchLine_ = new Feature(
|
||||
new LineString(this.sketchLineCoords_));
|
||||
this.sketchLine_ = new Feature(new LineString(this.sketchLineCoords_));
|
||||
}
|
||||
const geometry = this.geometryFunction_(this.sketchCoords_, undefined, projection);
|
||||
const geometry = this.geometryFunction_(
|
||||
this.sketchCoords_,
|
||||
undefined,
|
||||
projection
|
||||
);
|
||||
this.sketchFeature_ = new Feature();
|
||||
if (this.geometryName_) {
|
||||
this.sketchFeature_.setGeometryName(this.geometryName_);
|
||||
}
|
||||
this.sketchFeature_.setGeometry(geometry);
|
||||
this.updateSketchFeatures_();
|
||||
this.dispatchEvent(new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_));
|
||||
this.dispatchEvent(
|
||||
new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -748,26 +786,37 @@ class Draw extends PointerInteraction {
|
||||
}
|
||||
last[0] = coordinate[0];
|
||||
last[1] = coordinate[1];
|
||||
this.geometryFunction_(/** @type {!LineCoordType} */ (this.sketchCoords_), geometry, projection);
|
||||
this.geometryFunction_(
|
||||
/** @type {!LineCoordType} */ (this.sketchCoords_),
|
||||
geometry,
|
||||
projection
|
||||
);
|
||||
if (this.sketchPoint_) {
|
||||
const sketchPointGeom = this.sketchPoint_.getGeometry();
|
||||
sketchPointGeom.setCoordinates(coordinate);
|
||||
}
|
||||
/** @type {LineString} */
|
||||
let sketchLineGeom;
|
||||
if (geometry.getType() == GeometryType.POLYGON &&
|
||||
this.mode_ !== Mode.POLYGON) {
|
||||
if (
|
||||
geometry.getType() == GeometryType.POLYGON &&
|
||||
this.mode_ !== Mode.POLYGON
|
||||
) {
|
||||
if (!this.sketchLine_) {
|
||||
this.sketchLine_ = new Feature();
|
||||
}
|
||||
const ring = geometry.getLinearRing(0);
|
||||
sketchLineGeom = this.sketchLine_.getGeometry();
|
||||
if (!sketchLineGeom) {
|
||||
sketchLineGeom = new LineString(ring.getFlatCoordinates(), ring.getLayout());
|
||||
sketchLineGeom = new LineString(
|
||||
ring.getFlatCoordinates(),
|
||||
ring.getLayout()
|
||||
);
|
||||
this.sketchLine_.setGeometry(sketchLineGeom);
|
||||
} else {
|
||||
sketchLineGeom.setFlatCoordinates(
|
||||
ring.getLayout(), ring.getFlatCoordinates());
|
||||
ring.getLayout(),
|
||||
ring.getFlatCoordinates()
|
||||
);
|
||||
sketchLineGeom.changed();
|
||||
}
|
||||
} else if (this.sketchLineCoords_) {
|
||||
@@ -882,11 +931,17 @@ class Draw extends PointerInteraction {
|
||||
|
||||
// cast multi-part geometries
|
||||
if (this.type_ === GeometryType.MULTI_POINT) {
|
||||
sketchFeature.setGeometry(new MultiPoint([/** @type {PointCoordType} */(coordinates)]));
|
||||
sketchFeature.setGeometry(
|
||||
new MultiPoint([/** @type {PointCoordType} */ (coordinates)])
|
||||
);
|
||||
} else if (this.type_ === GeometryType.MULTI_LINE_STRING) {
|
||||
sketchFeature.setGeometry(new MultiLineString([/** @type {LineCoordType} */(coordinates)]));
|
||||
sketchFeature.setGeometry(
|
||||
new MultiLineString([/** @type {LineCoordType} */ (coordinates)])
|
||||
);
|
||||
} else if (this.type_ === GeometryType.MULTI_POLYGON) {
|
||||
sketchFeature.setGeometry(new MultiPolygon([/** @type {PolyCoordType} */(coordinates)]));
|
||||
sketchFeature.setGeometry(
|
||||
new MultiPolygon([/** @type {PolyCoordType} */ (coordinates)])
|
||||
);
|
||||
}
|
||||
|
||||
// First dispatch event to allow full set up of feature
|
||||
@@ -927,7 +982,6 @@ class Draw extends PointerInteraction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Append coordinates to the end of the geometry that is currently being drawn.
|
||||
* This can be used when drawing LineStrings or Polygons. Coordinates will
|
||||
@@ -943,7 +997,10 @@ class Draw extends PointerInteraction {
|
||||
if (mode === Mode.LINE_STRING) {
|
||||
sketchCoords = /** @type {LineCoordType} */ this.sketchCoords_;
|
||||
} else if (mode === Mode.POLYGON) {
|
||||
sketchCoords = this.sketchCoords_ && this.sketchCoords_.length ? /** @type {PolyCoordType} */ (this.sketchCoords_)[0] : [];
|
||||
sketchCoords =
|
||||
this.sketchCoords_ && this.sketchCoords_.length
|
||||
? /** @type {PolyCoordType} */ (this.sketchCoords_)[0]
|
||||
: [];
|
||||
}
|
||||
|
||||
// Remove last coordinate from sketch drawing (this coordinate follows cursor position)
|
||||
@@ -979,7 +1036,9 @@ class Draw extends PointerInteraction {
|
||||
this.finishCoordinate_ = last.slice();
|
||||
this.sketchCoords_.push(last.slice());
|
||||
this.updateSketchFeatures_();
|
||||
this.dispatchEvent(new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_));
|
||||
this.dispatchEvent(
|
||||
new DrawEvent(DrawEventType.DRAWSTART, this.sketchFeature_)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1015,18 +1074,16 @@ class Draw extends PointerInteraction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {import("../style/Style.js").StyleFunction} Styles.
|
||||
*/
|
||||
function getDefaultStyleFunction() {
|
||||
const styles = createEditingStyle();
|
||||
return function(feature, resolution) {
|
||||
return function (feature, resolution) {
|
||||
return styles[feature.getGeometry().getType()];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a `geometryFunction` for `type: 'Circle'` that will create a regular
|
||||
* polygon with a user specified number of sides and start angle instead of an
|
||||
@@ -1041,13 +1098,19 @@ function getDefaultStyleFunction() {
|
||||
* @api
|
||||
*/
|
||||
export function createRegularPolygon(opt_sides, opt_angle) {
|
||||
return function(coordinates, opt_geometry, projection) {
|
||||
const center = fromUserCoordinate(/** @type {LineCoordType} */ (coordinates)[0], projection);
|
||||
const end = fromUserCoordinate(/** @type {LineCoordType} */ (coordinates)[1], projection);
|
||||
const radius = Math.sqrt(
|
||||
squaredCoordinateDistance(center, end));
|
||||
const geometry = opt_geometry ? /** @type {Polygon} */ (opt_geometry) :
|
||||
fromCircle(new Circle(center), opt_sides);
|
||||
return function (coordinates, opt_geometry, projection) {
|
||||
const center = fromUserCoordinate(
|
||||
/** @type {LineCoordType} */ (coordinates)[0],
|
||||
projection
|
||||
);
|
||||
const end = fromUserCoordinate(
|
||||
/** @type {LineCoordType} */ (coordinates)[1],
|
||||
projection
|
||||
);
|
||||
const radius = Math.sqrt(squaredCoordinateDistance(center, end));
|
||||
const geometry = opt_geometry
|
||||
? /** @type {Polygon} */ (opt_geometry)
|
||||
: fromCircle(new Circle(center), opt_sides);
|
||||
let angle = opt_angle;
|
||||
if (!opt_angle) {
|
||||
const x = end[0] - center[0];
|
||||
@@ -1063,7 +1126,6 @@ export function createRegularPolygon(opt_sides, opt_angle) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a `geometryFunction` that will create a box-shaped polygon (aligned
|
||||
* with the coordinate system axes). Use this with the draw interaction and
|
||||
@@ -1072,34 +1134,35 @@ export function createRegularPolygon(opt_sides, opt_angle) {
|
||||
* @api
|
||||
*/
|
||||
export function createBox() {
|
||||
return (
|
||||
function(coordinates, opt_geometry, projection) {
|
||||
const extent = boundingExtent(/** @type {LineCoordType} */ (coordinates).map(function(coordinate) {
|
||||
return function (coordinates, opt_geometry, projection) {
|
||||
const extent = boundingExtent(
|
||||
/** @type {LineCoordType} */ (coordinates).map(function (coordinate) {
|
||||
return fromUserCoordinate(coordinate, projection);
|
||||
}));
|
||||
const boxCoordinates = [[
|
||||
})
|
||||
);
|
||||
const boxCoordinates = [
|
||||
[
|
||||
getBottomLeft(extent),
|
||||
getBottomRight(extent),
|
||||
getTopRight(extent),
|
||||
getTopLeft(extent),
|
||||
getBottomLeft(extent)
|
||||
]];
|
||||
let geometry = opt_geometry;
|
||||
if (geometry) {
|
||||
geometry.setCoordinates(boxCoordinates);
|
||||
} else {
|
||||
geometry = new Polygon(boxCoordinates);
|
||||
}
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
geometry.transform(projection, userProjection);
|
||||
}
|
||||
return geometry;
|
||||
getBottomLeft(extent),
|
||||
],
|
||||
];
|
||||
let geometry = opt_geometry;
|
||||
if (geometry) {
|
||||
geometry.setCoordinates(boxCoordinates);
|
||||
} else {
|
||||
geometry = new Polygon(boxCoordinates);
|
||||
}
|
||||
);
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
geometry.transform(projection, userProjection);
|
||||
}
|
||||
return geometry;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the drawing mode. The mode for mult-part geometries is the same as for
|
||||
* their single-part cousins.
|
||||
@@ -1108,22 +1171,22 @@ export function createBox() {
|
||||
*/
|
||||
function getMode(type) {
|
||||
let mode;
|
||||
if (type === GeometryType.POINT ||
|
||||
type === GeometryType.MULTI_POINT) {
|
||||
if (type === GeometryType.POINT || type === GeometryType.MULTI_POINT) {
|
||||
mode = Mode.POINT;
|
||||
} else if (type === GeometryType.LINE_STRING ||
|
||||
type === GeometryType.MULTI_LINE_STRING) {
|
||||
} else if (
|
||||
type === GeometryType.LINE_STRING ||
|
||||
type === GeometryType.MULTI_LINE_STRING
|
||||
) {
|
||||
mode = Mode.LINE_STRING;
|
||||
} else if (type === GeometryType.POLYGON ||
|
||||
type === GeometryType.MULTI_POLYGON) {
|
||||
} else if (
|
||||
type === GeometryType.POLYGON ||
|
||||
type === GeometryType.MULTI_POLYGON
|
||||
) {
|
||||
mode = Mode.POLYGON;
|
||||
} else if (type === GeometryType.CIRCLE) {
|
||||
mode = Mode.CIRCLE;
|
||||
}
|
||||
return (
|
||||
/** @type {!Mode} */ (mode)
|
||||
);
|
||||
return /** @type {!Mode} */ (mode);
|
||||
}
|
||||
|
||||
|
||||
export default Draw;
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
/**
|
||||
* @module ol/interaction/Extent
|
||||
*/
|
||||
import Feature from '../Feature.js';
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import {squaredDistanceToSegment, closestOnSegment, distance as coordinateDistance, squaredDistance as squaredCoordinateDistance} from '../coordinate.js';
|
||||
import Event from '../events/Event.js';
|
||||
import {boundingExtent, getArea} from '../extent.js';
|
||||
import Feature from '../Feature.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import {fromExtent as polygonFromExtent} from '../geom/Polygon.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import VectorLayer from '../layer/Vector.js';
|
||||
import VectorSource from '../source/Vector.js';
|
||||
import {boundingExtent, getArea} from '../extent.js';
|
||||
import {
|
||||
closestOnSegment,
|
||||
distance as coordinateDistance,
|
||||
squaredDistance as squaredCoordinateDistance,
|
||||
squaredDistanceToSegment,
|
||||
} from '../coordinate.js';
|
||||
import {createEditingStyle} from '../style/Style.js';
|
||||
import {fromExtent as polygonFromExtent} from '../geom/Polygon.js';
|
||||
import {toUserExtent} from '../proj.js';
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("../extent.js").Extent} [extent] Initial extent. Defaults to no
|
||||
@@ -32,7 +36,6 @@ import {toUserExtent} from '../proj.js';
|
||||
* in the X direction? Only affects visuals, not functionality.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
@@ -42,17 +45,15 @@ const ExtentEventType = {
|
||||
* @event ExtentEvent#extentchanged
|
||||
* @api
|
||||
*/
|
||||
EXTENTCHANGED: 'extentchanged'
|
||||
EXTENTCHANGED: 'extentchanged',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/Extent~Extent} instances are
|
||||
* instances of this type.
|
||||
*/
|
||||
class ExtentEvent extends Event {
|
||||
|
||||
/**
|
||||
* @param {import("../extent.js").Extent} extent the new extent
|
||||
*/
|
||||
@@ -66,10 +67,8 @@ class ExtentEvent extends Event {
|
||||
*/
|
||||
this.extent = extent;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to draw a vector box by clicking and dragging on the map.
|
||||
@@ -84,7 +83,6 @@ class Extent extends PointerInteraction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options || {};
|
||||
|
||||
super(/** @type {import("./Pointer.js").Options} */ (options));
|
||||
@@ -108,8 +106,8 @@ class Extent extends PointerInteraction {
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.pixelTolerance_ = options.pixelTolerance !== undefined ?
|
||||
options.pixelTolerance : 10;
|
||||
this.pixelTolerance_ =
|
||||
options.pixelTolerance !== undefined ? options.pixelTolerance : 10;
|
||||
|
||||
/**
|
||||
* Is the pointer snapped to an extent vertex
|
||||
@@ -144,11 +142,13 @@ class Extent extends PointerInteraction {
|
||||
this.extentOverlay_ = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
useSpatialIndex: false,
|
||||
wrapX: !!opt_options.wrapX
|
||||
wrapX: !!opt_options.wrapX,
|
||||
}),
|
||||
style: opt_options.boxStyle ? opt_options.boxStyle : getDefaultExtentStyleFunction(),
|
||||
style: opt_options.boxStyle
|
||||
? opt_options.boxStyle
|
||||
: getDefaultExtentStyleFunction(),
|
||||
updateWhileAnimating: true,
|
||||
updateWhileInteracting: true
|
||||
updateWhileInteracting: true,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -159,11 +159,13 @@ class Extent extends PointerInteraction {
|
||||
this.vertexOverlay_ = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
useSpatialIndex: false,
|
||||
wrapX: !!opt_options.wrapX
|
||||
wrapX: !!opt_options.wrapX,
|
||||
}),
|
||||
style: opt_options.pointerStyle ? opt_options.pointerStyle : getDefaultPointerStyleFunction(),
|
||||
style: opt_options.pointerStyle
|
||||
? opt_options.pointerStyle
|
||||
: getDefaultPointerStyleFunction(),
|
||||
updateWhileAnimating: true,
|
||||
updateWhileInteracting: true
|
||||
updateWhileInteracting: true,
|
||||
});
|
||||
|
||||
if (opt_options.extent) {
|
||||
@@ -179,9 +181,11 @@ class Extent extends PointerInteraction {
|
||||
*/
|
||||
snapToVertex_(pixel, map) {
|
||||
const pixelCoordinate = map.getCoordinateFromPixelInternal(pixel);
|
||||
const sortByDistance = function(a, b) {
|
||||
return squaredDistanceToSegment(pixelCoordinate, a) -
|
||||
squaredDistanceToSegment(pixelCoordinate, b);
|
||||
const sortByDistance = function (a, b) {
|
||||
return (
|
||||
squaredDistanceToSegment(pixelCoordinate, a) -
|
||||
squaredDistanceToSegment(pixelCoordinate, b)
|
||||
);
|
||||
};
|
||||
const extent = this.getExtentInternal();
|
||||
if (extent) {
|
||||
@@ -190,8 +194,7 @@ class Extent extends PointerInteraction {
|
||||
segments.sort(sortByDistance);
|
||||
const closestSegment = segments[0];
|
||||
|
||||
let vertex = (closestOnSegment(pixelCoordinate,
|
||||
closestSegment));
|
||||
let vertex = closestOnSegment(pixelCoordinate, closestSegment);
|
||||
const vertexPixel = map.getPixelFromCoordinateInternal(vertex);
|
||||
|
||||
//if the distance is within tolerance, snap to the segment
|
||||
@@ -204,8 +207,8 @@ class Extent extends PointerInteraction {
|
||||
const dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
this.snappedToVertex_ = dist <= this.pixelTolerance_;
|
||||
if (this.snappedToVertex_) {
|
||||
vertex = squaredDist1 > squaredDist2 ?
|
||||
closestSegment[1] : closestSegment[0];
|
||||
vertex =
|
||||
squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];
|
||||
}
|
||||
return vertex;
|
||||
}
|
||||
@@ -281,7 +284,10 @@ class Extent extends PointerInteraction {
|
||||
return true;
|
||||
}
|
||||
//display pointer (if not dragging)
|
||||
if (mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE && !this.handlingDownUpSequence) {
|
||||
if (
|
||||
mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE &&
|
||||
!this.handlingDownUpSequence
|
||||
) {
|
||||
this.handlePointerMove_(mapBrowserEvent);
|
||||
}
|
||||
//call pointer to determine up/down/drag
|
||||
@@ -303,7 +309,7 @@ class Extent extends PointerInteraction {
|
||||
let vertex = this.snapToVertex_(pixel, map);
|
||||
|
||||
//find the extent corner opposite the passed corner
|
||||
const getOpposingPoint = function(point) {
|
||||
const getOpposingPoint = function (point) {
|
||||
let x_ = null;
|
||||
let y_ = null;
|
||||
if (point[0] == extent[0]) {
|
||||
@@ -322,13 +328,15 @@ class Extent extends PointerInteraction {
|
||||
return null;
|
||||
};
|
||||
if (vertex && extent) {
|
||||
const x = (vertex[0] == extent[0] || vertex[0] == extent[2]) ? vertex[0] : null;
|
||||
const y = (vertex[1] == extent[1] || vertex[1] == extent[3]) ? vertex[1] : null;
|
||||
const x =
|
||||
vertex[0] == extent[0] || vertex[0] == extent[2] ? vertex[0] : null;
|
||||
const y =
|
||||
vertex[1] == extent[1] || vertex[1] == extent[3] ? vertex[1] : null;
|
||||
|
||||
//snap to point
|
||||
if (x !== null && y !== null) {
|
||||
this.pointerHandler_ = getPointHandler(getOpposingPoint(vertex));
|
||||
//snap to edge
|
||||
//snap to edge
|
||||
} else if (x !== null) {
|
||||
this.pointerHandler_ = getEdgeHandler(
|
||||
getOpposingPoint([x, extent[1]]),
|
||||
@@ -340,7 +348,7 @@ class Extent extends PointerInteraction {
|
||||
getOpposingPoint([extent[2], y])
|
||||
);
|
||||
}
|
||||
//no snap - new bbox
|
||||
//no snap - new bbox
|
||||
} else {
|
||||
vertex = map.getCoordinateFromPixelInternal(pixel);
|
||||
this.setExtent([vertex[0], vertex[1], vertex[0], vertex[1]]);
|
||||
@@ -395,7 +403,10 @@ class Extent extends PointerInteraction {
|
||||
* @api
|
||||
*/
|
||||
getExtent() {
|
||||
return toUserExtent(this.getExtentInternal(), this.getMap().getView().getProjection());
|
||||
return toUserExtent(
|
||||
this.getExtentInternal(),
|
||||
this.getMap().getView().getProjection()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -429,7 +440,7 @@ class Extent extends PointerInteraction {
|
||||
*/
|
||||
function getDefaultExtentStyleFunction() {
|
||||
const style = createEditingStyle();
|
||||
return function(feature, resolution) {
|
||||
return function (feature, resolution) {
|
||||
return style[GeometryType.POLYGON];
|
||||
};
|
||||
}
|
||||
@@ -441,7 +452,7 @@ function getDefaultExtentStyleFunction() {
|
||||
*/
|
||||
function getDefaultPointerStyleFunction() {
|
||||
const style = createEditingStyle();
|
||||
return function(feature, resolution) {
|
||||
return function (feature, resolution) {
|
||||
return style[GeometryType.POINT];
|
||||
};
|
||||
}
|
||||
@@ -451,7 +462,7 @@ function getDefaultPointerStyleFunction() {
|
||||
* @returns {function (import("../coordinate.js").Coordinate): import("../extent.js").Extent} event handler
|
||||
*/
|
||||
function getPointHandler(fixedPoint) {
|
||||
return function(point) {
|
||||
return function (point) {
|
||||
return boundingExtent([fixedPoint, point]);
|
||||
};
|
||||
}
|
||||
@@ -463,11 +474,11 @@ function getPointHandler(fixedPoint) {
|
||||
*/
|
||||
function getEdgeHandler(fixedP1, fixedP2) {
|
||||
if (fixedP1[0] == fixedP2[0]) {
|
||||
return function(point) {
|
||||
return function (point) {
|
||||
return boundingExtent([fixedP1, [point[0], fixedP2[1]]]);
|
||||
};
|
||||
} else if (fixedP1[1] == fixedP2[1]) {
|
||||
return function(point) {
|
||||
return function (point) {
|
||||
return boundingExtent([fixedP1, [fixedP2[0], point[1]]]);
|
||||
};
|
||||
} else {
|
||||
@@ -481,12 +492,23 @@ function getEdgeHandler(fixedP1, fixedP2) {
|
||||
*/
|
||||
function getSegments(extent) {
|
||||
return [
|
||||
[[extent[0], extent[1]], [extent[0], extent[3]]],
|
||||
[[extent[0], extent[3]], [extent[2], extent[3]]],
|
||||
[[extent[2], extent[3]], [extent[2], extent[1]]],
|
||||
[[extent[2], extent[1]], [extent[0], extent[1]]]
|
||||
[
|
||||
[extent[0], extent[1]],
|
||||
[extent[0], extent[3]],
|
||||
],
|
||||
[
|
||||
[extent[0], extent[3]],
|
||||
[extent[2], extent[3]],
|
||||
],
|
||||
[
|
||||
[extent[2], extent[3]],
|
||||
[extent[2], extent[1]],
|
||||
],
|
||||
[
|
||||
[extent[2], extent[1]],
|
||||
[extent[0], extent[1]],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
export default Extent;
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
* @module ol/interaction/Interaction
|
||||
*/
|
||||
import BaseObject from '../Object.js';
|
||||
import {easeOut, linear} from '../easing.js';
|
||||
import InteractionProperty from './Property.js';
|
||||
|
||||
import {easeOut, linear} from '../easing.js';
|
||||
|
||||
/**
|
||||
* Object literal with config options for interactions.
|
||||
@@ -17,7 +16,6 @@ import InteractionProperty from './Property.js';
|
||||
* are traversed in reverse order of the interactions collection of the map.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Abstract base class; normally only used for creating subclasses and not
|
||||
@@ -101,7 +99,6 @@ class Interaction extends BaseObject {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {import("../View.js").default} view View.
|
||||
* @param {import("../coordinate.js").Coordinate} delta Delta.
|
||||
@@ -114,7 +111,7 @@ export function pan(view, delta, opt_duration) {
|
||||
view.animateInternal({
|
||||
duration: opt_duration !== undefined ? opt_duration : 250,
|
||||
easing: linear,
|
||||
center: view.getConstrainedCenter(center)
|
||||
center: view.getConstrainedCenter(center),
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -142,7 +139,7 @@ export function zoomByDelta(view, delta, opt_anchor, opt_duration) {
|
||||
resolution: newResolution,
|
||||
anchor: opt_anchor,
|
||||
duration: opt_duration !== undefined ? opt_duration : 250,
|
||||
easing: easeOut
|
||||
easing: easeOut,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
/**
|
||||
* @module ol/interaction/KeyboardPan
|
||||
*/
|
||||
import {rotate as rotateCoordinate} from '../coordinate.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import Interaction, {pan} from './Interaction.js';
|
||||
import KeyCode from '../events/KeyCode.js';
|
||||
import {noModifierKeys, targetNotEditable} from '../events/condition.js';
|
||||
import Interaction, {pan} from './Interaction.js';
|
||||
|
||||
import {rotate as rotateCoordinate} from '../coordinate.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -20,7 +19,6 @@ import Interaction, {pan} from './Interaction.js';
|
||||
* press.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to pan the map using keyboard arrows.
|
||||
@@ -39,9 +37,8 @@ class KeyboardPan extends Interaction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
super({
|
||||
handleEvent: handleEvent
|
||||
handleEvent: handleEvent,
|
||||
});
|
||||
|
||||
const options = opt_options || {};
|
||||
@@ -51,17 +48,20 @@ class KeyboardPan extends Interaction {
|
||||
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.
|
||||
* @return {boolean} Combined condition result.
|
||||
*/
|
||||
this.defaultCondition_ = function(mapBrowserEvent) {
|
||||
return noModifierKeys(mapBrowserEvent) &&
|
||||
targetNotEditable(mapBrowserEvent);
|
||||
this.defaultCondition_ = function (mapBrowserEvent) {
|
||||
return (
|
||||
noModifierKeys(mapBrowserEvent) && targetNotEditable(mapBrowserEvent)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../events/condition.js").Condition}
|
||||
*/
|
||||
this.condition_ = options.condition !== undefined ?
|
||||
options.condition : this.defaultCondition_;
|
||||
this.condition_ =
|
||||
options.condition !== undefined
|
||||
? options.condition
|
||||
: this.defaultCondition_;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -73,14 +73,11 @@ class KeyboardPan extends Interaction {
|
||||
* @private
|
||||
* @type {number}
|
||||
*/
|
||||
this.pixelDelta_ = options.pixelDelta !== undefined ?
|
||||
options.pixelDelta : 128;
|
||||
|
||||
this.pixelDelta_ =
|
||||
options.pixelDelta !== undefined ? options.pixelDelta : 128;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a
|
||||
* `KeyEvent`, and decides the direction to pan to (if an arrow key was
|
||||
@@ -94,15 +91,18 @@ function handleEvent(mapBrowserEvent) {
|
||||
if (mapBrowserEvent.type == EventType.KEYDOWN) {
|
||||
const keyEvent = /** @type {KeyboardEvent} */ (mapBrowserEvent.originalEvent);
|
||||
const keyCode = keyEvent.keyCode;
|
||||
if (this.condition_(mapBrowserEvent) &&
|
||||
(keyCode == KeyCode.DOWN ||
|
||||
if (
|
||||
this.condition_(mapBrowserEvent) &&
|
||||
(keyCode == KeyCode.DOWN ||
|
||||
keyCode == KeyCode.LEFT ||
|
||||
keyCode == KeyCode.RIGHT ||
|
||||
keyCode == KeyCode.UP)) {
|
||||
keyCode == KeyCode.UP)
|
||||
) {
|
||||
const map = mapBrowserEvent.map;
|
||||
const view = map.getView();
|
||||
const mapUnitsDelta = view.getResolution() * this.pixelDelta_;
|
||||
let deltaX = 0, deltaY = 0;
|
||||
let deltaX = 0,
|
||||
deltaY = 0;
|
||||
if (keyCode == KeyCode.DOWN) {
|
||||
deltaY = -mapUnitsDelta;
|
||||
} else if (keyCode == KeyCode.LEFT) {
|
||||
|
||||
@@ -2,9 +2,8 @@
|
||||
* @module ol/interaction/KeyboardZoom
|
||||
*/
|
||||
import EventType from '../events/EventType.js';
|
||||
import {targetNotEditable} from '../events/condition.js';
|
||||
import Interaction, {zoomByDelta} from './Interaction.js';
|
||||
|
||||
import {targetNotEditable} from '../events/condition.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
@@ -16,7 +15,6 @@ import Interaction, {zoomByDelta} from './Interaction.js';
|
||||
* @property {number} [delta=1] The zoom level delta on each key press.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to zoom the map using keyboard + and -.
|
||||
@@ -35,9 +33,8 @@ class KeyboardZoom extends Interaction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
super({
|
||||
handleEvent: handleEvent
|
||||
handleEvent: handleEvent,
|
||||
});
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
@@ -59,12 +56,9 @@ class KeyboardZoom extends Interaction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 100;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the {@link module:ol/MapBrowserEvent map browser event} if it was a
|
||||
* `KeyEvent`, and decides whether to zoom in or out (depending on whether the
|
||||
@@ -75,14 +69,18 @@ class KeyboardZoom extends Interaction {
|
||||
*/
|
||||
function handleEvent(mapBrowserEvent) {
|
||||
let stopEvent = false;
|
||||
if (mapBrowserEvent.type == EventType.KEYDOWN ||
|
||||
mapBrowserEvent.type == EventType.KEYPRESS) {
|
||||
if (
|
||||
mapBrowserEvent.type == EventType.KEYDOWN ||
|
||||
mapBrowserEvent.type == EventType.KEYPRESS
|
||||
) {
|
||||
const keyEvent = /** @type {KeyboardEvent} */ (mapBrowserEvent.originalEvent);
|
||||
const charCode = keyEvent.charCode;
|
||||
if (this.condition_(mapBrowserEvent) &&
|
||||
(charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))) {
|
||||
if (
|
||||
this.condition_(mapBrowserEvent) &&
|
||||
(charCode == '+'.charCodeAt(0) || charCode == '-'.charCodeAt(0))
|
||||
) {
|
||||
const map = mapBrowserEvent.map;
|
||||
const delta = (charCode == '+'.charCodeAt(0)) ? this.delta_ : -this.delta_;
|
||||
const delta = charCode == '+'.charCodeAt(0) ? this.delta_ : -this.delta_;
|
||||
const view = map.getView();
|
||||
zoomByDelta(view, delta, undefined, this.duration_);
|
||||
mapBrowserEvent.preventDefault();
|
||||
|
||||
+237
-117
@@ -1,28 +1,48 @@
|
||||
/**
|
||||
* @module ol/interaction/Modify
|
||||
*/
|
||||
import {getUid} from '../util.js';
|
||||
import Collection from '../Collection.js';
|
||||
import CollectionEventType from '../CollectionEventType.js';
|
||||
import Feature from '../Feature.js';
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import {equals} from '../array.js';
|
||||
import {equals as coordinatesEqual, distance as coordinateDistance, squaredDistance as squaredCoordinateDistance, squaredDistanceToSegment, closestOnSegment} from '../coordinate.js';
|
||||
import Event from '../events/Event.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {always, primaryAction, altKeyOnly, singleClick} from '../events/condition.js';
|
||||
import {boundingExtent, buffer as bufferExtent, createOrUpdateFromCoordinate as createExtent} from '../extent.js';
|
||||
import Feature from '../Feature.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import Point from '../geom/Point.js';
|
||||
import {fromCircle} from '../geom/Polygon.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import RBush from '../structs/RBush.js';
|
||||
import VectorEventType from '../source/VectorEventType.js';
|
||||
import VectorLayer from '../layer/Vector.js';
|
||||
import VectorSource from '../source/Vector.js';
|
||||
import VectorEventType from '../source/VectorEventType.js';
|
||||
import RBush from '../structs/RBush.js';
|
||||
import {
|
||||
altKeyOnly,
|
||||
always,
|
||||
primaryAction,
|
||||
singleClick,
|
||||
} from '../events/condition.js';
|
||||
import {
|
||||
boundingExtent,
|
||||
buffer as bufferExtent,
|
||||
createOrUpdateFromCoordinate as createExtent,
|
||||
} from '../extent.js';
|
||||
import {
|
||||
closestOnSegment,
|
||||
distance as coordinateDistance,
|
||||
equals as coordinatesEqual,
|
||||
squaredDistance as squaredCoordinateDistance,
|
||||
squaredDistanceToSegment,
|
||||
} from '../coordinate.js';
|
||||
import {createEditingStyle} from '../style/Style.js';
|
||||
import {getUserProjection, fromUserExtent, toUserExtent, fromUserCoordinate, toUserCoordinate} from '../proj.js';
|
||||
|
||||
import {equals} from '../array.js';
|
||||
import {fromCircle} from '../geom/Polygon.js';
|
||||
import {
|
||||
fromUserCoordinate,
|
||||
fromUserExtent,
|
||||
getUserProjection,
|
||||
toUserCoordinate,
|
||||
toUserExtent,
|
||||
} from '../proj.js';
|
||||
import {getUid} from '../util.js';
|
||||
|
||||
/**
|
||||
* The segment index assigned to a circle's center when
|
||||
@@ -56,10 +76,9 @@ const ModifyEventType = {
|
||||
* @event ModifyEvent#modifyend
|
||||
* @api
|
||||
*/
|
||||
MODIFYEND: 'modifyend'
|
||||
MODIFYEND: 'modifyend',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} SegmentData
|
||||
* @property {Array<number>} [depth]
|
||||
@@ -70,7 +89,6 @@ const ModifyEventType = {
|
||||
* @property {Array<SegmentData>} [featureSegments]
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("../events/condition.js").Condition} [condition] A function that
|
||||
@@ -102,7 +120,6 @@ const ModifyEventType = {
|
||||
* overlay.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/Modify~Modify} instances are
|
||||
@@ -132,12 +149,9 @@ export class ModifyEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserPointerEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Interaction for modifying feature geometries. To modify features that have
|
||||
@@ -158,7 +172,6 @@ class Modify extends PointerInteraction {
|
||||
* @param {Options} options Options.
|
||||
*/
|
||||
constructor(options) {
|
||||
|
||||
super(/** @type {import("./Pointer.js").Options} */ (options));
|
||||
|
||||
/** @private */
|
||||
@@ -175,7 +188,7 @@ class Modify extends PointerInteraction {
|
||||
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Browser event.
|
||||
* @return {boolean} Combined condition result.
|
||||
*/
|
||||
this.defaultDeleteCondition_ = function(mapBrowserEvent) {
|
||||
this.defaultDeleteCondition_ = function (mapBrowserEvent) {
|
||||
return altKeyOnly(mapBrowserEvent) && singleClick(mapBrowserEvent);
|
||||
};
|
||||
|
||||
@@ -183,15 +196,17 @@ class Modify extends PointerInteraction {
|
||||
* @type {import("../events/condition.js").Condition}
|
||||
* @private
|
||||
*/
|
||||
this.deleteCondition_ = options.deleteCondition ?
|
||||
options.deleteCondition : this.defaultDeleteCondition_;
|
||||
this.deleteCondition_ = options.deleteCondition
|
||||
? options.deleteCondition
|
||||
: this.defaultDeleteCondition_;
|
||||
|
||||
/**
|
||||
* @type {import("../events/condition.js").Condition}
|
||||
* @private
|
||||
*/
|
||||
this.insertVertexCondition_ = options.insertVertexCondition ?
|
||||
options.insertVertexCondition : always;
|
||||
this.insertVertexCondition_ = options.insertVertexCondition
|
||||
? options.insertVertexCondition
|
||||
: always;
|
||||
|
||||
/**
|
||||
* Editing vertex.
|
||||
@@ -238,8 +253,8 @@ class Modify extends PointerInteraction {
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.pixelTolerance_ = options.pixelTolerance !== undefined ?
|
||||
options.pixelTolerance : 10;
|
||||
this.pixelTolerance_ =
|
||||
options.pixelTolerance !== undefined ? options.pixelTolerance : 10;
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
@@ -269,11 +284,11 @@ class Modify extends PointerInteraction {
|
||||
this.overlay_ = new VectorLayer({
|
||||
source: new VectorSource({
|
||||
useSpatialIndex: false,
|
||||
wrapX: !!options.wrapX
|
||||
wrapX: !!options.wrapX,
|
||||
}),
|
||||
style: options.style ? options.style : getDefaultStyleFunction(),
|
||||
updateWhileAnimating: true,
|
||||
updateWhileInteracting: true
|
||||
updateWhileInteracting: true,
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -290,10 +305,9 @@ class Modify extends PointerInteraction {
|
||||
'MultiLineString': this.writeMultiLineStringGeometry_.bind(this),
|
||||
'MultiPolygon': this.writeMultiPolygonGeometry_.bind(this),
|
||||
'Circle': this.writeCircleGeometry_.bind(this),
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_.bind(this)
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_.bind(this),
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @type {VectorSource}
|
||||
* @private
|
||||
@@ -304,8 +318,14 @@ class Modify extends PointerInteraction {
|
||||
if (options.source) {
|
||||
this.source_ = options.source;
|
||||
features = new Collection(this.source_.getFeatures());
|
||||
this.source_.addEventListener(VectorEventType.ADDFEATURE, this.handleSourceAdd_.bind(this));
|
||||
this.source_.addEventListener(VectorEventType.REMOVEFEATURE, this.handleSourceRemove_.bind(this));
|
||||
this.source_.addEventListener(
|
||||
VectorEventType.ADDFEATURE,
|
||||
this.handleSourceAdd_.bind(this)
|
||||
);
|
||||
this.source_.addEventListener(
|
||||
VectorEventType.REMOVEFEATURE,
|
||||
this.handleSourceRemove_.bind(this)
|
||||
);
|
||||
} else {
|
||||
features = options.features;
|
||||
}
|
||||
@@ -320,15 +340,20 @@ class Modify extends PointerInteraction {
|
||||
this.features_ = features;
|
||||
|
||||
this.features_.forEach(this.addFeature_.bind(this));
|
||||
this.features_.addEventListener(CollectionEventType.ADD, this.handleFeatureAdd_.bind(this));
|
||||
this.features_.addEventListener(CollectionEventType.REMOVE, this.handleFeatureRemove_.bind(this));
|
||||
this.features_.addEventListener(
|
||||
CollectionEventType.ADD,
|
||||
this.handleFeatureAdd_.bind(this)
|
||||
);
|
||||
this.features_.addEventListener(
|
||||
CollectionEventType.REMOVE,
|
||||
this.handleFeatureRemove_.bind(this)
|
||||
);
|
||||
|
||||
/**
|
||||
* @type {import("../MapBrowserPointerEvent.js").default}
|
||||
* @private
|
||||
*/
|
||||
this.lastPointerEvent_ = null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,7 +382,9 @@ class Modify extends PointerInteraction {
|
||||
willModifyFeatures_(evt) {
|
||||
if (!this.modified_) {
|
||||
this.modified_ = true;
|
||||
this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYSTART, this.features_, evt));
|
||||
this.dispatchEvent(
|
||||
new ModifyEvent(ModifyEventType.MODIFYSTART, this.features_, evt)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -372,7 +399,10 @@ class Modify extends PointerInteraction {
|
||||
this.overlay_.getSource().removeFeature(this.vertexFeature_);
|
||||
this.vertexFeature_ = null;
|
||||
}
|
||||
feature.removeEventListener(EventType.CHANGE, this.boundHandleFeatureChange_);
|
||||
feature.removeEventListener(
|
||||
EventType.CHANGE,
|
||||
this.boundHandleFeatureChange_
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -387,11 +417,12 @@ class Modify extends PointerInteraction {
|
||||
/**
|
||||
* @param {SegmentData} node RTree node.
|
||||
*/
|
||||
function(node) {
|
||||
function (node) {
|
||||
if (feature === node.feature) {
|
||||
nodesToRemove.push(node);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
for (let i = nodesToRemove.length - 1; i >= 0; --i) {
|
||||
const nodeToRemove = nodesToRemove[i];
|
||||
for (let j = this.dragSegments_.length - 1; j >= 0; --j) {
|
||||
@@ -498,7 +529,7 @@ class Modify extends PointerInteraction {
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
geometry: geometry,
|
||||
segment: [coordinates, coordinates]
|
||||
segment: [coordinates, coordinates],
|
||||
};
|
||||
|
||||
this.rBush_.insert(geometry.getExtent(), segmentData);
|
||||
@@ -520,7 +551,7 @@ class Modify extends PointerInteraction {
|
||||
geometry: geometry,
|
||||
depth: [i],
|
||||
index: i,
|
||||
segment: [coordinates, coordinates]
|
||||
segment: [coordinates, coordinates],
|
||||
};
|
||||
|
||||
this.rBush_.insert(geometry.getExtent(), segmentData);
|
||||
@@ -542,7 +573,7 @@ class Modify extends PointerInteraction {
|
||||
feature: feature,
|
||||
geometry: geometry,
|
||||
index: i,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
@@ -567,7 +598,7 @@ class Modify extends PointerInteraction {
|
||||
geometry: geometry,
|
||||
depth: [j],
|
||||
index: i,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
@@ -593,7 +624,7 @@ class Modify extends PointerInteraction {
|
||||
geometry: geometry,
|
||||
depth: [j],
|
||||
index: i,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
@@ -621,7 +652,7 @@ class Modify extends PointerInteraction {
|
||||
geometry: geometry,
|
||||
depth: [j, k],
|
||||
index: i,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
@@ -649,7 +680,7 @@ class Modify extends PointerInteraction {
|
||||
feature: feature,
|
||||
geometry: geometry,
|
||||
index: CIRCLE_CENTER_INDEX,
|
||||
segment: [coordinates, coordinates]
|
||||
segment: [coordinates, coordinates],
|
||||
};
|
||||
|
||||
/** @type {SegmentData} */
|
||||
@@ -657,7 +688,7 @@ class Modify extends PointerInteraction {
|
||||
feature: feature,
|
||||
geometry: geometry,
|
||||
index: CIRCLE_CIRCUMFERENCE_INDEX,
|
||||
segment: [coordinates, coordinates]
|
||||
segment: [coordinates, coordinates],
|
||||
};
|
||||
|
||||
const featureSegments = [centerSegmentData, circumferenceSegmentData];
|
||||
@@ -668,8 +699,12 @@ class Modify extends PointerInteraction {
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection && this.getMap()) {
|
||||
const projection = this.getMap().getView().getProjection();
|
||||
circleGeometry = circleGeometry.clone().transform(userProjection, projection);
|
||||
circleGeometry = fromCircle(/** @type {import("../geom/Circle.js").default} */ (circleGeometry)).transform(projection, userProjection);
|
||||
circleGeometry = circleGeometry
|
||||
.clone()
|
||||
.transform(userProjection, projection);
|
||||
circleGeometry = fromCircle(
|
||||
/** @type {import("../geom/Circle.js").default} */ (circleGeometry)
|
||||
).transform(projection, userProjection);
|
||||
}
|
||||
this.rBush_.insert(circleGeometry.getExtent(), circumferenceSegmentData);
|
||||
}
|
||||
@@ -718,13 +753,18 @@ class Modify extends PointerInteraction {
|
||||
this.lastPointerEvent_ = mapBrowserEvent;
|
||||
|
||||
let handled;
|
||||
if (!mapBrowserEvent.map.getView().getInteracting() &&
|
||||
mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE &&
|
||||
!this.handlingDownUpSequence) {
|
||||
if (
|
||||
!mapBrowserEvent.map.getView().getInteracting() &&
|
||||
mapBrowserEvent.type == MapBrowserEventType.POINTERMOVE &&
|
||||
!this.handlingDownUpSequence
|
||||
) {
|
||||
this.handlePointerMove_(mapBrowserEvent);
|
||||
}
|
||||
if (this.vertexFeature_ && this.deleteCondition_(mapBrowserEvent)) {
|
||||
if (mapBrowserEvent.type != MapBrowserEventType.SINGLECLICK || !this.ignoreNextSingleClick_) {
|
||||
if (
|
||||
mapBrowserEvent.type != MapBrowserEventType.SINGLECLICK ||
|
||||
!this.ignoreNextSingleClick_
|
||||
) {
|
||||
handled = this.removePoint();
|
||||
} else {
|
||||
handled = true;
|
||||
@@ -799,23 +839,30 @@ class Modify extends PointerInteraction {
|
||||
this.changingFeature_ = true;
|
||||
geometry.setCenter(vertex);
|
||||
this.changingFeature_ = false;
|
||||
} else { // We're dragging the circle's circumference:
|
||||
} else {
|
||||
// We're dragging the circle's circumference:
|
||||
this.changingFeature_ = true;
|
||||
const projection = evt.map.getView().getProjection();
|
||||
let radius = coordinateDistance(fromUserCoordinate(geometry.getCenter(), projection),
|
||||
fromUserCoordinate(vertex, projection));
|
||||
let radius = coordinateDistance(
|
||||
fromUserCoordinate(geometry.getCenter(), projection),
|
||||
fromUserCoordinate(vertex, projection)
|
||||
);
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
const circleGeometry = geometry.clone().transform(userProjection, projection);
|
||||
const circleGeometry = geometry
|
||||
.clone()
|
||||
.transform(userProjection, projection);
|
||||
circleGeometry.setRadius(radius);
|
||||
radius = circleGeometry.transform(projection, userProjection).getRadius();
|
||||
radius = circleGeometry
|
||||
.transform(projection, userProjection)
|
||||
.getRadius();
|
||||
}
|
||||
geometry.setRadius(radius);
|
||||
this.changingFeature_ = false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// pass
|
||||
// pass
|
||||
}
|
||||
|
||||
if (coordinates) {
|
||||
@@ -859,29 +906,46 @@ class Modify extends PointerInteraction {
|
||||
componentSegments[uid] = new Array(2);
|
||||
}
|
||||
|
||||
if (segmentDataMatch.geometry.getType() === GeometryType.CIRCLE && segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX) {
|
||||
const closestVertex = closestOnSegmentData(pixelCoordinate, segmentDataMatch, projection);
|
||||
if (coordinatesEqual(closestVertex, vertex) && !componentSegments[uid][0]) {
|
||||
if (
|
||||
segmentDataMatch.geometry.getType() === GeometryType.CIRCLE &&
|
||||
segmentDataMatch.index === CIRCLE_CIRCUMFERENCE_INDEX
|
||||
) {
|
||||
const closestVertex = closestOnSegmentData(
|
||||
pixelCoordinate,
|
||||
segmentDataMatch,
|
||||
projection
|
||||
);
|
||||
if (
|
||||
coordinatesEqual(closestVertex, vertex) &&
|
||||
!componentSegments[uid][0]
|
||||
) {
|
||||
this.dragSegments_.push([segmentDataMatch, 0]);
|
||||
componentSegments[uid][0] = segmentDataMatch;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coordinatesEqual(segment[0], vertex) && !componentSegments[uid][0]) {
|
||||
if (
|
||||
coordinatesEqual(segment[0], vertex) &&
|
||||
!componentSegments[uid][0]
|
||||
) {
|
||||
this.dragSegments_.push([segmentDataMatch, 0]);
|
||||
componentSegments[uid][0] = segmentDataMatch;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (coordinatesEqual(segment[1], vertex) && !componentSegments[uid][1]) {
|
||||
if (
|
||||
coordinatesEqual(segment[1], vertex) &&
|
||||
!componentSegments[uid][1]
|
||||
) {
|
||||
// prevent dragging closed linestrings by the connecting node
|
||||
if ((segmentDataMatch.geometry.getType() ===
|
||||
GeometryType.LINE_STRING ||
|
||||
if (
|
||||
(segmentDataMatch.geometry.getType() === GeometryType.LINE_STRING ||
|
||||
segmentDataMatch.geometry.getType() ===
|
||||
GeometryType.MULTI_LINE_STRING) &&
|
||||
componentSegments[uid][0] &&
|
||||
componentSegments[uid][0].index === 0) {
|
||||
GeometryType.MULTI_LINE_STRING) &&
|
||||
componentSegments[uid][0] &&
|
||||
componentSegments[uid][0].index === 0
|
||||
) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -890,9 +954,12 @@ class Modify extends PointerInteraction {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (getUid(segment) in this.vertexSegments_ &&
|
||||
(!componentSegments[uid][0] && !componentSegments[uid][1]) &&
|
||||
this.insertVertexCondition_(evt)) {
|
||||
if (
|
||||
getUid(segment) in this.vertexSegments_ &&
|
||||
!componentSegments[uid][0] &&
|
||||
!componentSegments[uid][1] &&
|
||||
this.insertVertexCondition_(evt)
|
||||
) {
|
||||
insertVertices.push([segmentDataMatch, vertex]);
|
||||
}
|
||||
}
|
||||
@@ -931,16 +998,26 @@ class Modify extends PointerInteraction {
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
const projection = evt.map.getView().getProjection();
|
||||
circleGeometry = circleGeometry.clone().transform(userProjection, projection);
|
||||
circleGeometry = fromCircle(circleGeometry).transform(projection, userProjection);
|
||||
circleGeometry = circleGeometry
|
||||
.clone()
|
||||
.transform(userProjection, projection);
|
||||
circleGeometry = fromCircle(circleGeometry).transform(
|
||||
projection,
|
||||
userProjection
|
||||
);
|
||||
}
|
||||
this.rBush_.update(circleGeometry.getExtent(), circumferenceSegmentData);
|
||||
this.rBush_.update(
|
||||
circleGeometry.getExtent(),
|
||||
circumferenceSegmentData
|
||||
);
|
||||
} else {
|
||||
this.rBush_.update(boundingExtent(segmentData.segment), segmentData);
|
||||
}
|
||||
}
|
||||
if (this.modified_) {
|
||||
this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt));
|
||||
this.dispatchEvent(
|
||||
new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt)
|
||||
);
|
||||
this.modified_ = false;
|
||||
}
|
||||
return false;
|
||||
@@ -964,14 +1041,22 @@ class Modify extends PointerInteraction {
|
||||
handlePointerAtPixel_(pixel, map, opt_coordinate) {
|
||||
const pixelCoordinate = opt_coordinate || map.getCoordinateFromPixel(pixel);
|
||||
const projection = map.getView().getProjection();
|
||||
const sortByDistance = function(a, b) {
|
||||
return projectedDistanceToSegmentDataSquared(pixelCoordinate, a, projection) -
|
||||
projectedDistanceToSegmentDataSquared(pixelCoordinate, b, projection);
|
||||
const sortByDistance = function (a, b) {
|
||||
return (
|
||||
projectedDistanceToSegmentDataSquared(pixelCoordinate, a, projection) -
|
||||
projectedDistanceToSegmentDataSquared(pixelCoordinate, b, projection)
|
||||
);
|
||||
};
|
||||
|
||||
const viewExtent = fromUserExtent(createExtent(pixelCoordinate, tempExtent), projection);
|
||||
const viewExtent = fromUserExtent(
|
||||
createExtent(pixelCoordinate, tempExtent),
|
||||
projection
|
||||
);
|
||||
const buffer = map.getView().getResolution() * this.pixelTolerance_;
|
||||
const box = toUserExtent(bufferExtent(viewExtent, buffer, tempExtent), projection);
|
||||
const box = toUserExtent(
|
||||
bufferExtent(viewExtent, buffer, tempExtent),
|
||||
projection
|
||||
);
|
||||
|
||||
const rBush = this.rBush_;
|
||||
const nodes = rBush.getInExtent(box);
|
||||
@@ -986,7 +1071,10 @@ class Modify extends PointerInteraction {
|
||||
/** @type {Object<string, boolean>} */
|
||||
const vertexSegments = {};
|
||||
|
||||
if (node.geometry.getType() === GeometryType.CIRCLE && node.index === CIRCLE_CIRCUMFERENCE_INDEX) {
|
||||
if (
|
||||
node.geometry.getType() === GeometryType.CIRCLE &&
|
||||
node.index === CIRCLE_CIRCUMFERENCE_INDEX
|
||||
) {
|
||||
this.snappedToVertex_ = true;
|
||||
this.createOrUpdateVertexFeature_(vertex);
|
||||
} else {
|
||||
@@ -997,15 +1085,20 @@ class Modify extends PointerInteraction {
|
||||
dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
this.snappedToVertex_ = dist <= this.pixelTolerance_;
|
||||
if (this.snappedToVertex_) {
|
||||
vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];
|
||||
vertex =
|
||||
squaredDist1 > squaredDist2
|
||||
? closestSegment[1]
|
||||
: closestSegment[0];
|
||||
}
|
||||
this.createOrUpdateVertexFeature_(vertex);
|
||||
for (let i = 1, ii = nodes.length; i < ii; ++i) {
|
||||
const segment = nodes[i].segment;
|
||||
if ((coordinatesEqual(closestSegment[0], segment[0]) &&
|
||||
coordinatesEqual(closestSegment[1], segment[1]) ||
|
||||
(coordinatesEqual(closestSegment[0], segment[1]) &&
|
||||
coordinatesEqual(closestSegment[1], segment[0])))) {
|
||||
if (
|
||||
(coordinatesEqual(closestSegment[0], segment[0]) &&
|
||||
coordinatesEqual(closestSegment[1], segment[1])) ||
|
||||
(coordinatesEqual(closestSegment[0], segment[1]) &&
|
||||
coordinatesEqual(closestSegment[1], segment[0]))
|
||||
) {
|
||||
vertexSegments[getUid(segment)] = true;
|
||||
} else {
|
||||
break;
|
||||
@@ -1073,7 +1166,7 @@ class Modify extends PointerInteraction {
|
||||
feature: feature,
|
||||
geometry: geometry,
|
||||
depth: depth,
|
||||
index: index
|
||||
index: index,
|
||||
};
|
||||
|
||||
rTree.insert(boundingExtent(newSegmentData.segment), newSegmentData);
|
||||
@@ -1085,7 +1178,7 @@ class Modify extends PointerInteraction {
|
||||
feature: feature,
|
||||
geometry: geometry,
|
||||
depth: depth,
|
||||
index: index + 1
|
||||
index: index + 1,
|
||||
};
|
||||
|
||||
rTree.insert(boundingExtent(newSegmentData2.segment), newSegmentData2);
|
||||
@@ -1099,11 +1192,16 @@ class Modify extends PointerInteraction {
|
||||
* @api
|
||||
*/
|
||||
removePoint() {
|
||||
if (this.lastPointerEvent_ && this.lastPointerEvent_.type != MapBrowserEventType.POINTERDRAG) {
|
||||
if (
|
||||
this.lastPointerEvent_ &&
|
||||
this.lastPointerEvent_.type != MapBrowserEventType.POINTERDRAG
|
||||
) {
|
||||
const evt = this.lastPointerEvent_;
|
||||
this.willModifyFeatures_(evt);
|
||||
const removed = this.removeVertex_();
|
||||
this.dispatchEvent(new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt));
|
||||
this.dispatchEvent(
|
||||
new ModifyEvent(ModifyEventType.MODIFYEND, this.features_, evt)
|
||||
);
|
||||
this.modified_ = false;
|
||||
return removed;
|
||||
}
|
||||
@@ -1139,7 +1237,6 @@ class Modify extends PointerInteraction {
|
||||
segmentsByFeature[uid].left = segmentData;
|
||||
segmentsByFeature[uid].index = segmentData.index + 1;
|
||||
}
|
||||
|
||||
}
|
||||
for (uid in segmentsByFeature) {
|
||||
right = segmentsByFeature[uid].right;
|
||||
@@ -1173,7 +1270,7 @@ class Modify extends PointerInteraction {
|
||||
break;
|
||||
case GeometryType.MULTI_POLYGON:
|
||||
component = component[segmentData.depth[1]];
|
||||
/* falls through */
|
||||
/* falls through */
|
||||
case GeometryType.POLYGON:
|
||||
component = component[segmentData.depth[0]];
|
||||
if (component.length > 4) {
|
||||
@@ -1191,7 +1288,7 @@ class Modify extends PointerInteraction {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// pass
|
||||
// pass
|
||||
}
|
||||
|
||||
if (deleted) {
|
||||
@@ -1206,17 +1303,19 @@ class Modify extends PointerInteraction {
|
||||
segments.push(right.segment[1]);
|
||||
}
|
||||
if (left !== undefined && right !== undefined) {
|
||||
|
||||
/** @type {SegmentData} */
|
||||
const newSegmentData = {
|
||||
depth: segmentData.depth,
|
||||
feature: segmentData.feature,
|
||||
geometry: segmentData.geometry,
|
||||
index: newIndex,
|
||||
segment: segments
|
||||
segment: segments,
|
||||
};
|
||||
|
||||
this.rBush_.insert(boundingExtent(newSegmentData.segment), newSegmentData);
|
||||
this.rBush_.insert(
|
||||
boundingExtent(newSegmentData.segment),
|
||||
newSegmentData
|
||||
);
|
||||
}
|
||||
this.updateSegmentIndices_(geometry, index, segmentData.depth, -1);
|
||||
if (this.vertexFeature_) {
|
||||
@@ -1225,7 +1324,6 @@ class Modify extends PointerInteraction {
|
||||
}
|
||||
dragSegments.length = 0;
|
||||
}
|
||||
|
||||
}
|
||||
return deleted;
|
||||
}
|
||||
@@ -1249,18 +1347,22 @@ class Modify extends PointerInteraction {
|
||||
* @private
|
||||
*/
|
||||
updateSegmentIndices_(geometry, index, depth, delta) {
|
||||
this.rBush_.forEachInExtent(geometry.getExtent(), function(segmentDataMatch) {
|
||||
if (segmentDataMatch.geometry === geometry &&
|
||||
(depth === undefined || segmentDataMatch.depth === undefined ||
|
||||
this.rBush_.forEachInExtent(geometry.getExtent(), function (
|
||||
segmentDataMatch
|
||||
) {
|
||||
if (
|
||||
segmentDataMatch.geometry === geometry &&
|
||||
(depth === undefined ||
|
||||
segmentDataMatch.depth === undefined ||
|
||||
equals(segmentDataMatch.depth, depth)) &&
|
||||
segmentDataMatch.index > index) {
|
||||
segmentDataMatch.index > index
|
||||
) {
|
||||
segmentDataMatch.index += delta;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {SegmentData} a The first segment data.
|
||||
* @param {SegmentData} b The second segment data.
|
||||
@@ -1270,7 +1372,6 @@ function compareIndexes(a, b) {
|
||||
return a.index - b.index;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the distance from a point to a line segment.
|
||||
*
|
||||
@@ -1281,7 +1382,11 @@ function compareIndexes(a, b) {
|
||||
* @param {import("../proj/Projection.js").default} projection The view projection.
|
||||
* @return {number} The square of the distance between a point and a line segment.
|
||||
*/
|
||||
function projectedDistanceToSegmentDataSquared(pointCoordinates, segmentData, projection) {
|
||||
function projectedDistanceToSegmentDataSquared(
|
||||
pointCoordinates,
|
||||
segmentData,
|
||||
projection
|
||||
) {
|
||||
const geometry = segmentData.geometry;
|
||||
|
||||
if (geometry.getType() === GeometryType.CIRCLE) {
|
||||
@@ -1290,12 +1395,16 @@ function projectedDistanceToSegmentDataSquared(pointCoordinates, segmentData, pr
|
||||
if (segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX) {
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
circleGeometry = /** @type {import("../geom/Circle.js").default} */ (circleGeometry.clone().transform(userProjection, projection));
|
||||
circleGeometry = /** @type {import("../geom/Circle.js").default} */ (circleGeometry
|
||||
.clone()
|
||||
.transform(userProjection, projection));
|
||||
}
|
||||
const distanceToCenterSquared =
|
||||
squaredCoordinateDistance(circleGeometry.getCenter(), fromUserCoordinate(pointCoordinates, projection));
|
||||
const distanceToCenterSquared = squaredCoordinateDistance(
|
||||
circleGeometry.getCenter(),
|
||||
fromUserCoordinate(pointCoordinates, projection)
|
||||
);
|
||||
const distanceToCircumference =
|
||||
Math.sqrt(distanceToCenterSquared) - circleGeometry.getRadius();
|
||||
Math.sqrt(distanceToCenterSquared) - circleGeometry.getRadius();
|
||||
return distanceToCircumference * distanceToCircumference;
|
||||
}
|
||||
}
|
||||
@@ -1319,30 +1428,41 @@ function projectedDistanceToSegmentDataSquared(pointCoordinates, segmentData, pr
|
||||
function closestOnSegmentData(pointCoordinates, segmentData, projection) {
|
||||
const geometry = segmentData.geometry;
|
||||
|
||||
if (geometry.getType() === GeometryType.CIRCLE && segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX) {
|
||||
if (
|
||||
geometry.getType() === GeometryType.CIRCLE &&
|
||||
segmentData.index === CIRCLE_CIRCUMFERENCE_INDEX
|
||||
) {
|
||||
let circleGeometry = /** @type {import("../geom/Circle.js").default} */ (geometry);
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
circleGeometry = /** @type {import("../geom/Circle.js").default} */ (circleGeometry.clone().transform(userProjection, projection));
|
||||
circleGeometry = /** @type {import("../geom/Circle.js").default} */ (circleGeometry
|
||||
.clone()
|
||||
.transform(userProjection, projection));
|
||||
}
|
||||
return toUserCoordinate(circleGeometry.getClosestPoint(fromUserCoordinate(pointCoordinates, projection)), projection);
|
||||
return toUserCoordinate(
|
||||
circleGeometry.getClosestPoint(
|
||||
fromUserCoordinate(pointCoordinates, projection)
|
||||
),
|
||||
projection
|
||||
);
|
||||
}
|
||||
const coordinate = fromUserCoordinate(pointCoordinates, projection);
|
||||
tempSegment[0] = fromUserCoordinate(segmentData.segment[0], projection);
|
||||
tempSegment[1] = fromUserCoordinate(segmentData.segment[1], projection);
|
||||
return toUserCoordinate(closestOnSegment(coordinate, tempSegment), projection);
|
||||
return toUserCoordinate(
|
||||
closestOnSegment(coordinate, tempSegment),
|
||||
projection
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {import("../style/Style.js").StyleFunction} Styles.
|
||||
*/
|
||||
function getDefaultStyleFunction() {
|
||||
const style = createEditingStyle();
|
||||
return function(feature, resolution) {
|
||||
return function (feature, resolution) {
|
||||
return style[GeometryType.POINT];
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default Modify;
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
/**
|
||||
* @module ol/interaction/MouseWheelZoom
|
||||
*/
|
||||
import {always, focus} from '../events/condition.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {DEVICE_PIXEL_RATIO, FIREFOX} from '../has.js';
|
||||
import Interaction, {zoomByDelta} from './Interaction.js';
|
||||
import {DEVICE_PIXEL_RATIO, FIREFOX} from '../has.js';
|
||||
import {always, focus} from '../events/condition.js';
|
||||
import {clamp} from '../math.js';
|
||||
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
*/
|
||||
export const Mode = {
|
||||
TRACKPAD: 'trackpad',
|
||||
WHEEL: 'wheel'
|
||||
WHEEL: 'wheel',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("../events/condition.js").Condition} [condition] A function that
|
||||
@@ -33,7 +31,6 @@ export const Mode = {
|
||||
* the center of the screen instead of zooming on the mouse's location.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to zoom the map by scrolling the mouse wheel.
|
||||
@@ -44,10 +41,11 @@ class MouseWheelZoom extends Interaction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super(/** @type {import("./Interaction.js").InteractionOptions} */ (options));
|
||||
super(
|
||||
/** @type {import("./Interaction.js").InteractionOptions} */ (options)
|
||||
);
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -83,7 +81,8 @@ class MouseWheelZoom extends Interaction {
|
||||
* @private
|
||||
* @type {boolean}
|
||||
*/
|
||||
this.useAnchor_ = options.useAnchor !== undefined ? options.useAnchor : true;
|
||||
this.useAnchor_ =
|
||||
options.useAnchor !== undefined ? options.useAnchor : true;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -133,7 +132,6 @@ class MouseWheelZoom extends Interaction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.deltaPerZoom_ = 300;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -149,14 +147,17 @@ class MouseWheelZoom extends Interaction {
|
||||
return pass && this.condition_(mapBrowserEvent);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
endInteraction_() {
|
||||
this.trackpadTimeoutId_ = undefined;
|
||||
const view = this.getMap().getView();
|
||||
view.endInteraction(undefined, this.lastDelta_ ? (this.lastDelta_ > 0 ? 1 : -1) : 0, this.lastAnchor_);
|
||||
view.endInteraction(
|
||||
undefined,
|
||||
this.lastDelta_ ? (this.lastDelta_ > 0 ? 1 : -1) : 0,
|
||||
this.lastAnchor_
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -188,8 +189,7 @@ class MouseWheelZoom extends Interaction {
|
||||
let delta;
|
||||
if (mapBrowserEvent.type == EventType.WHEEL) {
|
||||
delta = wheelEvent.deltaY;
|
||||
if (FIREFOX &&
|
||||
wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
|
||||
if (FIREFOX && wheelEvent.deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
|
||||
delta /= DEVICE_PIXEL_RATIO;
|
||||
}
|
||||
if (wheelEvent.deltaMode === WheelEvent.DOM_DELTA_LINE) {
|
||||
@@ -210,9 +210,7 @@ class MouseWheelZoom extends Interaction {
|
||||
}
|
||||
|
||||
if (!this.mode_ || now - this.startTime_ > this.trackpadEventGap_) {
|
||||
this.mode_ = Math.abs(delta) < 4 ?
|
||||
Mode.TRACKPAD :
|
||||
Mode.WHEEL;
|
||||
this.mode_ = Math.abs(delta) < 4 ? Mode.TRACKPAD : Mode.WHEEL;
|
||||
}
|
||||
|
||||
const view = map.getView();
|
||||
@@ -225,7 +223,10 @@ class MouseWheelZoom extends Interaction {
|
||||
}
|
||||
view.beginInteraction();
|
||||
}
|
||||
this.trackpadTimeoutId_ = setTimeout(this.endInteraction_.bind(this), this.timeout_);
|
||||
this.trackpadTimeoutId_ = setTimeout(
|
||||
this.endInteraction_.bind(this),
|
||||
this.timeout_
|
||||
);
|
||||
view.adjustZoom(-delta / this.deltaPerZoom_, this.lastAnchor_);
|
||||
this.startTime_ = now;
|
||||
return false;
|
||||
@@ -236,7 +237,10 @@ class MouseWheelZoom extends Interaction {
|
||||
const timeLeft = Math.max(this.timeout_ - (now - this.startTime_), 0);
|
||||
|
||||
clearTimeout(this.timeoutId_);
|
||||
this.timeoutId_ = setTimeout(this.handleWheelZoom_.bind(this, map), timeLeft);
|
||||
this.timeoutId_ = setTimeout(
|
||||
this.handleWheelZoom_.bind(this, map),
|
||||
timeLeft
|
||||
);
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -250,10 +254,15 @@ class MouseWheelZoom extends Interaction {
|
||||
if (view.getAnimating()) {
|
||||
view.cancelAnimations();
|
||||
}
|
||||
let delta = -clamp(this.totalDelta_, -this.maxDelta_ * this.deltaPerZoom_, this.maxDelta_ * this.deltaPerZoom_) / this.deltaPerZoom_;
|
||||
let delta =
|
||||
-clamp(
|
||||
this.totalDelta_,
|
||||
-this.maxDelta_ * this.deltaPerZoom_,
|
||||
this.maxDelta_ * this.deltaPerZoom_
|
||||
) / this.deltaPerZoom_;
|
||||
if (view.getConstrainResolution()) {
|
||||
// view has a zoom constraint, zoom by 1
|
||||
delta = delta ? delta > 0 ? 1 : -1 : 0;
|
||||
delta = delta ? (delta > 0 ? 1 : -1) : 0;
|
||||
}
|
||||
zoomByDelta(view, delta, this.lastAnchor_, this.duration_);
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
/**
|
||||
* @module ol/interaction/PinchRotate
|
||||
*/
|
||||
import PointerInteraction, {
|
||||
centroid as centroidFromPointers,
|
||||
} from './Pointer.js';
|
||||
import {FALSE} from '../functions.js';
|
||||
import PointerInteraction, {centroid as centroidFromPointers} from './Pointer.js';
|
||||
import {disable} from '../rotationconstraint.js';
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {number} [duration=250] The duration of the animation in
|
||||
@@ -13,7 +14,6 @@ import {disable} from '../rotationconstraint.js';
|
||||
* @property {number} [threshold=0.3] Minimal angle in radians to start a rotation.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to rotate the map by twisting with two fingers
|
||||
@@ -25,7 +25,6 @@ class PinchRotate extends PointerInteraction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
|
||||
@@ -71,7 +70,6 @@ class PinchRotate extends PointerInteraction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.duration_ = options.duration !== undefined ? options.duration : 250;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,13 +85,13 @@ class PinchRotate extends PointerInteraction {
|
||||
// angle between touches
|
||||
const angle = Math.atan2(
|
||||
touch1.clientY - touch0.clientY,
|
||||
touch1.clientX - touch0.clientX);
|
||||
touch1.clientX - touch0.clientX
|
||||
);
|
||||
|
||||
if (this.lastAngle_ !== undefined) {
|
||||
const delta = angle - this.lastAngle_;
|
||||
this.rotationDelta_ += delta;
|
||||
if (!this.rotating_ &&
|
||||
Math.abs(this.rotationDelta_) > this.threshold_) {
|
||||
if (!this.rotating_ && Math.abs(this.rotationDelta_) > this.threshold_) {
|
||||
this.rotating_ = true;
|
||||
}
|
||||
rotationDelta = delta;
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
/**
|
||||
* @module ol/interaction/PinchZoom
|
||||
*/
|
||||
import PointerInteraction, {
|
||||
centroid as centroidFromPointers,
|
||||
} from './Pointer.js';
|
||||
import {FALSE} from '../functions.js';
|
||||
import PointerInteraction, {centroid as centroidFromPointers} from './Pointer.js';
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {number} [duration=400] Animation duration in milliseconds.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Allows the user to zoom the map by pinching with two fingers
|
||||
@@ -22,7 +22,6 @@ class PinchZoom extends PointerInteraction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
|
||||
@@ -56,7 +55,6 @@ class PinchZoom extends PointerInteraction {
|
||||
* @type {number}
|
||||
*/
|
||||
this.lastScaleDelta_ = 1;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +77,6 @@ class PinchZoom extends PointerInteraction {
|
||||
}
|
||||
this.lastDistance_ = distance;
|
||||
|
||||
|
||||
const map = mapBrowserEvent.map;
|
||||
const view = map.getView();
|
||||
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
/**
|
||||
* @module ol/interaction/Pointer
|
||||
*/
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import Interaction from './Interaction.js';
|
||||
import MapBrowserEventType from '../MapBrowserEventType.js';
|
||||
import {getValues} from '../obj.js';
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {function(import("../MapBrowserPointerEvent.js").default):boolean} [handleDownEvent]
|
||||
@@ -33,7 +32,6 @@ import {getValues} from '../obj.js';
|
||||
* stopped?
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Base class that calls user-defined functions on `down`, `move` and `up`
|
||||
@@ -50,10 +48,11 @@ class PointerInteraction extends Interaction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
super(/** @type {import("./Interaction.js").InteractionOptions} */ (options));
|
||||
super(
|
||||
/** @type {import("./Interaction.js").InteractionOptions} */ (options)
|
||||
);
|
||||
|
||||
if (options.handleDownEvent) {
|
||||
this.handleDownEvent = options.handleDownEvent;
|
||||
@@ -92,7 +91,6 @@ class PointerInteraction extends Interaction {
|
||||
* @protected
|
||||
*/
|
||||
this.targetPointers = [];
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -142,7 +140,8 @@ class PointerInteraction extends Interaction {
|
||||
this.handleDragEvent(mapBrowserEvent);
|
||||
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {
|
||||
const handledUp = this.handleUpEvent(mapBrowserEvent);
|
||||
this.handlingDownUpSequence = handledUp && this.targetPointers.length > 0;
|
||||
this.handlingDownUpSequence =
|
||||
handledUp && this.targetPointers.length > 0;
|
||||
}
|
||||
} else {
|
||||
if (mapBrowserEvent.type == MapBrowserEventType.POINTERDOWN) {
|
||||
@@ -194,8 +193,7 @@ class PointerInteraction extends Interaction {
|
||||
const id = event.pointerId.toString();
|
||||
if (mapBrowserEvent.type == MapBrowserEventType.POINTERUP) {
|
||||
delete this.trackedPointers_[id];
|
||||
} else if (mapBrowserEvent.type ==
|
||||
MapBrowserEventType.POINTERDOWN) {
|
||||
} else if (mapBrowserEvent.type == MapBrowserEventType.POINTERDOWN) {
|
||||
this.trackedPointers_[id] = event;
|
||||
} else if (id in this.trackedPointers_) {
|
||||
// update only when there was a pointerdown event for this pointer
|
||||
@@ -204,10 +202,8 @@ class PointerInteraction extends Interaction {
|
||||
this.targetPointers = getValues(this.trackedPointers_);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {Array<PointerEvent>} pointerEvents List of events.
|
||||
* @return {import("../pixel.js").Pixel} Centroid pixel.
|
||||
@@ -223,7 +219,6 @@ export function centroid(pointerEvents) {
|
||||
return [clientX / length, clientY / length];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {import("../MapBrowserPointerEvent.js").default} mapBrowserEvent Event.
|
||||
* @return {boolean} Whether the event is a pointerdown, pointerdrag
|
||||
@@ -231,10 +226,11 @@ export function centroid(pointerEvents) {
|
||||
*/
|
||||
function isPointerDraggingEvent(mapBrowserEvent) {
|
||||
const type = mapBrowserEvent.type;
|
||||
return type === MapBrowserEventType.POINTERDOWN ||
|
||||
return (
|
||||
type === MapBrowserEventType.POINTERDOWN ||
|
||||
type === MapBrowserEventType.POINTERDRAG ||
|
||||
type === MapBrowserEventType.POINTERUP;
|
||||
type === MapBrowserEventType.POINTERUP
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
export default PointerInteraction;
|
||||
|
||||
@@ -6,5 +6,5 @@
|
||||
* @enum {string}
|
||||
*/
|
||||
export default {
|
||||
ACTIVE: 'active'
|
||||
ACTIVE: 'active',
|
||||
};
|
||||
|
||||
+102
-73
@@ -1,18 +1,17 @@
|
||||
/**
|
||||
* @module ol/interaction/Select
|
||||
*/
|
||||
import {getUid} from '../util.js';
|
||||
import Collection from '../Collection.js';
|
||||
import CollectionEventType from '../CollectionEventType.js';
|
||||
import {extend, includes} from '../array.js';
|
||||
import Event from '../events/Event.js';
|
||||
import {singleClick, never, shiftKeyOnly} from '../events/condition.js';
|
||||
import {TRUE} from '../functions.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import Interaction from './Interaction.js';
|
||||
import {TRUE} from '../functions.js';
|
||||
import {clear} from '../obj.js';
|
||||
import {createEditingStyle} from '../style/Style.js';
|
||||
import Collection from '../Collection.js';
|
||||
|
||||
import {extend, includes} from '../array.js';
|
||||
import {getUid} from '../util.js';
|
||||
import {never, shiftKeyOnly, singleClick} from '../events/condition.js';
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
@@ -23,10 +22,9 @@ const SelectEventType = {
|
||||
* @event SelectEvent#select
|
||||
* @api
|
||||
*/
|
||||
SELECT: 'select'
|
||||
SELECT: 'select',
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A function that takes an {@link module:ol/Feature} or
|
||||
* {@link module:ol/render/Feature} and an
|
||||
@@ -35,7 +33,6 @@ const SelectEventType = {
|
||||
* @typedef {function(import("../Feature.js").FeatureLike, import("../layer/Layer.js").default):boolean} FilterFunction
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("../events/condition.js").Condition} [addCondition] A function
|
||||
@@ -91,7 +88,6 @@ const SelectEventType = {
|
||||
* the radius around the given position will be checked for features.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/Select~Select} instances are instances of
|
||||
@@ -128,9 +124,7 @@ class SelectEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -139,7 +133,6 @@ class SelectEvent extends Event {
|
||||
*/
|
||||
const originalFeatureStyles = {};
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Interaction for selecting vector features. By default, selected features are
|
||||
@@ -160,9 +153,8 @@ class Select extends Interaction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
super({
|
||||
handleEvent: handleEvent
|
||||
handleEvent: handleEvent,
|
||||
});
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
@@ -193,13 +185,17 @@ class Select extends Interaction {
|
||||
* @private
|
||||
* @type {import("../events/condition.js").Condition}
|
||||
*/
|
||||
this.removeCondition_ = options.removeCondition ? options.removeCondition : never;
|
||||
this.removeCondition_ = options.removeCondition
|
||||
? options.removeCondition
|
||||
: never;
|
||||
|
||||
/**
|
||||
* @private
|
||||
* @type {import("../events/condition.js").Condition}
|
||||
*/
|
||||
this.toggleCondition_ = options.toggleCondition ? options.toggleCondition : shiftKeyOnly;
|
||||
this.toggleCondition_ = options.toggleCondition
|
||||
? options.toggleCondition
|
||||
: shiftKeyOnly;
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -223,7 +219,8 @@ class Select extends Interaction {
|
||||
* @private
|
||||
* @type {import("../style/Style.js").default|Array.<import("../style/Style.js").default>|import("../style/Style.js").StyleFunction|null}
|
||||
*/
|
||||
this.style_ = options.style !== undefined ? options.style : getDefaultStyleFunction();
|
||||
this.style_ =
|
||||
options.style !== undefined ? options.style : getDefaultStyleFunction();
|
||||
|
||||
/**
|
||||
* @private
|
||||
@@ -238,7 +235,7 @@ class Select extends Interaction {
|
||||
layerFilter = options.layers;
|
||||
} else {
|
||||
const layers = options.layers;
|
||||
layerFilter = function(layer) {
|
||||
layerFilter = function (layer) {
|
||||
return includes(layers, layer);
|
||||
};
|
||||
}
|
||||
@@ -298,9 +295,8 @@ class Select extends Interaction {
|
||||
* @api
|
||||
*/
|
||||
getLayer(feature) {
|
||||
return (
|
||||
/** @type {import('../layer/Vector.js').default} */ (this.featureLayerAssociation_[getUid(feature)])
|
||||
);
|
||||
return /** @type {import('../layer/Vector.js').default} */ (this
|
||||
.featureLayerAssociation_[getUid(feature)]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -326,15 +322,27 @@ class Select extends Interaction {
|
||||
}
|
||||
super.setMap(map);
|
||||
if (map) {
|
||||
this.features_.addEventListener(CollectionEventType.ADD, this.boundAddFeature_);
|
||||
this.features_.addEventListener(CollectionEventType.REMOVE, this.boundRemoveFeature_);
|
||||
this.features_.addEventListener(
|
||||
CollectionEventType.ADD,
|
||||
this.boundAddFeature_
|
||||
);
|
||||
this.features_.addEventListener(
|
||||
CollectionEventType.REMOVE,
|
||||
this.boundRemoveFeature_
|
||||
);
|
||||
|
||||
if (this.style_) {
|
||||
this.features_.forEach(this.applySelectedStyle_.bind(this));
|
||||
}
|
||||
} else {
|
||||
this.features_.removeEventListener(CollectionEventType.ADD, this.boundAddFeature_);
|
||||
this.features_.removeEventListener(CollectionEventType.REMOVE, this.boundRemoveFeature_);
|
||||
this.features_.removeEventListener(
|
||||
CollectionEventType.ADD,
|
||||
this.boundAddFeature_
|
||||
);
|
||||
this.features_.removeEventListener(
|
||||
CollectionEventType.REMOVE,
|
||||
this.boundRemoveFeature_
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -385,11 +393,20 @@ class Select extends Interaction {
|
||||
*/
|
||||
restorePreviousStyle_(feature) {
|
||||
const key = getUid(feature);
|
||||
const selectInteractions = /** @type {Array<Select>} */ (this.getMap().getInteractions().getArray().filter(function(interaction) {
|
||||
return interaction instanceof Select && interaction.getStyle() && interaction.getFeatures().getArray().indexOf(feature) !== -1;
|
||||
}));
|
||||
const selectInteractions = /** @type {Array<Select>} */ (this.getMap()
|
||||
.getInteractions()
|
||||
.getArray()
|
||||
.filter(function (interaction) {
|
||||
return (
|
||||
interaction instanceof Select &&
|
||||
interaction.getStyle() &&
|
||||
interaction.getFeatures().getArray().indexOf(feature) !== -1
|
||||
);
|
||||
}));
|
||||
if (selectInteractions.length > 0) {
|
||||
feature.setStyle(selectInteractions[selectInteractions.length - 1].getStyle());
|
||||
feature.setStyle(
|
||||
selectInteractions[selectInteractions.length - 1].getStyle()
|
||||
);
|
||||
} else {
|
||||
feature.setStyle(originalFeatureStyles[key]);
|
||||
delete originalFeatureStyles[key];
|
||||
@@ -405,7 +422,6 @@ class Select extends Interaction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the {@link module:ol/MapBrowserEvent map browser event} and may change the
|
||||
* selected state of features.
|
||||
@@ -430,23 +446,25 @@ function handleEvent(mapBrowserEvent) {
|
||||
// pixel, or clear the selected feature(s) if there is no feature at
|
||||
// the pixel.
|
||||
clear(this.featureLayerAssociation_);
|
||||
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
|
||||
(
|
||||
/**
|
||||
* @param {import("../Feature.js").FeatureLike} feature Feature.
|
||||
* @param {import("../layer/Layer.js").default} layer Layer.
|
||||
* @return {boolean|undefined} Continue to iterate over the features.
|
||||
*/
|
||||
function(feature, layer) {
|
||||
if (this.filter_(feature, layer)) {
|
||||
selected.push(feature);
|
||||
this.addFeatureLayerAssociation_(feature, layer);
|
||||
return !this.multi_;
|
||||
}
|
||||
}).bind(this), {
|
||||
map.forEachFeatureAtPixel(
|
||||
mapBrowserEvent.pixel,
|
||||
/**
|
||||
* @param {import("../Feature.js").FeatureLike} feature Feature.
|
||||
* @param {import("../layer/Layer.js").default} layer Layer.
|
||||
* @return {boolean|undefined} Continue to iterate over the features.
|
||||
*/
|
||||
function (feature, layer) {
|
||||
if (this.filter_(feature, layer)) {
|
||||
selected.push(feature);
|
||||
this.addFeatureLayerAssociation_(feature, layer);
|
||||
return !this.multi_;
|
||||
}
|
||||
}.bind(this),
|
||||
{
|
||||
layerFilter: this.layerFilter_,
|
||||
hitTolerance: this.hitTolerance_
|
||||
});
|
||||
hitTolerance: this.hitTolerance_,
|
||||
}
|
||||
);
|
||||
for (let i = features.getLength() - 1; i >= 0; --i) {
|
||||
const feature = features.item(i);
|
||||
const index = selected.indexOf(feature);
|
||||
@@ -463,28 +481,33 @@ function handleEvent(mapBrowserEvent) {
|
||||
}
|
||||
} else {
|
||||
// Modify the currently selected feature(s).
|
||||
map.forEachFeatureAtPixel(mapBrowserEvent.pixel,
|
||||
(
|
||||
/**
|
||||
* @param {import("../Feature.js").FeatureLike} feature Feature.
|
||||
* @param {import("../layer/Layer.js").default} layer Layer.
|
||||
* @return {boolean|undefined} Continue to iterate over the features.
|
||||
*/
|
||||
function(feature, layer) {
|
||||
if (this.filter_(feature, layer)) {
|
||||
if ((add || toggle) && !includes(features.getArray(), feature)) {
|
||||
selected.push(feature);
|
||||
this.addFeatureLayerAssociation_(feature, layer);
|
||||
} else if ((remove || toggle) && includes(features.getArray(), feature)) {
|
||||
deselected.push(feature);
|
||||
this.removeFeatureLayerAssociation_(feature);
|
||||
}
|
||||
return !this.multi_;
|
||||
map.forEachFeatureAtPixel(
|
||||
mapBrowserEvent.pixel,
|
||||
/**
|
||||
* @param {import("../Feature.js").FeatureLike} feature Feature.
|
||||
* @param {import("../layer/Layer.js").default} layer Layer.
|
||||
* @return {boolean|undefined} Continue to iterate over the features.
|
||||
*/
|
||||
function (feature, layer) {
|
||||
if (this.filter_(feature, layer)) {
|
||||
if ((add || toggle) && !includes(features.getArray(), feature)) {
|
||||
selected.push(feature);
|
||||
this.addFeatureLayerAssociation_(feature, layer);
|
||||
} else if (
|
||||
(remove || toggle) &&
|
||||
includes(features.getArray(), feature)
|
||||
) {
|
||||
deselected.push(feature);
|
||||
this.removeFeatureLayerAssociation_(feature);
|
||||
}
|
||||
}).bind(this), {
|
||||
return !this.multi_;
|
||||
}
|
||||
}.bind(this),
|
||||
{
|
||||
layerFilter: this.layerFilter_,
|
||||
hitTolerance: this.hitTolerance_
|
||||
});
|
||||
hitTolerance: this.hitTolerance_,
|
||||
}
|
||||
);
|
||||
for (let j = deselected.length - 1; j >= 0; --j) {
|
||||
features.remove(deselected[j]);
|
||||
}
|
||||
@@ -492,22 +515,29 @@ function handleEvent(mapBrowserEvent) {
|
||||
}
|
||||
if (selected.length > 0 || deselected.length > 0) {
|
||||
this.dispatchEvent(
|
||||
new SelectEvent(SelectEventType.SELECT,
|
||||
selected, deselected, mapBrowserEvent));
|
||||
new SelectEvent(
|
||||
SelectEventType.SELECT,
|
||||
selected,
|
||||
deselected,
|
||||
mapBrowserEvent
|
||||
)
|
||||
);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return {import("../style/Style.js").StyleFunction} Styles.
|
||||
*/
|
||||
function getDefaultStyleFunction() {
|
||||
const styles = createEditingStyle();
|
||||
extend(styles[GeometryType.POLYGON], styles[GeometryType.LINE_STRING]);
|
||||
extend(styles[GeometryType.GEOMETRY_COLLECTION], styles[GeometryType.LINE_STRING]);
|
||||
extend(
|
||||
styles[GeometryType.GEOMETRY_COLLECTION],
|
||||
styles[GeometryType.LINE_STRING]
|
||||
);
|
||||
|
||||
return function(feature) {
|
||||
return function (feature) {
|
||||
if (!feature.getGeometry()) {
|
||||
return null;
|
||||
}
|
||||
@@ -515,5 +545,4 @@ function getDefaultStyleFunction() {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export default Select;
|
||||
|
||||
+117
-65
@@ -1,21 +1,30 @@
|
||||
/**
|
||||
* @module ol/interaction/Snap
|
||||
*/
|
||||
import {getUid} from '../util.js';
|
||||
import CollectionEventType from '../CollectionEventType.js';
|
||||
import {distance as coordinateDistance, squaredDistance as squaredCoordinateDistance, closestOnCircle, closestOnSegment, squaredDistanceToSegment} from '../coordinate.js';
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
import EventType from '../events/EventType.js';
|
||||
import {boundingExtent, createEmpty} from '../extent.js';
|
||||
import {TRUE, FALSE} from '../functions.js';
|
||||
import GeometryType from '../geom/GeometryType.js';
|
||||
import {fromCircle} from '../geom/Polygon.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import {getValues} from '../obj.js';
|
||||
import VectorEventType from '../source/VectorEventType.js';
|
||||
import RBush from '../structs/RBush.js';
|
||||
import {getUserProjection, fromUserCoordinate, toUserCoordinate} from '../proj.js';
|
||||
|
||||
import VectorEventType from '../source/VectorEventType.js';
|
||||
import {FALSE, TRUE} from '../functions.js';
|
||||
import {boundingExtent, createEmpty} from '../extent.js';
|
||||
import {
|
||||
closestOnCircle,
|
||||
closestOnSegment,
|
||||
distance as coordinateDistance,
|
||||
squaredDistance as squaredCoordinateDistance,
|
||||
squaredDistanceToSegment,
|
||||
} from '../coordinate.js';
|
||||
import {fromCircle} from '../geom/Polygon.js';
|
||||
import {
|
||||
fromUserCoordinate,
|
||||
getUserProjection,
|
||||
toUserCoordinate,
|
||||
} from '../proj.js';
|
||||
import {getUid} from '../util.js';
|
||||
import {getValues} from '../obj.js';
|
||||
import {listen, unlistenByKey} from '../events.js';
|
||||
|
||||
/**
|
||||
* @typedef {Object} Result
|
||||
@@ -24,14 +33,12 @@ import {getUserProjection, fromUserCoordinate, toUserCoordinate} from '../proj.j
|
||||
* @property {import("../pixel.js").Pixel|null} vertexPixel
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} SegmentData
|
||||
* @property {import("../Feature.js").default} feature
|
||||
* @property {Array<import("../coordinate.js").Coordinate>} segment
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @typedef {Object} Options
|
||||
* @property {import("../Collection.js").default<import("../Feature.js").default>} [features] Snap to these features. Either this option or source should be provided.
|
||||
@@ -42,16 +49,22 @@ import {getUserProjection, fromUserCoordinate, toUserCoordinate} from '../proj.j
|
||||
* @property {import("../source/Vector.js").default} [source] Snap to features from this source. Either this option or features should be provided
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @param {import("../source/Vector.js").VectorSourceEvent|import("../Collection.js").CollectionEvent} evt Event.
|
||||
* @return {import("../Feature.js").default} Feature.
|
||||
*/
|
||||
function getFeatureFromEvent(evt) {
|
||||
if (/** @type {import("../source/Vector.js").VectorSourceEvent} */ (evt).feature) {
|
||||
return /** @type {import("../source/Vector.js").VectorSourceEvent} */ (evt).feature;
|
||||
} else if (/** @type {import("../Collection.js").CollectionEvent} */ (evt).element) {
|
||||
return /** @type {import("../Feature.js").default} */ (/** @type {import("../Collection.js").CollectionEvent} */ (evt).element);
|
||||
if (
|
||||
/** @type {import("../source/Vector.js").VectorSourceEvent} */ (evt).feature
|
||||
) {
|
||||
return /** @type {import("../source/Vector.js").VectorSourceEvent} */ (evt)
|
||||
.feature;
|
||||
} else if (
|
||||
/** @type {import("../Collection.js").CollectionEvent} */ (evt).element
|
||||
) {
|
||||
return /** @type {import("../Feature.js").default} */ (
|
||||
/** @type {import("../Collection.js").CollectionEvent} */ (evt).element
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +98,6 @@ class Snap extends PointerInteraction {
|
||||
* @param {Options=} opt_options Options.
|
||||
*/
|
||||
constructor(opt_options) {
|
||||
|
||||
const options = opt_options ? opt_options : {};
|
||||
|
||||
const pointerOptions = /** @type {import("./Pointer.js").Options} */ (options);
|
||||
@@ -157,21 +169,21 @@ class Snap extends PointerInteraction {
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.pixelTolerance_ = options.pixelTolerance !== undefined ?
|
||||
options.pixelTolerance : 10;
|
||||
this.pixelTolerance_ =
|
||||
options.pixelTolerance !== undefined ? options.pixelTolerance : 10;
|
||||
|
||||
/**
|
||||
* Segment RTree for each layer
|
||||
* @type {import("../structs/RBush.js").default<SegmentData>}
|
||||
* @private
|
||||
*/
|
||||
* Segment RTree for each layer
|
||||
* @type {import("../structs/RBush.js").default<SegmentData>}
|
||||
* @private
|
||||
*/
|
||||
this.rBush_ = new RBush();
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @private
|
||||
* @type {Object<string, function(import("../Feature.js").default, import("../geom/Geometry.js").default): void>}
|
||||
*/
|
||||
* @const
|
||||
* @private
|
||||
* @type {Object<string, function(import("../Feature.js").default, import("../geom/Geometry.js").default): void>}
|
||||
*/
|
||||
this.SEGMENT_WRITERS_ = {
|
||||
'Point': this.writePointGeometry_.bind(this),
|
||||
'LineString': this.writeLineStringGeometry_.bind(this),
|
||||
@@ -181,7 +193,7 @@ class Snap extends PointerInteraction {
|
||||
'MultiLineString': this.writeMultiLineStringGeometry_.bind(this),
|
||||
'MultiPolygon': this.writeMultiPolygonGeometry_.bind(this),
|
||||
'GeometryCollection': this.writeGeometryCollectionGeometry_.bind(this),
|
||||
'Circle': this.writeCircleGeometry_.bind(this)
|
||||
'Circle': this.writeCircleGeometry_.bind(this),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -199,7 +211,9 @@ class Snap extends PointerInteraction {
|
||||
if (geometry) {
|
||||
const segmentWriter = this.SEGMENT_WRITERS_[geometry.getType()];
|
||||
if (segmentWriter) {
|
||||
this.indexedFeaturesExtents_[feature_uid] = geometry.getExtent(createEmpty());
|
||||
this.indexedFeaturesExtents_[feature_uid] = geometry.getExtent(
|
||||
createEmpty()
|
||||
);
|
||||
segmentWriter(feature, geometry);
|
||||
}
|
||||
}
|
||||
@@ -208,7 +222,9 @@ class Snap extends PointerInteraction {
|
||||
this.featureChangeListenerKeys_[feature_uid] = listen(
|
||||
feature,
|
||||
EventType.CHANGE,
|
||||
this.handleFeatureChange_, this);
|
||||
this.handleFeatureChange_,
|
||||
this
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -317,7 +333,7 @@ class Snap extends PointerInteraction {
|
||||
if (extent) {
|
||||
const rBush = this.rBush_;
|
||||
const nodesToRemove = [];
|
||||
rBush.forEachInExtent(extent, function(node) {
|
||||
rBush.forEachInExtent(extent, function (node) {
|
||||
if (feature === node.feature) {
|
||||
nodesToRemove.push(node);
|
||||
}
|
||||
@@ -354,17 +370,33 @@ class Snap extends PointerInteraction {
|
||||
if (map) {
|
||||
if (this.features_) {
|
||||
keys.push(
|
||||
listen(this.features_, CollectionEventType.ADD,
|
||||
this.handleFeatureAdd_, this),
|
||||
listen(this.features_, CollectionEventType.REMOVE,
|
||||
this.handleFeatureRemove_, this)
|
||||
listen(
|
||||
this.features_,
|
||||
CollectionEventType.ADD,
|
||||
this.handleFeatureAdd_,
|
||||
this
|
||||
),
|
||||
listen(
|
||||
this.features_,
|
||||
CollectionEventType.REMOVE,
|
||||
this.handleFeatureRemove_,
|
||||
this
|
||||
)
|
||||
);
|
||||
} else if (this.source_) {
|
||||
keys.push(
|
||||
listen(this.source_, VectorEventType.ADDFEATURE,
|
||||
this.handleFeatureAdd_, this),
|
||||
listen(this.source_, VectorEventType.REMOVEFEATURE,
|
||||
this.handleFeatureRemove_, this)
|
||||
listen(
|
||||
this.source_,
|
||||
VectorEventType.ADDFEATURE,
|
||||
this.handleFeatureAdd_,
|
||||
this
|
||||
),
|
||||
listen(
|
||||
this.source_,
|
||||
VectorEventType.REMOVEFEATURE,
|
||||
this.handleFeatureRemove_,
|
||||
this
|
||||
)
|
||||
);
|
||||
}
|
||||
features.forEach(this.forEachFeatureAdd_.bind(this));
|
||||
@@ -378,19 +410,22 @@ class Snap extends PointerInteraction {
|
||||
* @return {Result} Snap result
|
||||
*/
|
||||
snapTo(pixel, pixelCoordinate, map) {
|
||||
const lowerLeft = map.getCoordinateFromPixel(
|
||||
[pixel[0] - this.pixelTolerance_, pixel[1] + this.pixelTolerance_]);
|
||||
const upperRight = map.getCoordinateFromPixel(
|
||||
[pixel[0] + this.pixelTolerance_, pixel[1] - this.pixelTolerance_]);
|
||||
const lowerLeft = map.getCoordinateFromPixel([
|
||||
pixel[0] - this.pixelTolerance_,
|
||||
pixel[1] + this.pixelTolerance_,
|
||||
]);
|
||||
const upperRight = map.getCoordinateFromPixel([
|
||||
pixel[0] + this.pixelTolerance_,
|
||||
pixel[1] - this.pixelTolerance_,
|
||||
]);
|
||||
const box = boundingExtent([lowerLeft, upperRight]);
|
||||
|
||||
let segments = this.rBush_.getInExtent(box);
|
||||
|
||||
// If snapping on vertices only, don't consider circles
|
||||
if (this.vertex_ && !this.edge_) {
|
||||
segments = segments.filter(function(segment) {
|
||||
return segment.feature.getGeometry().getType() !==
|
||||
GeometryType.CIRCLE;
|
||||
segments = segments.filter(function (segment) {
|
||||
return segment.feature.getGeometry().getType() !== GeometryType.CIRCLE;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -402,7 +437,7 @@ class Snap extends PointerInteraction {
|
||||
return {
|
||||
snapped: snapped,
|
||||
vertex: vertex,
|
||||
vertexPixel: vertexPixel
|
||||
vertexPixel: vertexPixel,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -431,23 +466,36 @@ class Snap extends PointerInteraction {
|
||||
const dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
if (dist <= this.pixelTolerance_) {
|
||||
snapped = true;
|
||||
vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];
|
||||
vertex =
|
||||
squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
}
|
||||
} else if (this.edge_) {
|
||||
const isCircle = closestSegmentData.feature.getGeometry().getType() === GeometryType.CIRCLE;
|
||||
const isCircle =
|
||||
closestSegmentData.feature.getGeometry().getType() ===
|
||||
GeometryType.CIRCLE;
|
||||
if (isCircle) {
|
||||
let circleGeometry = closestSegmentData.feature.getGeometry();
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
circleGeometry = circleGeometry.clone().transform(userProjection, projection);
|
||||
circleGeometry = circleGeometry
|
||||
.clone()
|
||||
.transform(userProjection, projection);
|
||||
}
|
||||
vertex = toUserCoordinate(closestOnCircle(projectedCoordinate,
|
||||
/** @type {import("../geom/Circle.js").default} */ (circleGeometry)), projection);
|
||||
vertex = toUserCoordinate(
|
||||
closestOnCircle(
|
||||
projectedCoordinate,
|
||||
/** @type {import("../geom/Circle.js").default} */ (circleGeometry)
|
||||
),
|
||||
projection
|
||||
);
|
||||
} else {
|
||||
tempSegment[0] = fromUserCoordinate(closestSegment[0], projection);
|
||||
tempSegment[1] = fromUserCoordinate(closestSegment[1], projection);
|
||||
vertex = toUserCoordinate(closestOnSegment(projectedCoordinate, tempSegment), projection);
|
||||
vertex = toUserCoordinate(
|
||||
closestOnSegment(projectedCoordinate, tempSegment),
|
||||
projection
|
||||
);
|
||||
}
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
|
||||
@@ -460,7 +508,10 @@ class Snap extends PointerInteraction {
|
||||
const squaredDist2 = squaredCoordinateDistance(vertexPixel, pixel2);
|
||||
const dist = Math.sqrt(Math.min(squaredDist1, squaredDist2));
|
||||
if (dist <= this.pixelTolerance_) {
|
||||
vertex = squaredDist1 > squaredDist2 ? closestSegment[1] : closestSegment[0];
|
||||
vertex =
|
||||
squaredDist1 > squaredDist2
|
||||
? closestSegment[1]
|
||||
: closestSegment[0];
|
||||
vertexPixel = map.getPixelFromCoordinate(vertex);
|
||||
}
|
||||
}
|
||||
@@ -474,7 +525,7 @@ class Snap extends PointerInteraction {
|
||||
return {
|
||||
snapped: snapped,
|
||||
vertex: vertex,
|
||||
vertexPixel: vertexPixel
|
||||
vertexPixel: vertexPixel,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -497,7 +548,9 @@ class Snap extends PointerInteraction {
|
||||
let circleGeometry = geometry;
|
||||
const userProjection = getUserProjection();
|
||||
if (userProjection) {
|
||||
circleGeometry = /** @type {import("../geom/Circle.js").default} */ (circleGeometry.clone().transform(userProjection, projection));
|
||||
circleGeometry = /** @type {import("../geom/Circle.js").default} */ (circleGeometry
|
||||
.clone()
|
||||
.transform(userProjection, projection));
|
||||
}
|
||||
const polygon = fromCircle(circleGeometry);
|
||||
if (userProjection) {
|
||||
@@ -508,7 +561,7 @@ class Snap extends PointerInteraction {
|
||||
const segment = coordinates.slice(i, i + 2);
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
}
|
||||
@@ -540,7 +593,7 @@ class Snap extends PointerInteraction {
|
||||
const segment = coordinates.slice(i, i + 2);
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
}
|
||||
@@ -559,7 +612,7 @@ class Snap extends PointerInteraction {
|
||||
const segment = coordinates.slice(i, i + 2);
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
}
|
||||
@@ -577,7 +630,7 @@ class Snap extends PointerInteraction {
|
||||
const coordinates = points[i];
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: [coordinates, coordinates]
|
||||
segment: [coordinates, coordinates],
|
||||
};
|
||||
this.rBush_.insert(geometry.getExtent(), segmentData);
|
||||
}
|
||||
@@ -598,7 +651,7 @@ class Snap extends PointerInteraction {
|
||||
const segment = coordinates.slice(i, i + 2);
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
}
|
||||
@@ -615,7 +668,7 @@ class Snap extends PointerInteraction {
|
||||
const coordinates = geometry.getCoordinates();
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: [coordinates, coordinates]
|
||||
segment: [coordinates, coordinates],
|
||||
};
|
||||
this.rBush_.insert(geometry.getExtent(), segmentData);
|
||||
}
|
||||
@@ -633,7 +686,7 @@ class Snap extends PointerInteraction {
|
||||
const segment = coordinates.slice(i, i + 2);
|
||||
const segmentData = {
|
||||
feature: feature,
|
||||
segment: segment
|
||||
segment: segment,
|
||||
};
|
||||
this.rBush_.insert(boundingExtent(segment), segmentData);
|
||||
}
|
||||
@@ -641,5 +694,4 @@ class Snap extends PointerInteraction {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export default Snap;
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
* @module ol/interaction/Translate
|
||||
*/
|
||||
import Collection from '../Collection.js';
|
||||
import {getChangeEventType} from '../Object.js';
|
||||
import Event from '../events/Event.js';
|
||||
import {TRUE} from '../functions.js';
|
||||
import {includes} from '../array.js';
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import InteractionProperty from './Property.js';
|
||||
|
||||
import PointerInteraction from './Pointer.js';
|
||||
import {TRUE} from '../functions.js';
|
||||
import {getChangeEventType} from '../Object.js';
|
||||
import {includes} from '../array.js';
|
||||
|
||||
/**
|
||||
* @enum {string}
|
||||
@@ -31,7 +30,7 @@ const TranslateEventType = {
|
||||
* @event TranslateEvent#translateend
|
||||
* @api
|
||||
*/
|
||||
TRANSLATEEND: 'translateend'
|
||||
TRANSLATEEND: 'translateend',
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -59,7 +58,6 @@ const TranslateEventType = {
|
||||
* will be checked for features.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Events emitted by {@link module:ol/interaction/Translate~Translate} instances
|
||||
@@ -74,7 +72,6 @@ export class TranslateEvent extends Event {
|
||||
* @param {import("../MapBrowserEvent.js").default} mapBrowserEvent Map browser event.
|
||||
*/
|
||||
constructor(type, features, coordinate, startCoordinate, mapBrowserEvent) {
|
||||
|
||||
super(type);
|
||||
|
||||
/**
|
||||
@@ -106,12 +103,9 @@ export class TranslateEvent extends Event {
|
||||
* @api
|
||||
*/
|
||||
this.mapBrowserEvent = mapBrowserEvent;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @classdesc
|
||||
* Interaction for translating (moving) features.
|
||||
@@ -142,7 +136,6 @@ class Translate extends PointerInteraction {
|
||||
*/
|
||||
this.startCoordinate_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* @type {Collection<import("../Feature.js").default>}
|
||||
* @private
|
||||
@@ -156,7 +149,7 @@ class Translate extends PointerInteraction {
|
||||
layerFilter = options.layers;
|
||||
} else {
|
||||
const layers = options.layers;
|
||||
layerFilter = function(layer) {
|
||||
layerFilter = function (layer) {
|
||||
return includes(layers, layer);
|
||||
};
|
||||
}
|
||||
@@ -188,8 +181,10 @@ class Translate extends PointerInteraction {
|
||||
*/
|
||||
this.lastFeature_ = null;
|
||||
|
||||
this.addEventListener(getChangeEventType(InteractionProperty.ACTIVE), this.handleActiveChanged_);
|
||||
|
||||
this.addEventListener(
|
||||
getChangeEventType(InteractionProperty.ACTIVE),
|
||||
this.handleActiveChanged_
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,8 +203,13 @@ class Translate extends PointerInteraction {
|
||||
|
||||
this.dispatchEvent(
|
||||
new TranslateEvent(
|
||||
TranslateEventType.TRANSLATESTART, features,
|
||||
event.coordinate, this.startCoordinate_, event));
|
||||
TranslateEventType.TRANSLATESTART,
|
||||
features,
|
||||
event.coordinate,
|
||||
this.startCoordinate_,
|
||||
event
|
||||
)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -229,8 +229,13 @@ class Translate extends PointerInteraction {
|
||||
|
||||
this.dispatchEvent(
|
||||
new TranslateEvent(
|
||||
TranslateEventType.TRANSLATEEND, features,
|
||||
event.coordinate, this.startCoordinate_, event));
|
||||
TranslateEventType.TRANSLATEEND,
|
||||
features,
|
||||
event.coordinate,
|
||||
this.startCoordinate_,
|
||||
event
|
||||
)
|
||||
);
|
||||
// cleanup
|
||||
this.startCoordinate_ = null;
|
||||
return true;
|
||||
@@ -250,7 +255,7 @@ class Translate extends PointerInteraction {
|
||||
|
||||
const features = this.features_ || new Collection([this.lastFeature_]);
|
||||
|
||||
features.forEach(function(feature) {
|
||||
features.forEach(function (feature) {
|
||||
const geom = feature.getGeometry();
|
||||
geom.translate(deltaX, deltaY);
|
||||
feature.setGeometry(geom);
|
||||
@@ -259,8 +264,13 @@ class Translate extends PointerInteraction {
|
||||
this.lastCoordinate_ = newCoordinate;
|
||||
this.dispatchEvent(
|
||||
new TranslateEvent(
|
||||
TranslateEventType.TRANSLATING, features,
|
||||
newCoordinate, this.startCoordinate_, event));
|
||||
TranslateEventType.TRANSLATING,
|
||||
features,
|
||||
newCoordinate,
|
||||
this.startCoordinate_,
|
||||
event
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,17 +301,20 @@ class Translate extends PointerInteraction {
|
||||
* @private
|
||||
*/
|
||||
featuresAtPixel_(pixel, map) {
|
||||
return map.forEachFeatureAtPixel(pixel,
|
||||
function(feature, layer) {
|
||||
return map.forEachFeatureAtPixel(
|
||||
pixel,
|
||||
function (feature, layer) {
|
||||
if (this.filter_(feature, layer)) {
|
||||
if (!this.features_ || includes(this.features_.getArray(), feature)) {
|
||||
return feature;
|
||||
}
|
||||
}
|
||||
}.bind(this), {
|
||||
}.bind(this),
|
||||
{
|
||||
layerFilter: this.layerFilter_,
|
||||
hitTolerance: this.hitTolerance_
|
||||
});
|
||||
hitTolerance: this.hitTolerance_,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user