1318 lines
44 KiB
JavaScript
1318 lines
44 KiB
JavaScript
import Circle from '../../../../../src/ol/geom/Circle.js';
|
|
import CircleStyle from '../../../../../src/ol/style/Circle.js';
|
|
import Collection from '../../../../../src/ol/Collection.js';
|
|
import Event from '../../../../../src/ol/events/Event.js';
|
|
import Feature from '../../../../../src/ol/Feature.js';
|
|
import GeometryCollection from '../../../../../src/ol/geom/GeometryCollection.js';
|
|
import LineString from '../../../../../src/ol/geom/LineString.js';
|
|
import Map from '../../../../../src/ol/Map.js';
|
|
import MapBrowserEvent from '../../../../../src/ol/MapBrowserEvent.js';
|
|
import Modify, {ModifyEvent} from '../../../../../src/ol/interaction/Modify.js';
|
|
import Point from '../../../../../src/ol/geom/Point.js';
|
|
import Polygon, {fromExtent} from '../../../../../src/ol/geom/Polygon.js';
|
|
import Snap from '../../../../../src/ol/interaction/Snap.js';
|
|
import VectorLayer from '../../../../../src/ol/layer/Vector.js';
|
|
import VectorSource from '../../../../../src/ol/source/Vector.js';
|
|
import View from '../../../../../src/ol/View.js';
|
|
import {Fill, Style} from '../../../../../src/ol/style.js';
|
|
import {MultiPoint} from '../../../../../src/ol/geom.js';
|
|
import {
|
|
clearUserProjection,
|
|
setUserProjection,
|
|
} from '../../../../../src/ol/proj.js';
|
|
import {
|
|
click,
|
|
doubleClick,
|
|
never,
|
|
} from '../../../../../src/ol/events/condition.js';
|
|
|
|
describe('ol.interaction.Modify', function () {
|
|
let target, map, layer, source, features;
|
|
|
|
const width = 360;
|
|
const height = 180;
|
|
|
|
beforeEach(function (done) {
|
|
target = document.createElement('div');
|
|
|
|
const style = target.style;
|
|
style.position = 'absolute';
|
|
style.left = '-1000px';
|
|
style.top = '-1000px';
|
|
style.width = width + 'px';
|
|
style.height = height + 'px';
|
|
document.body.appendChild(target);
|
|
|
|
features = [
|
|
new Feature({
|
|
geometry: new Polygon([
|
|
[
|
|
[0, 0],
|
|
[10, 20],
|
|
[0, 40],
|
|
[40, 40],
|
|
[40, 0],
|
|
],
|
|
]),
|
|
}),
|
|
];
|
|
|
|
source = new VectorSource({
|
|
features: features,
|
|
});
|
|
|
|
layer = new VectorLayer({source: source});
|
|
|
|
map = new Map({
|
|
target: target,
|
|
layers: [layer],
|
|
view: new View({
|
|
projection: 'EPSG:4326',
|
|
center: [0, 0],
|
|
resolution: 1,
|
|
}),
|
|
});
|
|
|
|
map.once('postrender', function () {
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function () {
|
|
map.dispose();
|
|
document.body.removeChild(target);
|
|
clearUserProjection();
|
|
});
|
|
|
|
/**
|
|
* Simulates a browser event on the map viewport. The client x/y location
|
|
* will be adjusted as if the map were centered at 0,0.
|
|
* @param {string} type Event type.
|
|
* @param {number} x Horizontal offset from map center.
|
|
* @param {number} y Vertical offset from map center.
|
|
* @param {Object} modifiers Lookup of modifier keys.
|
|
* @param {number} button The mouse button.
|
|
*/
|
|
function simulateEvent(type, x, y, modifiers, button) {
|
|
modifiers = modifiers || {};
|
|
const viewport = map.getViewport();
|
|
// calculated in case body has top < 0 (test runner with small window)
|
|
const position = viewport.getBoundingClientRect();
|
|
const pointerEvent = new Event();
|
|
pointerEvent.type = type;
|
|
pointerEvent.target = viewport.firstChild;
|
|
pointerEvent.clientX = position.left + x + width / 2;
|
|
pointerEvent.clientY = position.top + y + height / 2;
|
|
pointerEvent.shiftKey = modifiers.shift || false;
|
|
pointerEvent.altKey = modifiers.alt || false;
|
|
pointerEvent.pointerId = 1;
|
|
pointerEvent.preventDefault = function () {};
|
|
pointerEvent.button = button;
|
|
pointerEvent.isPrimary = true;
|
|
const event = new MapBrowserEvent(type, map, pointerEvent);
|
|
map.handleMapBrowserEvent(event);
|
|
}
|
|
|
|
/**
|
|
* Tracks events triggered by the interaction as well as feature
|
|
* modifications. Helper function to
|
|
* @param {ol.Feature} feature Modified feature.
|
|
* @param {ol.interaction.Modify} interaction The interaction.
|
|
* @return {Array<ModifyEvent|string>} events
|
|
*/
|
|
function trackEvents(feature, interaction) {
|
|
const events = [];
|
|
feature.on('change', function (event) {
|
|
events.push('change');
|
|
});
|
|
interaction.on('modifystart', function (event) {
|
|
events.push(event);
|
|
});
|
|
interaction.on('modifyend', function (event) {
|
|
events.push(event);
|
|
});
|
|
return events;
|
|
}
|
|
|
|
/**
|
|
* Validates the event array to verify proper event sequence. Checks
|
|
* that first and last event are correct ModifyEvents and that feature
|
|
* modifications event are in between.
|
|
* @param {Array<ModifyEvent|string>} events The events.
|
|
* @param {Array<ol.Feature>} features The features.
|
|
*/
|
|
function validateEvents(events, features) {
|
|
const startevent = events[0];
|
|
const endevent = events[events.length - 1];
|
|
|
|
// first event should be modifystart
|
|
expect(startevent).to.be.a(ModifyEvent);
|
|
expect(startevent.type).to.eql('modifystart');
|
|
|
|
// last event should be modifyend
|
|
expect(endevent).to.be.a(ModifyEvent);
|
|
expect(endevent.type).to.eql('modifyend');
|
|
|
|
// make sure we get change events to events array
|
|
expect(events.length > 2).to.be(true);
|
|
// middle events should be feature modification events
|
|
for (let i = 1; i < events.length - 1; i++) {
|
|
expect(events[i]).to.equal('change');
|
|
}
|
|
|
|
// ModifyEvents should include the expected features
|
|
expect(startevent.features.getArray()).to.eql(features);
|
|
expect(endevent.features.getArray()).to.eql(features);
|
|
}
|
|
|
|
describe('constructor', function () {
|
|
it('adds features to the RTree', function () {
|
|
const feature = new Feature(new Point([0, 0]));
|
|
const features = new Collection([feature]);
|
|
const modify = new Modify({
|
|
features: features,
|
|
});
|
|
const rbushEntries = modify.rBush_.getAll();
|
|
expect(rbushEntries.length).to.be(1);
|
|
expect(rbushEntries[0].feature).to.be(feature);
|
|
});
|
|
|
|
it('accepts feature without geometry', function () {
|
|
const feature = new Feature();
|
|
const features = new Collection([feature]);
|
|
const modify = new Modify({
|
|
features: features,
|
|
});
|
|
let rbushEntries = modify.rBush_.getAll();
|
|
expect(rbushEntries.length).to.be(0);
|
|
|
|
feature.setGeometry(new Point([0, 10]));
|
|
rbushEntries = modify.rBush_.getAll();
|
|
expect(rbushEntries.length).to.be(1);
|
|
expect(rbushEntries[0].feature).to.be(feature);
|
|
});
|
|
|
|
it('accepts a source', function () {
|
|
const feature = new Feature(new Point([0, 0]));
|
|
const source = new VectorSource({features: [feature]});
|
|
const modify = new Modify({source: source});
|
|
const rbushEntries = modify.rBush_.getAll();
|
|
expect(rbushEntries.length).to.be(1);
|
|
expect(rbushEntries[0].feature).to.be(feature);
|
|
});
|
|
|
|
it('accepts a hitDetection option', function () {
|
|
const feature = new Feature(new Point([0, 0]));
|
|
const source = new VectorSource({features: [feature]});
|
|
const layer = new VectorLayer({source: source});
|
|
const modify = new Modify({hitDetection: layer, source: source});
|
|
const rbushEntries = modify.rBush_.getAll();
|
|
expect(rbushEntries.length).to.be(1);
|
|
expect(rbushEntries[0].feature).to.be(feature);
|
|
expect(modify.hitDetection_).to.be(layer);
|
|
});
|
|
|
|
it('accepts a snapToPointer option', function () {
|
|
const modify = new Modify({source: source, snapToPointer: true});
|
|
expect(modify.snapToPointer_).to.be(true);
|
|
});
|
|
});
|
|
|
|
describe('vertex deletion', function () {
|
|
it('works when clicking on a shared vertex', function () {
|
|
features.push(features[0].clone());
|
|
|
|
const first = features[0];
|
|
const firstRevision = first.getGeometry().getRevision();
|
|
const second = features[1];
|
|
const secondRevision = second.getGeometry().getRevision();
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const events = trackEvents(first, modify);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision);
|
|
expect(first.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
expect(second.getGeometry().getRevision()).to.equal(secondRevision);
|
|
expect(second.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 10, -20, {alt: true}, 0);
|
|
simulateEvent('pointerup', 10, -20, {alt: true}, 0);
|
|
simulateEvent('click', 10, -20, {alt: true}, 0);
|
|
simulateEvent('singleclick', 10, -20, {alt: true}, 0);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision + 1);
|
|
expect(first.getGeometry().getCoordinates()[0]).to.have.length(4);
|
|
expect(second.getGeometry().getRevision()).to.equal(secondRevision + 1);
|
|
expect(second.getGeometry().getCoordinates()[0]).to.have.length(4);
|
|
|
|
validateEvents(events, features);
|
|
});
|
|
|
|
it('deletes first vertex of a LineString', function () {
|
|
const lineFeature = new Feature({
|
|
geometry: new LineString([
|
|
[0, 0],
|
|
[10, 20],
|
|
[0, 40],
|
|
[40, 40],
|
|
[40, 0],
|
|
]),
|
|
});
|
|
features.length = 0;
|
|
features.push(lineFeature);
|
|
features.push(lineFeature.clone());
|
|
|
|
const first = features[0];
|
|
const firstRevision = first.getGeometry().getRevision();
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const events = trackEvents(first, modify);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision);
|
|
expect(first.getGeometry().getCoordinates()).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 0, 0, {alt: true}, 0);
|
|
simulateEvent('pointerup', 0, 0, {alt: true}, 0);
|
|
simulateEvent('click', 0, 0, {alt: true}, 0);
|
|
simulateEvent('singleclick', 0, 0, {alt: true}, 0);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision + 1);
|
|
expect(first.getGeometry().getCoordinates()).to.have.length(4);
|
|
expect(first.getGeometry().getCoordinates()[0][0]).to.equal(10);
|
|
expect(first.getGeometry().getCoordinates()[0][1]).to.equal(20);
|
|
|
|
validateEvents(events, features);
|
|
});
|
|
|
|
it('deletes last vertex of a LineString', function () {
|
|
const lineFeature = new Feature({
|
|
geometry: new LineString([
|
|
[0, 0],
|
|
[10, 20],
|
|
[0, 40],
|
|
[40, 40],
|
|
[40, 0],
|
|
]),
|
|
});
|
|
features.length = 0;
|
|
features.push(lineFeature);
|
|
features.push(lineFeature.clone());
|
|
|
|
const first = features[0];
|
|
const firstRevision = first.getGeometry().getRevision();
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const events = trackEvents(first, modify);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision);
|
|
expect(first.getGeometry().getCoordinates()).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 40, 0, {alt: true}, 0);
|
|
simulateEvent('pointerup', 40, 0, {alt: true}, 0);
|
|
simulateEvent('click', 40, 0, {alt: true}, 0);
|
|
simulateEvent('singleclick', 40, 0, {alt: true}, 0);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision + 1);
|
|
expect(first.getGeometry().getCoordinates()).to.have.length(4);
|
|
expect(first.getGeometry().getCoordinates()[3][0]).to.equal(40);
|
|
expect(first.getGeometry().getCoordinates()[3][1]).to.equal(40);
|
|
|
|
validateEvents(events, features);
|
|
});
|
|
|
|
it('deletes vertex of a LineString programmatically', function () {
|
|
const lineFeature = new Feature({
|
|
geometry: new LineString([
|
|
[0, 0],
|
|
[10, 20],
|
|
[0, 40],
|
|
[40, 40],
|
|
[40, 0],
|
|
]),
|
|
});
|
|
features.length = 0;
|
|
features.push(lineFeature);
|
|
features.push(lineFeature.clone());
|
|
|
|
const first = features[0];
|
|
const firstRevision = first.getGeometry().getRevision();
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const events = trackEvents(first, modify);
|
|
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision);
|
|
expect(first.getGeometry().getCoordinates()).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 40, 0, null, 0);
|
|
simulateEvent('pointerup', 40, 0, null, 0);
|
|
|
|
const removed = modify.removePoint();
|
|
|
|
expect(removed).to.be(true);
|
|
expect(first.getGeometry().getRevision()).to.equal(firstRevision + 1);
|
|
expect(first.getGeometry().getCoordinates()).to.have.length(4);
|
|
expect(first.getGeometry().getCoordinates()[3][0]).to.equal(40);
|
|
expect(first.getGeometry().getCoordinates()[3][1]).to.equal(40);
|
|
|
|
validateEvents(events, features);
|
|
});
|
|
});
|
|
|
|
describe('vertex modification', function () {
|
|
it('keeps the third dimension', function () {
|
|
const lineFeature = new Feature({
|
|
geometry: new LineString([
|
|
[0, 0, 10],
|
|
[10, 20, 20],
|
|
[0, 40, 30],
|
|
[40, 40, 40],
|
|
[40, 0, 50],
|
|
]),
|
|
});
|
|
features.length = 0;
|
|
features.push(lineFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
// Move first vertex
|
|
simulateEvent('pointermove', 0, 0, null, 0);
|
|
simulateEvent('pointerdown', 0, 0, null, 0);
|
|
simulateEvent('pointermove', -10, -10, null, 0);
|
|
simulateEvent('pointerdrag', -10, -10, null, 0);
|
|
simulateEvent('pointerup', -10, -10, null, 0);
|
|
|
|
// Move middle vertex
|
|
simulateEvent('pointermove', 0, -40, null, 0);
|
|
simulateEvent('pointerdown', 0, -40, null, 0);
|
|
simulateEvent('pointermove', 10, -30, null, 0);
|
|
simulateEvent('pointerdrag', 10, -30, null, 0);
|
|
simulateEvent('pointerup', 10, -30, null, 0);
|
|
|
|
// Move last vertex
|
|
simulateEvent('pointermove', 40, 0, null, 0);
|
|
simulateEvent('pointerdown', 40, 0, null, 0);
|
|
simulateEvent('pointermove', 50, -10, null, 0);
|
|
simulateEvent('pointerdrag', 50, -10, null, 0);
|
|
simulateEvent('pointerup', 50, -10, null, 0);
|
|
|
|
expect(lineFeature.getGeometry().getCoordinates()[0][2]).to.equal(10);
|
|
expect(lineFeature.getGeometry().getCoordinates()[2][2]).to.equal(30);
|
|
expect(lineFeature.getGeometry().getCoordinates()[4][2]).to.equal(50);
|
|
});
|
|
|
|
it('keeps polygon geometries valid', function () {
|
|
const overlappingVertexFeature = new Feature({
|
|
geometry: new Polygon([
|
|
[
|
|
[10, 20],
|
|
[0, 20],
|
|
[0, 0],
|
|
[20, 0],
|
|
[20, 20],
|
|
[10, 20],
|
|
[15, 15],
|
|
[5, 15],
|
|
[10, 20],
|
|
],
|
|
]),
|
|
});
|
|
features.length = 0;
|
|
features.push(overlappingVertexFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
let coords, exteriorRing;
|
|
coords = overlappingVertexFeature.getGeometry().getCoordinates();
|
|
exteriorRing = coords[0];
|
|
|
|
expect(exteriorRing.length).to.equal(9);
|
|
expect(exteriorRing[0]).to.eql(exteriorRing[exteriorRing.length - 1]);
|
|
|
|
// move the overlapping vertice
|
|
simulateEvent('pointermove', 10, -20, null, 0);
|
|
simulateEvent('pointerdown', 10, -20, null, 0);
|
|
simulateEvent('pointermove', 10, -25, null, 0);
|
|
simulateEvent('pointerdrag', 10, -25, null, 0);
|
|
simulateEvent('pointerup', 10, -25, null, 0);
|
|
|
|
coords = overlappingVertexFeature.getGeometry().getCoordinates();
|
|
exteriorRing = coords[0];
|
|
|
|
expect(exteriorRing.length).to.equal(9);
|
|
expect(exteriorRing[0]).to.eql([10, 25]);
|
|
expect(exteriorRing[0]).to.eql(exteriorRing[exteriorRing.length - 1]);
|
|
});
|
|
});
|
|
|
|
describe('vertex insertion', function () {
|
|
it('only inserts one vertex per geometry', function () {
|
|
const lineFeature = new Feature({
|
|
geometry: new LineString([
|
|
[-10, -10],
|
|
[10, 10],
|
|
[-10, -10],
|
|
[10, 10],
|
|
]),
|
|
});
|
|
features.length = 0;
|
|
features.push(lineFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
// Click on line
|
|
simulateEvent('pointermove', 0, 0, null, 0);
|
|
simulateEvent('pointerdown', 0, 0, null, 0);
|
|
simulateEvent('pointerup', 0, 0, null, 0);
|
|
|
|
expect(lineFeature.getGeometry().getCoordinates().length).to.equal(5);
|
|
});
|
|
it('inserts one vertex into both linestrings with duplicate segments each', function () {
|
|
const lineFeature1 = new Feature(
|
|
new LineString([
|
|
[-10, -10],
|
|
[10, 10],
|
|
[-10, -10],
|
|
])
|
|
);
|
|
const lineFeature2 = new Feature(
|
|
new LineString([
|
|
[10, 10],
|
|
[-10, -10],
|
|
[10, 10],
|
|
])
|
|
);
|
|
features.length = 0;
|
|
features.push(lineFeature1, lineFeature2);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
let modifiedFeatures;
|
|
|
|
const onModifyStart = function (evt) {
|
|
modifiedFeatures = evt.features;
|
|
};
|
|
map.addInteraction(modify);
|
|
|
|
modify.on('modifystart', onModifyStart);
|
|
// Click on line
|
|
simulateEvent('pointermove', 0, 0, null, 0);
|
|
simulateEvent('pointerdown', 0, 0, null, 0);
|
|
simulateEvent('pointerup', 0, 0, null, 0);
|
|
modify.un('modifystart', onModifyStart);
|
|
|
|
expect(lineFeature1.getGeometry().getCoordinates().length).to.be(4);
|
|
expect(lineFeature2.getGeometry().getCoordinates().length).to.be(4);
|
|
expect(modifiedFeatures.getArray()).to.eql([lineFeature1, lineFeature2]);
|
|
});
|
|
});
|
|
|
|
describe('circle modification', function () {
|
|
it('changes the circle radius and center', function () {
|
|
const circleFeature = new Feature(new Circle([10, 10], 20));
|
|
features.length = 0;
|
|
features.push(circleFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
// Change center
|
|
simulateEvent('pointermove', 10, -10, null, 0);
|
|
simulateEvent('pointerdown', 10, -10, null, 0);
|
|
simulateEvent('pointermove', 5, -5, null, 0);
|
|
simulateEvent('pointerdrag', 5, -5, null, 0);
|
|
simulateEvent('pointerup', 5, -5, null, 0);
|
|
|
|
expect(circleFeature.getGeometry().getRadius()).to.equal(20);
|
|
expect(circleFeature.getGeometry().getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along x axis
|
|
simulateEvent('pointermove', 25, -4, null, 0);
|
|
simulateEvent('pointerdown', 25, -4, null, 0);
|
|
simulateEvent('pointermove', 30, -5, null, 0);
|
|
simulateEvent('pointerdrag', 30, -5, null, 0);
|
|
simulateEvent('pointerup', 30, -5, null, 0);
|
|
|
|
expect(circleFeature.getGeometry().getRadius()).to.roughlyEqual(25, 0.1);
|
|
expect(circleFeature.getGeometry().getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along y axis
|
|
simulateEvent('pointermove', 4, -30, null, 0);
|
|
simulateEvent('pointerdown', 4, -30, null, 0);
|
|
simulateEvent('pointermove', 5, -35, null, 0);
|
|
simulateEvent('pointerdrag', 5, -35, null, 0);
|
|
simulateEvent('pointerup', 5, -35, null, 0);
|
|
|
|
expect(circleFeature.getGeometry().getRadius()).to.roughlyEqual(30, 0.1);
|
|
expect(circleFeature.getGeometry().getCenter()).to.eql([5, 5]);
|
|
});
|
|
|
|
it('changes the circle radius and center in a user projection', function () {
|
|
const userProjection = 'EPSG:3857';
|
|
setUserProjection(userProjection);
|
|
const viewProjection = map.getView().getProjection();
|
|
|
|
const circleFeature = new Feature(
|
|
new Circle([10, 10], 20).transform(viewProjection, userProjection)
|
|
);
|
|
features.length = 0;
|
|
features.push(circleFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
// Change center
|
|
simulateEvent('pointermove', 10, -10, null, 0);
|
|
simulateEvent('pointerdown', 10, -10, null, 0);
|
|
simulateEvent('pointermove', 5, -5, null, 0);
|
|
simulateEvent('pointerdrag', 5, -5, null, 0);
|
|
simulateEvent('pointerup', 5, -5, null, 0);
|
|
|
|
const geometry1 = circleFeature
|
|
.getGeometry()
|
|
.clone()
|
|
.transform(userProjection, viewProjection);
|
|
expect(geometry1.getRadius()).to.roughlyEqual(20, 1e-9);
|
|
expect(geometry1.getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along x axis
|
|
simulateEvent('pointermove', 25, -4, null, 0);
|
|
simulateEvent('pointerdown', 25, -4, null, 0);
|
|
simulateEvent('pointermove', 30, -5, null, 0);
|
|
simulateEvent('pointerdrag', 30, -5, null, 0);
|
|
simulateEvent('pointerup', 30, -5, null, 0);
|
|
|
|
const geometry2 = circleFeature
|
|
.getGeometry()
|
|
.clone()
|
|
.transform(userProjection, viewProjection);
|
|
expect(geometry2.getRadius()).to.roughlyEqual(25, 0.1);
|
|
expect(geometry2.getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along y axis
|
|
simulateEvent('pointermove', 4, -30, null, 0);
|
|
simulateEvent('pointerdown', 4, -30, null, 0);
|
|
simulateEvent('pointermove', 5, -35, null, 0);
|
|
simulateEvent('pointerdrag', 5, -35, null, 0);
|
|
simulateEvent('pointerup', 5, -35, null, 0);
|
|
|
|
const geometry3 = circleFeature
|
|
.getGeometry()
|
|
.clone()
|
|
.transform(userProjection, viewProjection);
|
|
expect(geometry3.getRadius()).to.roughlyEqual(30, 0.1);
|
|
expect(geometry3.getCenter()).to.eql([5, 5]);
|
|
});
|
|
});
|
|
|
|
describe('boundary modification', function () {
|
|
let modify, feature, events;
|
|
|
|
beforeEach(function () {
|
|
features.push(new Feature(new Point([12, 34])));
|
|
modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
feature = features[0];
|
|
|
|
events = trackEvents(feature, modify);
|
|
});
|
|
|
|
it('clicking vertex should delete it and +r1', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 10, -20, {alt: true}, 0);
|
|
simulateEvent('pointerup', 10, -20, {alt: true}, 0);
|
|
simulateEvent('click', 10, -20, {alt: true}, 0);
|
|
simulateEvent('singleclick', 10, -20, {alt: true}, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(2);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(4);
|
|
|
|
validateEvents(events, [feature]);
|
|
});
|
|
|
|
it('single clicking boundary should add vertex and +r1', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 40, -20, null, 0);
|
|
simulateEvent('pointerup', 40, -20, null, 0);
|
|
simulateEvent('click', 40, -20, null, 0);
|
|
simulateEvent('singleclick', 40, -20, null, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(2);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(6);
|
|
|
|
validateEvents(events, [feature]);
|
|
});
|
|
|
|
it('single clicking on created vertex should delete it again', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 40, -20, null, 0);
|
|
simulateEvent('pointerup', 40, -20, null, 0);
|
|
simulateEvent('click', 40, -20, null, 0);
|
|
simulateEvent('singleclick', 40, -20, null, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(2);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(6);
|
|
|
|
validateEvents(events, [feature]);
|
|
events.length = 0;
|
|
|
|
simulateEvent('pointerdown', 40, -20, {alt: true}, 0);
|
|
simulateEvent('pointerup', 40, -20, {alt: true}, 0);
|
|
simulateEvent('click', 40, -20, {alt: true}, 0);
|
|
simulateEvent('singleclick', 40, -20, {alt: true}, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(3);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
validateEvents(events, [feature]);
|
|
});
|
|
|
|
it('clicking with drag should add vertex and +r3', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointermove', 40, -20, null, 0);
|
|
simulateEvent('pointerdown', 40, -20, null, 0);
|
|
simulateEvent('pointermove', 30, -20, null, 0);
|
|
simulateEvent('pointerdrag', 30, -20, null, 0);
|
|
simulateEvent('pointerup', 30, -20, null, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(4);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(6);
|
|
|
|
validateEvents(events, [feature]);
|
|
});
|
|
|
|
it('clicking with right button should not add a vertex', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointermove', 40, -20, null, 0);
|
|
// right click
|
|
simulateEvent('pointerdown', 40, -20, null, 1);
|
|
simulateEvent('pointermove', 30, -20, null, 1);
|
|
simulateEvent('pointerdrag', 30, -20, null, 1);
|
|
simulateEvent('pointerup', 30, -20, null, 1);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
expect(events).to.have.length(0);
|
|
});
|
|
});
|
|
|
|
describe('geometry collection modification', function () {
|
|
it('all geometries should be modified', function () {
|
|
const firstPolygon = new Polygon([
|
|
[
|
|
[0, 0],
|
|
[1, 0],
|
|
[1, 1],
|
|
[0, 1],
|
|
[0, 0],
|
|
],
|
|
]);
|
|
const secondPolygon = firstPolygon.clone();
|
|
|
|
const firstLineString = new LineString([
|
|
[-2, 0],
|
|
[0, 0],
|
|
[2, 0],
|
|
]);
|
|
const secondLineString = new LineString([
|
|
[0, 2],
|
|
[0, 0],
|
|
[0, -2],
|
|
]);
|
|
|
|
const point = new Point([0, 0]);
|
|
|
|
const circle = new Circle([0, 0], 1);
|
|
|
|
const geometryCollection = new GeometryCollection([
|
|
firstPolygon,
|
|
secondPolygon,
|
|
firstLineString,
|
|
secondLineString,
|
|
point,
|
|
circle,
|
|
]);
|
|
|
|
const feature = new Feature({
|
|
geometry: geometryCollection,
|
|
});
|
|
|
|
features.length = 0;
|
|
features.push(feature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
// Move vertex
|
|
simulateEvent('pointermove', 0, 0, null, 0);
|
|
simulateEvent('pointerdown', 0, 0, null, 0);
|
|
simulateEvent('pointermove', -1, 0, null, 0);
|
|
simulateEvent('pointerdrag', -1, 0, null, 0);
|
|
simulateEvent('pointerup', -1, 0, null, 0);
|
|
|
|
let geomCoords;
|
|
geomCoords = firstPolygon.getCoordinates()[0];
|
|
expect(geomCoords[0][0]).to.equal(-1);
|
|
expect(geomCoords[0][1]).to.equal(0);
|
|
|
|
geomCoords = secondPolygon.getCoordinates()[0];
|
|
expect(geomCoords[0][0]).to.equal(-1);
|
|
expect(geomCoords[0][1]).to.equal(0);
|
|
|
|
geomCoords = firstLineString.getCoordinates();
|
|
expect(geomCoords[1][0]).to.equal(-1);
|
|
expect(geomCoords[1][1]).to.equal(0);
|
|
|
|
geomCoords = secondLineString.getCoordinates();
|
|
expect(geomCoords[1][0]).to.equal(-1);
|
|
expect(geomCoords[1][1]).to.equal(0);
|
|
|
|
geomCoords = point.getCoordinates();
|
|
expect(geomCoords[0]).to.equal(-1);
|
|
expect(geomCoords[1]).to.equal(0);
|
|
|
|
geomCoords = circle.getCenter();
|
|
expect(geomCoords[0]).to.equal(-1);
|
|
expect(geomCoords[1]).to.equal(0);
|
|
});
|
|
});
|
|
|
|
describe('double click deleteCondition', function () {
|
|
let modify, feature, events;
|
|
|
|
beforeEach(function () {
|
|
modify = new Modify({
|
|
features: new Collection(features),
|
|
deleteCondition: doubleClick,
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
feature = features[0];
|
|
|
|
events = trackEvents(feature, modify);
|
|
});
|
|
|
|
it('should delete vertex on double click', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 10, -20, null, 0);
|
|
simulateEvent('pointerup', 10, -20, null, 0);
|
|
simulateEvent('click', 10, -20, null, 0);
|
|
simulateEvent('pointerdown', 10, -20, null, 0);
|
|
simulateEvent('pointerup', 10, -20, null, 0);
|
|
simulateEvent('click', 10, -20, null, 0);
|
|
simulateEvent('dblclick', 10, -20, null, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(2);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(4);
|
|
|
|
validateEvents(events, features);
|
|
});
|
|
|
|
it('should do nothing on single click', function () {
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
simulateEvent('pointerdown', 10, -20, null, 0);
|
|
simulateEvent('pointerup', 10, -20, null, 0);
|
|
simulateEvent('click', 10, -20, null, 0);
|
|
simulateEvent('singleclick', 10, -20, null, 0);
|
|
|
|
expect(feature.getGeometry().getRevision()).to.equal(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
expect(events.length).to.eql(0);
|
|
});
|
|
});
|
|
|
|
describe('insertVertexCondition', function () {
|
|
it('calls the callback function', function () {
|
|
const listenerSpy = sinon.spy(function (event) {
|
|
return false;
|
|
});
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
insertVertexCondition: listenerSpy,
|
|
});
|
|
map.addInteraction(modify);
|
|
const feature = features[0];
|
|
|
|
// move first vertex
|
|
simulateEvent('pointermove', 0, 0, null, 0);
|
|
simulateEvent('pointerdown', 0, 0, null, 0);
|
|
simulateEvent('pointermove', -10, -10, null, 0);
|
|
simulateEvent('pointerdrag', -10, -10, null, 0);
|
|
simulateEvent('pointerup', -10, -10, null, 0);
|
|
|
|
expect(listenerSpy.callCount).to.be(0);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
|
|
// try to add vertex
|
|
simulateEvent('pointerdown', 40, -20, null, 0);
|
|
simulateEvent('pointerup', 40, -20, null, 0);
|
|
simulateEvent('click', 40, -20, null, 0);
|
|
simulateEvent('singleclick', 40, -20, null, 0);
|
|
|
|
expect(listenerSpy.callCount).to.be(1);
|
|
expect(feature.getGeometry().getCoordinates()[0]).to.have.length(5);
|
|
});
|
|
|
|
it('does not fire `modifystart` when nothing is modified', function (done) {
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
insertVertexCondition: never,
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
let modifystart = false;
|
|
modify.on('modifystart', function () {
|
|
modifystart = true;
|
|
});
|
|
|
|
// try to add vertex
|
|
simulateEvent('pointermove', 40, -20, null, 0);
|
|
simulateEvent('pointerdown', 40, -20, null, 0);
|
|
simulateEvent('pointermove', 42, -30, null, 0);
|
|
simulateEvent('pointerdrag', 42, -30, null, 0);
|
|
simulateEvent('pointerup', 42, -30, null, 0);
|
|
simulateEvent('click', 42, -30, null, 0);
|
|
simulateEvent('singleclick', 42, -30, null, 0);
|
|
|
|
setTimeout(function () {
|
|
expect(modifystart).to.be(false);
|
|
done();
|
|
}, 0);
|
|
});
|
|
|
|
it('does not fire `modifyend` when nothing is modified', function (done) {
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
deleteCondition: click,
|
|
insertVertexCondition: never,
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
let modifyend = false;
|
|
modify.on('modifyend', function (e) {
|
|
modifyend = true;
|
|
});
|
|
|
|
// try to add vertex
|
|
simulateEvent('pointermove', 40, -20, null, 0);
|
|
simulateEvent('pointerdown', 40, -20, null, 0);
|
|
simulateEvent('pointerdrag', 42, -30, null, 0);
|
|
simulateEvent('pointerup', 42, -30, null, 0);
|
|
simulateEvent('click', 42, -30, null, 0);
|
|
simulateEvent('singleclick', 42, -30, null, 0);
|
|
|
|
setTimeout(function () {
|
|
expect(modifyend).to.be(false);
|
|
done();
|
|
}, 0);
|
|
});
|
|
});
|
|
|
|
describe('handle feature change', function () {
|
|
let getModifyListeners;
|
|
|
|
beforeEach(function () {
|
|
getModifyListeners = function (feature, modify) {
|
|
const listeners = feature.listeners_['change'];
|
|
const candidates = Object.values(modify);
|
|
return listeners.filter(function (listener) {
|
|
return candidates.indexOf(listener) !== -1;
|
|
});
|
|
};
|
|
});
|
|
|
|
it('updates circle segment data', function () {
|
|
const feature = new Feature(new Circle([10, 10], 20));
|
|
features.length = 0;
|
|
features.push(feature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
let listeners;
|
|
|
|
listeners = getModifyListeners(feature, modify);
|
|
expect(listeners).to.have.length(1);
|
|
|
|
let firstSegmentData;
|
|
|
|
firstSegmentData = modify.rBush_.forEachInExtent(
|
|
[0, 0, 5, 5],
|
|
function (node) {
|
|
return node;
|
|
}
|
|
);
|
|
expect(firstSegmentData.segment[0]).to.eql([10, 10]);
|
|
expect(firstSegmentData.segment[1]).to.eql([10, 10]);
|
|
|
|
const center = feature.getGeometry().getCenter();
|
|
center[0] = 1;
|
|
center[1] = 1;
|
|
feature.getGeometry().setCenter(center);
|
|
|
|
firstSegmentData = modify.rBush_.forEachInExtent(
|
|
[0, 0, 5, 5],
|
|
function (node) {
|
|
return node;
|
|
}
|
|
);
|
|
expect(firstSegmentData.segment[0]).to.eql([1, 1]);
|
|
expect(firstSegmentData.segment[1]).to.eql([1, 1]);
|
|
|
|
listeners = getModifyListeners(feature, modify);
|
|
expect(listeners).to.have.length(1);
|
|
});
|
|
|
|
it('updates polygon segment data', function () {
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const feature = features[0];
|
|
let listeners;
|
|
|
|
listeners = getModifyListeners(feature, modify);
|
|
expect(listeners).to.have.length(1);
|
|
|
|
let firstSegmentData;
|
|
|
|
firstSegmentData = modify.rBush_.forEachInExtent(
|
|
[0, 0, 5, 5],
|
|
function (node) {
|
|
return node;
|
|
}
|
|
);
|
|
expect(firstSegmentData.segment[0]).to.eql([0, 0]);
|
|
expect(firstSegmentData.segment[1]).to.eql([10, 20]);
|
|
|
|
const coordinates = feature.getGeometry().getCoordinates();
|
|
const firstVertex = coordinates[0][0];
|
|
firstVertex[0] = 1;
|
|
firstVertex[1] = 1;
|
|
feature.getGeometry().setCoordinates(coordinates);
|
|
|
|
firstSegmentData = modify.rBush_.forEachInExtent(
|
|
[0, 0, 5, 5],
|
|
function (node) {
|
|
return node;
|
|
}
|
|
);
|
|
expect(firstSegmentData.segment[0]).to.eql([1, 1]);
|
|
expect(firstSegmentData.segment[1]).to.eql([10, 20]);
|
|
|
|
listeners = getModifyListeners(feature, modify);
|
|
expect(listeners).to.have.length(1);
|
|
});
|
|
});
|
|
|
|
describe('handle feature removal during down-up sequence', function () {
|
|
it('removes segment data of removed features from dragSegments_', function () {
|
|
const collection = new Collection(features);
|
|
const modify = new Modify({
|
|
features: collection,
|
|
});
|
|
map.addInteraction(modify);
|
|
simulateEvent('pointermove', 0, 0, null, 0);
|
|
simulateEvent('pointerdown', 0, 0, null, 0);
|
|
simulateEvent('pointermove', -10, -10, null, 0);
|
|
simulateEvent('pointerdrag', -10, -10, null, 0);
|
|
collection.remove(features[0]);
|
|
expect(function () {
|
|
simulateEvent('pointerup', -10, -10, null, 0);
|
|
}).to.not.throwException();
|
|
});
|
|
});
|
|
|
|
describe('Vertex feature', function () {
|
|
it('tracks features and geometries and removes the vertexFeature on deactivation', function () {
|
|
const collection = new Collection(features);
|
|
const modify = new Modify({
|
|
features: collection,
|
|
});
|
|
map.addInteraction(modify);
|
|
expect(modify.vertexFeature_).to.be(null);
|
|
|
|
simulateEvent('pointermove', 10, -20, null, 0);
|
|
expect(modify.vertexFeature_).to.not.be(null);
|
|
expect(modify.vertexFeature_.get('features').length).to.be(1);
|
|
expect(modify.vertexFeature_.get('geometries').length).to.be(1);
|
|
|
|
modify.setActive(false);
|
|
expect(modify.vertexFeature_).to.be(null);
|
|
map.removeInteraction(modify);
|
|
});
|
|
|
|
it('tracks features and geometries - multi geometry', function () {
|
|
const collection = new Collection();
|
|
const modify = new Modify({
|
|
features: collection,
|
|
});
|
|
map.addInteraction(modify);
|
|
const feature = new Feature(
|
|
new MultiPoint([
|
|
[10, 10],
|
|
[10, 20],
|
|
])
|
|
);
|
|
collection.push(feature);
|
|
simulateEvent('pointermove', 10, -20, null, 0);
|
|
expect(modify.vertexFeature_.get('features')[0]).to.eql(feature);
|
|
expect(modify.vertexFeature_.get('geometries')[0]).to.eql(
|
|
feature.getGeometry()
|
|
);
|
|
map.removeInteraction(modify);
|
|
});
|
|
|
|
it('tracks features and geometries - geometry collection', function () {
|
|
const collection = new Collection();
|
|
const modify = new Modify({
|
|
features: collection,
|
|
});
|
|
map.addInteraction(modify);
|
|
const feature = new Feature(
|
|
new GeometryCollection([fromExtent([0, 0, 10, 10]), new Point([5, 5])])
|
|
);
|
|
collection.push(feature);
|
|
simulateEvent('pointermove', 5, -5, null, 0);
|
|
expect(modify.vertexFeature_.get('features')[0]).to.eql(feature);
|
|
expect(modify.vertexFeature_.get('geometries')[0]).to.eql(
|
|
feature.getGeometry().getGeometriesArray()[1]
|
|
);
|
|
});
|
|
|
|
it('works with hit detection of point features', function () {
|
|
const modify = new Modify({
|
|
hitDetection: layer,
|
|
source: source,
|
|
});
|
|
map.addInteraction(modify);
|
|
source.clear();
|
|
const pointFeature = new Feature(new Point([0, 0]));
|
|
source.addFeature(pointFeature);
|
|
layer.setStyle(
|
|
new Style({
|
|
image: new CircleStyle({
|
|
radius: 30,
|
|
fill: new Fill({
|
|
color: 'fuchsia',
|
|
}),
|
|
}),
|
|
})
|
|
);
|
|
map.renderSync();
|
|
simulateEvent('pointermove', 10, -10, null, 0);
|
|
expect(modify.vertexFeature_.get('features')[0]).to.eql(pointFeature);
|
|
expect(modify.vertexFeature_.get('geometries')[0]).to.eql(
|
|
pointFeature.getGeometry()
|
|
);
|
|
});
|
|
|
|
it('snaps to pointer by default', function () {
|
|
const modify = new Modify({
|
|
source: source,
|
|
});
|
|
map.addInteraction(modify);
|
|
source.clear();
|
|
const pointFeature = new Feature(new Point([0, 0]));
|
|
source.addFeature(pointFeature);
|
|
map.renderSync();
|
|
simulateEvent('pointerdown', 2, 2, null, 0);
|
|
simulateEvent('pointerdrag', 2, 2, null, 0);
|
|
simulateEvent('pointerup', 2, 2, null, 0);
|
|
expect(pointFeature.getGeometry().getCoordinates()).to.eql([2, -2]);
|
|
});
|
|
|
|
it('does not snap to pointer when snapToPointer is false', function () {
|
|
const modify = new Modify({
|
|
source: source,
|
|
snapToPointer: false,
|
|
});
|
|
map.addInteraction(modify);
|
|
source.clear();
|
|
const pointFeature = new Feature(new Point([0, 0]));
|
|
source.addFeature(pointFeature);
|
|
map.renderSync();
|
|
simulateEvent('pointerdown', 2, 2, null, 0);
|
|
simulateEvent('pointerdrag', 2, 2, null, 0);
|
|
simulateEvent('pointerup', 2, 2, null, 0);
|
|
expect(pointFeature.getGeometry().getCoordinates()).to.eql([0, 0]);
|
|
});
|
|
});
|
|
|
|
describe('#getOverlay', function () {
|
|
it('returns the feature overlay layer', function () {
|
|
const modify = new Modify({
|
|
features: new Collection(),
|
|
});
|
|
expect(modify.getOverlay()).to.eql(modify.overlay_);
|
|
});
|
|
});
|
|
|
|
describe('circle modification with snap', function () {
|
|
it('changes the circle radius and center', function () {
|
|
const circleFeature = new Feature(new Circle([10, 10], 20));
|
|
features.length = 0;
|
|
features.push(circleFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const snap = new Snap({
|
|
features: new Collection(features),
|
|
pixelTolerance: 1,
|
|
});
|
|
map.addInteraction(snap);
|
|
|
|
// Change center
|
|
simulateEvent('pointermove', 10, -10, null, 0);
|
|
simulateEvent('pointerdown', 10, -10, null, 0);
|
|
simulateEvent('pointermove', 5, -5, null, 0);
|
|
simulateEvent('pointerdrag', 5, -5, null, 0);
|
|
simulateEvent('pointerup', 5, -5, null, 0);
|
|
|
|
expect(circleFeature.getGeometry().getRadius()).to.equal(20);
|
|
expect(circleFeature.getGeometry().getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along x axis
|
|
simulateEvent('pointermove', 25, -4, null, 0);
|
|
simulateEvent('pointerdown', 25, -4, null, 0);
|
|
simulateEvent('pointermove', 30, -5, null, 0);
|
|
simulateEvent('pointerdrag', 30, -5, null, 0);
|
|
simulateEvent('pointerup', 30, -5, null, 0);
|
|
|
|
expect(circleFeature.getGeometry().getRadius()).to.roughlyEqual(25, 1e-9);
|
|
expect(circleFeature.getGeometry().getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along y axis
|
|
simulateEvent('pointermove', 4, -30, null, 0);
|
|
simulateEvent('pointerdown', 4, -30, null, 0);
|
|
simulateEvent('pointermove', 5, -35, null, 0);
|
|
simulateEvent('pointerdrag', 5, -35, null, 0);
|
|
simulateEvent('pointerup', 5, -35, null, 0);
|
|
|
|
expect(circleFeature.getGeometry().getRadius()).to.equal(30);
|
|
expect(circleFeature.getGeometry().getCenter()).to.eql([5, 5]);
|
|
});
|
|
|
|
it('changes the circle radius and center in a user projection', function () {
|
|
const userProjection = 'EPSG:3857';
|
|
setUserProjection(userProjection);
|
|
const viewProjection = map.getView().getProjection();
|
|
|
|
const circleFeature = new Feature(
|
|
new Circle([10, 10], 20).transform(viewProjection, userProjection)
|
|
);
|
|
features.length = 0;
|
|
features.push(circleFeature);
|
|
|
|
const modify = new Modify({
|
|
features: new Collection(features),
|
|
});
|
|
map.addInteraction(modify);
|
|
|
|
const snap = new Snap({
|
|
features: new Collection(features),
|
|
pixelTolerance: 1,
|
|
});
|
|
map.addInteraction(snap);
|
|
|
|
// Change center
|
|
simulateEvent('pointermove', 10, -10, null, 0);
|
|
simulateEvent('pointerdown', 10, -10, null, 0);
|
|
simulateEvent('pointermove', 5, -5, null, 0);
|
|
simulateEvent('pointerdrag', 5, -5, null, 0);
|
|
simulateEvent('pointerup', 5, -5, null, 0);
|
|
|
|
const geometry1 = circleFeature
|
|
.getGeometry()
|
|
.clone()
|
|
.transform(userProjection, viewProjection);
|
|
expect(geometry1.getRadius()).to.roughlyEqual(20, 1e-9);
|
|
expect(geometry1.getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along x axis
|
|
simulateEvent('pointermove', 25, -4, null, 0);
|
|
simulateEvent('pointerdown', 25, -4, null, 0);
|
|
simulateEvent('pointermove', 30, -5, null, 0);
|
|
simulateEvent('pointerdrag', 30, -5, null, 0);
|
|
simulateEvent('pointerup', 30, -5, null, 0);
|
|
|
|
const geometry2 = circleFeature
|
|
.getGeometry()
|
|
.clone()
|
|
.transform(userProjection, viewProjection);
|
|
expect(geometry2.getRadius()).to.roughlyEqual(25, 1e-9);
|
|
expect(geometry2.getCenter()).to.eql([5, 5]);
|
|
|
|
// Increase radius along y axis
|
|
simulateEvent('pointermove', 4, -30, null, 0);
|
|
simulateEvent('pointerdown', 4, -30, null, 0);
|
|
simulateEvent('pointermove', 5, -35, null, 0);
|
|
simulateEvent('pointerdrag', 5, -35, null, 0);
|
|
simulateEvent('pointerup', 5, -35, null, 0);
|
|
|
|
const geometry3 = circleFeature
|
|
.getGeometry()
|
|
.clone()
|
|
.transform(userProjection, viewProjection);
|
|
expect(geometry3.getRadius()).to.roughlyEqual(30, 1e-9);
|
|
expect(geometry3.getCenter()).to.eql([5, 5]);
|
|
});
|
|
});
|
|
});
|