gmap-ol
Version:
A set of helper classes for working with openLayers.
131 lines (119 loc) • 4.31 kB
JavaScript
/*
* @Author: xuhongling
* @Date: 2022-09-02 10:27:17
* @Last Modified by: xuhongling
* @Last Modified time: 2024-05-07 09:23:37
*/
import { DragBox, Select } from 'ol/interaction';
import { platformModifierKeyOnly } from 'ol/events/condition';
import { getLayerByName } from '../LayerUtil/LayerUtil';
import { getOptionsStyle } from '../MapUtil/MapUtil';
function boxSelectionFeatures(olMap, boxSelectionOptions, selectionCallbackFn) {
if (olMap === null || olMap === undefined) {
return; // 终止函数执行
}
const layer = getLayerByName(olMap, boxSelectionOptions.layerName);
if (!layer) {
console.error('发生异常:没有找到图层,请检查配置!');
return;
}
const vectorSource = layer.getSource();
const selectedStyle = {
fill: {
color: 'rgba(255, 255, 255, 0.3)',
},
stroke: {
color: 'rgba(255, 255, 255, 1)',
width: 2,
},
text: {
font: '12px Microsoft YaHei',
fill: { color: 'rgba(255, 255, 255, 1)' },
stroke: {
color: 'rgba(0, 0, 0, 1)',
width: 1.5,
},
text: '',
},
};
// a normal select interaction to handle click
const select = new Select({
style: function (feature) {
const color = feature.get('COLOR') || feature.get('color');
const lineColor = feature.get('LINE_COLOR');
const name = feature.get('NAME') || feature.get('name');
if (color) {
selectedStyle.fill.color = color;
}
if (lineColor) {
selectedStyle.stroke.color = color;
}
if (name !== '') {
selectedStyle.text.text = name;
}
const newSelectedStyle = {
...selectedStyle,
...boxSelectionOptions.styles,
};
return getOptionsStyle(newSelectedStyle);
},
});
olMap.addInteraction(select);
const selectedFeatures = select.getFeatures();
// a DragBox interaction used to select features by drawing boxes
const dragBox = new DragBox({
condition: platformModifierKeyOnly,
});
olMap.addInteraction(dragBox);
dragBox.on('boxend', function () {
const extent = dragBox.getGeometry().getExtent();
const boxFeatures = vectorSource.getFeaturesInExtent(extent).filter((feature) => feature.getGeometry().intersectsExtent(extent));
// 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 = olMap.getView().getRotation();
const oblique = rotation % (Math.PI / 2) !== 0;
// 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();
boxFeatures.forEach(function (feature) {
const geometry = feature.getGeometry().clone();
geometry.rotate(-rotation, anchor);
if (geometry.intersectsExtent(extent)) {
selectedFeatures.push(feature);
}
});
} else {
selectedFeatures.extend(boxFeatures);
}
});
// clear selection when drawing a new box and when clicking on the map
dragBox.on('boxstart', function () {
selectedFeatures.clear();
});
let timer = null;
selectedFeatures.on(['add', 'remove'], function () {
const names = selectedFeatures.getArray().map(function (feature) {
const name = boxSelectionOptions.textFieldName ? feature.get(boxSelectionOptions.textFieldName) : feature.get('name');
return name;
});
if (names.length > 0) {
if (timer !== null) {
clearTimeout(timer);
}
timer = setTimeout(() => {
return selectionCallbackFn ? selectionCallbackFn(names) : null;
}, 500);
}
});
}
export default boxSelectionFeatures;