Update definitionExpression with two clauses?

499
2
05-12-2022 04:31 PM
JessicaHendricks444
New Contributor II

I am a JS newbie, so please forgive my possibly terrible coding. I am copying and pasting from a bunch of different examples to try to get to my end-product. 

My code works for all layers that have a single clause in the definitionExpression. My most important layer (roads layer) has a definitionExpression with two clauses that I'm trying to update using js. The first clause is chosen from a sql filter and the second clause from a slider value.

I just can't get this one to work. I've attached the JS and have bolded the text pertaining to the sublayer in the hopes that someone can help me. Many thanks for any suggestions!

 

JS: 

var OVERRIDE = true;
require([
    "esri/Map",
    "esri/views/MapView",
    "esri/layers/FeatureLayer",
    "esri/views/layers/FeatureLayerView",
    "esri/widgets/Slider",
    "esri/core/watchUtils",
    "esri/widgets/LayerList",
    "esri/widgets/Legend",
    "esri/layers/GroupLayer",
    "esri/core/Collection",
    "esri/widgets/Expand",
    "esri/widgets/Zoom",
    "esri/renderers/SimpleRenderer",
    "esri/symbols/WebStyleSymbol",
    "esri/layers/ImageryLayer",
    "esri/renderers/UniqueValueRenderer",
    "esri/layers/MapImageLayer",
    "esri/layers/support/DimensionalDefinition",
    "esri/layers/support/MosaicRule",
    "esri/layers/support/RasterFunction",
    "esri/layers/support/Sublayer",
    "esri/PopupTemplate",
    "esri/renderers/ClassBreaksRenderer",
    "esri/layers/WMSLayer"

], function (Map, MapView, FeatureLayer, FeatureLayerView, Slider, { whenFalseOnce },
    LayerList, Legend, GroupLayer, Collection, Expand, Zoom, SimpleRenderer,
    WebStyleSymbol, ImageryLayer, UniqueValueRenderer, MapImageLayer, DimensionalDefinition,
    MosaicRule, RasterFunction, Sublayer, PopupTemplate, ClassBreaksRenderer, WMSLayer) {

    const label = document.getElementById("flooding");
const baseDefinitionExpression = 'SourceID = DO0';

    let roadRenderer = {
        type: "simple",
        symbol: {
            type: "simple-line",
            width: 2.0,
            color: "#8C1C13",
        }
    };

    const layer = new MapImageLayer({
        url: ,
        visible: true,
        sublayers: [
           
            {
                id: 3,
                minScale: 90000,
                maxScale: 0,
                visible: false,
                definitionExpression: "Flooding <=0.5",
                outfields: ["Flooding"],
                title: "Inundation",
            },
           
      
            {
                id: 0,
                minScale: 0,
                maxScale: 0,
                visible: true,
                outfields: ["Flooding", "SourceID", "comb_name"],
                title: "Inaccessible Roads",
                definitionExpression: baseDefinitionExpression,
                renderer: roadRenderer,
                popupTemplate: {
                    title: "Inaccessible Roads",
                    content: [{
                        type: "text",
                        text: "{comb_name}",
                    }],
                }
            },
          ]
    });

    const map = new Map({
        // basemap: "streets-night-vector",
        basemap: "satellite",
        layers: [layer],
    });

    const view = new MapView({
        container: "viewDiv",
        map: map,
        center: [-76.467596, 36.873272],
        zoom: 9
    });
    view.ui.move("zoom", "bottom-right");


    // This code below uses SQL to filter for source point, based on field SourceID
    // Create a UI with the filter expressions
    const sqlExpressions = ["SourceID = ''", "SourceID = 'DO0'", "SourceID = 'AHQ0'", "SourceID = 'AHQ1'",
        "SourceID = 'AHQ2'", "SourceID = 'AHQ3'", "SourceID = 'AHQ4'", "SourceID = 'AHQ5'", "SourceID = 'AHQ6'", "SourceID = 'AHQ7'",
        "SourceID = 'AHQ8'", "SourceID = 'AHQ9'", "SourceID = 'AHQ10'", "SourceID = 'AFac0'", "SourceID = 'AFac1'",
        "SourceID = 'AFac2'", "SourceID = 'AFac3'", "SourceID = 'AFac4'", "SourceID = 'AFac5'", "SourceID = 'AFac6'"];
 

    // UI for Source point select
   
    const selectFilter = document.createElement("select")
    selectFilter.setAttribute("class", "esri-widget esri-select");
    // selectFilter.setAttribute("style", "width: 500px; font-family: Avenir Next W00; font-size: 1em;");
    sqlExpressions.forEach(function (sql, b) {
        let option = document.createElement("option");
        option.value = sql;
        option.text = opt_names[b];
        //  option.innerHTML = sql;
        selectFilter.appendChild(option);
    });
    document.getElementById("filter").append(selectFilter);
    // Server-side filter
    function setFeatureLayerFilter(SourceExpression) {
        const sources = layer.findSublayerById(5);
        const roads = layer.findSublayerById(0);
        sources.definitionExpression = SourceExpression;
        roads.definitionExpression = SourceExpression;
    }

    // Event listener
    selectFilter.addEventListener('change', function (event) {
        setFeatureLayerFilter(event.target.value);
    });

    //sets up slider element and layer effect for flooding level

    // ** Slider element
    let selectedFlooding = 0.5;
    const slider = new Slider({
        view: view,
        container: "slider",
        snapOnClickEnabled: false,
        min: 0,
        max: 3.05,
        values: [ selectedFlooding],
        steps: 0.1,
        effectiveMin: 0.0,
        effectiveMax: 3.0,
        visibleElements: {
            labels: true,
            rangeLabels: false,
        },
        tickConfigs: [{
            mode: "position",
            values: [0.0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0],
            labelsVisible: true,
            labelFormatFunction: function (value) {
                if (value == "1.75") {
                    return "2050 MHW"
                }
                if (value == "0") {
                    return "MHW"
                }
                return value + "m"
            }
        }],
        labelFormatFunction: function (value, type) {
            return "+" + value + " meters flooding";
        },
        layout: "vertical"

    });

    layer.when(() => {
        const inun = layer.findSublayerById(3);
        const roads = layer.findSublayerById(0);
        const floodingValueChanged = (event) => {
            selectedFlooding = event.value;
            document.getElementById("flooding")
            // update the layers after the user stops the slider to avoid continues requests
            if (event.state === 'stop') {
                inun.definitionExpression = "Flooding <= " + selectedFlooding;
                roads.definitionExpression = `${baseDefinitionExpression} AND Flooding <= ${selectedFlooding}`;
                         }
        }
        slider.on("thumb-drag", floodingValueChanged);
           
        });

 


});
0 Kudos
2 Replies
KenBuja
MVP Esteemed Contributor

One thing I notice is the baseDefinitionExpression is incorrect. It should be

const baseDefinitionExpression = "SourceID = 'DO0'";
0 Kudos
JessicaHendricks444
New Contributor II

Thanks. You are correct in that. 

I figured out another way to get the result I'm looking for. I separated the sublayer out into a feature layer and then applied a layer effect. 

 

Thanks for the suggestion!

0 Kudos