Hello,
in my ArcGIS Pro add-in project I`m writing features into a file geodatabase feature class. At the moment this process takes far to much time. This is why I split up my features. For example I want to write 7000 Features/Rows into the FeatureClass then I start 7 async Tasks with packages of each 1000 objects.
This is what I`m doing:
public Task<int> WriteDataIntoFeatureClass(string name, int index, Component selectedComponent, Config config, FeatureClassFieldInfo[] fieldInfos)
{
return QueuedTask.Run(() =>
{
SpatialReference dhdn3_zone3 = SpatialReferenceBuilder.CreateSpatialReference(31467);
SpatialReference wgs84 = SpatialReferences.WGS84;
ProjectionTransformation customTransformation = ArcGIS.Core.Geometry.ProjectionTransformation.Create(wgs84, dhdn3_zone3);
// Only write to feature class if it's empty
if (selectedComponent.Measures.Count() != 0)
{
EditOperation editoperation = new EditOperation();
string message;
int packageSize = Convert.ToInt16(Math.Floor(Convert.ToDouble(selectedComponent.Measures.Count() / 7)));
using (Geodatabase geodatabase = new Geodatabase(config.FGDB.Path))
{
double progressStep = Convert.ToDouble(80) / Convert.ToDouble(selectedComponent.Measures.Count());
using (ArcGIS.Core.Data.FeatureClass featureClass = geodatabase.OpenDataset<ArcGIS.Core.Data.FeatureClass> (name + "_" + selectedComponent.Kid.ToString()))
using (SpatialReferenceBuilder srbuilder = new SpatialReferenceBuilder(4326))
using (var rowbuffer = featureClass.CreateRowBuffer())
using (FeatureClassDefinition fcDefinition = featureClass.GetDefinition())
{
editoperation.Callback(context =>
{
Feature feature = null;
try
{
for (var m = (index - 1) * packageSize; m < (index * packageSize) - 1; m++)
{
if (selectedComponent.Measures.Long != null && selectedComponent.Measures.Lat != null)
{
MapPoint point = MapPointBuilder.CreateMapPoint(
Convert.ToDouble(selectedComponent.Measures.Long),
Convert.ToDouble(selectedComponent.Measures.Lat));
MapPoint pointDhdn = GeometryEngine.ProjectEx(point, customTransformation) as MapPoint;
rowbuffer[fcDefinition.GetShapeField()] = point;
rowbuffer[fieldInfos[0].Name] = selectedComponent.Measures.Id;
rowbuffer[fieldInfos[1].Name] = selectedComponent.Measures.Wert;
rowbuffer[fieldInfos[2].Name] = selectedComponent.Measures.Zeit;
rowbuffer[fieldInfos[3].Name] = selectedComponent.Measures.Status;
rowbuffer[fieldInfos[4].Name] = pointDhdn.X;
rowbuffer[fieldInfos[5].Name] = pointDhdn.Y;
feature = featureClass.CreateRow(rowbuffer);
context.Invalidate(feature);
}
var status = Convert.ToInt32((1 + m) * progressStep);
}
}
catch (GeodatabaseException exObj)
{
// ToDo throw meaningful exception
Console.WriteLine(exObj);
}
finally
{
if (rowbuffer != null)
rowbuffer.Dispose();
if (feature != null)
feature.Dispose();
}
}, featureClass);
var task = editoperation.ExecuteAsync();
var creationResult = task.Result;
if (!creationResult)
message = editoperation.ErrorMessage;
}
}
}
return 20 + (index * 10);
});
}
I think I`m not doing much special action. Just creating rowBuffer like in the examples and assign my object properties to it. I`m doing an additional geometry transformation but also without it it seems to be to slow in comparison to same actions in arcpy for example. I tried to remove 'context.Invalidate(feature);'. If I do so my writing process goes much faster but the feature class is empty in the end.
Am I doing something wrong? Can I improve this somehow?
Thank you for any help!