Hi everyone,
I'm working on a slightly older app with ArcGIS JS API 3.x. I want to send a query only on the visible layers. The query works in such a way that a polygon is drawn by the user and only visible layers are queried. All other layers that are hidden should not be taken into account.
So far I have managed to draw a polygon and send a statistic definition query. It works OK. However, all layers are taken into account. And that's what I don't want
Here is my code. I am grateful for any help!
var fields = ["City", "System", "voltage", "kw"];
var fc_0 = new FeatureLayer("https://arcgis/rest/services/Tracks/MapServer/0", {
mode: FeatureLayer.MODE_ONDEMAND,
supportsStatistics: true,
outFields: ['*'],
visible: false,
id: "fLayer"
});
var fc_1 = new FeatureLayer("https://arcgis/rest/services/Tracks/MapServer/1", {
mode: FeatureLayer.MODE_ONDEMAND,
supportsStatistics: true,
outFields: ['*'],
visible: false,
id: "fLayer"
});
var fc_2 = new FeatureLayer("https://arcgis/rest/services/Tracks/MapServer/2", {
mode: FeatureLayer.MODE_ONDEMAND,
supportsStatistics: true,
outFields: ['*'],
visible: false,
id: "fLayer"
});
var fc_3 = new FeatureLayer("https://arcgis/rest/services/Tracks/MapServer/3", {
mode: FeatureLayer.MODE_ONDEMAND,
supportsStatistics: true,
outFields: ['*'],
visible: false,
id: "fLayer"
});
map.addLayers([fc_0, fc_1, fc_2, fc_3]);
/******Selection Symbol*****/
var color = new Color([48, 178, 255, 0.8]);
var selectionSymbol = new SimpleMarkerSymbol({
"color": color,
"size": 6,
"angle": -30,
"xoffset": 0,
"yoffset": 0,
"type": "esriSMS",
"style": "esriSMSCircle",
"outline": {
"color": [48, 255, 0, 0.3],
"width": 1,
"type": "esriSLS",
"style": "esriSLSSolid"
}
});
featureLayer.setSelectionSymbol(selectionSymbol);
/************************************************************************************************/
/*****StatistcDefinition*****/
var getKWH = new StatisticDefinition();
getKWH.statisticType = "sum";
getKWH.onStatisticField = "kw";
getKWH.outStatisticFieldName = "kwh";
var queryParams = new Query();
queryParams.outFields = fields;
queryParams.returnGeometry = true;
queryParams.outStatistics = [getKWH];
/******Draw Polygon*******/
map.on("load", createToolbar);
var polygonToolbar;
function createToolbar(themap) {
polygonToolbar = new Draw(map);
polygonToolbar.on("draw-end", getPolygon);
}
function activateTool() {
polygonToolbar.activate(Draw["POLYGON"])
//deactivate InfoWindow when the user clicks on the draw toolbar.
map.setInfoWindowOnClick(false);
}
function getPolygon(evt) {
if (evt.geometry.type == "polygon") {
polygonToolbar.deactivate();
}
var polygon = evt.geometry;
queryParams.geometry = polygon;
map.graphics.clear();
switch (evt.geometry.type) {
case "point":
case "multipoint":
symbol = new SimpleMarkerSymbol();
break;
case "polyline":
symbol = new SimpleLineSymbol();
break;
default:
symbol = new SimpleFillSymbol(SimpleFillSymbol.STYLE_SOLID,
new SimpleLineSymbol(SimpleLineSymbol.STYLE_LONGDASHDOT,
new Color([255, 0, 0, 1]), 3), new Color([125, 125, 125, 0.30]));
break;
}
var graphic = new Graphic(evt.geometry, symbol);
map.graphics.add(graphic)
// this Part query only one Feature Layer
fc_0.queryFeatures(queryParams, getStats, errback);
}
function getStats(results) {
var _sumkWh, _sum;
arrayUtils.forEach(results.features, function(feature) {
_sumkWh = feature.attributes.kwh;
_sum = _sumkWh.toFixed(2);
console.log("Sum kWH:", _sumkWh);
});
dom.byId("sumKWH").innerHTML = _sum + " " + "[kW]";
};
/**********Event handler for Polygon Tool ***********/
on(dom.byId('calculateButton'), 'click', function() {
activateTool();
});
on(dom.byId('clearCalculatationButton'), "click", function() {
$(".stats").empty();
map.graphics.clear();
map.setInfoWindowOnClick(true);
});
Hi Denis,
You can use the 'visible' property of a layer
https://developers.arcgis.com/javascript/3/jsapi/layer-amd.html#visible
if (fc_0.visible){
fc_0.queryFeatures(queryParams, getStats, errback);
};
BR,
Adam
Hi Adam,
Thank you for your help! I just tested it and it works. 🙂 Only visible layers are queried. That's great. With that I am one step further. But I have another problem, which I overlooked before: I use Statistic Definition to sum up query layers. However, what I get are separate sums of all query layers. The goal, however, is to create a total that includes all of the sums from all layers. I think my approach to solving this is not a good one. It's not good because I keep repeating the getStats() function. And because of the local variable scope, I can't get it out of function. I posted my code below. How can that solve, only query visible layers and then add their sums together. Thank you for your help in advance.
if (fc_0.visible){
fc_0.queryFeatures(queryParams, getStats, errback);
}else {
console.log("fc_0 isn't visible");
};
if (fc_1.visible){
fc_1.queryFeatures(queryParams, getStats1, errback);
}else {
console.log("fc_1 isn't visible");
};
if (fc_2.visible){
fc_2.queryFeatures(queryParams, getStats2, errback);
}else {
console.log("fc_2 isn't visible");
};
if (fc_3.visible){
fc_3.queryFeatures(queryParams, getStats3, errback);
}else {
console.log("fc_3 isn't visible");
};
if (fc_4.visible){
fc_4.queryFeatures(queryParams, getStats4, errback);
}else {
console.log("fc_4 isn't visible");
};
function getStats(results) {
var _sumkWh, _sum;
arrayUtils.forEach(results.features, function(feature) {
_sumkWh = feature.attributes.kwh;
_sum = _sumkWh.toFixed(2);
console.log("Sum kWH:", _sumkWh);
});
dom.byId("sumKWH").innerHTML = _sum + " " + "[kW]";
};
function getStats1(results) {
var _sumkWh, _sum;
arrayUtils.forEach(results.features, function(feature) {
_sumkWh = feature.attributes.kwh;
_sum = _sumkWh.toFixed(2);
console.log("Sum kWH:", _sumkWh);
});
dom.byId("sumKWH").innerHTML = _sum + " " + "[kW]";
};
function getStats2(results) {
var _sumkWh, _sum;
arrayUtils.forEach(results.features, function(feature) {
_sumkWh = feature.attributes.kwh;
_sum = _sumkWh.toFixed(2);
console.log("Sum kWH:", _sumkWh);
});
dom.byId("sumKWH").innerHTML = _sum + " " + "[kW]";
};
function getStats3(results) {
var _sumkWh, _sum;
arrayUtils.forEach(results.features, function(feature) {
_sumkWh = feature.attributes.kwh;
_sum = _sumkWh.toFixed(2);
console.log("Sum kWH:", _sumkWh);
});
dom.byId("sumKWH").innerHTML = _sum + " " + "[kW]";
};
function getStats4(results) {
var _sumkWh, _sum;
arrayUtils.forEach(results.features, function(feature) {
_sumkWh = feature.attributes.kwh;
_sum = _sumkWh.toFixed(2);
console.log("Sum kWH:", _sumkWh);
});
dom.byId("sumKWH").innerHTML = _sum + " " + "[kW]";
};
Hi Denis,
I reckon you need to take a look on tihis sample to manage your queries:
https://developers.arcgis.com/javascript/3/jssamples/query_deferred_list.html
BR,
Adam
Adam,
What would the script look like to query only visible features on screen point in 4.x?