Select to view content in your preferred language

Changing definitionExpression doesn't work

4760
15
Jump to solution
06-07-2016 01:41 AM
MohamedHamoud
Deactivated User

definitionExpression attribute of FeatureLayer works fine when the application is loaded, but when I click a button that changes the definitionExpression attribute of the layer, the displayed features disappear from the map but I don't see the new features based on the new definitionExpression, although the attribute is changed.

The code I am using:

 
  var buildingsLyr = new FeatureLayer({
      url: "myURL",
      id: "BuildingsBM",
      renderer: renderer,
      popupTemplate: {
      title: "{ID}",
      content: "{*}"
    },
    outFields: ["ID", "Use", "Z"],
    definitionExpression: "Sector = 'S1'", // show only buildings within this sector
  });

  map = new Map({
    basemap: "streets",
    layers: [buildingsLyr]
  });

  view = new SceneView({
    container: "viewDiv",
    map: map
   ,
   camera: {
      position: [54, 24, 30000],
      heading: 0,
      tilt: 35
    }
  });

// on button click, change the         definitionExpression   

  on(document.getElementById("btnLocate"), "click", function (e) {
     
      buildingsLyr.definitionExpression = "Sector = 'S2'"
  });
0 Kudos
1 Solution

Accepted Solutions
FC_Basson
MVP Regular Contributor

Hi Mohamed.  Take a look at this fiddle: Edit fiddle - JSFiddle .  I've added buttons to increase and decrease the building elevation. I have to agree with you that the behaviour is "buggy".  I also suspect that it might have something to do with the maximum feature count provided by the REST endpoint (2000).

View solution in original post

15 Replies
FC_Basson
MVP Regular Contributor

Try setting the definition expression after the layer load.

0 Kudos
MohamedHamoud
Deactivated User

This is what I am doing, but the layer is disappearing after I change definitionExpression

0 Kudos
MohamedHamoud
Deactivated User

To simulate my case, you may check the following example:

ArcGIS API for JavaScript Sandbox

And use the following updated code, then after clicking the button on the top of the map, the building's layer is disappearing:

<!DOCTYPE html>

<html>

<head>

  <meta charset="utf-8">

  <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">

  <title>Extrude building footprints based on real world heights - 4.0</title>

  <link rel="stylesheet" href="https://js.arcgis.com/4.0/esri/css/main.css">

  <script src="https://js.arcgis.com/4.0/"></script>

  <style>

    html,

    body,

    #viewDiv {

      padding: 0;

      margin: 0;

      height: 100%;

      width: 100%;

    }

  </style>

  <script>

    require([

      "esri/Map",

      "esri/views/SceneView",

      "esri/layers/FeatureLayer",

      "esri/renderers/UniqueValueRenderer",

      "esri/symbols/ExtrudeSymbol3DLayer",

      "esri/symbols/PolygonSymbol3D",

      "dojo/on",

      "dojo/domReady!"

    ], function(

      Map, SceneView, FeatureLayer, UniqueValueRenderer,

      ExtrudeSymbol3DLayer, PolygonSymbol3D, on

    ) {

      /*****************************************************************

       * Define symbols for each unique type of building. One each for

       * residential, condos, and other.

       *****************************************************************/

      var resSym = new PolygonSymbol3D({

        symbolLayers: [

          new ExtrudeSymbol3DLayer({

            material: {

              color: "#FC921F"

            }

          })

        ]

      });

      var condoSym = new PolygonSymbol3D({

        symbolLayers: [

          new ExtrudeSymbol3DLayer({

            material: {

              color: "#9E559C"

            }

          })

        ]

      });

      /*****************************************************************

       * Set each unique value directly in the renderer's constructor.

       * At least one field must be used (in this case the "DESCLU" field).

       * The label property of each unique value will be used to indicate

       * the field value and symbol in the legend.

       *

       * The size visual variable sets the height of each building as it

       * exists in the real world according to the "ELEVATION" field.

       *****************************************************************/

      var renderer = new UniqueValueRenderer({

        defaultSymbol: new PolygonSymbol3D({

          symbolLayers: [new ExtrudeSymbol3DLayer({

            material: {

              color: "#A7C636"

            }

          })]

        }),

        defaultLabel: "Other",

        field: "DESCLU",

        visualVariables: [{

          type: "size",

          field: "ELEVATION",

          valueUnit: "feet" // Converts and extrudes all data values in feet

        }]

      });

      // Set the renderer on the layer

      var buildingsLyr = new FeatureLayer({

        url: "https://services1.arcgis.com/jjVcwHv9AQEq3DH3/ArcGIS/rest/services/Buildings/FeatureServer/0",

        renderer: renderer,

        popupTemplate: {

          title: "{DESCLU}",

          content: "{*}"

        },

        outFields: ["ADDRESS", "DESCLU", "ELEVATION"],

        definitionExpression: "ELEVATION > 0", // show only buildings with height

      });

      var map = new Map({

        basemap: "streets",

        ground: "world-elevation",

        layers: [buildingsLyr]

      });

      var view = new SceneView({

        container: "viewDiv",

        map: map,

        camera: {

          position: {

            x: -8354148,

            y: 4641966,

            z: 129,

            spatialReference: {

              wkid: 3857

            }

          },

          heading: 300,

          tilt: 75

        }

      });

     

     

     

          on(document.getElementById("ChangeExpression"), "click", function (e) {

         

          buildingsLyr.definitionExpression = "ELEVATION > 30"

          //alert(buildingsLyr.definitionExpression);

      });

     

     

     

    });

  </script>

</head>

<body>

  <button id="ChangeExpression">ChangeExpression</button>

  <div id="viewDiv"></div>

 

</body>

</html>

0 Kudos
FC_Basson
MVP Regular Contributor

The scope of your buildingsLayer variable is not right.  Define the variable before the require statement.

var buildingsLyr;
require([...
0 Kudos
MohamedHamoud
Deactivated User

didn't work

0 Kudos
FC_Basson
MVP Regular Contributor

Well, I tried the code you provided and changed it as I advised and it worked.  Did you remove the buildingsLayer variable declaration further down in the require function?

0 Kudos
MohamedHamoud
Deactivated User

Here is the fiddle with your advised code. Still not working for me:

Edit fiddle - JSFiddle

0 Kudos
FC_Basson
MVP Regular Contributor

Completing your Javascript line statements with a semi-colon is good practice.

buildingsLyr.definitionExpression = "ELEVATION > 30";

0 Kudos
MohamedHamoud
Deactivated User

Dears,

I made a fiddle to simulate the problem:

Edit fiddle - JSFiddle

Run the page and wait until the buildings are added to the map, then click on "ChangeExpression" button. The expected result is that only buildings higher then 30will be visible. The actual result is that all buildings are disappearing.

0 Kudos