我在尝试将属性过滤和从FeatureLayerView中查询特征之间的功能结合起来时遇到了麻烦。下面是两个示例。
https:/developers.arcgis.comjavascriptlatestsample-codeefeaturefilter-attributesindex.html。
https:/developers.arcgis.comjavascriptlatestsample-codeefaturelayerview-queryindex.html。
目的是应用所选择的过滤器(通过属性过滤特征),并将该过滤器应用到侧面板中显示的Query FeatureLayerView中。
目前,我们已经在一个示例中让这两个功能都正确地工作了,但是它们仍然是相互孤立地工作。我已经添加了下面的代码。
任何帮助将是非常感激的。
<script src="https://js.arcgis.com/4.15/"></script>
<style>
html,
body,
#viewDiv {
padding: 0;
margin: 0;
height: 100%;
width: 100%;
}
#seasons-filter {
height: 160px;
width: 160px;
width: 100%;
visibility: hidden;
}
.season-item {
width: 100%;
padding: 12px;
text-align: center;
vertical-align: baseline;
cursor: pointer;
height: 40px;
height: 50px;
}
.season-item:focus {
background-color: dimgrey;
}
.season-item:hover {
background-color: dimgrey;
}
.panel-container {
position: relative;
width: 100%;
height: 100%;
}
.panel-side {
padding: 2px;
box-sizing: border-box;
width: 300px;
height: 100%;
position: absolute;
top: 0;
right: 0;
color: #fff;
background-color: rgba(0, 0, 0, 0.6);
overflow: auto;
z-index: 60;
}
.panel-side h3 {
padding: 0 20px;
margin: 20px 0;
}
.panel-side ul {
list-style: none;
margin: 0;
padding: 0;
}
.panel-side li {
list-style: none;
padding: 10px 20px;
}
.panel-result {
cursor: pointer;
margin: 2px 0;
background-color: rgba(0, 0, 0, 0.3);
}
.panel-result:hover,
.panel-result:focus {
color: orange;
background-color: rgba(0, 0, 0, 0.75);
}
</style>
<script>
require([
"esri/views/MapView",
"esri/Map",
"esri/layers/FeatureLayer",
"esri/widgets/Expand"
], function(MapView, Map, FeatureLayer, Expand) {
let floodLayerView;
let graphics;
const listNode = document.getElementById("nyc_graphics");
const popupTemplate = {
// autocasts as new PopupTemplate()
title: "{NAME} in {COUNTY}",
content: [
{
type: "fields",
fieldInfos: [
{
fieldName: "B12001_calc_pctMarriedE",
label: "% Married",
format: {
places: 0,
digitSeparator: true
}
}
]
}
]
};
// flash flood warnings layer
const layer = new FeatureLayer({
url:
"https://services.arcgis.com/P3ePLMYs2RVChkJx/ArcGIS/rest/services/ACS_Marital_Status_Boundaries/FeatureServer/2",
outFields: ["NAME", "GEOID"], // used by queryFeatures
popupTemplate: popupTemplate
});
const map = new Map({
basemap: "gray-vector",
layers: [layer]
});
const view = new MapView({
map: map,
container: "viewDiv",
center: [-73.95, 40.702],
zoom: 11
});
const seasonsNodes = document.querySelectorAll(`.season-item`);
const seasonsElement = document.getElementById("seasons-filter");
// click event handler for seasons choices
seasonsElement.addEventListener("click", filterBySeason);
// User clicked on Winter, Spring, Summer or Fall
// set an attribute filter on flood warnings layer view
// to display the warnings issued in that season
function filterBySeason(event) {
const selectedSeason = event.target.getAttribute("data-season");
floodLayerView.filter = {
where: "State = '" + selectedSeason + "'"
};
}
view.whenLayerView(layer).then(function(layerView) {
// flash flood warnings layer loaded
// get a reference to the flood warnings layerview
floodLayerView = layerView;
// set up UI items
seasonsElement.style.visibility = "visible";
const seasonsExpand = new Expand({
view: view,
content: seasonsElement,
expandIconClass: "esri-icon-filter",
group: "top-left"
});
//clear the filters when user closes the expand widget
seasonsExpand.watch("expanded", function() {
if (!seasonsExpand.expanded) {
floodLayerView.filter = null;
}
});
view.ui.add(seasonsExpand, "top-left");
});
// Start Of Side Bar Element
view.whenLayerView(layer).then(function(layerView) {
layerView.watch("updating", function(value) {
if (!value) {
// wait for the layer view to finish updating
// query all the features available for drawing.
layerView
.queryFeatures({
geometry: view.extent,
returnGeometry: true,
orderByFields: ["NAME"]
})
.then(function(results) {
graphics = results.features;
const fragment = document.createDocumentFragment();
graphics.forEach(function(result, index) {
const attributes = result.attributes;
const name = attributes.NAME;
// Create a list zip codes in NY
const li = document.createElement("li");
li.classList.add("panel-result");
li.tabIndex = 0;
li.setAttribute("data-result-id", index);
li.textContent = name;
fragment.appendChild(li);
});
// Empty the current list
listNode.innerHTML = "";
listNode.appendChild(fragment);
})
.catch(function(error) {
console.error("query failed: ", error);
});
}
});
});
// listen to click event on the zip code list
listNode.addEventListener("click", onListClickHandler);
function onListClickHandler(event) {
const target = event.target;
const resultId = target.getAttribute("data-result-id");
// get the graphic corresponding to the clicked zip code
const result =
resultId && graphics && graphics[parseInt(resultId, 10)];
if (result) {
// open the popup at the centroid of zip code polygon
// and set the popup's features which will populate popup content and title.
view
.goTo(result.geometry.extent.expand(2))
.then(function() {
view.popup.open({
features: [result],
location: result.geometry.centroid
});
})
.catch(function(error) {
if (error.name != "AbortError") {
console.error(error);
}
});
}
}
});
</script>
你可以做的是用一个简单的条件对查询得到的图形进行过滤。使用ArcGIS的两个例子,我把我认为你想得到的东西放在一起。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta
name="viewport"
content="initial-scale=1,maximum-scale=1,user-scalable=no"
/>
<title>Filter and Query - 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%;
}
#seasons-filter {
height: 160px;
width: 100%;
visibility: hidden;
}
.season-item {
width: 100%;
padding: 12px;
text-align: center;
vertical-align: baseline;
cursor: pointer;
height: 40px;
}
.season-item:focus {
background-color: dimgrey;
}
.season-item:hover {
background-color: dimgrey;
}
#titleDiv {
padding: 10px;
}
#titleText {
font-size: 20pt;
font-weight: 60;
padding-bottom: 10px;
}
.panel-container {
position: relative;
width: 100%;
height: 100%;
}
.panel-side {
padding: 2px;
box-sizing: border-box;
width: 300px;
height: 100%;
position: absolute;
top: 0;
right: 0;
color: #fff;
background-color: rgba(0, 0, 0, 0.6);
overflow: auto;
z-index: 60;
}
.panel-side h3 {
padding: 0 20px;
margin: 20px 0;
}
.panel-side ul {
list-style: none;
margin: 0;
padding: 0;
}
.panel-side li {
list-style: none;
padding: 10px 20px;
}
.panel-result {
cursor: pointer;
margin: 2px 0;
background-color: rgba(0, 0, 0, 0.3);
}
.panel-result:hover,
.panel-result:focus {
color: orange;
background-color: rgba(0, 0, 0, 0.75);
}
</style>
<script>
require([
"esri/views/MapView",
"esri/Map",
"esri/layers/FeatureLayer",
"esri/widgets/Expand"
], function(MapView, Map, FeatureLayer, Expand) {
const listNode = document.getElementById("list_graphics");
const seasonsNodes = document.querySelectorAll(`.season-item`);
const seasonsElement = document.getElementById("seasons-filter");
let layer, map, view;
let selectedSeason = null;
let floodLayerView;
let graphics = null;
// functions
const filterBySeason = function (event) {
selectedSeason = event.target.getAttribute("data-season");
floodLayerView.filter = {
where: "Season = '" + selectedSeason + "'"
};
updateList();
};
const updateList = function () {
if (!graphics) {
return;
}
const fragment = document.createDocumentFragment();
graphics.forEach(function(result, index) {
const attributes = result.attributes;
if (!selectedSeason || attributes.SEASON === selectedSeason) {
const name = attributes.IssueDate;
// Create the list
const li = document.createElement("li");
li.classList.add("panel-result");
li.tabIndex = 0;
li.setAttribute("data-result-id", index);
li.textContent = name;
fragment.appendChild(li);
}
});
// Empty the current list
listNode.innerHTML = "";
listNode.appendChild(fragment);
};
// flash flood warnings layer
layer = new FeatureLayer({
portalItem: {
id: "f9e348953b3848ec8b69964d5bceae02"
},
outFields: ["SEASON", "IssueDate"]
});
map = new Map({
basemap: "gray-vector",
layers: [layer]
});
view = new MapView({
map: map,
container: "viewDiv",
center: [-98, 40],
zoom: 10
});
// click event handler for seasons choices
seasonsElement.addEventListener("click", filterBySeason);
view.whenLayerView(layer).then(function(layerView) {
/*
filter
*/
floodLayerView = layerView;
// set up UI items
seasonsElement.style.visibility = "visible";
const seasonsExpand = new Expand({
view: view,
content: seasonsElement,
expandIconClass: "esri-icon-filter",
group: "top-left"
});
//clear the filters when user closes the expand widget
seasonsExpand.watch("expanded", function() {
if (!seasonsExpand.expanded) {
floodLayerView.filter = null;
}
});
view.ui.add(seasonsExpand, "top-left");
view.ui.add("titleDiv", "bottom-left");
/*
query
*/
layerView.watch("updating", function(value) {
if (!value) {
// wait for the layer view to finish updating
// query all the features available for drawing.
layerView
.queryFeatures({
geometry: view.extent,
returnGeometry: true,
orderByFields: ["IssueDate"]
})
.then(function (results) {
graphics = results.features;
updateList();
})
.catch(function(error) {
console.error("query failed: ", error);
});
}
});
});
/*
query
*/
// listen to click event on list items
listNode.addEventListener("click", onListClickHandler);
function onListClickHandler(event) {
const target = event.target;
const resultId = target.getAttribute("data-result-id");
// get the graphic corresponding to the clicked item
const result =
resultId && graphics && graphics[parseInt(resultId, 10)];
if (result) {
// open the popup at the centroid of polygon
// and set the popup's features which will populate popup content and title.
view
.goTo(result.geometry.extent.expand(2))
.then(function() {
view.popup.open({
features: [result],
location: result.geometry.centroid
});
})
.catch(function(error) {
if (error.name != "AbortError") {
console.error(error);
}
});
}
};
});
</script>
</head>
<body>
<div class="panel-container">
<div id="seasons-filter" class="esri-widget">
<div class="season-item visible-season" data-season="Winter">Winter</div>
<div class="season-item visible-season" data-season="Spring">Spring</div>
<div class="season-item visible-season" data-season="Summer">Summer</div>
<div class="season-item visible-season" data-season="Fall">Fall</div>
</div>
<div class="panel-side esri-widget">
<ul id="list_graphics">
<li>Loading…</li>
</ul>
</div>
<div id="viewDiv"></div>
<div id="titleDiv" class="esri-widget">
<div id="titleText">Flash Floods by Season</div>
<div>Flash Flood Warnings (2002 - 2012)</div>
</div>
</div>
</body>
</html>
我只是把东西移了一点,所以每次用户用季节过滤时,侧板的列表都会更新.现在,你会看到,我不查询一个新的季节,我只是过滤我们已经拥有的图形.每次进行新的查询时,列表都会以同样的方式进行过滤。
我还试图在下拉列表中添加一个选项来清除或过滤和重置侧板。我已经添加了一个on-click事件,它可以清除过滤器,但它没有重置侧面板。
任何帮助将是非常感激的。
require([
"esri/views/MapView",
"esri/Map",
"esri/layers/FeatureLayer",
"esri/widgets/Expand"
], function(MapView, Map, FeatureLayer, Expand) {
const listNode = document.getElementById("list_graphics");
const seasonsNodes = document.querySelectorAll(`.season-item`);
const seasonsElement = document.getElementById("seasons-filter");
let layer, map, view;
let selectedSeason = null;
let floodLayerView;
let graphics = null;
// functions
const filterBySeason = function (event) {
selectedSeason = event.target.getAttribute("data-season");
floodLayerView.filter = {
where: "Season = '" + selectedSeason + "'"
};
document
.getElementById("filterReset")
.addEventListener("click", function() {
floodLayerView.filter = selectedSeason;
});
updateList();
};
const updateList = function () {
if (!graphics) {
return;
}
const fragment = document.createDocumentFragment();
graphics.forEach(function(result, index) {
const attributes = result.attributes;
if (!selectedSeason || attributes.SEASON === selectedSeason) {
const name = attributes.IssueDate;
// Create the list
const li = document.createElement("li");
li.classList.add("panel-result");
li.tabIndex = 0;
li.setAttribute("data-result-id", index);
li.textContent = name;
fragment.appendChild(li);
}
});
// Empty the current list
listNode.innerHTML = "";
listNode.appendChild(fragment);
};
// flash flood warnings layer
layer = new FeatureLayer({
portalItem: {
id: "f9e348953b3848ec8b69964d5bceae02"
},
outFields: ["SEASON", "IssueDate"]
});
map = new Map({
basemap: "gray-vector",
layers: [layer]
});
view = new MapView({
map: map,
container: "viewDiv",
center: [-98, 40],
zoom: 10
});
// click event handler for seasons choices
seasonsElement.addEventListener("click", filterBySeason);
view.whenLayerView(layer).then(function(layerView) {
/*
filter
*/
floodLayerView = layerView;
// set up UI items
seasonsElement.style.visibility = "visible";
const seasonsExpand = new Expand({
view: view,
content: seasonsElement,
expandIconClass: "esri-icon-filter",
group: "top-left"
});
//clear the filters when user closes the expand widget
view.ui.add(seasonsExpand, "top-left");
view.ui.add("titleDiv", "bottom-left");
/*
query
*/
layerView.watch("updating", function(value) {
if (!value) {
// wait for the layer view to finish updating
// query all the features available for drawing.
layerView
.queryFeatures({
geometry: view.extent,
returnGeometry: true,
orderByFields: ["IssueDate"]
})
.then(function (results) {
graphics = results.features;
updateList();
})
.catch(function(error) {
console.error("query failed: ", error);
});
}
});
});
/*
query
*/
// listen to click event on list items
listNode.addEventListener("click", onListClickHandler);
function onListClickHandler(event) {
const target = event.target;
const resultId = target.getAttribute("data-result-id");
// get the graphic corresponding to the clicked item
const result =
resultId && graphics && graphics[parseInt(resultId, 10)];
if (result) {
// open the popup at the centroid of polygon
// and set the popup's features which will populate popup content and title.
view
.goTo(result.geometry.extent.expand(2))
.then(function() {
view.popup.open({
features: [result],
location: result.geometry.centroid
});
})
.catch(function(error) {
if (error.name != "AbortError") {
console.error(error);
}
});
}
};
});
</script>```