//--------------------------------------------------------- void CSG_Shape_Points::_Update_Extent(void) { if( m_bUpdate ) { bool bFirst; int iPart; for(iPart=0, bFirst=true; iPart<m_nParts; iPart++) { CSG_Shape_Part *pPart = m_pParts[iPart]; if( pPart->Get_Count() > 0 ) { if( bFirst ) { bFirst = false; m_Extent = pPart->Get_Extent(); m_ZMin = pPart->Get_ZMin(); m_ZMax = pPart->Get_ZMax(); m_MMin = pPart->Get_MMin(); m_MMax = pPart->Get_MMax(); } else { m_Extent.Union(pPart->Get_Extent()); if( m_ZMin > pPart->Get_ZMin() ) m_ZMin = pPart->Get_ZMin(); if( m_ZMax < pPart->Get_ZMax() ) m_ZMax = pPart->Get_ZMax(); if( m_MMin > pPart->Get_MMin() ) m_MMin = pPart->Get_MMin(); if( m_MMax < pPart->Get_MMax() ) m_MMax = pPart->Get_MMax(); } } } m_bUpdate = false; } }
//--------------------------------------------------------- TSG_Intersection CSG_Shape_Line::On_Intersects(TSG_Rect Region) { // called if polygon's bounding box contains or overlaps with region. // now let's figure out how region intersects with polygon itself //----------------------------------------------------- for(int iPart=0; iPart<m_nParts; iPart++) { CSG_Shape_Part *pPart = m_pParts[iPart]; switch( pPart->Get_Extent().Intersects(Region) ) { case INTERSECTION_None: // region and line part are distinct break; case INTERSECTION_Identical: // region contains line part case INTERSECTION_Contained: return( Get_Extent().Intersects(Region) ); case INTERSECTION_Contains: case INTERSECTION_Overlaps: // region overlaps with line part's extent, now let's look at the line part itself! if( pPart->Get_Count() > 1 ) { TSG_Point *pa, *pb, c; pb = pPart->m_Points; pa = pb + 1; for(int iPoint=1; iPoint<pPart->Get_Count(); iPoint++, pb=pa++) { if( SG_Get_Crossing_InRegion(c, *pa, *pb, Region) ) { return( INTERSECTION_Overlaps ); } } } break; } } //----------------------------------------------------- TSG_Point p = Get_Point(0, 0); if( Region.xMin <= p.x && p.x <= Region.xMax && Region.yMin <= p.y && p.y <= Region.yMax ) { return( INTERSECTION_Contained ); } return( INTERSECTION_None ); }
//--------------------------------------------------------- bool CPolygon_Transect::On_Execute(void) { CSG_Table *pTransect_Result; CSG_Shapes *pTheme, *pTransect; CSG_Shape_Line *pLine; CSG_Shape_Polygon *pTheme_Shape; int Theme_Field; pTransect = Parameters("TRANSECT")->asShapes(); pTheme = Parameters("THEME")->asShapes(); pTransect_Result = Parameters("TRANSECT_RESULT")->asTable(); Theme_Field = Parameters("THEME_FIELD")->asInt(); //----------------------------------------------------- // Check for valid parameter settings... //----------------------------------------------------- if (pTheme->Get_Type() != SHAPE_TYPE_Polygon){ Error_Set(CSG_String("[THEME] is not a polygon file")); return(false); } if (pTransect->Get_Type() != SHAPE_TYPE_Line){ Error_Set(CSG_String("[TRANSECT] is not a line shapefile")); return(false); } if (pTheme->Get_Count() ==0 || pTransect->Get_Count()==0) { Error_Set(CSG_String("[TRANSECT] or [THEME] is empty")); return(false); } if (!(pTheme->Get_Extent().Intersects(pTransect->Get_Extent()))) { Error_Set(CSG_String("[TRANSECT] and [THEME] do not intersect")); return(false); } const int LINE_ID = pTransect_Result->Get_Field_Count(); pTransect_Result->Add_Field(SG_T("line_id"), SG_DATATYPE_Int); const int START = pTransect_Result->Get_Field_Count(); pTransect_Result->Add_Field(SG_T("start"), SG_DATATYPE_Double); const int END = pTransect_Result->Get_Field_Count(); pTransect_Result->Add_Field(SG_T("end"), SG_DATATYPE_Double); const int POLY_ID = pTransect_Result->Get_Field_Count(); pTransect_Result->Add_Field(SG_T("poly_id"), SG_DATATYPE_Int); const int FIELD = pTransect_Result->Get_Field_Count(); pTransect_Result->Add_Field(SG_T("field"), pTheme->Get_Field_Type(Theme_Field)); // Short description of the algorithm: // For every line it is checked whether it crosses a polygon. If it does, // the points where it crosses are recorded in the map LineBorders, with // the polygon_id as key. for (int iLine=0; iLine<pTransect->Get_Count() && Set_Progress(iLine, pTransect->Get_Count()); iLine++) { pLine =(CSG_Shape_Line *) pTransect->Get_Shape(iLine); for (int iLinePart=0;iLinePart<pLine->Get_Part_Count();iLinePart++) { CSG_Shape_Part *pLinePart =pLine->Get_Part(iLinePart); CSG_Rect LinePartExtent = pLinePart->Get_Extent(); map<int,list<double> > LineBorders; for (int iShape=0; iShape<pTheme->Get_Count();iShape++) { pTheme_Shape = (CSG_Shape_Polygon *) pTheme->Get_Shape(iShape); if (pLinePart->Get_Extent().Intersects(pTheme_Shape->Get_Extent())>0) { for (int iPart=0; iPart<pTheme_Shape->Get_Part_Count(); iPart++) { CSG_Shape_Polygon_Part *pPart = (CSG_Shape_Polygon_Part *) pTheme_Shape->Get_Part(iPart); if (pPart->Contains(pLinePart->Get_Point(0))) LineBorders[iShape].push_back(0); if (pPart->Contains(pLinePart->Get_Point(pLinePart->Get_Count()))) LineBorders[iShape].push_back(pLine->Get_Length(iLinePart)); for (int iPoint=0; iPoint<pPart->Get_Count();iPoint++) { int iPoint2 = (iPoint!=pPart->Get_Count()-1)?iPoint+1:0; TSG_Point Crossing; double Length=0; for (int iLinePartPoint=0; iLinePartPoint<pLinePart->Get_Count(); iLinePartPoint++) { if (SG_Get_Crossing(Crossing,pPart->Get_Point(iPoint),pPart->Get_Point(iPoint2), pLinePart->Get_Point(iLinePartPoint), pLinePart->Get_Point(iLinePartPoint+1))) { LineBorders[iShape].push_back(Length+SG_Get_Distance(Crossing, pLinePart->Get_Point(iLinePartPoint))); } Length+=SG_Get_Distance(pLinePart->Get_Point(iLinePartPoint), pLinePart->Get_Point(iLinePartPoint+1)); } } } } } // convert LineBorders to the result table // the table contains the lineids and the distance to the origin of the line, // and it is sorted by lineid, polygonid CSG_Table_Record *pRecord; for (map<int,list<double> >::iterator shapeit=LineBorders.begin();shapeit!=LineBorders.end();++shapeit) { //shapeit->second.sort(); bool start=1; for (list<double>::iterator i=shapeit->second.begin(); i!=shapeit->second.end();++i) { if (start){ pRecord =pTransect_Result->Add_Record(); pRecord->Set_Value(LINE_ID, iLine); pRecord->Set_Value(START, *i); pRecord->Set_Value(POLY_ID, shapeit->first); CSG_Table_Record *pTheme_Record =pTheme->Get_Shape(shapeit->first) ; if(pTheme->Get_Field_Type(Theme_Field)== SG_DATATYPE_String ) pRecord->Set_Value(FIELD, pTheme_Record->asString(Theme_Field)); else pRecord->Set_Value(FIELD, pTheme_Record->asDouble(Theme_Field)); start = 0; } else { pRecord->Set_Value(END, *i); start=1; } } } } } return( true ); }