1.) with the where filter 2.) definition expression 3.) iterating through all attribute ids and bringing them back.
The problem: All exists for only allowing/displaying one per attribute id
at a time.. my goal is to feed the attribute ids
into a checkbox list (which I have done), but allowing for items via attribute id to be added to the map as they are checked, collectively, one at a time - currently I can not seem to get this to work with the aspect of having multiple or more then one appear at a time on the map - each filter or attempt results in the next item being added while at the same time the previous is replaced (only showing one at a time).
1.) i.e. the below filter (attempted logic 1) - & also here is CodePen of:
..... function filterByID(event) { const selectedID = event.target.getAttribute("data-id"); eqLayerView.filter = { where: "id = '" + selectedID + "'" }; } view.whenLayerView(fl) .then(function(layerView) { eqLayerView = layerView; eqLayerView.filter = { where: "id = ''" };.............
2.) i.e. another attempted logic (adding multiple at a time here, line by line, or via array):
layer.definitionExpression = "id = 'us70008jr5'",layer.definitionExpression = "id = 'cgi988jr52'",
3.) i.e. 3rd attempt with a suggestion here on GIS exchange: Loop through attribute ids of FeatureLayer
layer .load() .then(() => { // create a query from the layer const query = layer.createQuery(); query.returnDistinctValues = true; query.where = "grid_value > 2"; // or 1=1 if you need them all // the field you want distinct values for query.outFields = ["id"]; return layer.queryFeatures(query); }) .then(({ features }) => { // extract the ids to a list const ids = features.map(({ attributes }) => attributes.id); return ids; }) .then((ids) => { // You can store them how you want, in this case, // I put them in a dropdown select menu const fragment = document.createDocumentFragment(); ids.forEach((id) => { const option = document.createElement('option'); option.value = id; option.innerText = id; fragment.appendChild(option); }); list.appendChild(fragment); map.add(layer);});
All attempted logic above result in the toggling of a shakemap by attribute id
to be displayed only one at a time — by toggling a new on, the previous turns off, I need the ability to have multiple being able to exist on the map at once.
Solved! Go to Solution.
Updated code to ensure only unique vals added as checkboxes.
Cam,
Here is my changes to your code.
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no">
<title>ArcGIS JavaScript Tutorials: Add layers to a map</title>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
.contn {
position: absolute;
bottom: 0px;
left: 0px;
}
</style>
<link rel="stylesheet" href="https://js.arcgis.com/4.15/esri/themes/light/main.css">
<script src="https://js.arcgis.com/4.15/"></script>
<script>
require([
"esri/Map",
"esri/views/MapView",
"esri/layers/FeatureLayer",
"esri/geometry/geometryEngine",
"esri/geometry/Circle",
"esri/Graphic",
"esri/symbols/SimpleFillSymbol",
"esri/renderers/ClassBreaksRenderer",
"esri/widgets/Legend",
"esri/tasks/QueryTask",
"esri/tasks/support/Query"
], function (
Map,
MapView,
FeatureLayer,
geometryEngine,
Circle,
Graphic,
SimpleFillSymbol,
ClassBreaksRenderer,
Legend,
QueryTask,
Query) {
var map = new Map({
basemap: "gray"
});
var view = new MapView({
container: "viewDiv",
map: map,
center: [-122, 37],
zoom: 2
});
let eqLayerView;
let fl;
let gras = [];
let dVals = [];
let QT = new QueryTask({
url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1"
});
let query = new Query();
query.where = "eventTime >= CURRENT_TIMESTAMP - 30 AND grid_value > 2";
query.outFields = ["id"];
query.returnDistinctValues = true;
query.returnGeometry = false;
query.orderByFields =["id"];
QT.execute(query).then(function (results) {
results.features.map(function (feat) {
let id = feat.attributes["id"];
if(dVals[id] === undefined){
dVals[id] = true;
let opt = document.createElement("input");
opt.type = "checkbox";
let label = document.createElement('label')
label.innerHTML = id;
opt.className = "id-item visible-id shakeids";
opt.setAttribute("data-id", id);
opt.name = "shaks";
idElement.appendChild(opt);
idElement.appendChild(label);
getCur(event);
}
});
}).catch(function(err){
console.error(err);
});
function getCur(event) {
let chkst = document.querySelector('.shaked');
if (chkst) {
chkst.addEventListener("click", filterByID);
} else {
getCur();
}
}
query.outFields = ["*"];
query.returnDistinctValues = false;
query.returnGeometry = true;
QT.execute(query).then(function (evt) {
evt.features.forEach(function (feature) {
var att = feature.attributes
var test = geometryEngine.convexHull(feature.geometry)
var genpoly = null
if (att.grid_value <= 4.0) {
var rad = att.Shape__Length / 75
genpoly = new Circle({
center: test.centroid,
radius: rad,
radiusUnit: "meters"
})
} else {
genpoly = test
}
var polygonGraphic = new Graphic({
geometry: genpoly,
attributes: att,
type: "polygon"
});
gras.push(polygonGraphic);
});
var renderer = {
type: "class-breaks",
field: "grid_value",
classificationMethod: "esriClassifyManual",
classBreakInfos: [{
minValue: 0,
maxValue: 1.9999,
symbol: {
color: [0, 0, 0, 0],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "I (Not Felt)"
},
{
minValue: 2.0,
maxValue: 3.0,
symbol: {
color: [191, 204, 255, .3],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "II (Weak)"
},
{
minValue: 3.1,
maxValue: 3.9,
symbol: {
color: [153, 153, 255, .4],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "III (Weak)"
},
{
minValue: 4.0,
maxValue: 4.5,
symbol: {
color: [136, 255, 255, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "IV (Light)"
},
{
minValue: 4.5,
maxValue: 4.9999,
symbol: {
color: [125, 248, 148, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "V (Light)"
},
{
minValue: 6.0,
maxValue: 6.9999,
symbol: {
color: [255, 255, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "VI (Strong)"
},
{
minValue: 7.0,
maxValue: 7.9999,
symbol: {
color: [255, 221, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "VII (Very Strong)"
},
{
minValue: 8.0,
maxValue: 8.9999,
symbol: {
color: [255, 145, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "VIII (Severe) "
},
{
minValue: 9.0,
maxValue: 9.9999,
symbol: {
color: [255, 0, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "IX (Violent)"
},
{
minValue: 10.0,
maxValue: 10.9999,
symbol: {
color: [221, 0, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "X"
},
{
minValue: 11.0,
maxValue: 11.9999,
symbol: {
color: [136, 0, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "XI"
},
{
minValue: 12.0,
maxValue: 12.0,
symbol: {
color: [68, 0, 0, 1],
outline: {
color: [0, 0, 0, 0],
width: 0.4,
type: "simple-line",
style: "solid"
},
type: "simple-fill",
style: "solid"
},
label: "XII"
}
]
}
var popuptemp = {
title: "Shake Intensity",
content: [{
type: "fields",
fieldInfos: [{
fieldName: "grid_value",
label: "Grid Value"
},
{
fieldName: "id",
label: "id"
},
{
fieldName: "ObjectID",
label: "ObjectID"
},
{
fieldName: "url",
label: "Url"
}
]
}]
}
fl = new FeatureLayer({
source: gras,
objectIdField: "ObjectID",
geometryType: "polygon",
fields: [{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
}, {
name: "id",
alias: "id",
type: "string"
}, {
name: "url",
alias: "url",
type: "string"
}, {
name: "grid_value",
alias: "grid_value",
type: "double"
}],
renderer: renderer,
popupEnabled: true,
popupTemplate: popuptemp
});
map.add(fl);
view.whenLayerView(fl).then(function (layerView) {
eqLayerView = layerView;
eqLayerView.filter = {
where: "id = ''"
};
});
});
let quakeFoldr = document.getElementById("Shakemaps").parentElement;
let onup = quakeFoldr.parentElement;
let twup = onup.parentElement;
let idElement = document.createElement("div");
let isElement = document.createElement("ul");
idElement.className += "shaked";
isElement.className += "k-group";
twup.appendChild(idElement);
idElement.appendChild(isElement);
function filterByID(event) {
let sqlExp = '';
let idChkBoxes = document.querySelectorAll(`.id-item`);
idChkBoxes.forEach(function (node) {
if (node.checked) {
sqlExp += "'" + node.getAttribute("data-id") + "' ";
}
});
sqlExp = sqlExp.replace(/' /g, "', ");
sqlExp = sqlExp.substring(0, sqlExp.length - 2);
console.info(sqlExp);
eqLayerView.filter = {
where: "id IN (" + sqlExp + ")"
};
}
});
</script>
</head>
<body>
<div id="viewDiv"></div>
<div class="contn">
<div>
<div>
<div id="Shakemaps">Shakemaps</div>
</div>
</div>
</div>
</body>
</html>
Cam,
It is simply a matter of building a proper SQL expression for multiple values.
"id IN ('us70008jr5','cgi988jr52')"
Thanks so much Robert, was pursuing this until noticed this service is now gone since today? https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServe... (no layers found) - It was working yesterday, is this just maintenance or it being marked as depreciated as well?
Sorry I don't know. My guess is some issue or maintenance though.
It is back now, strange....
Is it possible to update or add to and already declared definition expression? For instance, in your format above I can declare multiple in the initial definationExpression with id, but as soon as I try to update or add to it, it never reads.
I am able to hardcode the values in now initially, or pass initial variables in with multiple taking effect now - but as soon as I try to update or change my initial i.e. my 'layer.definitionExpression = "id IN ('"+ selectedID + "','us6000a4yi')";' - it does not update, only seemingly executing the first instance of definitionExpression with the id.
It appears now I'm struggling with how to update a definitionExpression (add to, remove, or replace) - I have tried layer.refresh(); in attempt for it to read my latest definition, but still didn't seem to work, I have also tried nesting them in variables and functions. This appears to be similar to what I'm trying to do: How to setDefinitionExpression on FeatureLayer in web map? (v3.30) -except in 3.30 version, I also tried this and wont take the syntax in 4.xx.
let selectedID; let datA; layer.definitionExpression = "id IN ('')"; function filterByID(event) { console.log('filter hit'); selectedID = event.target.getAttribute("data-id"); console.log(selectedID); layer.refresh(); layer.definitionExpression = "id IN ('"+ selectedID +"')"; }
i.e. a simple demo logic, where I can't seem to update a definationExpression (add to, remove, re-add as a new), starting with none, here I try to simple add one, console log is fine, just wont seem to take a second instant of. You can see my attempt to refresh() and "" in attempt to add a new.
let selectedID; let datA; layer.definitionExpression = "id IN ('')"; <-------- initial state nothing function filterByID(event) { console.log('filter hit'); selectedID = event.target.getAttribute("data-id"); console.log(selectedID); layer.refresh(); layer.definitionExpression = "id IN ('"+ selectedID +"')"; <------- attempt to update/replace with selected id }
You have a typo on your last line. It's "definitionExpression", not "DefinitionExpression"
Thanks, yeah late night typo.. I have edited the above, even with the above corrected the current dilemma persists. Here the question seems clearer: arcgis javascript api - Updating/add to definition expression - Geographic Information Systems Stack...
Cam,
Sounds like you are missing the basic logic that you need to be applying. So right now you have the filterById function firing when a checkbox is checked/unchecked. Your main issue is that you are not trying to see if an other checkboxes are checked/unchecked. Each time a checkbox is checked you need to be looping through all the check boxes to see which are checked and which are not. That way you can be building your SQL statement properly.
function filterByID(event) {
let sqlExp = '';
let idChkBoxes = document.querySelectorAll(`.id-item`);
idChkBoxes.forEach(function(node){
if(node.checked){
sqlExp += "'" + node.getAttribute("data-id") + "' ";
}
});
sqlExp = sqlExp.replace(/' /g, "', ");
sqlExp = sqlExp.substring(0, sqlExp.length - 2);
console.info(sqlExp);
eqLayerView.filter = {
where: "id IN (" + sqlExp + ")"
};
}