Problem using "Shape.STLength()" field in the CalculateStatistics method

1147
7
Jump to solution
11-06-2019 03:36 PM
StuartBricker
New Contributor III

I am writing a reporting application so the boss can quickly get the number of linear miles in a variety of polyline feature classes. I am using the .CalculateStatistics method based on the examples on Github. The following code works precisely as intended for all numeric fields except "Shape.STLength()", which unfortunately is the field I need. The code is as follows:

double GetLength(FeatureClass fc)
{
    try
    {
         using (FeatureClassDefinition fcd = fc.GetDefinition())
         {
             Field LengthField = fcd.GetFields().FirstOrDefault(x => x.Name.Equals("Shape.STLength()")); //"PIPEDIAM" and other numeric fields work fine, Shape.STLength() fails, as does fcd.GetLengthField();
             if (LengthField == null) return 0;
             Debug.WriteLine(LengthField.Name); // Output is "Shape.STLength()" as expected

             StatisticsDescription SumDesc = new StatisticsDescription(LengthField, new List<StatisticsFunction>() { StatisticsFunction.Sum });
             TableStatisticsDescription tsd = new TableStatisticsDescription(new List<StatisticsDescription>() { SumDesc });

             return fc.CalculateStatistics(tsd).FirstOrDefault().StatisticsResults.FirstOrDefault().Sum; // exception is thrown on this line
          }
     }
     catch (Exception ex)
     {
             ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.ToString(), "Error");
             return 0;
     }
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

The exception that is thrown on line 14 is as follows:

Error image

Again, it is noteworthy that everything works fine when I set the fieldname on line 7 to any numeric (double) field other than Shape.STLength(). 

0 Kudos
1 Solution

Accepted Solutions
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Your assumption was correct.  The dev team for the statistics class(es) is planning a fix for one of the upcoming releases.  It's too late for the fix to make it into the 2.5 release though.

View solution in original post

7 Replies
Wolf
by Esri Regular Contributor
Esri Regular Contributor

What kind of a feature class are you using?   If I use the community sample data, specifically the 'FeatureTest' data (TestLines feature class) your method works fine if I use Shape_Length  instead of Shape.STLength() ....

    internal class CalcStats : Button
    {
        protected override void OnClick()
        {
            try
            {
                var featureLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(fl => fl.Name.Contains("TestLines")).FirstOrDefault();
                var len = QueuedTask.Run(() =>
                {
                    var fc = featureLayer.GetFeatureClass();
                    return GetLength(fc);
                });
                MessageBox.Show($@"Len: {len.Result}");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString(), "Error");
            }
        }

        double GetLength(FeatureClass fc)
        {
            try
            {
                using (FeatureClassDefinition fcd = fc.GetDefinition())
                {
                    Field LengthField = fcd.GetFields().FirstOrDefault(x => x.Name.Equals("Shape_Length")); //"PIPEDIAM" and other numeric fields work fine, Shape.STLength() fails, as does fcd.GetLengthField();
                    if (LengthField == null) return 0;
                    System.Diagnostics.Debug.WriteLine(LengthField.Name); // Output is "Shape.STLength()" as expected

                    StatisticsDescription SumDesc = new StatisticsDescription(LengthField, new List<StatisticsFunction>() { StatisticsFunction.Sum });
                    TableStatisticsDescription tsd = new TableStatisticsDescription(new List<StatisticsDescription>() { SumDesc });

                    return fc.CalculateStatistics(tsd).FirstOrDefault().StatisticsResults.FirstOrDefault().Sum; // exception is thrown on this line
                }
            }
            catch (Exception ex)
            {
                ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show(ex.ToString(), "Error");
                return 0;
            }
        }
    }
0 Kudos
StuartBricker
New Contributor III

Hi Wolfgang! Thanks for your help.

I am passing a SQL Server Enterprise Geodatabase polyline feature class into the GetLength method. The length field for all of our polyline feature classes is Shape.STLength() as per the attached screen capture. During troubleshooting, I added a Debug.WriteLine(fcd.GetLengthField().ToString()); line, and the output was "Shape.STLength()".

I notice that for file geodatabases, the length field is "Shape_Length", but for all of our Enterprise SDE databases, the length field is "Shape.STLength()".

Thanks again!

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

I created a SQL Server enterprise geodatabase with a line feature class and I am getting the same exception.  I will check with the Geodatabase team.  

0 Kudos
StuartBricker
New Contributor III

Thanks again Wolfgang. I really appreciate you looking into this. I strongly suspect that it is related to either the dot or parentheses in the field name.

0 Kudos
Wolf
by Esri Regular Contributor
Esri Regular Contributor

Your assumption was correct.  The dev team for the statistics class(es) is planning a fix for one of the upcoming releases.  It's too late for the fix to make it into the 2.5 release though.

Wolf
by Esri Regular Contributor
Esri Regular Contributor

If you just need to get the 'sum' of all lengths, then you can use the following workaround for the time being:

        double GetLength(FeatureClass fc)
        {
            try
            {
                using (FeatureClassDefinition fcd = fc.GetDefinition())
                {
                    Field LengthField = fcd.GetFields().FirstOrDefault(x => x.Name.Equals("Shape.STLength()")); //"PIPEDIAM" and other numeric fields work fine, Shape.STLength() fails, as does fcd.GetLengthField();
                    if (LengthField == null) return 0;
                    System.Diagnostics.Debug.WriteLine(LengthField.Name); // Output is "Shape.STLength()" as expected
                    double totalLen = 0.0;
                    var cur = fc.Search();
                    while (cur.MoveNext())
                    {
                        var feat = cur.Current;
                        totalLen += Convert.ToDouble(feat["Shape.STLength()"]);

                        
                    }
                    return totalLen;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
0 Kudos
PCK
by
New Contributor

Hello, I am having a similar issue in ArcMap 10.8.1. Our dataset lives on a SQL Server and I am trying to use the SHAPE.STLength() in a calculation using Field Calculator.  Is there a solution to this with ArcMap?  The field I'm doing the calculation in is also a Double field. I am basically calculating the Slope of a pipe using the Up Elevation and Down Elevation. My calculation is ((abs( !UPELEV! - !DOWNELEV! ))/!SHAPE.STLength()!)*100. Thanks.

0 Kudos