//--------------------------------------------------------- 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 ); }
//--------------------------------------------------------- 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; } }
//--------------------------------------------------------- bool CPolygon_Clip::Dissolve(CSG_Shapes *pPolygons, CSG_Shapes *pOutput) { pOutput->Create(SHAPE_TYPE_Polygon); pOutput->Add_Field(_TL("ID"), SG_DATATYPE_Int); CSG_Shape *pDissolved = pOutput->Add_Shape(pPolygons->Get_Shape(0), SHAPE_COPY_GEOM); for(int iPolygon=1; iPolygon<pPolygons->Get_Count() && Set_Progress(iPolygon, pPolygons->Get_Count()); iPolygon++) { CSG_Shape *pPolygon = pPolygons->Get_Shape(iPolygon); for(int iPart=0; iPart<pPolygon->Get_Part_Count(); iPart++) { CSG_Shape_Part *pPart = ((CSG_Shape_Polygon *)pPolygon)->Get_Part(iPart); for(int iPoint=0, nParts=pDissolved->Get_Part_Count(); iPoint<pPart->Get_Count(); iPoint++) { pDissolved->Add_Point(pPart->Get_Point(iPoint), nParts); } } } return( SG_Polygon_Dissolve(pDissolved) ); }
//--------------------------------------------------------- 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 CPolygon_Shared_Edges::On_Execute(void) { //----------------------------------------------------- CSG_Shapes *pPolygons = Parameters("POLYGONS")->asShapes(); m_Field = Parameters("ATTRIBUTE")->asInt(); m_pEdges = Parameters("EDGES")->asShapes(); m_pEdges->Create(SHAPE_TYPE_Line, CSG_String::Format(SG_T("%s [%s]"), pPolygons->Get_Name(), _TL("Edges"))); m_pEdges->Add_Field("ID_A", m_Field < 0 ? SG_DATATYPE_Int : pPolygons->Get_Field_Type(m_Field)); m_pEdges->Add_Field("ID_B", m_Field < 0 ? SG_DATATYPE_Int : pPolygons->Get_Field_Type(m_Field)); // m_pNodes = Parameters("NODES")->asShapes(); // m_pNodes->Create(SHAPE_TYPE_Point, CSG_String::Format(SG_T("%s [%s]"), pPolygons->Get_Name(), _TL("Nodes"))); // m_pNodes->Add_Field("ID", SG_DATATYPE_Int); bool bVertices = Parameters("VERTICES")->asBool (); double Epsilon = Parameters("EPSILON" )->asDouble(); int iPolygon, nAdded = 0, nRemoved = 0; //----------------------------------------------------- if( bVertices ) { for(iPolygon=0; iPolygon<pPolygons->Get_Count() && Set_Progress(iPolygon, pPolygons->Get_Count()); iPolygon++) { CSG_Shape_Polygon *pPolygon = (CSG_Shape_Polygon *)pPolygons->Get_Shape(iPolygon); for(int iPart=0; iPart<pPolygon->Get_Part_Count() && Process_Get_Okay(); iPart++) { CSG_Shape_Part *pPart = pPolygon->Get_Part(iPart); CSG_Point A = pPart->Get_Point(pPart->Get_Count() - 1); if( A != pPart->Get_Point(0) ) { pPart->Add_Point(A); } for(int iPoint=pPart->Get_Count()-2; iPoint>=0; iPoint--) { CSG_Point B = A; A = pPart->Get_Point(iPoint); if( A == B ) { pPart->Del_Point(iPoint + 1); nRemoved--; } } } } } //----------------------------------------------------- for(iPolygon=0; iPolygon<pPolygons->Get_Count()-1 && Set_Progress(iPolygon, pPolygons->Get_Count()-1); iPolygon++) { CSG_Shape_Polygon *pA = (CSG_Shape_Polygon *)pPolygons->Get_Shape(iPolygon); for(int jPolygon=iPolygon+1; jPolygon<pPolygons->Get_Count() && Process_Get_Okay(); jPolygon++) { CSG_Shape_Polygon *pB = (CSG_Shape_Polygon *)pPolygons->Get_Shape(jPolygon); for(int iPart=0; iPart<pA->Get_Part_Count() && Process_Get_Okay(); iPart++) { for(int jPart=0; jPart<pB->Get_Part_Count() && Process_Get_Okay(); jPart++) { if( pA->Get_Part(iPart)->Get_Extent().Intersects(pB->Get_Part(jPart)->Get_Extent()) ) { if( bVertices ) { nAdded += Check_Vertices(pA->Get_Part(iPart), pB->Get_Part(jPart), Epsilon); nAdded += Check_Vertices(pB->Get_Part(jPart), pA->Get_Part(iPart), Epsilon); } Get_Shared_Edges(pA->Get_Part(iPart), pB->Get_Part(jPart), Epsilon); } } } } } //----------------------------------------------------- if( Parameters("DOUBLE")->asBool() ) { for(int iEdge=0, nEdges=m_pEdges->Get_Count(); iEdge<nEdges && Set_Progress(iEdge, nEdges); iEdge++) { CSG_Shape *pA = m_pEdges->Get_Shape(iEdge); CSG_Shape *pB = m_pEdges->Add_Shape(pA); *(pB->Get_Value(0)) = *(pA->Get_Value(1)); *(pB->Get_Value(1)) = *(pA->Get_Value(0)); } } //----------------------------------------------------- if( nAdded > 0 || nRemoved > 0 ) { Message_Add(CSG_String::Format(SG_T("\n%s: %d %s, %d %s\n"), _TL("Vertices"), nAdded , _TL("added" ), nRemoved, _TL("removed") ), false); DataObject_Update(pPolygons); } return( true ); }