Arcade Intersects area wrong; combine multiple soils in report

526
2
Jump to solution
12-06-2022 11:07 AM
Labels (1)
LyonMNGIS
Occasional Contributor II

Hello,

I am having trouble creating an arcade script that will report the number of soil acres by type for a given parcel.  I am having two issues with the combined script that calculates the soil area as a percentage and as total acres.

Issue 1:

The intersect function is multiplying the total acres by 2)  The purple line below shows how I need to divide the acreage by 2

Issue 2:

I would like to combine (dissolve) similar soil types in my popup. In the example below "Amiret loam, 2-6 percent slopes" occurs in two different polygons.  One of them lists 0.27 acres while the other lists 3.74 acres.Is there a way to combine these records so that "Amiret loam, 2-6 percent slopes" is only listed once with a total of 4.01 acres?

*note this second issue is not related to the first!

LyonMNGIS_0-1670352589232.png

LyonMNGIS_1-1670353090950.png

 

//list soils in a parcel by type and acreage.

//get the features from the soil layer is overlaped by the parcel layer
var gensoils = Intersects(FeatureSetByName($map,"gensoils"),$feature)

//return the number of soil types wihtin the boundary of the selected parcel
var numsoil = Count(gensoils)

//Set the variable to hold the total amount of area of the soils within the selected soils
var soil_sum = 0;

//begin the results variable to show on popup
var results = 'There are ' + numsoil + ' types(s) of General Soils.' + textFormatting.NewLine

//return the area of each soil (usinf a for loop) within the boundary of the parcel
//add each area to the soil_sum variable
for (var s in gensoils){
  soil_sum += Area(Intersection($feature, s),'acre')/2
}

results += "The Total Area of the parcel is " + round(soil_sum,2) + " Acre(s)" + TextFormatting.NewLine

//using another for loop cycle through the soils creating several variables. Append text to the results variable.

for (var g in gensoils){
var soil_area = Area(Intersection($feature, g),'acre')/2
var soil_percent = (soil_area / soil_sum) * 100
var soilname = g.muname
results += TextFormatting.NewLine + soilname + '----' + round(soil_percent,2) + "%";
results += " or " + round(soil_area,2) + " ac(s)";
//results += TextFormatting.NewLine + soilname + '----' + round(soil_percent,2) + "%";
//results += TextFormatting.NewLine + soilname + '----' + round(soil_area,2) + " ac(s)";
//results += TextFormatting.NewLine + " - " + soilname + " - " + round((Area(Intersection($feature, timber),"acres")* ratio),2) + " +/- ac(s)";
}

//return results to the populated popup
return results

Tags (3)
0 Kudos
1 Solution

Accepted Solutions
JohannesLindner
MVP Frequent Contributor

Your first problem (Having to halve the area):

No idea. I can't reproduce this, all areas are the same as when i measure them manually in Pro. The most obvious reason could be that you have doubled soil polygons. Also, compare the soil area sum against the parcel area. They should be the same.

 

Your second problem (combine areas of the same type):

Use a dictionary with the soil type as keys. If you encounter a type the first time, store its area. If you encounter it again, add its area to the stored one.

 

//list soils in a parcel by type and acreage.

//get the features from the soil layer is overlaped by the parcel layer
var gensoils = Intersects(FeatureSetByName($map,"gensoils"),$feature)

// create a dictionary that stores the areas for each soil type
var soil_areas = Dictionary()
// create a variable that stores the sum of all soil areas
var soil_area_sum = 0

// loop over the soil polygons
for(var s in gensoils) {
    // get the area of the intersection
    var a = Area(Intersection($feature, s), "acre")
    // add it to the sum
    soil_area_sum += a
    // store it in the dict
    var type = s.muname
    if(HasKey(soil_areas, type)) {
        soil_areas[type] += a
    } else {
        soil_areas[type] = a
    }
}

// get some general result info
var result = [
    `The total area of the parcel is ${Round(Area($feature, "acres"))} Acre(s).`,
    `The total area of soil in this parcel is ${Round(soil_area_sum)} Acre(s).`,
    `There are ${Count(gensoils)} type(s) of General Soils.`
]
// loop over the soil types and append their area and percentage
for(var type in soil_areas) {
    var a = soil_areas[type]
    var p = a / soil_area_sum * 100
    Push(result, `${type} ---- ${Round(p, 2)}% or ${Round(a, 2)} ac(s)`)
}
return Concatenate(result, TextFormatting.NewLine)

JohannesLindner_0-1670402793022.pngJohannesLindner_1-1670402808026.png

 


Have a great day!
Johannes

View solution in original post

2 Replies
JohannesLindner
MVP Frequent Contributor

Your first problem (Having to halve the area):

No idea. I can't reproduce this, all areas are the same as when i measure them manually in Pro. The most obvious reason could be that you have doubled soil polygons. Also, compare the soil area sum against the parcel area. They should be the same.

 

Your second problem (combine areas of the same type):

Use a dictionary with the soil type as keys. If you encounter a type the first time, store its area. If you encounter it again, add its area to the stored one.

 

//list soils in a parcel by type and acreage.

//get the features from the soil layer is overlaped by the parcel layer
var gensoils = Intersects(FeatureSetByName($map,"gensoils"),$feature)

// create a dictionary that stores the areas for each soil type
var soil_areas = Dictionary()
// create a variable that stores the sum of all soil areas
var soil_area_sum = 0

// loop over the soil polygons
for(var s in gensoils) {
    // get the area of the intersection
    var a = Area(Intersection($feature, s), "acre")
    // add it to the sum
    soil_area_sum += a
    // store it in the dict
    var type = s.muname
    if(HasKey(soil_areas, type)) {
        soil_areas[type] += a
    } else {
        soil_areas[type] = a
    }
}

// get some general result info
var result = [
    `The total area of the parcel is ${Round(Area($feature, "acres"))} Acre(s).`,
    `The total area of soil in this parcel is ${Round(soil_area_sum)} Acre(s).`,
    `There are ${Count(gensoils)} type(s) of General Soils.`
]
// loop over the soil types and append their area and percentage
for(var type in soil_areas) {
    var a = soil_areas[type]
    var p = a / soil_area_sum * 100
    Push(result, `${type} ---- ${Round(p, 2)}% or ${Round(a, 2)} ac(s)`)
}
return Concatenate(result, TextFormatting.NewLine)

JohannesLindner_0-1670402793022.pngJohannesLindner_1-1670402808026.png

 


Have a great day!
Johannes
LyonMNGIS
Occasional Contributor II

Perfect!

I was too distracted with the doubling issue before considering arrays in Arcade (which is cool that you can do in popups).  Reloading the project eliminated the doubling issue.

I also noticed that I need to iterate the soil type count near line 21-23.

 

 

0 Kudos