Hello,
I am curious if there is anything to do to optimize discovery of the layers in a geodatabase. Basically I am creating a tree of the datasets, layers, and other tables - much like ArcCatalog would. Here is what I have now. I am wondering if using LINQ may offer performance boosts or if there are any other suggestions to speed up the method.
Thanks in advance, -Bil
internal int GetEsriDatasetMap(
int message_id,
bool include_tables,
bool layer_names_only)
{
// Get all the feature datasets and the classes in them.
// ESRI databases have proper datasets containing feature classes as well
// as improper datasets which are feature classes with no enclosing dataset.
// Find all the proper datasets, verify their CRS is WGS84 and
// if so collect their feature classes. Then find all the improper datasets
// which are feature classes without an enclosing dataset. These also
// have a CRS which must be WGS84.
// Feature classes within an enclosing dataset have the same CRS as the dataset.
int error = -1;
//EsriMessageBox.DisplayMessage("Attach debugger bish");
if (m_dataset_map == null) {
m_dataset_map = new EsriDatasetMap();
}
// Check to see if this has already been done
if (m_dataset_map.Count > 0)
{
error = 0;
EsriLogger.Log("Datasets already figured. Moving along.");
}
else
{
string empty_dataset_name = SEE_NO_DATASET;
List<String> all_layer_names = new List<string>();
List<string> layer_names_in_datsets = new List<string>();
string layer_name = "";
IReadOnlyList<FeatureClassDefinition> featureClassDefinitions = geodb.GetDefinitions<FeatureClassDefinition>();
IEnumerable<Definition> featureClasses = featureClassDefinitions;
foreach (var fc in featureClasses)
{
layer_name = fc.GetName();
DatasetType fc_dst = fc.DatasetType;
all_layer_names.Add(layer_name);
m_layer_names.Add(layer_name);
//EsriLogger.Log("Layer name is: " + layer_name + ". Type is: " + fc_dst);
}
if (include_tables)
{
IReadOnlyList<TableDefinition> tableDefinitions = geodb.GetDefinitions<TableDefinition>();
IEnumerable<Definition> tables = tableDefinitions;
foreach (var table in tables)
{
layer_name = table.GetName();
DatasetType td = table.DatasetType;
m_layer_names.Add(layer_name);
//EsriLogger.Log("Table name is: " + layer_name + ". Type is: " + td);
}
}
error = 0;
m_layer_names.Sort();
// Sometime after release 2.2 dataset definitions were added making it possible to
// get the layers in their respective datasets instead of flattening all of thrm under
// one dataset.
// Get feature datasets
IReadOnlyList<Definition> feature_datasets_list = geodb.GetDefinitions<FeatureDatasetDefinition>();
// Get all the feature classes under their respective dataset folders and package them up
// to send back to SGXP.
foreach (var feature_dataset in feature_datasets_list)
{
EsriLogger.Log("feature_dataset name is: " + feature_dataset.GetName() + ". Type is: " + feature_dataset.GetType());
var defsInDataset = geodb.GetRelatedDefinitions(feature_dataset, DefinitionRelationshipType.DatasetInFeatureDataset);
List<String> classes = new List<string>();
bool ds_has_features = false;
foreach (var def in defsInDataset)
{ //Or use LINQ .Where( d => d.DatasetType ...
EsriLogger.Log("def name is: " + def.GetName() + ". Type is: " + def.GetType());
if (def.DatasetType == DatasetType.FeatureClass)
{
classes.Add(def.GetName());
m_layer_names.Add(def.GetName());
ds_has_features = true;
layer_names_in_datsets.Add(def.GetName());
}
}
if (ds_has_features)
{
m_dataset_map.Add(feature_dataset.GetName(), classes);
}
}
// Add all features not in datasets or just tables
List<string> layers_not_in_datasets = new List<string>();
foreach (var lyr_name in m_layer_names)
{
if (!layer_names_in_datsets.Contains(lyr_name))
{
layers_not_in_datasets.Add(lyr_name);
}
}
if (layers_not_in_datasets.Count > 0)
{
m_dataset_map.Add(empty_dataset_name, layers_not_in_datasets);
}
}
// Pack up the byte stream and send the result via IPC
int command = SEE_DATASET_MAP_POPULATED;
int total_len = DEFAULT_BUFLEN;
int offset = EsriUtil.CreateMessageHeader(out byte[] message, total_len, command, message_id, error);
// serialize the map.
EsriUtil.AddInt(m_dataset_map.Count, ref message, ref offset);
foreach (var dm in m_dataset_map) {
// name of the dataset
EsriUtil.AddStringWithLength(dm.Key, ref message, ref offset);
// number of layers in this dataset
EsriUtil.AddInt(dm.Value.Count, ref message, ref offset);
foreach (var layer in dm.Value) {
// layer names in this dataset
EsriUtil.AddStringWithLength(layer, ref message, ref offset);
}
}
EsriManager.Instance.SendMessage(message);
return error;
}