//---------------------------------------------------------
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 );
}
示例#2
0
//---------------------------------------------------------
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) );
}
示例#4
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 );
}
//---------------------------------------------------------
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 );
}