OpenLayers 6 filter with multiple criteria to show/hide polygons according to their features

53 Views Asked by At

I have a series of geojson files containing a number of features, which are grouped in arrays, so that selection can be made automatically on all files.

source_group=[] and layers_group[]

Each geojson file contains several polygons, each one with a number of features (I am going to show just a few as an example, but they are more) such as:

country / species / identification

Each feature may contain more than one criteria (for example a single polygon can be part of different countries, or contain more than one species etc.)

My code can show/ hide polygons correctly if only one filter criterion is applied (for example I filter by country). If on the other hand I try to apply a multiple filter the code as written shows all the polygons with a certain species, disregarding the country selected.

/*
geojson files features are
Jurisdiction; Species;QueryCrite
*/
//First set layers transparent and not visible to reset the view
var j;
for (j = 0; j < layers_group.length; ++j){
    layers_group[j].setStyle(transparentStyle);
    layers_group[j].setVisible(false);
};
//Second, set previous source features transparent to reset the view        
var index;
for (index = 0; index < source_group.length; ++index){
    source_group[index].forEachFeature(function(feat){
        feat.setStyle(transparentStyle);
    }
)};   
//Get the filtered selected on.click (we can have just one or all the parameters below)
var country_selected = [...checked_countries].map(option => option.value);
var checked_areas = document.querySelectorAll('#isra_filter :checked');
var checked_species = document.querySelectorAll('#species_filter :checked');
var species_selected = [...checked_species].map(option => option.value);
var checked_depth = document.querySelectorAll('#depth_filter :checked');
var depth_selected = [...checked_depth].map(option => option.value);

//select countries
if(country_selected.length !== 0) {
    //more than one variable can be selected, so I pass through the array country_selecte[] 
    for (k = 0; k < country_selected.length; ++k){
    var feature_sel = country_selected[k];
    //check for each single country selected if it is present in the source_group 
        for (index = 0; index < source_group.length; ++index){                
                source_group[index].forEachFeature(function(feat){                    
                    let countries = feat.get('Jurisdiction');                    
                    if(countries.indexOf(feature_sel)!=-1) { 
                        //if matches = true                       
                        for (j = 0; j < layers_group.length; ++j){
                            layers_group[j].setVisible(true);
                        };
                        //apply different style according to a further geojson file feature == Status                                   
                        if (feat.get('Status') == "cISRA") {        
                            feat.setStyle(cIsraStyle);
                        } else if (feat.get('Status') == "ISRA") {
                            feat.setStyle(borderSurfaceIsra);
                        }
                        else if (feat.get('Status') == "AoI") {
                            feat.setStyle(aoiStyle);
                        }                       
                    }                                                               
                })
        };  
    };
}
//select species
if(species_selected.length !== 0) {
    //more than one variable can be selected, so I pass through the array country_selecte[]     
    for (k = 0; k < country_selected.length; ++k){
    var feature_sel = species_selected[k];
    //check for each single species selected if it is present in the source_group     
        for (index = 0; index < source_group.length; ++index){                
                source_group[index].forEachFeature(function(feat){                    
                    let species = feat.get('Species');                    
                    if(species.indexOf(feature_sel)!=-1) { 
                        //if match = true                         
                        for (j = 0; j < layers_group.length; ++j){
                            layers_group[j].setVisible(true);
                        };
                        //apply different style according to a further geojson file feature == Status                                           
                        if (feat.get('Status') == "cISRA") {        
                            feat.setStyle(cIsraStyle);
                        } else if (feat.get('Status') == "ISRA") {
                            feat.setStyle(borderSurfaceIsra);
                        }
                        else if (feat.get('Status') == "AoI") {
                            feat.setStyle(aoiStyle);
                        }                       
                    }                                                               
                })
        };  
    };
}
//select criteria
if(depth_selected.length !== 0) {
    //more than one variable can be selected, so I pass through the array depth_selected[]     
    for (k = 0; k < identification_selected.length; ++k){
    var feature_sel = depth_selected[k];
    //check for each single depth selected if it is present in the source_group  
        for (index = 0; index < source_group.length; ++index){                
                source_group[index].forEachFeature(function(feat){                    
                    let depth = feat.get('Depth');                   
                    if(depth.indexOf(feature_sel)!=-1) {    
                        //if match = true                      
                        for (j = 0; j < layers_group.length; ++j){
                            layers_group[j].setVisible(true);
                        };
                        //apply different style according to a further geojson file feature == Status                                           
                        if (feat.get('Status') == "cISRA") {        
                            feat.setStyle(cIsraStyle);
                        } else if (feat.get('Status') == "ISRA") {
                            feat.setStyle(borderSurfaceIsra);
                        }
                        else if (feat.get('Status') == "AoI") {
                            feat.setStyle(aoiStyle);
                        }                       
                    }                                                               
                })
        };  
    };
}

Here's a practical example:

source_group contains the following:

3 polygons (P1, P2, P3) -> country = Spain; species = Species1, Species 2
2 polygons (P4, P5) -> country = Spain, France; species = Species2
4 polygons (P6, P7, P8, P9)-> country = Italy; species = Species1

At the moment if I filter by "Spain" + "Species1" the resulting polygons are P1,P2,P3,P6,P7,P8,P9, while the result I want is polygons P1,P2,P3

Filter must be adaptable also to more complex situations, such as >2 criteria filtered.

SOLUTION TRIED BUT NOT WORKING

if(country_selected.length !== 0) {
    //more than one variable can be selected, so I pass through the array country_selecte[] 
    for (k = 0; k < country_selected.length; ++k){
    var country_sel = country_selected[k];
    var filteredCountries = [];
    //check for each single country selected if it is present in the source_group 
        for (index = 0; index < source_group.length; ++index){                
                source_group[index].forEachFeature(function(feat){                    
                    let countries = feat.get('Jurisdiction');                    
                    if(countries.indexOf(country_sel)!=-1) { 
                        //push the single polygons meeting country_selected in a new array
                        filteredCountries.push(feat);

                        //before taking action, check if species_selected contains something
                        if(species_selected.length !==0) {
                            for (k = 0; k < species_selected.length; ++k){
                                var species_sel = species_selected[k];

                                for (i=0; i<filteredCountries.length;++i) {
                                    //****the following is not working
                                    filteredCountries[i].forEachFeature(function(feat){
                                        let species = feat.get('Species');
                                        if (species.indexOf(species_sel)!=-1) {
  
                                            //if matches = true                       
                                            for (j = 0; j < layers_group.length; ++j){
                                                layers_group[j].setVisible(true);
                                            };
                                            //apply different style according to a further geojson file feature == Status                                   
                                            if (feat.get('Status') == "cISRA") {        
                                                feat.setStyle(cIsraStyle);
                                            } else if (feat.get('Status') == "ISRA") {
                                                feat.setStyle(borderSurfaceIsra);
                                            }
                                            else if (feat.get('Status') == "AoI") {
                                                feat.setStyle(aoiStyle);
                                            }                                               
                                        }
                                    });
                                }
                            }
                            
                        }
                        else {
                            //show only info about countries filtered
                        }

                    }                                                               
                });
        };  
    };
}

The array filteredCountries[] is created correctly, but then I cannot use it with the function forEachFeature, as I have a console error.

I a struggling to find a working solution, could you help?

0

There are 0 best solutions below