AnsweredAssumed Answered

Writing Features into FGDB very slow

Question asked by EternalDOOM on Aug 7, 2017
Latest reply on Feb 28, 2018 by sean_jones-esristaff

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[m].Long != null && selectedComponent.Measures[m].Lat != null)
                                    {
                                        MapPoint point = MapPointBuilder.CreateMapPoint(

                                                                    Convert.ToDouble(selectedComponent.Measures[m].Long),
                                                                    Convert.ToDouble(selectedComponent.Measures[m].Lat));

                                        MapPoint pointDhdn = GeometryEngine.ProjectEx(point, customTransformation) as MapPoint;

                                        rowbuffer[fcDefinition.GetShapeField()] = point;

                                        rowbuffer[fieldInfos[0].Name] = selectedComponent.Measures[m].Id;
                                        rowbuffer[fieldInfos[1].Name] = selectedComponent.Measures[m].Wert;
                                        rowbuffer[fieldInfos[2].Name] = selectedComponent.Measures[m].Zeit;
                                        rowbuffer[fieldInfos[3].Name] = selectedComponent.Measures[m].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!

Outcomes