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
This commit is contained in:
mike-000
2019-08-26 22:11:41 +01:00
committed by GitHub
parent aca4a39863
commit 654f78388b

View File

@@ -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