How to calculate intersected areas in Arcade?

811
5
Jump to solution
07-01-2020 08:26 AM
DeborahHide
New Contributor II

Two questions I suppose - is it possible to calculate the overlapping areas of two separate polygon layers in Arcade? And if so, how?

I have two layers - land blocks and survey areas. For each of the survey areas, I want to know what area of it intersects/overlaps with the blocks. It might be completely within a block, completely outside a block, or partially intersecting. If I was doing this via geoprocessing in Pro, I'd probably use the Summarize Within tool. However I'm looking for an equivalent in ArcGIS Online that calculates the overlapping areas into a field within the survey areas layer.

I've been looking at the Intersection Arcade function, but struggling and can't find any examples of Intersection in use (it's all Intersects).

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
XanderBakker
Esri Esteemed Contributor

Hi Deborah Hide ,

With a couple of adjustments you get the result you are after:

var blocks = Intersects(FeatureSetByName($datastore, "Blocks"), $feature);
var cnt = Count(blocks);

var intersectArea = 0;
if (cnt > 0) {
// we have overlapping blocks, loop through blocks
for (var block in blocks) {
// intersect with polygon, and add area to the total
intersectArea += Area(Intersection($feature, block), "hectare");
}
}

return Round(intersectArea, 2);‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Which will result in:

Notice that I switched off the Union (a union requieres two or more geometries to be successful) since this would make the processing time larger. I recommend you not to use it unless your blocks are regions and have overlap. If this is not the case, you do not need it. 

You can also enhance the result by including more information, for instance the percentage of the area that has overlap with the blocks and perhaps information of the blocks that overlap. See below (I blurred parts of it since I don't know if it contains sensitive data):

To do this, you would need the expression below:

var blocks = Intersects(FeatureSetByName($datastore, "Blocks"), $feature);
var cnt = Count(blocks);

var intersectArea = 0;
if (cnt > 0) {
// we have overlapping blocks, loop through blocks
var blocknames = "Block names:";
for (var block in blocks) {
// intersect with polygon, and add area to the total
intersectArea += Area(Intersection($feature, block), "hectare");
blocknames += TextFormatting.NewLine + " - " + block.extent;
}
// calculate the percentage of overlap
var zoneArea = Area($feature, "hectare");
var percentage = Round(intersectArea * 100.0 / zoneArea, 1);
// format the resulting text
var result = cnt + " Building block(s) found:"
result += TextFormatting.NewLine + " - Test Area : " + Round(zoneArea, 2) + " ha.";
result += TextFormatting.NewLine + " - Overlap Area: " + Round(intersectArea, 2) + " ha.";
result += TextFormatting.NewLine + " - Percentage Overlap: " + percentage + "%";
result += TextFormatting.NewLine + blocknames;
return result;
} else {
return "No overlap with building blocks..."
}

View solution in original post

5 Replies
XanderBakker
Esri Esteemed Contributor

Hi Deborah Hide ,

It is possible to determine the intersected area of a polygon with a layer of polygons. It would start with reading out the current feature (the survey area) and use the Intersects function to filter those land blocks that intersect with the survey area. If you have any results, you would loop through the land blocks and use the Intersection function to create a new geometry with the intersecting area. Then you would sum the areas and compare it to the area of the survey area to determine the percentage of survey area covered by land blocks. This is assuming the land block do not have overlap with other land blocks. If that would be the case, you would need to use the Union first on the land blocks that intersect with the  survey area.

If you are able to share the information (create a group, invite me using my ArcGIS Online user "xbakker.spx" and share the webmap and layers to that group), I would be able to help better.

Please also have a look at this post where the FEMA map is used to determine percentage of overlap: https://community.esri.com/message/897153-re-arcade-expression-intersecting-feature-sets-with-overla... 

0 Kudos
DeborahHide
New Contributor II

Hi Xander, thanks for your reply. I have tried to write an expression based on your suggestions but all values are coming out as zero so I'm obviously doing something wrong!

This is what I have so far:

var blocks = FeatureSetByName($datastore,"Blocks");

var intersectLayer = Intersects(blocks, $feature);
var cnt = Count(intersectLayer);

for (var block in blocks) {
if (cnt > 0) {
var blocksUnion = Union(block);
var intersectArea = Area(Intersection($feature, blocksUnion), "hectare");
return intersectArea;
} else {
return 0
}
}

If I take out lines 8-10 and put in "return 1" instead, I get a value of 1 for the correct (i.e. intersecting) features, so the count of the intersectLayer variable seems to work ok.

By the way I'm using Area instead of AreaGeodetic because my data needs to be in British National Grid coordinate system.


I've shared a sample dataset with you and invited you to my Arcade Test group. Any suggestions you can make are very welcome! Many thanks.

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi Deborah Hide ,

With a couple of adjustments you get the result you are after:

var blocks = Intersects(FeatureSetByName($datastore, "Blocks"), $feature);
var cnt = Count(blocks);

var intersectArea = 0;
if (cnt > 0) {
// we have overlapping blocks, loop through blocks
for (var block in blocks) {
// intersect with polygon, and add area to the total
intersectArea += Area(Intersection($feature, block), "hectare");
}
}

return Round(intersectArea, 2);‍‍‍‍‍‍‍‍‍‍‍‍‍‍

Which will result in:

Notice that I switched off the Union (a union requieres two or more geometries to be successful) since this would make the processing time larger. I recommend you not to use it unless your blocks are regions and have overlap. If this is not the case, you do not need it. 

You can also enhance the result by including more information, for instance the percentage of the area that has overlap with the blocks and perhaps information of the blocks that overlap. See below (I blurred parts of it since I don't know if it contains sensitive data):

To do this, you would need the expression below:

var blocks = Intersects(FeatureSetByName($datastore, "Blocks"), $feature);
var cnt = Count(blocks);

var intersectArea = 0;
if (cnt > 0) {
// we have overlapping blocks, loop through blocks
var blocknames = "Block names:";
for (var block in blocks) {
// intersect with polygon, and add area to the total
intersectArea += Area(Intersection($feature, block), "hectare");
blocknames += TextFormatting.NewLine + " - " + block.extent;
}
// calculate the percentage of overlap
var zoneArea = Area($feature, "hectare");
var percentage = Round(intersectArea * 100.0 / zoneArea, 1);
// format the resulting text
var result = cnt + " Building block(s) found:"
result += TextFormatting.NewLine + " - Test Area : " + Round(zoneArea, 2) + " ha.";
result += TextFormatting.NewLine + " - Overlap Area: " + Round(intersectArea, 2) + " ha.";
result += TextFormatting.NewLine + " - Percentage Overlap: " + percentage + "%";
result += TextFormatting.NewLine + blocknames;
return result;
} else {
return "No overlap with building blocks..."
}

View solution in original post

DeborahHide
New Contributor II

It works, thank you so much! Really appreciate your help and the time you've spent doing that.

0 Kudos
XanderBakker
Esri Esteemed Contributor

Hi deborah.hide.fls , 

I'm glad it works and my pleasure. If you have any follow-up question you can post them here and I will get a notification.

0 Kudos