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'" | |
}); |
Solved! Go to Solution.
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).
Try setting the definition expression after the layer load.
This is what I am doing, but the layer is disappearing after I change definitionExpression
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>
The scope of your buildingsLayer variable is not right. Define the variable before the require statement.
var buildingsLyr; require([...
didn't work
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?
Here is the fiddle with your advised code. Still not working for me:
Completing your Javascript line statements with a semi-colon is good practice.
buildingsLyr.definitionExpression = "ELEVATION > 30";
Dears,
I made a fiddle to simulate the problem:
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.