public OverlapSegment(LineSeg s, ArcSegInf m, ArcSegInf o) { Seg = s; Fid = m.SrcFid; OFid = o == null ? -1 : o.SrcFid; Shell = m.ShellNum; OShell = o == null ? -1 : o.ShellNum; SegNum = m.SegNum; OSegNum = o == null ? -1 : o.SegNum; }
public void Run(IFeatureClass inp, IFeatureClass outp, ProgressCallback progress) { IFeatureCursor all_inp = inp.Search(null, true); LineSegOverlay <ArcSegInf> op = new LineSegOverlay <ArcSegInf>(new PMQTree(4, 8), m_atol, m_dtol); double inp_count = inp.FeatureCount(null); int steps = (int)Math.Ceiling((double)inp_count / 20.0); int inp_progress = 0; IFeature infeat = all_inp.NextFeature(); while (infeat != null) { int fid = infeat.OID; IGeometryCollection c = infeat.Shape as IGeometryCollection; for (int shell_num = 0; shell_num < c.GeometryCount; shell_num++) { IPointCollection ps = c.get_Geometry(shell_num) as IPointCollection; IPoint last = null; for (int seg_num = 0; seg_num < ps.PointCount; seg_num++) { IPoint cur = ps.get_Point(seg_num); if (last != null) { LineSeg seg = LineSeg.FromEndpoints(new Vector(last.X, last.Y), new Vector(cur.X, cur.Y)); op.Insert(new ArcSegInf(seg, fid, shell_num, seg_num)); m_seensegs++; } last = cur; } } inp_progress++; if (inp_progress % steps == 0) { progress(0.5 * (inp_progress / inp_count)); } infeat = all_inp.NextFeature(); } int lfid = outp.FindField("left_fid"); int rfid = outp.FindField("right_fid"); // Reassemble line strings SegmentAssembler sa = new SegmentAssembler(); foreach (Pair <LineSeg, IEnumerable <ArcSegInf> > r in op.Segments) { int overlap_count = 0; foreach (Pair <ArcSegInf, ArcSegInf> v in Pair <ArcSegInf, ArcSegInf> .Pairs(r.Second)) { OverlapSegment o = new OverlapSegment(r.First, v.First, v.Second); if (v.First.SrcFid < v.Second.SrcFid) { sa.AddSegment(o); } overlap_count++; } if (overlap_count == 0) { // TODO: add exterior boundaries? ArcSegInf seen = null; foreach (ArcSegInf seg in r.Second) { seen = seg; } sa.AddSegment(new OverlapSegment(r.First, seen, null)); } } double outp_count = sa.OverlapCount; int outp_progress = 0; int outp_steps = (int)Math.Ceiling((double)outp_count / 20.0); IFeatureBuffer outfeat = outp.CreateFeatureBuffer(); IFeatureCursor outcursor = outp.Insert(true); foreach (Pair <Pair <int, int>, Pair <int, int> > ss in sa.SegsAndShells) { int rhs_fid = ss.First.First; int rhs_shellid = ss.First.Second; int lhs_fid = ss.Second.First; int lhs_shellid = ss.Second.Second; foreach (Pair <Pair <int, int>, List <LineSeg> > linestring in sa.GetStrings(ss)) { IPolyline line = assemblePolyLine(linestring.Second); outfeat.set_Value(lfid, lhs_fid); outfeat.set_Value(rfid, rhs_fid); outfeat.Shape = line; outcursor.InsertFeature(outfeat); // Same boundary but swapped! outfeat.set_Value(lfid, rhs_fid); outfeat.set_Value(rfid, lhs_fid); outfeat.Shape = line; outcursor.InsertFeature(outfeat); } // progress outp_progress++; if (outp_progress % outp_steps == 0) { progress(0.5 + (0.5 * outp_progress / outp_count)); } } outcursor.Flush(); System.Runtime.InteropServices.Marshal.ReleaseComObject(outcursor); }