Hi,
Is it possible to get the current count of a feature layer without using the underlying feature class or having to iterate through a search and incrementing a counter? I have a layer that was created using a selection and I've tried getting the count of that layer but it only displays the count based on the underlying feature class.
Solved! Go to Solution.
I don't see another way, however, i think processing will be fast since the layer data is cached in memory. Here is my sample:
3141 records in 0.017 seconds.
These are the code changes to measure the timing:
// count rows in each feature layer
StringBuilder result = new StringBuilder();
await QueuedTask.Run(() =>
{
foreach (FeatureLayer layer in featureLayers)
{
// Get the row count for the feature layer
// this is not working since it is getting the underlying table (which has all records in
// the case where a layer is created with a 'select' clause
// long rowCount = layer.GetTable().GetCount();
// create a cursor for the layer (not the table)
var rowCursor = layer.Search();
long rowCount = 0;
var timer = new Stopwatch();
timer.Start();
while (rowCursor.MoveNext())
{
rowCount++;
}
timer.Stop();
var elapsedTime = timer.Elapsed;
result.AppendLine($"{layer.Name}: {rowCount} rows {elapsedTime:m\\:ss\\.fff} min.");
}
});
// Show the result in a message box
MessageBox.Show(result.ToString(), "Row Count Results", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
If you select all features in the newly created layer you can use GetSelection () and the selection count on the layer, otherwise you have to use a RowCursor on the FeatureLayer itself (not on the underlying FeatureClass or Table):
try
{
// get all feature layers in the current map
var map = MapView.Active.Map;
if (map == null)
{
MessageBox.Show("No active map found.", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
return;
}
var featureLayers = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().ToList();
if (featureLayers.Count == 0)
{
MessageBox.Show("No feature layers found in the active map.", "Information", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
return;
}
// count rows in each feature layer
StringBuilder result = new StringBuilder();
await QueuedTask.Run(() =>
{
foreach (FeatureLayer layer in featureLayers)
{
// Get the row count for the feature layer
// this is not working since it is getting the underlying table (which has all records in
// the case where a layer is created with a 'select' clause
// long rowCount = layer.GetTable().GetCount();
// create a cursor for the layer (not the table)
var rowCursor = layer.Search();
long rowCount = 0;
while (rowCursor.MoveNext())
{
rowCount++;
}
result.AppendLine($"{layer.Name}: {rowCount} rows");
}
});
// Show the result in a message box
MessageBox.Show(result.ToString(), "Row Count Results", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
}
catch (Exception ex)
{
MessageBox.Show($"An error occurred: {ex.Message}", "Error", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Error);
}
Thank you for the reply Wolf, is there any way you would suggest doing the count on a layer that has thousands or tens of thousands of features? I think having to select all features or iterating through each row would cause delay.
I don't see another way, however, i think processing will be fast since the layer data is cached in memory. Here is my sample:
3141 records in 0.017 seconds.
These are the code changes to measure the timing:
// count rows in each feature layer
StringBuilder result = new StringBuilder();
await QueuedTask.Run(() =>
{
foreach (FeatureLayer layer in featureLayers)
{
// Get the row count for the feature layer
// this is not working since it is getting the underlying table (which has all records in
// the case where a layer is created with a 'select' clause
// long rowCount = layer.GetTable().GetCount();
// create a cursor for the layer (not the table)
var rowCursor = layer.Search();
long rowCount = 0;
var timer = new Stopwatch();
timer.Start();
while (rowCursor.MoveNext())
{
rowCount++;
}
timer.Stop();
var elapsedTime = timer.Elapsed;
result.AppendLine($"{layer.Name}: {rowCount} rows {elapsedTime:m\\:ss\\.fff} min.");
}
});
// Show the result in a message box
MessageBox.Show(result.ToString(), "Row Count Results", System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Information);
That worked great thank you!