From 654f78388b1066e8157565678e43a12289dedf49 Mon Sep 17 00:00:00 2001 From: mike-000 <49240900+mike-000@users.noreply.github.com> Date: Mon, 26 Aug 2019 22:11:41 +0100 Subject: [PATCH] Handle rotation in the Box Selection example oblique rotations (i.e. not 0, 90, 180 or 270 degrees) require additional filtering of features intersecting the extent of the rotated box --- examples/box-selection.js | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/examples/box-selection.js b/examples/box-selection.js index 3f1bb763c6..5f6b3de1a8 100644 --- a/examples/box-selection.js +++ b/examples/box-selection.js @@ -25,7 +25,8 @@ const map = new Map({ target: 'map', view: new View({ center: [0, 0], - zoom: 2 + zoom: 2, + constrainRotation: 16 }) }); @@ -43,12 +44,39 @@ const dragBox = new DragBox({ map.addInteraction(dragBox); dragBox.on('boxend', function() { - // features that intersect the box are added to the collection of - // selected features + // features that intersect the box geometry are added to the + // collection of selected features + + // if the view is not obliquely rotated the box geometry and + // its extent are equalivalent so intersecting features can + // be added directly to the collection + const rotation = map.getView().getRotation(); + const oblique = rotation % (Math.PI / 2) !== 0; + const candidateFeatures = oblique ? [] : selectedFeatures; const extent = dragBox.getGeometry().getExtent(); vectorSource.forEachFeatureIntersectingExtent(extent, function(feature) { - selectedFeatures.push(feature); + candidateFeatures.push(feature); }); + + // when the view is obliquely rotated the box extent will + // exceed its geometry so both the box and the candidate + // feature geometries are rotated around a common anchor + // to confirm that, with the box geometry aligned with its + // extent, the geometries intersect + if (oblique) { + const anchor = [0, 0]; + const geometry = dragBox.getGeometry().clone(); + geometry.rotate(-rotation, anchor); + const extent = geometry.getExtent(); + candidateFeatures.forEach(function(feature) { + const geometry = feature.getGeometry().clone(); + geometry.rotate(-rotation, anchor); + if (geometry.intersectsExtent(extent)) { + selectedFeatures.push(feature); + } + }); + } + }); // clear selection when drawing a new box and when clicking on the map