0

UPDATE 17 NOV 22 + FURTHER CLARIFICATIONS

I add some more info to my question below.

The vector layers are coming from geojson files that appears like the following

 {
"type": "FeatureCollection",
"name": "ISRA_examples",
"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
"features": [
{ "type": "Feature", "properties": { 
"Status": "ISRA",
"Region": "Central and South America Pacific", 
"Countries": "El Salvador", 
"Order": "SQUALIFORMES", 
"Family": "Squalidae, Somniosidae, Arhynchobatidae", 
"Species": "<em>Squalus acanthias<\/em>, <em>Squalus mitsukurii<\/em>, <em>Zameus squamulosus<\/em>, <em>Bathyraja fedorovi<\/em>, <em>Notoraja sticta<\/em>, <em>Rhinoraja kujiensis<\/em>"
}, 
"geometry": { "type": "MultiPolygon", "coordinates": [ [ [ [ -112.416034535675877, 29.377821790373176 ], .... ] ] ] ] } },

//it goes on like that, each polygon having different terms for each feature
]
}

Each geojson file corresponds to a world region (so I have 1 file per each region. They are grouped in a array named layers_group[] and their source are also grouped in another array source_group[].

I have a created filter in which I can select the features in order to show only those areas that match the selected filters (with the function feat.setStyle to apply transparency or color to the selected features).

Any kind of selection I pick up from the filters is visualized on the map. Either I filter by country only (or region or species etc.), or I filter by 2 different parameters (e.g. region(s) + species, or country(ies) + family etc.).
No problem for that: the code below is already doing it.

My problem is the following. In case I have the following output from my filter

var country_selected = Array [ "Chile", "Mexico" ]

var checked_species = Array [ "Carcharhinus plumbeus" ]

the areas that are visualized with the code I wrote below will be:

  • Areas with Mexico as country feature
  • Areas with Chile as country feature
  • Areas with Charcharhinus plumbeus as species feature -> these may be also areas from other countries (not only Chile and Mexico), that anyway contain the word Charcharhinus plumbeus in the species feature.

Instead, I would like to being able to visualize the areas containing the selected species (or family or orders), only within the countries that where selected.

PRESENT FUNCTION

(function($) {
    
    document.getElementById('submit_filters').onclick = function() {
        var checked_region = document.querySelectorAll('#region_filter :checked');
        var region_selected = [...checked_region].map(option => option.value);
        var checked_countries = document.querySelectorAll('#country_filter :checked');
        var country_selected = [...checked_countries].map(option => option.value);
        var checked_status = document.querySelectorAll('#isra_filter :checked');
        var status_selected = [...checked_status].map(option => option.value);
        var checked_region = document.querySelectorAll('#region_filter :checked');
        var region_selected = [...checked_region].map(option => option.value);
        var checked_countries = document.querySelectorAll('#country_filter :checked');
        var country_selected = [...checked_countries].map(option => option.value);
        var checked_areas = document.querySelectorAll('#isra_filter :checked');
        var areas_selected = [...checked_areas].map(option => option.value);        
        var checked_order = document.querySelectorAll('#order_filter :checked');
        var order_selected = [...checked_order].map(option => option.value);
        var checked_family = document.querySelectorAll('#family_filter :checked');
        var family_selected = [...checked_family].map(option => option.value);
        var checked_species = document.querySelectorAll('#species_filter :checked');

                        //We pass the array of selected variables, in order to match each one with the source

                       //regions
                        if(region_selected.length !== 0) {
                            for (k = 0; k < region_selected.length; ++k){
                                var feature_sel = region_selected[k];
                                //if "all" 
                                if (feature_sel == "all"){
                                    for (j = 0; j < layers_group.length; ++j){
                                        layers_group[j].setVisible(true);
                                    };
                                    for (index = 0; index < source_group.length; ++index){
                                        source_group[index].forEachFeature(function(feat){
                                            if (feat.get('Status') == "cISRA") {
                                                feat.setStyle(cIsraStyle);
                                            } else if (feat.get('Status') == "ISRA") {
                                                feat.setStyle(defaultStyle);
                                            }
                                            else if (feat.get('Status') == "AoI") {
                                                feat.setStyle(aoiStyle);
                                            }
                                        })
                                    };   
                                }
                                //else pass the specific term(s)
                                else {
                                    for (index = 0; index < source_group.length; ++index){
                                        source_group[index].forEachFeature(function(feat){
                                            let regions = feat.get('Region');
                                            if(regions.indexOf(feature_sel)!=-1) {
                                                for (j = 0; j < layers_group.length; ++j){
                                                    layers_group[j].setVisible(true);
                                                };                                              
                                                if (feat.get('Status') == "cISRA") {        
                                                    feat.setStyle(cIsraStyle);
                                                } else if (feat.get('Status') == "ISRA") {
                                                    feat.setStyle(defaultStyle);
                                                }
                                                else if (feat.get('Status') == "AoI") {
                                                    feat.setStyle(aoiStyle);
                                                }
                                            }                                           
                                        })
                                    };
                                }                                
                            };
                        }

                        //countries
                        if(country_selected.length !== 0) {
                            for (k = 0; k < country_selected.length; ++k){
                                var feature_sel = country_selected[k];
                                    if (feature_sel == "all"){
                                        for (j = 0; j < layers_group.length; ++j){
                                            layers_group[j].setVisible(true);
                                        };
                                        for (index = 0; index < source_group.length; ++index){
                                            source_group[index].forEachFeature(function(feat){
                                                if (feat.get('Status') == "cISRA") {
                                                    feat.setStyle(cIsraStyle);
                                                } else if (feat.get('Status') == "ISRA") {
                                                    feat.setStyle(defaultStyle);
                                                }
                                                else if (feat.get('Status') == "AoI") {
                                                    feat.setStyle(aoiStyle);
                                                }
                                            })
                                        };   
                                    }
                                    else {
                                        for (index = 0; index < source_group.length; ++index){                                           
                                            source_group[index].forEachFeature(function(feat){                                                
                                                let countries = feat.get('Countries');                                               
                                                if(countries.indexOf(feature_sel)!=-1) {                                                   
                                                    for (j = 0; j < layers_group.length; ++j){
                                                        layers_group[j].setVisible(true);
                                                    };                                              
                                                    if (feat.get('Status') == "cISRA") {        
                                                        feat.setStyle(cIsraStyle);
                                                    } else if (feat.get('Status') == "ISRA") {
                                                        feat.setStyle(defaultStyle);
                                                    }
                                                    else if (feat.get('Status') == "AoI") {
                                                        feat.setStyle(aoiStyle);
                                                    }                                                    
                                                }                                        
                                            })
                                        };   
                                    }
                            };
                        }
// ..... it goes on like that passing all the filters
    };

})( jQuery );  
14
  • On first sight there seems to be discrepancy between comments and actual code. Comment says //First of all we set layers transparent and not visible to reset the view, but actual code sets layers to visible: layers_group[j].setVisible(true).
    – TomazicM
    Nov 7, 2022 at 18:36
  • Given the nature of geojson files (each file corresponds to a region and within each region I have different polygons with a series of features such as "region name", country name" species name" etc.) I set the layers visible, but with a transparent style. Following the filters, features are given a certain style (with different colors fill) so that I can see only those polygons that meet the conditions given in the filter Nov 8, 2022 at 7:54
  • It's then just not clear why you are explicitly setting layers visible, since they are nowhere in the above code set as not visible.
    – TomazicM
    Nov 8, 2022 at 8:35
  • Yes you are right, since I forgot it sets the layers visible later on. So I put the layers_group[j].setVisible(false), but still it doesn't work. I though did a step forward by joining the array_Filters in one single array feature_selected = array_Filters.flat(); so I can pass one by one the options selected. Still I don't find the proper argument to apply the function indexOf() on different features contemporarily Nov 8, 2022 at 9:15
  • Logic of what is shown upon various combinations of selections is not clear. I suppose it goes like so: if only region and/or country is selected, but no order, family or species is selected, nothing is shown. For something to be shown, at least one of order, family or species has to be selected. If no country or region is selected, order, family or species are shown for all countries and regions. If countries and/or regions are selected, order, family or species are shown for selected countries and regions. Please edit your question to clarify this.
    – TomazicM
    Nov 18, 2022 at 11:22

1 Answer 1

2

Solution below is based on the following understanding of feature display on the basis of criteria selection:

  • if no country or region is selected, features are displayed for all selected orders, families and species;
  • if countries and/or regions are selected, features are displayed for all selected orders, families and species in those countries/regions;
  • if countries and/or regions are selected, but no order, family or species is selected, all features for those countries/regions are displayed.

Basic idea is to iterate over all features only once and check all conditions for each feature. If conditions for display are not met, feature style is set to hiddenStyle which prevents display. There is no layer hiding/displaying.

Code could then look something like this (not tested):

var hiddenStyle = new ol.style.Style({
  zIndex: 0
});

for (var i = 0; i < source_group.length; i++) {
  var selected, region_OK, country_OK, style;
  source_group[i].forEachFeature(function(feature){
    var selected = false;
    var region_OK = (region_selected.length == 0);
    var country_OK = (country_selected.length == 0);
    if (species_selected.indexOf(feature.get('Species')) >= 0) selected = true;
    if (family_selected.indexOf(feature.get('Family')) >= 0) selected = true;
    if (order_selected.indexOf(feature.get('Order')) >= 0) selected = true;
    if ((country_selected.length > 0) && (country_selected.indexOf(feature.get('Countries')) < 0)) country_OK = false;
    if ((region_selected.length > 0) && (country_selected.indexOf(feature.get('Region')) < 0)) region_OK = false;
    if (!(country_OK || region_OK)) selected = false;
    if (!selected)
      style = hiddenStyle;
    else {
      if (feat.get('Status') == "cISRA")
        style = cIsraStyle;
      else if (feat.get('Status') == "ISRA")
        style = defaultStyle;
      else if (feat.get('Status') == "AoI") {
        style = aoiStyle;
      }
    }
    feat.setStyle(style);
  });
}
1
  • Thanks very much @TomazicM. The code doesn't work as it is, but I understand the logic and I will work on it. I am sure I will solve the problem with your suggestions. Nov 21, 2022 at 7:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.