Select to view content in your preferred language

How to query only visible Feature Layers with Draw Polygon (3.x)

1581
4
03-12-2021 03:13 AM
Den-GIS
Regular Contributor

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);
        });
0 Kudos
4 Replies
nita14
by
Frequent Contributor

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

0 Kudos
Den-GIS
Regular Contributor

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]";
        };

 

0 Kudos
nita14
by
Frequent Contributor

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

0 Kudos
Rice_GIS
Occasional Contributor

Adam,

What would the script look like to query only visible features on screen point in 4.x?

0 Kudos