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
Solved! Go to Solution.
Maybe try using FeatureClass.Search and pass it a queryfilter that has only the shapefield as a subfield, then also set userecycling to true.
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();
Maybe try using FeatureClass.Search and pass it a queryfilter that has only the shapefield as a subfield, then also set userecycling to true.
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();
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