开放层 - 使用 "in-like" 子句从另一层过滤层



我有两个图层:

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

当将一个点悬停时,与之关联的多边形特征(由territory属性显示为绿色)

当你将蓝点(区域A)悬停时,多边形区域A将被着色为绿色

我想,在悬停橙色点时,两个多边形都被着色为绿色(因为橙色点持有A和B作为领土属性)

我试过切换"=="在json过滤器中使用In子句,但它不起作用。一个y想法?

下面是一个工作示例

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

在您的示例中,看起来您已经混淆了对selectedTerr的调用,好像有时它是一个数组(当您使用[0]索引它时),有时是一个开放层功能(当您调用selectedTerr.setStyle(...)时)。

逻辑实现来解决你的问题应该如下:
(0)重置多边形风格
(1)在悬停点时,检索的领土或领土是指
(2)遍历多边形列表中检索对应的区域或地区
(3)应用样式这些多边形

我修改的你的代码如下,包括这4个步骤的编号:

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;
});
});

所以在我的代码中,selectedTerr始终是一个数组(或null),即使有时这个数组只包含一个元素。

下面是修改后的完整代码:

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