I am working with openlayers 6 and my main target is to be able to draw multiple feature and then to be able to select each of the drawn feature individually and style it with different style, I tried to use the Select interaction to get the selected feature and change its style, it changes but after unselecting it, the feature goes back to its main style, I want the style to be persistence.
here what I have achieved
<html>
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css"
type="text/css"
/>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
<style>
html,
body,
.map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<input type="number" id="number" />
<script>
const mainStyle = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: "#000",
width: 2,
}),
}),
];
const selectStyle = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: "#000",
width: 2,
}),
}),
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: "#f59e0b",
}),
stroke: new ol.style.Stroke({
color: "#000",
width: 2,
}),
}),
geometry: function (feature) {
const coordinates = feature.getGeometry().getCoordinates();
return new ol.geom.MultiPoint(coordinates);
},
}),
];
var raster = new ol.layer.Tile({
source: new ol.source.OSM(),
});
var source = new ol.source.Vector({ wrapX: false });
var vector = new ol.layer.Vector({
source: source,
});
var map = new ol.Map({
layers: [raster, vector],
target: "map",
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4,
}),
});
var draw = new ol.interaction.Draw({
source: source,
condition: ol.events.condition.altKeyOnly,
type: "LineString",
style: function (feature) {
if (feature.getGeometry().getType() === "LineString") {
feature.setStyle(mainStyle);
}
},
});
map.addInteraction(draw);
const select = new ol.interaction.Select({
layers: [vector],
hitTolerance: 10,
style: selectStyle,
});
map.addInteraction(select);
document.getElementById("number").addEventListener("change", (event) => {
let width = event.target.value;
let selectedFeature = select.getFeatures().array_[0];
selectedFeature.getStyle()[0].getStroke().setWidth(width);
selectedFeature.changed();
});
</script>
</body>
</html>
Define the select interaction with a null style so it does not set temporary styles and set a persistence style in the select event
<html>
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/css/ol.css"
type="text/css"
/>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.5.0/build/ol.js"></script>
<style>
html,
body,
.map {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
<input type="number" id="number" />
<script>
const mainStyle = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: "#000",
width: 2,
}),
}),
];
const selectStyle = [
new ol.style.Style({
stroke: new ol.style.Stroke({
color: "#000",
width: 2,
}),
}),
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: "#f59e0b",
}),
stroke: new ol.style.Stroke({
color: "#000",
width: 2,
}),
}),
geometry: function (feature) {
const coordinates = feature.getGeometry().getCoordinates();
return new ol.geom.MultiPoint(coordinates);
},
}),
];
var raster = new ol.layer.Tile({
source: new ol.source.OSM(),
});
var source = new ol.source.Vector({ wrapX: false });
var vector = new ol.layer.Vector({
source: source,
});
var map = new ol.Map({
layers: [raster, vector],
target: "map",
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4,
}),
});
var draw = new ol.interaction.Draw({
source: source,
condition: ol.events.condition.altKeyOnly,
type: "LineString",
style: function (feature) {
if (feature.getGeometry().getType() === "LineString") {
feature.setStyle(mainStyle);
}
},
});
map.addInteraction(draw);
const select = new ol.interaction.Select({
layers: [vector],
hitTolerance: 10,
style: null,
});
select.on('select', (event) => {
event.selected.forEach((feature) => {
feature.setStyle(selectStyle);
});
});
map.addInteraction(select);
</script>
</body>
</html>