Ejemplo n.º 1
0
        public void TestUnrelated()
        {
            // Super strict...
            double ang_tol              = System.Double.Epsilon;
            double dist_tol             = System.Double.Epsilon;
            Dictionary <int, bool> seen = new Dictionary <int, bool>();

            ISegIdx spidx = GetIndex(dist_tol, ang_tol);
            LineSegOverlay <NumLineSeg> overlay =
                new LineSegOverlay <NumLineSeg>(spidx,
                                                ang_tol, dist_tol);

            int idx = 0;

            foreach (LineSeg l in Take(TestCount, LineSegs))
            {
                overlay.Insert(new NumLineSeg(l, idx++));
            }

            foreach (Pair <LineSeg, IEnumerable <NumLineSeg> > res in overlay.Segments)
            {
                bool here = false;
                foreach (NumLineSeg r in res.Second)
                {
                    Assert.IsFalse(seen.ContainsKey(r.Idx));
                    Assert.IsFalse(here);
                    seen[r.Idx] = true;
                    here        = true;
                }
            }

            for (int i = 0; i < TestCount; i++)
            {
                Assert.IsTrue(seen[i]);
            }

            DumpIndex(spidx);
        }
Ejemplo n.º 2
0
        void OverlayFn(LineSeg a,
                       LineSeg b,
                       double ang_tol,
                       double disttol,
                       out LineSeg before,
                       out bool a_before,
                       out LineSeg overlap,
                       out LineSeg after,
                       out bool a_after)
        {
            before   = null;
            a_before = false; overlap = null; after = null; a_after = false;

            OverlayObj aobj = new OverlayObj(a, true);
            OverlayObj bobj = new OverlayObj(b, false);

            double dtol = Math.Sqrt(disttol);

            LineSegOverlay <OverlayObj> overlay =
                new LineSegOverlay <OverlayObj>(GetIndex(dtol, ang_tol),
                                                ang_tol, dtol);

            overlay.Insert(aobj);
            overlay.Insert(bobj);

            List <Pair <LineSeg, OverlayObj> > nonoverlaps = new List <Pair <LineSeg, OverlayObj> >();

            bool have_overlay = false;

            foreach (Pair <LineSeg, IEnumerable <OverlayObj> > r in overlay.Segments)
            {
                int        count = 0; bool fsta = false;
                OverlayObj o = null;

                foreach (OverlayObj os in r.Second)
                {
                    o = os;
                    if (count > 0 && os.FromA != fsta) // An overlay.
                    {
                        overlap      = r.First;
                        have_overlay = true;
                    }
                    else if (count == 0)
                    {
                        fsta = os.FromA;
                    }
                    count++;
                }

                if (count == 1)
                {
                    nonoverlaps.Add(new Pair <LineSeg, OverlayObj>(r.First, o));
                }
            }

            if (have_overlay)
            {
                foreach (Pair <LineSeg, OverlayObj> ls in nonoverlaps)
                {
                    double start_tval, end_tval;
                    ls.First.PointDistanceSq(overlap.Start, out start_tval);
                    ls.First.PointDistanceSq(overlap.End, out end_tval);


                    bool dir = (start_tval - disttol <= 0.0);

                    if (dir)
                    {
                        after   = ls.First;
                        a_after = ls.Second.FromA;
                    }
                    else
                    {
                        before   = ls.First;
                        a_before = ls.Second.FromA;
                    }
                }
            }
            else
            {
                overlap = null; before = null; after = null;
            }
        }
Ejemplo n.º 3
0
        public void TestBeforeAndAfter()
        {
            int    count               = TestCount;
            double ang_tol             = 0.0001;
            double dist_tol            = 0.000001;
            Dictionary <int, int> seen = new Dictionary <int, int>();

            ISegIdx spidx = GetIndex(dist_tol, ang_tol);
            LineSegOverlay <NumLineSeg> overlay =
                new LineSegOverlay <NumLineSeg>(spidx,
                                                ang_tol, dist_tol);

            int idx = 0;

            LineSeg[] lines = new LineSeg[count];
            foreach (LineSeg ll in Take(count, LineSegs))
            {
                LineSeg l = ll;
                if (idx == 0)
                {
                    l = LineSeg.FromEndpoints(new Vector(0, 0),
                                              new Vector(0, 1));
                }
                lines[idx] = l;

                idx++;
            }

            for (int i = 0; i < lines.Length; i++)
            {
                double ta = -0.75;
                double tb = 0.25;
                ta = 0.75;
                tb = 1.75;
                // The 'before' half:
                LineSeg bl = LineSeg.FromEndpoints(lines[i].Start + (ta * lines[i].Dir),
                                                   lines[i].Start + (tb * lines[i].Dir));

                // the 'after' half:
                ta = -0.75;
                tb = 0.25;
                LineSeg al = LineSeg.FromEndpoints(lines[i].Start + (ta * lines[i].Dir),
                                                   lines[i].Start + (tb * lines[i].Dir));

                NumLineSeg a = new NumLineSeg(al, count + i);
                NumLineSeg b = new NumLineSeg(bl, 2 * count + i);
                NumLineSeg c = new NumLineSeg(lines[i], i);
                switch (Int(6))
                {
                case 0:
                    overlay.Insert(a); overlay.Insert(b); overlay.Insert(c);
                    break;

                case 5:
                    overlay.Insert(a); overlay.Insert(c); overlay.Insert(b);
                    break;

                case 1:
                    overlay.Insert(b); overlay.Insert(a); overlay.Insert(c);
                    break;

                case 4:
                    overlay.Insert(b); overlay.Insert(c); overlay.Insert(a);
                    break;

                case 2:
                    overlay.Insert(c); overlay.Insert(b); overlay.Insert(a);
                    break;

                case 3:
                    overlay.Insert(c); overlay.Insert(a); overlay.Insert(b);
                    break;
                }
            }

            DumpIndex(spidx);

            int rcount = 0;

            foreach (Pair <LineSeg, IEnumerable <NumLineSeg> > res in overlay.Segments)
            {
                //	Console.Error.WriteLine("Res-----");
                foreach (NumLineSeg r in res.Second)
                {
                    // Console.Error.WriteLine("  Portion: " + r.Idx);
                    if (!seen.ContainsKey(r.Idx))
                    {
                        seen[r.Idx] = 0;
                    }
                    seen[r.Idx]++;
                }
                rcount++;
            }

            Assert.AreEqual(5 * count, rcount);

            for (int i = 0; i < 3 * count; i++)
            {
                if (i < count)
                {
                    Assert.AreEqual(3, seen[i]);
                }
                if (i > count)
                {
                    Assert.AreEqual(2, seen[i]);
                }
            }
        }
Ejemplo n.º 4
0
        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);
        }