I have two Layer :
POLYGON
-Feature Id:1 Territory: A
-Feature Id:2 Territory: B
POINT
-Feature Id:1 Color:blue Territory: A
-Feature Id:2 Color:orange Territory: A,B
When hovering a point the polygon feature associated with (by the territory attribute get colorized in green)
When you hover the blue point (territory A) the polygon territory A gets colorized in green
I would like, on hovering the orange point, both polygon to be colorized in green (since the orange point hold A and B as territory attribute)
I tried by switching "==" in the json filter by a in clause, but it doesn't work. An,y ideas?
Here is a working example
<html>
<head>
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css">
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/Viglino/ol-ext/master/dist/ol-ext.min.js"></script>
</head>
<div id="map" style="width:600px; height:400px;">
</html>
<script type="text/javascript">
var osm = new ol.layer.Tile({ source: new ol.source.OSM() });
// The map
var map = new ol.Map({
target: 'map',
view: new ol.View({
zoom: 12,
center: [258348.20298867254,6251660.567134761]
}),
layers:[
osm
]
});
var myGeoJSON_polygon =
{
"type": "FeatureCollection",
"totalFeatures": 2,
"features": [
{
"type": "Feature",
"id": "1",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [
[
[
260367.02192332118,
6250556.546642702
],
[
260995.1341454634,
6250123.266520023
],
[
261610.65442527525,
6251470.486675286
],
[
261693.70008903166,
6251705.530616308
],
[
261182.61728993867,
6251926.157505688
],
[
260061.0334155549,
6252410.348833421
]
]
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 1,
"TERRITORY": "A"
}
},
{
"type": "Feature",
"id": "2",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Polygon",
"coordinates": [
[
[
259138.1286811567,
6252808.7905083215
],
[
260061.0334155549,
6252410.348833421
],
[
261182.61728993867,
6251926.157505688
],
[
261693.70008903166,
6251705.530616308
],
[
262058.7899222064,
6252709.954330505
],
[
261358.82144623742,
6252938.575515379
],
[
259138.1286811567,
6252808.7905083215
]
]
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 2,
"TERRITORY": "B"
}
}
],
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::3857"
}
}
};
var myGeoJSON_point = {
"type": "FeatureCollection",
"totalFeatures": 2,
"features": [
{
"type": "Feature",
"id": "1",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [
260828.02345910599,
6247410.0048086485
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 1,
"COLOR":'blue',
"TERRITORY": "A"
}
},
{
"type": "Feature",
"id": "2",
"geometry": {
"type": "GeometryCollection",
"geometries": [
{
"type": "Point",
"coordinates": [
266849.73999407736,
6251709.352439402
]
}
]
},
"geometry_name": "GEOMETRY",
"properties": {
"ID": 2,
"COLOR":'orange',
"TERRITORY": "A, B"
}
}
],
"crs": {
"type": "name",
"properties": {
"name": "urn:ogc:def:crs:EPSG::3857"
}
}
}
var polygonLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(myGeoJSON_polygon, { featureProjection: 'EPSG:3857' })
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color : 'red'
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
});
function getStyle(feature){
return new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: feature.get('COLOR')
}),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
})
})
})
}
var pointLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(myGeoJSON_point, { featureProjection: 'EPSG:3857' })
}),
style: getStyle
});
map.addLayer(polygonLayer);
map.addLayer(pointLayer)
const selectStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: 'green'
}),
stroke: new ol.style.Stroke({
color: 'green',
width: 4
})
});
let selectedTerr = null;
map.on('pointermove', function (evt) {
if (selectedTerr !== null) {
selectedTerr[0].setStyle(undefined);
selectedTerr = null;
}
map.forEachFeatureAtPixel(evt.pixel, function(feature, layer) {
if(layer === pointLayer){
selectedTerr = polygonLayer
.getSource()
.getFeatures()
.filter(l => l.getProperties().TERRITORY == feature.A.TERRITORY)
selectedTerr[0].setStyle(selectStyle)
}
return true;
});
});
</script>
In your example, it looks like you have mixed up the calls to selectedTerr
as if sometimes it was an array (when you index it with [0]
) and sometimes an openlayers feature (when you call selectedTerr.setStyle(...)
).
The logic to implement to solve your problem should be as follows:
(0) reset the polygon style
(1) when hovering over a point, retrieve the territory or territories to which it refers
(2) traverses the polygons list to retrieve the corresponding territory or territories
(3) apply the style to these polygons
The part of your code that I have modified is the following and includes the numbering of these 4 steps:
let selectedTerr = null;
map.on("pointermove", function (evt) {
// (0) reset the polygons style
if (selectedTerr !== null) {
selectedTerr.forEach((territory) => { territory.setStyle(undefined); });
selectedTerr = null;
}
map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
if (layer === pointLayer) {
// (1) retrieve the territory or territories to which it refers
// and store it / them in an array
const targetTerritories = feature.get('TERRITORY').split(', ');
// (2) retrieve the feature(s) of corresponding territory or territories
selectedTerr = polygonLayer
.getSource()
.getFeatures()
.filter((l) => targetTerritories.includes(l.get('TERRITORY')));
// (3) apply the style to each of them
selectedTerr.forEach((territory) => { territory.setStyle(selectStyle); });
}
return true;
});
});
So in my code, selectedTerr
is always an array (or null) even if sometimes this array contains only one element.
Below is the complete modified code :
<html>
<head>
<link rel="stylesheet" href="https://openlayers.org/en/latest/css/ol.css" />
<script type="text/javascript" src="https://openlayers.org/en/latest/build/ol.js"></script>
<script type="text/javascript" src="https://cdn.rawgit.com/Viglino/ol-ext/master/dist/ol-ext.min.js"></script>
</head>
<body>
<div id="map" style="width: 600px; height: 400px;"></div>
</body>
<script type="text/javascript">
var osm = new ol.layer.Tile({ source: new ol.source.OSM() });
var map = new ol.Map({
target: "map",
view: new ol.View({
zoom: 12,
center: [258348.20298867254, 6251660.567134761],
}),
layers: [osm],
});
var myGeoJSON_polygon = {
type: "FeatureCollection",
totalFeatures: 2,
features: [
{
type: "Feature",
id: "1",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Polygon",
coordinates: [
[
[260367.02192332118, 6250556.546642702],
[260995.1341454634, 6250123.266520023],
[261610.65442527525, 6251470.486675286],
[261693.70008903166, 6251705.530616308],
[261182.61728993867, 6251926.157505688],
[260061.0334155549, 6252410.348833421],
],
],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 1,
TERRITORY: "A",
},
},
{
type: "Feature",
id: "2",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Polygon",
coordinates: [
[
[259138.1286811567, 6252808.7905083215],
[260061.0334155549, 6252410.348833421],
[261182.61728993867, 6251926.157505688],
[261693.70008903166, 6251705.530616308],
[262058.7899222064, 6252709.954330505],
[261358.82144623742, 6252938.575515379],
[259138.1286811567, 6252808.7905083215],
],
],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 2,
TERRITORY: "B",
},
},
],
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:EPSG::3857",
},
},
};
var myGeoJSON_point = {
type: "FeatureCollection",
totalFeatures: 2,
features: [
{
type: "Feature",
id: "1",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Point",
coordinates: [260828.02345910599, 6247410.0048086485],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 1,
COLOR: "blue",
TERRITORY: "A",
},
},
{
type: "Feature",
id: "2",
geometry: {
type: "GeometryCollection",
geometries: [
{
type: "Point",
coordinates: [266849.73999407736, 6251709.352439402],
},
],
},
geometry_name: "GEOMETRY",
properties: {
ID: 2,
COLOR: "orange",
TERRITORY: "A, B",
},
},
],
crs: {
type: "name",
properties: {
name: "urn:ogc:def:crs:EPSG::3857",
},
},
};
var polygonLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(myGeoJSON_polygon, { featureProjection: "EPSG:3857" }),
}),
style: new ol.style.Style({
fill: new ol.style.Fill({
color: "red",
}),
stroke: new ol.style.Stroke({
color: "white",
width: 2,
}),
}),
});
function getStyle(feature) {
return new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
fill: new ol.style.Fill({
color: feature.get("COLOR"),
}),
stroke: new ol.style.Stroke({
color: "white",
width: 2,
}),
}),
});
}
var pointLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: new ol.format.GeoJSON().readFeatures(myGeoJSON_point, { featureProjection: "EPSG:3857" }),
}),
style: getStyle,
});
map.addLayer(polygonLayer);
map.addLayer(pointLayer);
const selectStyle = new ol.style.Style({
fill: new ol.style.Fill({
color: "green",
}),
stroke: new ol.style.Stroke({
color: "green",
width: 4,
}),
});
let selectedTerr = null;
map.on("pointermove", function (evt) {
if (selectedTerr !== null) {
selectedTerr.forEach((territory) => { territory.setStyle(undefined); });
selectedTerr = null;
}
map.forEachFeatureAtPixel(evt.pixel, function (feature, layer) {
if (layer === pointLayer) {
const targetTerritories = feature.get('TERRITORY').split(', ');
selectedTerr = polygonLayer
.getSource()
.getFeatures()
.filter((l) => targetTerritories.includes(l.get('TERRITORY')));
selectedTerr.forEach((territory) => { territory.setStyle(selectStyle); });
}
return true;
});
});
</script>
</html>