My goal is to be able to toggle shake intensities on / or off (display or hide) individually via either an ID
or name
... I see options of id and object id available in the data field options in the rest doc.. however, I am unsure how to implement... In my below codepen, you can see I am doing a rest call and returning all the shake map data at once... I am trying to return them one at a time per earthquake name or ID... so, I can filter them later "on" or "off"...
Full 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%; } </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/widgets/Legend" ], function(Map, MapView, FeatureLayer, Legend) { var map = new Map({ basemap: "gray" }); var view = new MapView({ container: "viewDiv", map: map, center: [-122, 37], zoom: 5 }); view.ui.add( new Legend({ view: view }), "bottom-left" ); // Define a popup for USGS_Seismic_Data_v1 var popupUSGS = { title: "Shake Intensity", content: [ { type: "fields", fieldInfos: [ { fieldName: "grid_value", label: "Grid Value" }, { fieldName: "mag", label: "Magnitude" }, { fieldName: "eventTime", label: "Event Time", format: { dateFormat: "short-date-short-time" } }, { fieldName: "updated", label: "Updated", format: { dateFormat: "short-date-short-time" } }, { fieldName: "url", label: "Url" } ] } ] } // USGS_Seismic_Data_v1 feature layer (polygons) var SeismicData = new FeatureLayer({ title: "MMI - Shake Intensity", url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1/", outFields: ["mag","eventTime","url"], popupTemplate: popupUSGS }); map.add(SeismicData); }); </script></head><body> <div id="viewDiv"></div></body></html>
Solved! Go to Solution.
Cam,
Just set a filter from the start them.
view.whenLayerView(layer).then(function(layerView) {
eqLayerView = layerView;
eqLayerView.filter = {
where: "id = ''"
};
...
Cam Code,
It looks like this sample is what you are looking for then:
Thanks, I'm seeming to get a better handle with this approach... except, would there be a way to loop through the definitionExpression ids without having to manually specify?
I have tried to console log SeismicData , but for some reason I am not finding a collection of ids but only one.. I would like to loop through and store these ids in variables as I will later add a time range parameter...
const SeismicData = new FeatureLayer({
title: "MMI - Shake Intensity",
url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1/",
outFields: ["id","mag","eventTime","url"],
popupTemplate: popupUSGS
});
SeismicData.definitionExpression = "grid_value > 2",
SeismicData.definitionExpression = "id = 'us70008jr5'", <------------ i.e. here
map.add(SeismicData);
Ultimately I suppose how could I loop through and get all the shakemap ids returned from my rest URL call?
Cam,
Here the sample updated for that:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Filter features by attribute - 4.15</title>
<link
rel="stylesheet"
href="https://js.arcgis.com/4.15/esri/themes/light/main.css"
/>
<script src="https://js.arcgis.com/4.15/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#id-filter {
max-height: 400px;
width: 100%;
visibility: hidden;
overflow-y: scroll;
}
.id-item {
width: 100%;
padding: 12px;
text-align: center;
vertical-align: baseline;
cursor: pointer;
height: 40px;
}
.id-item:focus {
background-color: dimgrey;
}
.id-item:hover {
background-color: dimgrey;
}
#titleDiv {
padding: 10px;
}
#titleText {
font-size: 20pt;
font-weight: 60;
padding-bottom: 10px;
}
</style>
<script>
require([
"esri/views/MapView",
"esri/Map",
"esri/layers/FeatureLayer",
"esri/widgets/Expand"
], function(MapView, Map, FeatureLayer, Expand) {
let floodLayerView;
// flash flood warnings layer
const layer = new FeatureLayer({
url: "https://services9.arcgis.com/RHVPKKiFTONKtxq3/arcgis/rest/services/USGS_Seismic_Data_v1/FeatureServer/1/",
outFields: ["*"]
});
const map = new Map({
basemap: "gray-vector",
layers: [layer]
});
const view = new MapView({
map: map,
container: "viewDiv",
center: [-98, 40],
zoom: 4
});
const idNodes = document.querySelectorAll(`.id-item`);
const idElement = document.getElementById("id-filter");
// click event handler for id choices
idElement.addEventListener("click", filterByID);
// User clicked on EQ id
// set an attribute filter on earthquake layer view
// to display the areas in that id
function filterByID(event) {
const selectedID = event.target.getAttribute("data-id");
eqLayerView.filter = {
where: "id = '" + selectedID + "'"
};
}
view.whenLayerView(layer).then(function(layerView) {
eqLayerView = layerView;
// set up UI items
idElement.style.visibility = "visible";
const idExpand = new Expand({
view: view,
content: idElement,
expandIconClass: "esri-icon-filter",
group: "top-left"
});
//clear the filters when user closes the expand widget
idExpand.watch("expanded", function() {
if (!idExpand.expanded) {
eqLayerView.filter = null;
}
});
view.ui.add(idExpand, "top-left");
view.ui.add("titleDiv", "top-right");
var query = layer.createQuery();
query.outFields = ["id"];
query.returnDistinctValues = true;
query.returnGeometry = false;
layer.queryFeatures(query).then(function(results){
results.features.map(function(feat){
var id = feat.attributes.id;
var opt = document.createElement("div");
opt.className = "id-item visible-id";
opt.setAttribute("data-id", id);
opt.innerHTML = id;
idElement.appendChild(opt);
});
});
});
});
</script>
</head>
<body>
<div id="id-filter" class="esri-widget">
</div>
<div id="viewDiv"></div>
<div id="titleDiv" class="esri-widget">
<div id="titleText">Earthquakes</div>
<div>Shake Intensity</div>
</div>
</body>
</html>
Thanks so much, Robert! Small question - is it necessary to add the layer (all) first, or initially, before being able to accomplish the filter?
For instance, in my CodePen
I've added all the layers by the id as checkboxes, the goal would be to add each when clicked one at a time, starting with no layers. It works after I click one checkbox initally which seems to clear all, then I select a layer. But I'd like to start with no shake maps, and add just the ones that are checked via checkbox one at a time.
Cam,
Just set a filter from the start them.
view.whenLayerView(layer).then(function(layerView) {
eqLayerView = layerView;
eqLayerView.filter = {
where: "id = ''"
};
...
Thanks Robert, is it possible to 'toggle by attribute id' on or off showing multiple at a time...
The goal would be push the attributes ids in a checkbox list, and check or unchecked to toggle the display of each shakemap by attribute id. The current problem is I've only been able to get it work as follows: start with nothing display -> checked checkbox would only show one at a time (and hide previous checked).
In other words I'm trying to create the ability to show or hide specific quakes by id, not just showing one a time as such with the definition expression technique and filter above, but rather the ability to check and show multiple at a time, is this possible?
i.e. with the below how could I retain multiple if needed (if checked)? It seems to only operate with one at a time.
eqLayerView.filter = {
where: "id = '" + selectedID + "'"
};
Thanks so much again. Robert, I have found one last issue with this I'm struggling with... Now with the popups, once I hit paginate... the pagination is displaying pop-up content for my shake graphics that are not visible (that are filtered out); how do I get my popup pagination to reflect the filter as well? Thanks so much for any advise