Exemplo n.º 1
0
//---------------------------------------------------------
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 );
}
Exemplo n.º 2
0
//---------------------------------------------------------
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 );
}