예제 #1
0
        /// <summary>
        /// Build a linked list for vertices.
        /// </summary>
        /// <param name="vertices"></param>
        /// <param name="isLoop">Indicate whether the curve is a loop</param>
        /// <returns></returns>
        public static LinkedPoint GetLinkedPoints(List <Point3d> vertices, bool isLoop)
        {
            LinkedPoint ptLink = null;
            LinkedPoint prevPt = null;

            foreach (var point3D in vertices)
            {
                // Rotated point is useless here.
                var tempLinkPt = new LinkedPoint(point3D);
                if (prevPt != null)
                {
                    tempLinkPt.Prev = prevPt;
                }
                else
                {
                    ptLink = tempLinkPt;
                }
                prevPt = tempLinkPt;
            }

            // NOTE: Let it to be a closed list
            // prevPt is the last point
            if (prevPt != null && isLoop)
            {
                prevPt.Next = ptLink;
            }
            return(ptLink);
        }
예제 #2
0
 public CurveLinkedPoint(LinkedPoint linkedPoint, ObjectId id)
 {
     LinkedPoint = linkedPoint;
     ObjectId    = id;
 }
예제 #3
0
        public static Dictionary <ObjectId, List <Point3d> > GetCrotchPoints(Database database,
                                                                             IEnumerable <ObjectId> parcelIds)
        {
            var result = new Dictionary <ObjectId, List <Point3d> >();
            // Create a kd tree.
            var allVertices = new List <CurveVertex>();

            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var objId in parcelIds)
                {
                    var curve = transaction.GetObject(objId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }
                    var vertices = CurveUtils.GetDistinctVertices(curve, transaction);
                    allVertices.AddRange(vertices.Select(it => new CurveVertex(it, objId)));
                }
                transaction.Commit();
            }
            var kdTree = new CurveVertexKdTree <CurveVertex>(allVertices, it => it.Point.ToArray(), ignoreZ: true);

            // 搜索三岔口
            //using (var tolerance = new ToleranceOverrule(null))
            using (var transaction = database.TransactionManager.StartTransaction())
            {
                foreach (var parcelId in parcelIds)
                {
                    var curve = transaction.GetObject(parcelId, OpenMode.ForRead) as Curve;
                    if (curve == null)
                    {
                        continue;
                    }

                    var ptLink     = LinkedPoint.GetLinkedPoints(curve, transaction, isLoop: true);
                    var ptTraverse = ptLink;
                    // Use records to improve performance.
                    var records = new Dictionary <LinkedPoint, IEnumerable <CurveVertex> >();
                    while (ptTraverse != null)
                    {
                        var prev = ptTraverse.Prev;
                        var next = ptTraverse.Next;
                        if (!records.ContainsKey(prev))
                        {
                            records[prev] = kdTree.NearestNeighbours(prev.Point.ToArray(), radius: 0.001);
                        }
                        if (!records.ContainsKey(ptTraverse))
                        {
                            records[ptTraverse] = kdTree.NearestNeighbours(ptTraverse.Point.ToArray(), radius: 0.001);
                        }
                        if (!records.ContainsKey(next))
                        {
                            records[next] = kdTree.NearestNeighbours(next.Point.ToArray(), radius: 0.001);
                        }

                        foreach (var vertex in records[ptTraverse])
                        {
                            if (result.ContainsKey(parcelId) && result[parcelId].Contains(vertex.Point))
                            {
                                continue;
                            }

                            if (vertex.Id == parcelId || vertex.Point != ptTraverse.Point)
                            {
                                continue;
                            }
                            var prevVertex = new CurveVertex(prev.Point, vertex.Id);
                            var nextVertex = new CurveVertex(next.Point, vertex.Id);
                            if (records[prev].Contains(prevVertex) && records[next].Contains(nextVertex))
                            {
                                continue;
                            }

                            List <Point3d> list = null;
                            if (result.ContainsKey(parcelId))
                            {
                                list = result[parcelId];
                            }
                            else
                            {
                                list             = new List <Point3d>();
                                result[parcelId] = list;
                            }
                            list.Add(ptTraverse.Point);
                        }

                        ptTraverse = ptTraverse.Next;
                        if (ptTraverse == ptLink)
                        {
                            break;
                        }
                    }
                }
                transaction.Commit();
            }

            return(result);
        }