Select to view content in your preferred language

Dashboard Data Expression Intersects

289
11
Jump to solution
a week ago
Labels (1)
LukeGilner1
Frequent Contributor

I'm trying to set up some data expressions in Dashboards to use with Indictor widgets.  I have a tracts layer (322 features) and a lakes layer (11,200 features) and I want to intersect these to get the total number of lakes and a sum of lake acres in the Indicator.  Here is the code, which appears to work, but takes about 20 minutes to run.  What can I do to speed this up?  Can I run an intersection before the loop to filter out most of the lakes?  There should only be about 1,020 lakes that actually intersect with the tracts.  I only know a little Arcade; most of this was done with the help of CoPilot.

var port = Portal("https://www.arcgis.com");

// Load layers with correct area field name
var tracts = FeatureSetByPortalItem(port, "b9fcbedac0384e32bc3dba6aec1a8cf6", 0, ["OBJECTID"], true);
var lakes = FeatureSetByPortalItem(port, "5564b2e702364aefba08df8c95216a1f", 0, ["OBJECTID", "Shape__Area_2"], true);

var fsDict = {
    fields: [
        { name: "OBJECTID", type: "esriFieldTypeOID" },
        { name: "LakeCount", type: "esriFieldTypeInteger" },
        { name: "Acres", type: "esriFieldTypeDouble" }
    ],
    geometryType: "",
    features: []
};

for (var t in tracts) {
    var tractGeom = Geometry(t);
    var lakeCount = 0;
    var totalAcres = 0;

    for (var lake in lakes) {
        if (Intersects(Geometry(lake), tractGeom)) {
            lakeCount += 1;
            totalAcres += lake["Shape__Area_2"] / 4046.8564224;
        }
    }

    Push(fsDict.features, {
        attributes: {
            OBJECTID: t.OBJECTID,
            LakeCount: lakeCount,
            Acres: Round(totalAcres, 1)
        }
    });
}

return FeatureSet(fsDict)

 

0 Kudos
11 Replies
MiaWhite34
Emerging Contributor

The main slowdown comes from looping all 11,200 lakes for every tract. To speed it up, you can filter lakes first using Intersects with the entire tracts layer or Filter on the lakes FeatureSet. Example:

var intersectingLakes = Filter(lakes, Intersects(lakes, Union(tracts)));


Then loop over only intersectingLakes, reducing the number of comparisons from 11,200 to ~1,020. Also, use Geometry(lake) once per lake outside inner loops if possible, to avoid repeated geometry calculations.

This approach can cut runtime from 20 minutes to a few seconds.

0 Kudos
LukeGilner1
Frequent Contributor

@MiaWhite34 could you show your recommendation using the code from the post marked as solution?  I'm still very new to arcade so the exact code would be helpful.

0 Kudos