//--------------------------------------------------------- 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 ); }
//--------------------------------------------------------- bool CLine_Crossings::On_Execute(void) { CSG_Shapes *pLines_A = Parameters("LINES_A" )->asShapes(); CSG_Shapes *pLines_B = Parameters("LINES_B" )->asShapes(); CSG_Shapes *pCrossings = Parameters("CROSSINGS")->asShapes(); if( !pLines_A->is_Valid() || !pLines_B->is_Valid() || pLines_A->Get_Extent().Intersects(pLines_B->Get_Extent()) == INTERSECTION_None ) { Error_Set(_TL("no intersection")); return( false ); } //-------------------------------------------------------- int Attributes = Parameters("ATTRIBUTES")->asInt(); pCrossings->Create(SHAPE_TYPE_Point, CSG_String::Format("%s [%s - %s]", _TL("Crossings"), pLines_A->Get_Name(), pLines_B->Get_Name())); if( Attributes == 0 || Attributes == 2 ) { pCrossings->Add_Field("ID_A", SG_DATATYPE_Int); pCrossings->Add_Field("ID_B", SG_DATATYPE_Int); } if( Attributes == 1 || Attributes == 2 ) { Add_Attributes(pCrossings, pLines_A); Add_Attributes(pCrossings, pLines_B); } //-------------------------------------------------------- for(int aLine=0, iPair=0, nPairs=pLines_A->Get_Count()*pLines_B->Get_Count() && Process_Get_Okay(); aLine<pLines_A->Get_Count(); aLine++) { CSG_Shape_Line *pA = (CSG_Shape_Line *)pLines_A->Get_Shape(aLine); for(int bLine=0; bLine<pLines_B->Get_Count() && Set_Progress(iPair++, nPairs); bLine++) { CSG_Shape_Line *pB = (CSG_Shape_Line *)pLines_B->Get_Shape(bLine); if( pA->Intersects(pB) ) { for(int aPart=0; aPart<pA->Get_Part_Count(); aPart++) { TSG_Point A[2]; A[1] = pA->Get_Point(0, aPart); for(int aPoint=1; aPoint<pA->Get_Point_Count(aPart); aPoint++) { A[0] = A[1]; A[1] = pA->Get_Point(aPoint, aPart); for(int bPart=0; bPart<pB->Get_Part_Count(); bPart++) { TSG_Point B[2], C; B[1] = pB->Get_Point(0, bPart); for(int bPoint=1; bPoint<pB->Get_Point_Count(bPart); bPoint++) { B[0] = B[1]; B[1] = pB->Get_Point(bPoint, bPart); if( SG_Get_Crossing(C, A[0], A[1], B[0], B[1]) ) { Set_Crossing(C, pA, pB, pCrossings->Add_Shape(), Attributes); } } } } } } } } //-------------------------------------------------------- return( pCrossings->Get_Count() > 0 ); }