Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pCptbCtgl"></param>
        /// <param name="SgCpt"></param>
        /// <returns></returns>
        /// <remarks >the first or last vertex of a SgCpl can be computed many times, but it doesn't matter</remarks>
        private CPoint CalFirstAffineCpt(CCptbCtgl pCptbCtgl, CPoint SgCpt, SortedDictionary <CPoint, CPoint> pInterLSCptSD)
        {
            CTriangulation pFrCtgl = pCptbCtgl.FrCtgl;
            CTriangulation pToCtgl = pCptbCtgl.ToCtgl;

            CPoint AffineCpt = null;
            CPoint outcpt;
            bool   blnContainsKey = pInterLSCptSD.TryGetValue(SgCpt, out outcpt);

            if (blnContainsKey == true)
            {
                AffineCpt = pToCtgl.CptLt[outcpt.indexID];
            }
            else
            {
                AffineCpt = CalFirstSingleAffineCpt(SgCpt, pFrCtgl, pToCtgl);
            }
            return(AffineCpt);
        }
Пример #2
0
        /// <summary>
        /// Transform interior polylines in one province
        /// </summary>
        /// <param name="pParameterInitialize"></param>
        /// <param name="InterLSIplLt"></param>
        /// <param name="InterSSIplLt"></param>
        /// <param name="SgIplLt"></param>
        /// <returns></returns>
        /// <remarks>InterLSIplLt and InterSSIplLt can be clockwise of counterclockwise.
        /// we will construct DCEL, in which the directions will be counterclockwise.
        /// InterLSIplLt and InterSSIplLt should have the same direction and the corresponding start points</remarks>
        private List <CPolyline> CTTransform(List <IPolyline5> InterLSIplLt, List <IPolyline5> InterSSIplLt,
                                             List <IPolyline5> SgIplLt, bool blnMaxCommonChords = true)
        {
            CConstants.dblVerySmallCoord /= 10;  //this assignment should equal to _dblVerySmallDenominator = 10000000


            var InterLSCplLt = CHelpFunc.GenerateCGeoEbAccordingToGeoEb <CPolyline>(InterLSIplLt).ToList();
            var InterSSCplLt = CHelpFunc.GenerateCGeoEbAccordingToGeoEb <CPolyline>(InterSSIplLt).ToList();
            var SgCplEb      = CHelpFunc.GenerateCGeoEbAccordingToGeoEb <CPolyline>(SgIplLt);

            //there are only two faces: the super face and a normal face. Face *.FaceCpgLt[1] is the normal face
            var pInterLSDCEL = new CDCEL(InterLSCplLt);

            pInterLSDCEL.ConstructDCEL();
            pInterLSDCEL.FaceCpgLt[1].SetOuterFaceCptlt(false, true, InterLSCplLt[0].CptLt[0]);

            //there are only two faces: the super face and a normal face. Face *.FaceCpgLt[1] is the normal face
            var pInterSSDCEL = new CDCEL(InterSSCplLt);

            pInterSSDCEL.ConstructDCEL();
            pInterSSDCEL.FaceCpgLt[1].SetOuterFaceCptlt(false, true, InterSSCplLt[0].CptLt[0]);

            //we maintaine this SD so that for a point from single polyline,
            //we can know whether this single point overlaps a point of a larger-scale polyline
            var pInterLSCptSD = pInterLSDCEL.FaceCpgLt[1].CptLt.ToSD(cpt => cpt, new CCmpCptYX_VerySmall());


            var pCptbCtgl = new CCptbCtgl(pInterLSDCEL.FaceCpgLt[1], pInterSSDCEL.FaceCpgLt[1],
                                          blnMaxCommonChords, _blnSave);

            pCptbCtgl.ConstructCcptbCtgl();
            var TransSgCPlLt = new List <CPolyline>(SgIplLt.Count);

            foreach (var SgCpl in SgCplEb)
            {
                TransSgCPlLt.Add(GenerateCorrSgCpl(pCptbCtgl, SgCpl, pInterLSCptSD));
            }

            CConstants.dblVerySmallCoord *= 10;
            return(TransSgCPlLt);
        }
