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:
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().
Solved! Go to Solution.
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.
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;
}
}
}
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!
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.
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.
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.
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;
}
}
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.