2

I am trying to create a script in C# that would look into a geodatabase in ArcGIS Pro, which has multiple geodatabase tables and do some simple math using the fields in these tables. I want to be able to reuse this script for multiple fields within these tables to calculate different soil properties, since the math logic and sequences are the same. For this script, the two geodatabase tables are "component" and "horizon." The common field within both tables is a unique field called "cokey." Basically, a set of cokeys are looked-up. For each cokeys in the component table, in the horizon table, there are a set of fields associated with that cokey. I am relatively new to C# and ArcGIS Pro for.Net. Therefore, the script below is my draft attempt.

How do I look-up the specific fields I need to perform my calculations based on the soil property I need to calculate?

If you look at line 19 & 20 and 26 & 27 are the lines where I tried to declare the variables, cokey and rCompPercent for the fields,"cokey" and "comppet_r" and to initialize it. I wrote a do while loop, which will run till it loops through all the looked-up cokeys. I want to calculate the minimum value (rlow) and the highest value (rhigh) within a set of rows associated with the look-up cokey (rlow_value, rhigh_value) and the representative value, which is the calculation on line 50.

public double Chorizon([mukey, awc_1, awc_r, awc_h, compTable])
 {
 using (Geodatabase compTable = Geodatabase.OpenDataset<Table>("gSURRGO_CA.GDB.component"))
            {

                try
                {
                    var cokey = row["cokey"];
                    var rCompPercent = row["comppet_r"]
                    int i = 0;
                    int nu_cokey = 0;

                    do
                    {
                        cokey = Row.value.cokey
                        rCompPercent = Row.value.cokey
                        nu_cokey += i;
                        i++;

                        var rThick = 0;
                        var rLow = 0;
                        var rRep = 0;
                        var rHigh = 0;

  //Calculating the total soil depth thickness and properties of the field 

                        if (iStat = 0)
                        {
                            var botDepth = Row["hzdepb_r"];
                            var topDepth = Row["hzdept_r"];
                            var rLow =Row[sField_l];
                            var rRep = Row[sField_r];
                            var rHigh = Row[sField_h];

                            for (var x = 0; x >nu_cokey;x++)
                            {   
                                rThick = botDepth - topDepth;
                                rLow = Math.Min(rLow, rLow_Value);
                                rRep=rRep+rThick+rValue_Rep
                                var rRep_total = rThick + rRep;
                                rHigh=Math.Max(rHigh,rValue_High)
                            }
                        }
                       
                        var rRep_mu = rRep_total / (rThick_Sum / (rThick_Sum * rCompPercent));
                        var rCompPercent_Sum = rCompPercent++
                    } while cokey != 0;

                }
0

1 Answer 1

1

You're on the right track. In the ArcGIS Pro SDK, you can access a feature's fields by using indexers on the feature object. This can either be the 0th-based index value (if you know it; otherwise, there are methods available to get it), or the name of the field. For example, the following should return the same value:

var cokeyValue = feature[5]; //assuming the field's index is 5
var cokeyValue = feature["cokey"];

Getting access, however, to the individual features generally requires opening a search cursor on the table that houses the feature, which you then iterate over to get the features, one by one. Here's a basic example, with notes in the comments throughout the code:

//wrapping it in the QueuedTask.Run ensures that your search is run on the right thread.
        await QueuedTask.Run(() =>
        {

        //open the geodatabase; this will vary based on what kind of database you are trying to open.
        using (Geodatabase gdb = new Geodatabase(new DatabaseConnectionFile(new Uri(@"C:\data\SDE_Files\mydatabase.sde"))))
        {
            //open the component table as well
            using (Table compTable = gdb.OpenDataset<Table>("gSURRGO_CA.GDB.component"))
            {
                //to read the feature (and the coKeys), you need a cursor, which you then loop over
                //passing null as the parameter in the search method returns you all the features
                using (RowCursor rowCursor = compTable.Search(null))
                {
                    while (rowCursor.MoveNext())
                    {
                        using (Row componentRow = rowCursor.Current)
                        {
                            var cokey = componentRow["cokey"];
                            //do whatever you need to do here to store the individual cokeys to look them up for your horizon table.
                        }
                    }
                }

            }

            //now the horizon feature class/table, which needs to be opened separately than the components table
            using (Table horizonTable = gdb.OpenDataset<Table>("gSURRGO_CA.GDB.horizon"))
            {
                //here it's a repeat of above.  to find the feature that relates to each of the cokeys you got from the component table, you could do 
                //a QueryFilter to retrieve just those features that match each cokey field gotten from the component table, which saves processing time.
                //Something like this:
                QueryFilter queryFilter = new QueryFilter() {WhereClause = "cokey = 8675309"};
                using (RowCursor horizonCursor = horizonTable.Search(queryFilter))
                {
                     while (horizonCursor.MoveNext())
                    {
                        using (Row horizonRow = horizonCursor.Current)
                        {
                            var botDepth = horizonRow["hzdepb_r"];
                            var topDepth = horizonRow["hzdept_r"];

                            //do the rest of your calculations
                        }

                    }
                }
            }

        });

If you haven't already looked at it, I'd point you to Esri's documentation on Github that goes into pretty good detail about the concepts behind accessing your data using the SDK. Specifically, these two pages will help get you started:

ProConcepts - Geodatabase and ProSnippets - Geodatabase

2
  • Thanks Turbo for your help! When I tried to perform my calculations (e.g. var rthick = botDepth - topDepth), there is an operator error (CS0019). How can I fix this problem? Thanks! Sep 13, 2021 at 21:09
  • @GIS_developer, No problem! According to Microsoft's help, CS0019 happens when the operator doesn't match the type that you are trying to use it with, for example when using subtraction with a string. I'd suggest checking the field type of the field you are reading from in Pro. Then, you would want to make sure that your code has the value stored in a variable with the right type before computing your rthick value. There are a number of ways to do that in C#, but that's a whole separate question.
    – Turbo
    Oct 5, 2021 at 5:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.