In my add-in, I'm creating random points using a constraining feature class with the Create Random Points tool. However, since the tool creates the number of points for each feature in the constraining feature class, I first dissolve the feature class and use that as the constraining feature class. I use a temporary file name for the dissolved feature class and delete it after creating the points.
private Geodatabase MemoryGeodatabase; //set elsewhere
private SchemaBuilder MemorySchemaBuilder; //set elsewhere
MemoryConnectionProperties memoryConnectionProperties = new();
string tempFileName = Path.GetFileNameWithoutExtension(Path.GetTempFileName());
using (MemoryGeodatabase ??= SchemaBuilder.CreateGeodatabase(memoryConnectionProperties))
{
MemorySchemaBuilder ??= new(MemoryGeodatabase);
StatusMessage = $"Dissolving {SelectedFrameFeatureLayer.Name}...";
IGPResult dissolveResult = await DissolveFeatures(frameFeatureClass, "", "", $"memory\\{tempFileName}", GPExecuteToolFlags.AddToHistory);
if (dissolveResult.IsFailed)
{
Show_Status_Bar = false;
StatusMessage = "";
MessageBox.Show("Dissolving feature class failed");
return;
}
using (FeatureClass dissolveFC = MemoryGeodatabase.OpenDataset<FeatureClass>(tempFileName))
{
string Distance = "";
if (Use_Minimum_Distance && Minimum_Distance > 0) Distance = $"{Minimum_Distance} {SR.Unit.ToString().ToLower()}";
StatusMessage = "Generating points...";
IGPResult CreateRandomPointsResult = await CreateRandomPoints($"memory\\{tempFileName}", Path.GetDirectoryName(outputFileName), Path.GetFileName(outputFileName), SimpleRandomCount, Distance, GPExecuteToolFlags.AddOutputsToMap);
FeatureClassDescription DissolveFCDescription = new(dissolveFC.GetDefinition());
MemorySchemaBuilder.Delete(DissolveFCDescription);
MemorySchemaBuilder.Build();
}
}
This runs properly the first time, but if I run it again, it throws an error on line 16 when it gets the temporary layer. The layer is created according to the history, but I get the error
"Could not open the dataset 'tmp5EB3' of type FeatureClass. Please make sure a valid geodatabase or data store has been opened first."
Why isn't this working on the second attempt?
Solved! Go to Solution.
Hi @KenBuja
I cannot replicate the issue on my machine, and the following code snippets work for me. See if it works for you.
protected override void OnClick()
{
QueuedTask.Run(async () =>
{
MemoryConnectionProperties memoryConnectionProperties = new MemoryConnectionProperties();
using (Geodatabase memoryGeodatabase = new Geodatabase(memoryConnectionProperties))
{
SchemaBuilder schemaBuilder = new SchemaBuilder(memoryGeodatabase);
IReadOnlyList<string> dissolveParamsValueArray = Geoprocessing.MakeValueArray(@"C:\Default.gdb\FrameFeatureClass", @"memory\FrameFeatureClass_Dissolved", null, null, "MULTI_PART", "DISSOLVE_LINES", null);
IGPResult dissolveResult = await Geoprocessing.ExecuteToolAsync("management.Dissolve", dissolveParamsValueArray, null, CancelableProgressor.None, GPExecuteToolFlags.AddToHistory);
if (dissolveResult.IsFailed)
{
System.Diagnostics.Debug.WriteLine("Dissolve errors");
}
using (FeatureClass dissolveFc = memoryGeodatabase.OpenDataset<FeatureClass>("FrameFeatureClass_Dissolved"))
using (FeatureClassDefinition dissolveDefn = dissolveFc.GetDefinition())
{
IReadOnlyList<string> createPointsParamsValueArray = Geoprocessing.MakeValueArray(@"memory", "RandomPointsFC", @"memory\FrameFeatureClass_Dissolved", new List<dynamic>() { 0, 0, 250, 250 }, 100, "5 Meters", "POINT", 10);
IGPResult createRandomPointsMessage = await Geoprocessing.ExecuteToolAsync("management.CreateRandomPoints", createPointsParamsValueArray, null, CancelableProgressor.None, GPExecuteToolFlags.AddOutputsToMap);
if (createRandomPointsMessage.IsFailed)
{
System.Diagnostics.Debug.WriteLine("Create random points errors");
}
schemaBuilder.Delete(new FeatureClassDescription(dissolveDefn));
bool deleteStatus = schemaBuilder.Build();
if (!deleteStatus)
{
System.Diagnostics.Debug.WriteLine("Delete feature class failed");
}
}
}
});
}
Hi @KenBuja
I cannot replicate the issue on my machine, and the following code snippets work for me. See if it works for you.
protected override void OnClick()
{
QueuedTask.Run(async () =>
{
MemoryConnectionProperties memoryConnectionProperties = new MemoryConnectionProperties();
using (Geodatabase memoryGeodatabase = new Geodatabase(memoryConnectionProperties))
{
SchemaBuilder schemaBuilder = new SchemaBuilder(memoryGeodatabase);
IReadOnlyList<string> dissolveParamsValueArray = Geoprocessing.MakeValueArray(@"C:\Default.gdb\FrameFeatureClass", @"memory\FrameFeatureClass_Dissolved", null, null, "MULTI_PART", "DISSOLVE_LINES", null);
IGPResult dissolveResult = await Geoprocessing.ExecuteToolAsync("management.Dissolve", dissolveParamsValueArray, null, CancelableProgressor.None, GPExecuteToolFlags.AddToHistory);
if (dissolveResult.IsFailed)
{
System.Diagnostics.Debug.WriteLine("Dissolve errors");
}
using (FeatureClass dissolveFc = memoryGeodatabase.OpenDataset<FeatureClass>("FrameFeatureClass_Dissolved"))
using (FeatureClassDefinition dissolveDefn = dissolveFc.GetDefinition())
{
IReadOnlyList<string> createPointsParamsValueArray = Geoprocessing.MakeValueArray(@"memory", "RandomPointsFC", @"memory\FrameFeatureClass_Dissolved", new List<dynamic>() { 0, 0, 250, 250 }, 100, "5 Meters", "POINT", 10);
IGPResult createRandomPointsMessage = await Geoprocessing.ExecuteToolAsync("management.CreateRandomPoints", createPointsParamsValueArray, null, CancelableProgressor.None, GPExecuteToolFlags.AddOutputsToMap);
if (createRandomPointsMessage.IsFailed)
{
System.Diagnostics.Debug.WriteLine("Create random points errors");
}
schemaBuilder.Delete(new FeatureClassDescription(dissolveDefn));
bool deleteStatus = schemaBuilder.Build();
if (!deleteStatus)
{
System.Diagnostics.Debug.WriteLine("Delete feature class failed");
}
}
}
});
}
I tried using this code in my add-in, but could not use it as-is. I would get this error on line 6 of your snippet.
In order to make this work, I had to add in a line (line 2) from my code to create another MemoryGeodatabase:
MemoryConnectionProperties memoryConnectionProperties = new MemoryConnectionProperties();
using (MemoryGeodatabase ??= SchemaBuilder.CreateGeodatabase(memoryConnectionProperties))
using (Geodatabase memoryGeodatabase = new Geodatabase(memoryConnectionProperties))
{
SchemaBuilder schemaBuilder = new SchemaBuilder(memoryGeodatabase);
I'm curious about how you were able to get this to work in your application and why I have to add in the additional line.
Good catch; that was the enhancement in 3.1. I was testing on the 3.1 beta and forgot to revert the code.
BTW, did the GP workflow run successfully after your change?
Yes it did. I was waiting to accept the answer before getting clarification on this. What would be the proper code for 3.0.x?
Creating a memory geodatabase and connecting to it in two steps, as you did, is the preferred way for 3.0.x.