How to read geometries from (CAD) layer most efficiently

767
2
Jump to solution
03-09-2021 01:53 AM
RehmSoftware
New Contributor III

Hi,

simple task: I want to read polygons from a CAD layer. And I want to do it as fast as I can. The CAD layer contains a TIN network and I want to process the invidividual triangles. However, reading from the layer takes quite some time... I use the following code to read all the polygons from the layer:

FeatureLayer sourceLayer = //Obtain FeatureLayer... 
uint numSteps = (uint)await QueuedTask.Run(() => sourceLayer.GetTable().GetCount());
var polygons = new List<Polygon>((int)numSteps);    //Holds all polygons from the layer
using (var progressDialog = new ProgressDialog("Reading polygons...", "", numSteps)) {
    var cps = new CancelableProgressorSource(progressDialog);
    cps.Progressor.Max = numSteps;

    await QueuedTask.Run(() => {
        using (var rowCursor = sourceLayer.Search()) {
            while (rowCursor.MoveNext()) {
                if (cps.CancellationTokenSource.IsCancellationRequested) {
                    polygons.Clear();
                    return;
                }

                var pg = (Polygon)rowCursor.Current["SHAPE"];
                if (pg.PointCount < 3 || pg.PointCount > 4) {
                    //Invalid polygon shape..
                    continue;
                }
                else if (pg.PointCount == 4) {
                    //Check if the polygon is "closed", i.e. forms a triangle
                    var firstPoint = pg.Points[0];
                    var lastPoint = pg.Points[3];
                    if (firstPoint.IsEqual(lastPoint) == false)
                        continue;
                }

                polygons.Add(pg);
                ++cps.Value;
                cps.Status = String.Format("Progress {0}%", 100.0 * cps.Value / cps.Max);
            }
        }
    }, cps.Progressor);
}

//Do something with the polygons-list

As you can see, there's nothing fancy going on. The CAD layer contains 753.780 rows and executing this code takes about 1:53 minutes, which seems slow to me. After running a profiler most of the time is spent in the RowCursor object.

Is there a way to speed up reading from the CAD layer using the RowCursor or maybe there is a completely different way to read all the polygons from the layer that is faster? Any help is greatly appreciated!

If anybody want to take a look, I uploaded the DWG file here: https://gofile.io/d/6Npgyw

Best regards

Christian

0 Kudos
1 Solution

Accepted Solutions
KirkKuykendall1
Occasional Contributor III

Maybe try using FeatureClass.Search and pass it a queryfilter that has only the shapefield as a subfield, then also set userecycling to true.

KirkKuykendall1_0-1615658200642.png

 

I'm not sure, but when setting recycling to true, you might need to clone the polygon geometry since you're keeping it in a list.  With arcobjects the same reference would get re-used with each iteration.  ArcObjects had a ShapeCopy() method on IFeature, but with Pro I don't see a Feature.ShapeCopy();

 

 

View solution in original post

2 Replies
KirkKuykendall1
Occasional Contributor III

Maybe try using FeatureClass.Search and pass it a queryfilter that has only the shapefield as a subfield, then also set userecycling to true.

KirkKuykendall1_0-1615658200642.png

 

I'm not sure, but when setting recycling to true, you might need to clone the polygon geometry since you're keeping it in a list.  With arcobjects the same reference would get re-used with each iteration.  ArcObjects had a ShapeCopy() method on IFeature, but with Pro I don't see a Feature.ShapeCopy();

 

 

RehmSoftware
New Contributor III

Hi,

I did test your approach and it was about 15 seconds faster. Setting useRecyclcingCursor to true didn't yield any benefits, so I didn't do that (but it also wasn't necessary to copy the shape when it was true).

The speed benefit obviously came from setting the subfield. Thanks a lot for your suggestions!

Best regards

Christian

0 Kudos