Intersection between two featureSets

Apr 7, 2014 at 5:58 PM
Hello everyone,

I have a task to select something in a polygon layer and then get features from another layer that are in the polygon before (lets say, get rivers in a spesific city or smth.).

Basically I have to perform intersection on two shapefiles/layers/featuresets.

My main apporoach is to take the polygon feature set and the whole second layers' feature set and loop it around. The main issue is that it takes lots of time (~22 minutes, ~67k features).

Second thing I have tried was to use FeatureSet.Intersects() method but it returns an empty feature set (0 rows).

            var layers = appManager1.Map.GetLayers();
            var layer1 = layers[0] as IFeatureLayer;
            var layer2 = layers[1] as IFeatureLayer;
            var selection1 = layer1.Selection.ToFeatureSet();
First approach(working buf super-slow):
var result = new FeatureSet(FeatureType.Line);
foreach (IFeature feature in selection1.Features)
    foreach (IFeature other in layer2.DataSet.Features)
        if (feature.Intersects(other))
Second approach (does not work)
var result = selection1.Intersection(layer2.DataSet, FieldJoinType.All, appManager1.ProgressHandler);
As far as I know, MapWinGis has GetIntersection method which is something I need:
Shapefile sfResult = sfPolygon.GetIntersection(true, sfRivers, true, ShpfileType.SHP_NULLSHAPE, null);
Can anyone help with this issue?

P.S. I have tried multi-threading with my first try and it helps 22 minutes become 5 while using 8 threads (4 and 8 and 12 threads do not make any difference - still 5 minutes)
Apr 10, 2014 at 9:39 AM
Edited Apr 10, 2014 at 9:43 AM
You could try to build a unioned geometry of your first feature set and then iterate just once of the second feature set.
//beware, code has not seen a compiler
IGeometry union1 = null;
foreach (var f in selection1.Features)
    union1 = union1 != null ? union1.Union(f.Geometry) : f.Geometry;

//IGeometry union2 = null;
//foreach (var f in layer2.DataSet.Features)
//    union2 = union2 != null ? union2.Union(f.Geometry) : f.Geometry;

var result = new FeatureSet(FeatureType.Line);
//foreach (var f in selection1.Features)
//    if (f.Intersects(union2)) result.Add(f);
foreach (var f in layer2.DataSet.Features)
    if (f.Intersects(union1)) result.Add(f);
If that still is not fast enough, you could try to use NetTopologySuite's prepared geometry functionality.