Oscar Jnn
Oscar Jnn

Reputation: 154

Openlayer - filter layer by another one (intersect?)

I have two point on a map, one red, one blue. On this map is also a grey area.

Of my two point, I would like to display only the blue one, which inside the area.

To sum things up, I would like to filter the geometry of a layer (point) by the geometry of another layer (area)

what is the proper way to do this, with intersect?

Here is a working example :

//Point layer Json
var GeoJSON = {
    "type": "FeatureCollection",
    "totalFeatures": 2,
    "features": [{
            "type": "Feature",
            "id": "1",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    294958.91163697134,
                    6246510.814409403
                ]
            },
            "geometry_name": "GEOMETRY",
            "properties": {
                "ID": 1,
                "color": "blue"
            }
        },
        {
            "type": "Feature",
            "id": "2",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    255020.37350418963,
                    6246791.991868377
                ]
            },
            "geometry_name": "GEOMETRY",
            "properties": {
                "ID": 2,
                "color": "red"
            }
        }
    ],
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::3857"
        }
    }
};

//Base layer
var osm = new ol.layer.Tile({
    source: new ol.source.OSM()
});

//Areal layer
let areal = new ol.layer.Vector({
    source: new ol.source.Vector({
        url: "https://wxs.ign.fr/administratif/geoportail/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&srsName=EPSG:3857&typenames=ADMINEXPRESS-COG-CARTO.LATEST:departement&outputformat=application/json&CQL_FILTER=insee_dep=77",
        format: new ol.format.GeoJSON()
    }),
    style: new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'grey',
            width: 2
        }),
        fill: new ol.style.Fill({
            color: 'darkgrey'
        })
    })
});

//Point layer
var point =
    new ol.layer.Vector({
        source: new ol.source.Vector({
            features: (new ol.format.GeoJSON()).readFeatures(GeoJSON, {
                featureProjection: 'EPSG:3857'
            })
        }),
        style: (feature) => {
            return new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 8,
                    fill: new ol.style.Fill({
                        color: feature.get("color")
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'white',
                        width: 2
                    })
                })
            })
        }
    })

// The map
var map = new ol.Map({
    target: 'map',
    view: new ol.View({
        zoom: 8,
        center: [255000, 6266791]
    }),
    layers: [
        osm,
        areal,
        point
    ]
});
<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>
</head>

<div id="map" style="width:100%; height:600px;">

Upvotes: 0

Views: 543

Answers (1)

Mike
Mike

Reputation: 17907

If you have a single polygon or multipolygon feature you could use the intersectsCoordinate method to test if the geometry contains the point coordinate when styling the point.

//Point layer Json
var GeoJSON = {
    "type": "FeatureCollection",
    "totalFeatures": 2,
    "features": [{
            "type": "Feature",
            "id": "1",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    294958.91163697134,
                    6246510.814409403
                ]
            },
            "geometry_name": "GEOMETRY",
            "properties": {
                "ID": 1,
                "color": "blue"
            }
        },
        {
            "type": "Feature",
            "id": "2",
            "geometry": {
                "type": "Point",
                "coordinates": [
                    255020.37350418963,
                    6246791.991868377
                ]
            },
            "geometry_name": "GEOMETRY",
            "properties": {
                "ID": 2,
                "color": "red"
            }
        }
    ],
    "crs": {
        "type": "name",
        "properties": {
            "name": "urn:ogc:def:crs:EPSG::3857"
        }
    }
};

//Base layer
var osm = new ol.layer.Tile({
    source: new ol.source.OSM()
});

//Areal layer
let areal = new ol.layer.Vector({
    source: new ol.source.Vector({
        url: "https://wxs.ign.fr/administratif/geoportail/wfs?SERVICE=WFS&VERSION=2.0.0&REQUEST=GetFeature&srsName=EPSG:3857&typenames=ADMINEXPRESS-COG-CARTO.LATEST:departement&outputformat=application/json&CQL_FILTER=insee_dep=77",
        format: new ol.format.GeoJSON()
    }),
    style: new ol.style.Style({
        stroke: new ol.style.Stroke({
            color: 'grey',
            width: 2
        }),
        fill: new ol.style.Fill({
            color: 'darkgrey'
        })
    })
});

let areaGeometry;

//Point layer
var point =
    new ol.layer.Vector({
        source: new ol.source.Vector({
            features: (new ol.format.GeoJSON()).readFeatures(GeoJSON, {
                featureProjection: 'EPSG:3857'
            })
        }),
        style: (feature) => {
          if (areaGeometry && 
              areaGeometry.intersectsCoordinate(
                  feature.getGeometry().getCoordinates()
              )
          ) {
            return new ol.style.Style({
                image: new ol.style.Circle({
                    radius: 8,
                    fill: new ol.style.Fill({
                        color: feature.get("color")
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'white',
                        width: 2
                    })
                })
            })
          }
        }
    })

    areal.getSource().on('featuresloadend', function(){
        areaGeometry = areal.getSource().getFeatures()[0].getGeometry();
        point.changed();
    });

// The map
var map = new ol.Map({
    target: 'map',
    view: new ol.View({
        zoom: 8,
        center: [255000, 6266791]
    }),
    layers: [
        osm,
        areal,
        point
    ]
});
<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>
</head>

<div id="map" style="width:100%; height:600px;">

Upvotes: 1

Related Questions