Revert delete Select interaction commit 3838b68427

This commit is contained in:
Tobias Kohr
2019-09-25 10:33:38 +02:00
parent 14b931371d
commit 38124d770b
16 changed files with 1127 additions and 293 deletions

View File

@@ -3,7 +3,8 @@ layout: example.html
title: Box Selection
shortdesc: Using a DragBox interaction to select features.
docs: >
<p>This example shows how to use a <code>DragBox</code> interaction to select features.</p>
<p>This example shows how to use a <code>DragBox</code> interaction to select features. Selected features are added
to the feature overlay of a select interaction (<code>ol/interaction/Select</code>) for highlighting.</p>
<p>Use <code>Ctrl+Drag</code> (<code>Command+Drag</code> on Mac) to draw boxes.</p>
tags: "DragBox, feature, selection, box"
---

View File

@@ -2,13 +2,9 @@ import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {platformModifierKeyOnly} from '../src/ol/events/condition.js';
import GeoJSON from '../src/ol/format/GeoJSON.js';
import {DragBox} from '../src/ol/interaction.js';
import {DragBox, Select} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
import Collection from '../src/ol/Collection.js';
import Style from '../src/ol/style/Style.js';
import Fill from '../src/ol/style/Fill.js';
import Stroke from '../src/ol/style/Stroke.js';
const vectorSource = new VectorSource({
@@ -34,37 +30,11 @@ const map = new Map({
})
});
const selectedFeatures = new Collection();
// a normal select interaction to handle click
const select = new Select();
map.addInteraction(select);
// style features in collection
const highlightStyle = new Style({
fill: new Fill({
color: 'rgba(255,255,255,0.7)'
}),
stroke: new Stroke({
color: '#3399CC',
width: 3
})
});
selectedFeatures.on('add', function(e) {
e.element.setStyle(highlightStyle);
});
selectedFeatures.on('remove', function(e) {
e.element.setStyle(undefined);
});
// handle clicks
map.on('singleclick', function(e) {
selectedFeatures.clear();
map.forEachFeatureAtPixel(e.pixel, function(f) {
selectedFeatures.push(f);
});
});
const selectedFeatures = select.getFeatures();
// a DragBox interaction used to select features by drawing boxes
const dragBox = new DragBox({

View File

@@ -5,7 +5,7 @@ shortdesc: Demonstrates the use of style geometries to render source features of
docs: >
<p>This example parses a KML file and renders the features as clusters on a vector layer. The styling in this example is quite involved. Single earthquake locations
(rendered as stars) have a size relative to their magnitude. Clusters have an opacity relative to the number of features in the cluster, and a size that represents
the extent of the features that make up the cluster. When hovering over a cluster, the individual features that make up the cluster will be shown.</p>
the extent of the features that make up the cluster. When clicking or hovering on a cluster, the individual features that make up the cluster will be shown.</p>
<p>To achieve this, we make heavy use of style functions.</p>
tags: "KML, vector, style, geometry, cluster"
---

View File

@@ -2,6 +2,7 @@ import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {createEmpty, getWidth, getHeight, extend} from '../src/ol/extent.js';
import KML from '../src/ol/format/KML.js';
import {defaults as defaultInteractions, Select} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {Cluster, Stamen, Vector as VectorSource} from '../src/ol/source.js';
import {Circle as CircleStyle, Fill, RegularShape, Stroke, Style, Text} from '../src/ol/style.js';
@@ -68,50 +69,48 @@ const calculateClusterInfo = function(resolution) {
};
let currentResolution;
let hovered = null;
function styleFunction(feature, resolution) {
if (feature !== hovered) {
if (resolution != currentResolution) {
calculateClusterInfo(resolution);
currentResolution = resolution;
}
let style;
const size = feature.get('features').length;
if (size > 1) {
style = new Style({
image: new CircleStyle({
radius: feature.get('radius'),
fill: new Fill({
color: [255, 153, 0, Math.min(0.8, 0.4 + (size / maxFeatureCount))]
})
}),
text: new Text({
text: size.toString(),
fill: textFill,
stroke: textStroke
})
});
} else {
const originalFeature = feature.get('features')[0];
style = createEarthquakeStyle(originalFeature);
}
return style;
} else {
const styles = [new Style({
if (resolution != currentResolution) {
calculateClusterInfo(resolution);
currentResolution = resolution;
}
let style;
const size = feature.get('features').length;
if (size > 1) {
style = new Style({
image: new CircleStyle({
radius: feature.get('radius'),
fill: invisibleFill
fill: new Fill({
color: [255, 153, 0, Math.min(0.8, 0.4 + (size / maxFeatureCount))]
})
}),
text: new Text({
text: size.toString(),
fill: textFill,
stroke: textStroke
})
})];
const originalFeatures = feature.get('features');
let originalFeature;
for (let i = originalFeatures.length - 1; i >= 0; --i) {
originalFeature = originalFeatures[i];
styles.push(createEarthquakeStyle(originalFeature));
}
return styles;
});
} else {
const originalFeature = feature.get('features')[0];
style = createEarthquakeStyle(originalFeature);
}
return style;
}
function selectStyleFunction(feature) {
const styles = [new Style({
image: new CircleStyle({
radius: feature.get('radius'),
fill: invisibleFill
})
})];
const originalFeatures = feature.get('features');
let originalFeature;
for (let i = originalFeatures.length - 1; i >= 0; --i) {
originalFeature = originalFeatures[i];
styles.push(createEarthquakeStyle(originalFeature));
}
return styles;
}
vector = new VectorLayer({
@@ -135,17 +134,16 @@ const raster = new TileLayer({
const map = new Map({
layers: [raster, vector],
interactions: defaultInteractions().extend([new Select({
condition: function(evt) {
return evt.type == 'pointermove' ||
evt.type == 'singleclick';
},
style: selectStyleFunction
})]),
target: 'map',
view: new View({
center: [0, 0],
zoom: 2
})
});
map.on('pointermove', function(e) {
hovered = null;
map.forEachFeatureAtPixel(e.pixel, function(f) {
hovered = f;
f.changed();
});
});

View File

@@ -2,6 +2,7 @@ import Feature from '../src/ol/Feature.js';
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import Point from '../src/ol/geom/Point.js';
import Select from '../src/ol/interaction/Select.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import Stamen from '../src/ol/source/Stamen.js';
import VectorSource from '../src/ol/source/Vector.js';
@@ -43,35 +44,27 @@ const map = new Map({
});
const selectStyle = {};
let selected = null;
map.on('singleclick', function(e) {
if (selected !== null) {
selected.setStyle(undefined);
}
map.forEachFeatureAtPixel(e.pixel, function(f) {
f.setStyle(function(feature) {
const image = feature.get('style').getImage().getImage();
if (!selectStyle[image.src]) {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, image.width, image.height);
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0, ii = data.length; i < ii; i = i + (i % 4 == 2 ? 2 : 1)) {
data[i] = 255 - data[i];
}
context.putImageData(imageData, 0, 0);
selectStyle[image.src] = createStyle(undefined, canvas);
const select = new Select({
style: function(feature) {
const image = feature.get('style').getImage().getImage();
if (!selectStyle[image.src]) {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d');
canvas.width = image.width;
canvas.height = image.height;
context.drawImage(image, 0, 0, image.width, image.height);
const imageData = context.getImageData(0, 0, canvas.width, canvas.height);
const data = imageData.data;
for (let i = 0, ii = data.length; i < ii; i = i + (i % 4 == 2 ? 2 : 1)) {
data[i] = 255 - data[i];
}
return selectStyle[image.src];
});
selected = f;
return true;
});
context.putImageData(imageData, 0, 0);
selectStyle[image.src] = createStyle(undefined, canvas);
}
return selectStyle[image.src];
}
});
map.addInteraction(select);
map.on('pointermove', function(evt) {
map.getTargetElement().style.cursor =

View File

@@ -3,7 +3,7 @@ layout: example.html
title: Modify Features
shortdesc: Editing features with the modify interaction.
docs: >
<p>This example demonstrates how the modify interaction can be used. Zoom in to an area of interest and select a feature for editing.
<p>This example demonstrates how the modify and select interactions can be used together. Zoom in to an area of interest and select a feature for editing.
Then drag points around to modify the feature. You can preserve topology by selecting multiple features before editing (<code>Shift+Click</code> to select multiple features).</p>
tags: "modify, edit, vector"
---

View File

@@ -1,14 +1,9 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import GeoJSON from '../src/ol/format/GeoJSON.js';
import {defaults as defaultInteractions, Modify} from '../src/ol/interaction.js';
import {defaults as defaultInteractions, Modify, Select} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
import {shiftKeyOnly} from '../src/ol/events/condition.js';
import Collection from '../src/ol/Collection.js';
import Style from '../src/ol/style/Style.js';
import Fill from '../src/ol/style/Fill.js';
import Stroke from '../src/ol/style/Stroke.js';
const raster = new TileLayer({
@@ -23,34 +18,16 @@ const vector = new VectorLayer({
})
});
const features = new Collection();
// style features in collection
const highlightStyle = new Style({
fill: new Fill({
color: 'rgba(255,255,255,0.7)'
}),
stroke: new Stroke({
color: 'rgb(51,153,204)',
width: 3
})
});
features.on('add', function(e) {
e.element.setStyle(highlightStyle);
});
features.on('remove', function(e) {
e.element.setStyle(undefined);
const select = new Select({
wrapX: false
});
const modify = new Modify({
features: features
features: select.getFeatures()
});
const map = new Map({
interactions: defaultInteractions().extend([modify]),
interactions: defaultInteractions().extend([select, modify]),
layers: [raster, vector],
target: 'map',
view: new View({
@@ -58,12 +35,3 @@ const map = new Map({
zoom: 2
})
});
map.on('singleclick', function(e) {
if (!shiftKeyOnly(e)) {
features.clear();
}
map.forEachFeatureAtPixel(e.pixel, function(f) {
features.push(f);
});
});

View File

@@ -1,11 +1,10 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import GeoJSON from '../src/ol/format/GeoJSON.js';
import {defaults as defaultInteractions, Modify} from '../src/ol/interaction.js';
import {defaults as defaultInteractions, Modify, Select} from '../src/ol/interaction.js';
import VectorLayer from '../src/ol/layer/Vector.js';
import VectorSource from '../src/ol/source/Vector.js';
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
import Collection from '../src/ol/Collection.js';
const styleFunction = (function() {
@@ -212,29 +211,23 @@ const overlayStyle = (function() {
};
})();
const collection = new Collection();
collection.on('add', function(e) {
e.element.setStyle(overlayStyle);
});
collection.on('remove', function(e) {
e.element.setStyle(undefined);
const select = new Select({
style: overlayStyle
});
const modify = new Modify({
features: collection,
features: select.getFeatures(),
style: overlayStyle,
insertVertexCondition: function() {
// prevent new vertices to be added to the polygons
return !collection.getArray().every(function(feature) {
return !select.getFeatures().getArray().every(function(feature) {
return feature.getGeometry().getType().match(/Polygon/);
});
}
});
const map = new Map({
interactions: defaultInteractions().extend([modify]),
interactions: defaultInteractions().extend([select, modify]),
layers: [layer],
target: 'map',
view: new View({
@@ -242,12 +235,3 @@ const map = new Map({
zoom: 2
})
});
map.on('singleclick', function(e) {
collection.clear();
map.forEachFeatureAtPixel(e.pixel, function(f) {
collection.push(f);
});
});

View File

@@ -0,0 +1,85 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {click, pointerMove, altKeyOnly} from '../src/ol/events/condition.js';
import GeoJSON from '../src/ol/format/GeoJSON.js';
import Select from '../src/ol/interaction/Select.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import OSM from '../src/ol/source/OSM.js';
import VectorSource from '../src/ol/source/Vector.js';
const raster = new TileLayer({
source: new OSM()
});
const vector = new VectorLayer({
source: new VectorSource({
url: 'data/geojson/countries.geojson',
format: new GeoJSON()
})
});
const map = new Map({
layers: [raster, vector],
target: 'map',
view: new View({
center: [0, 0],
zoom: 2
})
});
let select = null; // ref to currently selected interaction
// select interaction working on "singleclick"
const selectSingleClick = new Select();
// select interaction working on "click"
const selectClick = new Select({
condition: click
});
// select interaction working on "pointermove"
const selectPointerMove = new Select({
condition: pointerMove
});
const selectAltClick = new Select({
condition: function(mapBrowserEvent) {
return click(mapBrowserEvent) && altKeyOnly(mapBrowserEvent);
}
});
const selectElement = document.getElementById('type');
const changeInteraction = function() {
if (select !== null) {
map.removeInteraction(select);
}
const value = selectElement.value;
if (value == 'singleclick') {
select = selectSingleClick;
} else if (value == 'click') {
select = selectClick;
} else if (value == 'pointermove') {
select = selectPointerMove;
} else if (value == 'altclick') {
select = selectAltClick;
} else {
select = null;
}
if (select !== null) {
map.addInteraction(select);
select.on('select', function(e) {
document.getElementById('status').innerHTML = '&nbsp;' +
e.target.getFeatures().getLength() +
' selected features (last operation selected ' + e.selected.length +
' and deselected ' + e.deselected.length + ' features)';
});
}
};
/**
* onchange callback on the select element.
*/
selectElement.onchange = changeInteraction;
changeInteraction();

View File

@@ -1,11 +1,9 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import {Draw, Modify, Snap} from '../src/ol/interaction.js';
import {Draw, Modify, Select, Snap} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {OSM, Vector as VectorSource} from '../src/ol/source.js';
import {Circle as CircleStyle, Fill, Stroke, Style} from '../src/ol/style.js';
import Collection from '../src/ol/Collection.js';
import {shiftKeyOnly} from '../src/ol/events/condition.js';
const raster = new TileLayer({
source: new OSM()
@@ -39,53 +37,29 @@ const map = new Map({
})
});
const highlightStyle = new Style({
fill: new Fill({
color: 'rgba(255,255,255,0.7)'
}),
stroke: new Stroke({
color: 'rgb(51,153,204)',
width: 3
})
});
const ExampleModify = {
init: function() {
this.features = new Collection();
this.features.on('add', function(e) {
e.element.setStyle(highlightStyle);
});
this.features.on('remove', function(e) {
e.element.setStyle(undefined);
});
this.select = function(e) {
if (!shiftKeyOnly(e)) {
this.features.clear();
}
map.forEachFeatureAtPixel(e.pixel, function(f) {
this.features.push(f);
}.bind(this));
}.bind(this);
this.select = new Select();
map.addInteraction(this.select);
this.modify = new Modify({
features: this.features
features: this.select.getFeatures()
});
map.addInteraction(this.modify);
this.setEvents();
},
setEvents: function() {
const selectedFeatures = this.select.getFeatures();
this.select.on('change:active', function() {
selectedFeatures.forEach(function(each) {
selectedFeatures.remove(each);
});
});
},
setActive: function(active) {
if (active) {
this.features.clear();
map.on('singleclick', this.select);
} else {
map.un('singleclick', this.select);
}
this.select.setActive(active);
this.modify.setActive(active);
}
};

View File

@@ -1,15 +1,10 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import GeoJSON from '../src/ol/format/GeoJSON.js';
import {defaults as defaultInteractions, Translate} from '../src/ol/interaction.js';
import {defaults as defaultInteractions, Select, Translate} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import OSM from '../src/ol/source/OSM.js';
import VectorSource from '../src/ol/source/Vector.js';
import Collection from '../src/ol/Collection.js';
import Style from '../src/ol/style/Style.js';
import Fill from '../src/ol/style/Fill.js';
import Stroke from '../src/ol/style/Stroke.js';
import {shiftKeyOnly} from '../src/ol/events/condition.js';
const raster = new TileLayer({
@@ -23,32 +18,14 @@ const vector = new VectorLayer({
})
});
const features = new Collection();
const highlightStyle = new Style({
fill: new Fill({
color: 'rgba(255,255,255,0.7)'
}),
stroke: new Stroke({
color: 'rgb(51,153,204)',
width: 3
})
});
features.on('add', function(e) {
e.element.setStyle(highlightStyle);
});
features.on('remove', function(e) {
e.element.setStyle(undefined);
});
const select = new Select();
const translate = new Translate({
features: features
features: select.getFeatures()
});
const map = new Map({
interactions: defaultInteractions().extend([translate]),
interactions: defaultInteractions().extend([select, translate]),
layers: [raster, vector],
target: 'map',
view: new View({
@@ -56,12 +33,3 @@ const map = new Map({
zoom: 2
})
});
map.on('singleclick', function(e) {
if (!shiftKeyOnly(e)) {
features.clear();
}
map.forEachFeatureAtPixel(e.pixel, function(f) {
features.push(f);
});
});

View File

@@ -1,18 +1,13 @@
import Map from '../src/ol/Map.js';
import View from '../src/ol/View.js';
import EsriJSON from '../src/ol/format/EsriJSON.js';
import {defaults as defaultInteractions, Draw, Modify} from '../src/ol/interaction.js';
import {defaults as defaultInteractions, Draw, Modify, Select} from '../src/ol/interaction.js';
import {Tile as TileLayer, Vector as VectorLayer} from '../src/ol/layer.js';
import {tile as tileStrategy} from '../src/ol/loadingstrategy.js';
import {fromLonLat} from '../src/ol/proj.js';
import VectorSource from '../src/ol/source/Vector.js';
import XYZ from '../src/ol/source/XYZ.js';
import {createXYZ} from '../src/ol/tilegrid.js';
import Collection from '../src/ol/Collection.js';
import Style from '../src/ol/style/Style.js';
import Fill from '../src/ol/style/Fill.js';
import Stroke from '../src/ol/style/Stroke.js';
import {shiftKeyOnly} from '../src/ol/events/condition.js';
const serviceUrl = 'https://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/' +
@@ -68,32 +63,17 @@ const draw = new Draw({
type: 'Polygon'
});
const selected = new Collection();
const highlightStyle = new Style({
fill: new Fill({
color: 'rgba(255,255,255,0.7)'
}),
stroke: new Stroke({
color: 'rgb(51,153,204)',
width: 3
})
});
selected.on('add', function(e) {
e.element.setStyle(highlightStyle);
});
selected.on('remove', function(e) {
e.element.setStyle(undefined);
});
const select = new Select();
select.setActive(false);
const selected = select.getFeatures();
const modify = new Modify({
features: selected
});
modify.setActive(false);
const map = new Map({
interactions: defaultInteractions().extend([draw, modify]),
interactions: defaultInteractions().extend([draw, select, modify]),
layers: [raster, vector],
target: document.getElementById('map'),
view: new View({
@@ -102,15 +82,6 @@ const map = new Map({
})
});
function select(e) {
if (!shiftKeyOnly(e)) {
selected.clear();
}
map.forEachFeatureAtPixel(e.pixel, function(f) {
selected.push(f);
});
}
const typeSelect = document.getElementById('type');
@@ -121,11 +92,6 @@ typeSelect.onchange = function() {
draw.setActive(typeSelect.value === 'DRAW');
select.setActive(typeSelect.value === 'MODIFY');
modify.setActive(typeSelect.value === 'MODIFY');
if (typeSelect.value === 'MODIFY') {
map.on('singleclick', select);
} else {
map.un('singleclick', select);
}
};
const dirty = {};