Пример #3
0
        //private void SgCplTraverse(CTriangulation pFrCtgl, List <CEdge > SgCEdgeLt, ref int intIndex)
        private CPolyline GenerateCorrSgCpl(CCptbCtgl pCptbCtgl, CPolyline SgCpl, SortedDictionary <CPoint, CPoint> pInterLSCptSD)
        {
            CTriangulation pFrCtgl     = pCptbCtgl.FrCtgl;
            CTriangulation pToCtgl     = pCptbCtgl.ToCtgl;
            var            AffineCptLt = new List <CPoint>(SgCpl.CptLt.Count);

            AffineCptLt.Add(CalFirstAffineCpt(pCptbCtgl, SgCpl.CptLt[0], pInterLSCptSD));   //the first vertex

            SgCpl.JudgeAndFormCEdgeLt();
            //CareCEdge is an edge that current edge may cross with current triangle
            //CareCEdgeLt has three edges at most
            var CareCEdgeLt = FindCareCEdgeLtForFirstCEdge(pFrCtgl, SgCpl.CEdgeLt[0], pInterLSCptSD);

            if (SgCpl.CEdgeLt.Count == 1 && CCmpMethods.CmpCEdgeCoord(CareCEdgeLt[0], SgCpl.CEdgeLt[0]) == 0)
            {
                //this is a special case where a single polyline has only one edge (SgCEdge),
                //at the same time, this edge is used by the combined triangulation
                var newCEdge = pToCtgl.HalfEdgeLt[CareCEdgeLt[0].indexID];
                AffineCptLt.Add(newCEdge.ToCpt);
                return(new CPolyline(SgCpl.ID, AffineCptLt));
            }


            int intEdgeCount = 0;
            var CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount++];

            do
            {
                bool isFoundExit = false;  //whether this edge can go out current polygon (a triangle)
                foreach (var carecedge in CareCEdgeLt)
                {
                    var pIntersection = CurrentCEdge.IntersectWith(carecedge);

                    switch (pIntersection.enumIntersectionType)
                    {
                    case CEnumIntersectionType.NoNo:
                        break;

                    //this case is actually only for the fisrt vertex of a SgCpl,
                    //because for other intersections which coincide a triangulation node,
                    //we would not add the two neighbour edges in to CareCEdgeLt
                    case CEnumIntersectionType.FrFr:
                        CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge);
                        isFoundExit = true;
                        break;

                    //this case is actually only for the fisrt vertex of a SgCpl,
                    //because for other intersections which coincide a triangulation node,
                    //we would not add the two neighbour edges in to CareCEdgeLt
                    case CEnumIntersectionType.FrIn:
                        //this can happen, when the first SgCpt is on an triangle edge of FrCtgl
                        CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false);
                        isFoundExit = true;
                        break;

                    //this case is actually only for the fisrt vertex of a SgCpl,
                    //because for other intersections which coincide a triangulation node,
                    //we would not add the two neighbour edges in to CareCEdgeLt
                    case CEnumIntersectionType.FrTo:
                        CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge);      //this can happen
                        isFoundExit = true;
                        break;

                    case CEnumIntersectionType.InFr:
                        AffineCptLt.Add(pToCtgl.CptLt[carecedge.FrCpt.indexID]);
                        CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge);
                        isFoundExit = true;
                        break;

                    case CEnumIntersectionType.InIn:
                        AffineCptLt.Add(ComputeAffineCptForInbetween(pToCtgl, pIntersection));
                        CareCEdgeLt = GetCareCEdgeLt(carecedge.cedgeTwin, false);
                        isFoundExit = true;
                        break;

                    case CEnumIntersectionType.InTo:
                        AffineCptLt.Add(pToCtgl.CptLt[carecedge.ToCpt.indexID]);
                        CareCEdgeLt = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge);
                        isFoundExit = true;
                        break;

                    case CEnumIntersectionType.ToFr:       //come to the end of an edge
                        AffineCptLt.Add(pToCtgl.CptLt[carecedge.FrCpt.indexID]);
                        if (intEdgeCount < SgCpl.CEdgeLt.Count)
                        {
                            CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount];
                            CareCEdgeLt  = GetCareCEdgeLtCptCoincident(carecedge.FrCpt, CurrentCEdge);
                        }
                        intEdgeCount++;
                        isFoundExit = true;
                        break;

                    case CEnumIntersectionType.ToIn:       //come to the end of an edge
                        AffineCptLt.Add(ComputeAffineCptForInbetween(pToCtgl, pIntersection));
                        if (intEdgeCount < SgCpl.CEdgeLt.Count)
                        {
                            CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount];
                            CareCEdgeLt  = GetCareCEdgeLt(carecedge.cedgeTwin, false);
                        }
                        intEdgeCount++;
                        isFoundExit = true;
                        break;

                    case CEnumIntersectionType.ToTo:       //come to the end of an edge
                        AffineCptLt.Add(pToCtgl.CptLt[carecedge.ToCpt.indexID]);
                        if (intEdgeCount < SgCpl.CEdgeLt.Count)
                        {
                            CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount];
                            CareCEdgeLt  = GetCareCEdgeLtCptCoincident(carecedge.ToCpt, CurrentCEdge);
                        }
                        intEdgeCount++;
                        isFoundExit = true;
                        break;

                    //maybe we can just ignore overlap, because if there is overlap, then there is also other cases
                    case CEnumIntersectionType.Overlap:
                        MessageBox.Show("we didn't consider Overlap when GenerateCorrSgCpl in:" + this.ToString() + ".cs   ");
                        break;

                    default:
                        break;
                    }

                    if (isFoundExit == true)
                    {
                        break;
                    }
                }

                if (isFoundExit == false)   //come to the end of an edge
                {
                    AffineCptLt.Add(CalAffineCpt(CurrentCEdge.ToCpt, CareCEdgeLt[0], pFrCtgl, pToCtgl));
                    if (intEdgeCount < SgCpl.CEdgeLt.Count)
                    {
                        CurrentCEdge = SgCpl.CEdgeLt[intEdgeCount];
                        CareCEdgeLt  = GetCareCEdgeLt(CareCEdgeLt[0], true);
                    }
                    intEdgeCount++;
                }
            } while (intEdgeCount <= SgCpl.CEdgeLt.Count);

            return(new CPolyline(SgCpl.ID, AffineCptLt));
        }