Beispiel #1
0
//---------------------------------------------------------
bool Trace_Polygon(CSG_Shape *pPolygon, CSG_Network &Network, int iEdge)
{
	bool		bAscending	= true;
	CSG_Shape	*pEdge		= Network.Get_Edges().Get_Shape(iEdge);

	if( pEdge->asInt(3) == SHAPE_TYPE_Polygon )
	{
		if( pEdge->asInt(4) )
		{
			return( false );
		}

		bAscending	= true;
	}
	else if( (pEdge->asInt(4) & 0x1) == 0 )
	{
		bAscending	= true;
	}
	else if( (pEdge->asInt(4) & 0x2) == 0 )
	{
		bAscending	= false;
	}
	else
	{
		return( false );
	}

	while( pEdge != NULL )
	{
		pEdge->Set_Value(4, pEdge->asInt(4) | (bAscending ? 0x1 : 0x2));

		for(int iPoint=0; iPoint<pEdge->Get_Point_Count(0); iPoint++)
		{
			pPolygon->Add_Point(pEdge->Get_Point(iPoint, 0, bAscending));
		}

		int	End_Node	= pEdge->asInt(bAscending ? 2 : 1);

		iEdge		= Network.Get_Node(End_Node).Get_Edge_Next(iEdge, false);
		pEdge		= Network.Get_Edges().Get_Shape(iEdge);

		if( pEdge )
		{
			bAscending	= pEdge->asInt(3) == SHAPE_TYPE_Polygon || End_Node == pEdge->asInt(1);

			if( (pEdge->asInt(4) & (bAscending ? 0x1 : 0x2)) )
			{
				pEdge	= NULL;
			}
		}
	}

	return( pPolygon->is_Valid() );
}
Beispiel #2
0
//---------------------------------------------------------
bool CWatershed_Segmentation::Segment_Change(int ID, int new_ID)
{
    bool	bContinue;
    int		ax, ay, bx, by;

    //-----------------------------------------------------
    CSG_Shape	*pSeed	= m_pSeeds->Get_Shape(ID);

    pSeed->Set_Value(SEED_JOIN, new_ID);

    ax	= bx	= pSeed->asInt(SEED_X);
    ay	= by	= pSeed->asInt(SEED_Y);

    do
    {
        bContinue	= false;

        for(int x=ax; x<=bx; x++)
        {
            if( m_pSegments->asInt( x, ay) == ID )
            {
                m_pSegments->Set_Value( x, ay, new_ID);

                bContinue	= true;
            }

            if( m_pSegments->asInt( x, by) == ID )
            {
                m_pSegments->Set_Value( x, by, new_ID);

                bContinue	= true;
            }
        }

        for(int y=ay; y<=by; y++)
        {
            if( m_pSegments->asInt(ax,  y) == ID )
            {
                m_pSegments->Set_Value(ax,  y, new_ID);

                bContinue	= true;
            }

            if( m_pSegments->asInt(bx,  y) == ID )
            {
                m_pSegments->Set_Value(bx,  y, new_ID);

                bContinue	= true;
            }
        }

        if( ax > 0 )			ax--;
        if( ay > 0 )			ay--;
        if( bx < Get_NX() - 1 )	bx++;
        if( by < Get_NY() - 1 )	by++;
    }
    while( bContinue );

    return( true );
}
Beispiel #3
0
//---------------------------------------------------------
bool COGR_DataSource::Write_Shapes(CSG_Shapes *pShapes)
{
	OGRLayer	*pLayer;

	//-----------------------------------------------------
	if( m_pDataSource && pShapes && pShapes->is_Valid() && (pLayer = m_pDataSource->CreateLayer(SG_STR_SGTOMB(pShapes->Get_Name()), NULL, g_OGR_Driver.Get_Type(pShapes->Get_Type()))) != NULL )
	{
		bool			bResult	= true;
		int				iField;

		//-------------------------------------------------
		for(iField=0; iField<pShapes->Get_Field_Count() && bResult; iField++)
		{
			OGRFieldDefn	DefField(SG_STR_SGTOMB(pShapes->Get_Field_Name(iField)), g_OGR_Driver.Get_Type(pShapes->Get_Field_Type(iField)));

			//	DefField.SetWidth(32);

			if( pLayer->CreateField(&DefField) != OGRERR_NONE )
			{
				bResult	= false;
			}
		}

		//-------------------------------------------------
		for(int iShape=0; iShape<pShapes->Get_Count() && bResult && SG_UI_Process_Set_Progress(iShape, pShapes->Get_Count()); iShape++)
		{
			CSG_Shape	*pShape		= pShapes->Get_Shape(iShape);
			OGRFeature	*pFeature	= OGRFeature::CreateFeature(pLayer->GetLayerDefn());

			for(iField=0; iField<pShapes->Get_Field_Count(); iField++)
			{
				switch( pShapes->Get_Field_Type(iField) )
				{
				default:
				case SG_DATATYPE_Char:
				case SG_DATATYPE_String:
				case SG_DATATYPE_Date:
					pFeature->SetField(iField, SG_STR_SGTOMB(pShape->asString(iField)));
					break;

				case SG_DATATYPE_Short:
				case SG_DATATYPE_Int:
				case SG_DATATYPE_Long:
				case SG_DATATYPE_Color:
					pFeature->SetField(iField, pShape->asInt(iField));
					break;

				case SG_DATATYPE_Float:
				case SG_DATATYPE_Double:
					pFeature->SetField(iField, pShape->asDouble(iField));
					break;
				}
			}

			if( !_Write_Geometry(pShape, pFeature) || pLayer->CreateFeature(pFeature) != OGRERR_NONE )
			{
				bResult	= false;
			}

			OGRFeature::DestroyFeature(pFeature);
		}

		//-------------------------------------------------
		return( bResult );
	}

	return( false );
}
Beispiel #4
0
//---------------------------------------------------------
bool CPolygon_Line_Intersection::Get_Intersection(CSG_Shape_Polygon *pPolygon)
{
	CSG_Network	Network;

	for(int iLine=0; iLine<m_pLines->Get_Count(); iLine++)
	{
		CSG_Shape	*pLine	= m_pLines->Get_Shape(iLine);

		if( pLine->Intersects(pPolygon) )
		{
			Network.Add_Shape(pLine);
		}
	}

	if( Network.Get_Edges().Get_Count() == 0 )
	{
		return( false );
	}

	Network.Add_Shape(pPolygon);
	Network.Update();
	Network.Remove_End_Nodes();

	//-----------------------------------------------------
	int			iEdge, iPolygon;
	CSG_Shapes	Intersection(SHAPE_TYPE_Polygon);

	Intersection.Add_Field(SG_T("ID"), SG_DATATYPE_Int);

	for(iEdge=0; iEdge<Network.Get_Edges().Get_Count(); iEdge++)
	{
		CSG_Shape	*pEdge	= Network.Get_Edges().Get_Shape(iEdge);

		if( pEdge->asInt(3) == SHAPE_TYPE_Polygon )
		{
			Trace_Polygon(Intersection.Add_Shape(), Network, iEdge);
		}
		else if( pPolygon->Contains(pEdge->Get_Point(0)) && pPolygon->Contains(pEdge->Get_Point(pEdge->Get_Point_Count(0) - 1)) )
		{
			Trace_Polygon(Intersection.Add_Shape(), Network, iEdge);
			Trace_Polygon(Intersection.Add_Shape(), Network, iEdge);
		}
	}

	//-----------------------------------------------------
	for(iPolygon=0; iPolygon<Intersection.Get_Count(); iPolygon++)	// 1. outer rings
	{
		CSG_Shape	*pIntersect	= Intersection.Get_Shape(iPolygon);

		if( pIntersect->Get_Point_Count() > 0 && ((CSG_Shape_Polygon *)pIntersect)->is_Clockwise(0) == true )
		{
			pIntersect->Set_Value(0, m_pIntersection->Get_Count());

			((CSG_Table_Record *)m_pIntersection->Add_Shape(pIntersect, SHAPE_COPY_GEOM))->Assign(pPolygon);
		}
	}

	for(iPolygon=0; iPolygon<Intersection.Get_Count(); iPolygon++)	// 2. inner rings
	{
		CSG_Shape	*pIntersect	= Intersection.Get_Shape(iPolygon);

		if( pIntersect->Get_Point_Count() > 0 && ((CSG_Shape_Polygon *)pIntersect)->is_Clockwise(0) == false )
		{
			for(int j=0; j<Intersection.Get_Count(); j++)
			{
				if( ((CSG_Shape_Polygon *)Intersection.Get_Shape(j))->Contains(pIntersect->Get_Point(0)) )
				{
					CSG_Shape	*pShape	= m_pIntersection->Get_Shape(Intersection[j].asInt(0));

					for(int iPoint=0, iPart=pShape->Get_Part_Count(); iPoint<pIntersect->Get_Point_Count(0); iPoint++)
					{
						pShape->Add_Point(pIntersect->Get_Point(iPoint), iPart);
					}

					break;
				}
			}
		}
	}

	//-----------------------------------------------------
	return( true );
}
Beispiel #5
0
//---------------------------------------------------------
bool CSG_Network::Remove_End_Nodes(void)
{
	int		iEdge, n;

	//-----------------------------------------------------
	for(iEdge=0; iEdge<m_Edges.Get_Count(); iEdge++)
	{
		CSG_Shape	*pEdge	= m_Edges.Get_Shape(iEdge);

		if( pEdge->asInt(3) == SHAPE_TYPE_Line )
		{
			bool	bRemove	= false;

			for(int iNode=1; iNode<=2 && !bRemove; iNode++)
			{
				CSG_Network_Node	&Node	= Get_Node(pEdge->asInt(iNode));
				CSG_Point			Point	= Node.Get_Point();
				CSG_Shape			*pNext;

				if(	(	(pNext = m_Edges.Get_Shape(Node.Get_Edge_Next(pEdge->asInt(0),  true))) != NULL
						&&	pNext->asInt(3) == SHAPE_TYPE_Polygon
						&&	!Point.is_Equal(pNext->Get_Point(0, 0, false)) )
				||	(	(pNext = m_Edges.Get_Shape(Node.Get_Edge_Next(pEdge->asInt(0), false))) != NULL
						&&	pNext->asInt(3) == SHAPE_TYPE_Polygon
						&&	!Point.is_Equal(pNext->Get_Point(0, 0,  true)) ) )
				{
					bRemove	= true;
				}
			}

			if( bRemove )
			{
				Get_Node(pEdge->asInt(1)).Del_Edge(pEdge->asInt(0));
				Get_Node(pEdge->asInt(2)).Del_Edge(pEdge->asInt(0));

				pEdge->Set_Value(4, 1);
			}
		}
	}

	//-----------------------------------------------------
	do
	{
		for(n=0, iEdge=0; iEdge<m_Edges.Get_Count(); iEdge++)
		{
			CSG_Shape	*pEdge	= m_Edges.Get_Shape(iEdge);

			if( pEdge->asInt(3) == SHAPE_TYPE_Line && pEdge->asInt(4) == 0 )
			{
				if(	Get_Node(pEdge->asInt(1)).Get_Edge_Count() <= 1
				||	Get_Node(pEdge->asInt(2)).Get_Edge_Count() <= 1 )
				{
					Get_Node(pEdge->asInt(1)).Del_Edge(pEdge->asInt(0));
					Get_Node(pEdge->asInt(2)).Del_Edge(pEdge->asInt(0));

					pEdge->Set_Value(4, 1);

					n++;
				}
			}
		}
	}
	while( n > 0 );

	//-----------------------------------------------------
	for(iEdge=m_Edges.Get_Count()-1; iEdge>=0; iEdge--)
	{
		if( m_Edges[iEdge][4] )
		{
			m_Edges.Del_Shape(iEdge);
		}
	}

	//-----------------------------------------------------
	return( Update() );
}
//---------------------------------------------------------
bool CWatersheds_ext::On_Execute(void)
{
	int			x, y;
	CSG_Grid	*pBasins, *pSubBasins, Inflows;
	CSG_Shapes	*pHeads, *pMouths, *pVBasins, *pVSubBasins;

	m_pDEM		= Parameters("DEM")			->asGrid(); 
	m_pChannels	= Parameters("CHANNELS")	->asGrid();
	pBasins		= Parameters("BASINS")		->asGrid();
	pSubBasins	= Parameters("SUBBASINS")	->asGrid();
	pVBasins	= Parameters("V_BASINS")	->asShapes();
	pVSubBasins	= Parameters("V_SUBBASINS")	->asShapes();
	pHeads		= Parameters("HEADS")		->asShapes();
	pMouths		= Parameters("MOUTHS")		->asShapes();

	//-----------------------------------------------------
	Inflows		.Create(*Get_System(), SG_DATATYPE_Char);

	m_Direction	.Create(*Get_System(), SG_DATATYPE_Char);
	m_Direction	.Set_NoData_Value(-1);

	m_Distance	.Create(*Get_System(), SG_DATATYPE_Float);
	m_Distance	.Set_NoData_Value(-1);
	m_Distance	.Assign_NoData();

	pBasins		->Assign(0.0);
	pBasins		->Set_NoData_Value(0.0);

	pSubBasins	->Assign(0.0);
	pSubBasins	->Set_NoData_Value(0.0);

	pHeads		->Create(SHAPE_TYPE_Point	, _TL("Heads"));
	pHeads		->Add_Field("ID"			, SG_DATATYPE_Int);
	pHeads		->Add_Field("MAIN_ID"		, SG_DATATYPE_Int);
	pHeads		->Add_Field("ELEVATION"		, SG_DATATYPE_Double);
	pHeads		->Add_Field("DISTANCE"		, SG_DATATYPE_Double);

	pMouths		->Create(SHAPE_TYPE_Point	, _TL("Mouths"));
	pMouths		->Add_Field("ID"			, SG_DATATYPE_Int);
	pMouths		->Add_Field("MAIN_ID"		, SG_DATATYPE_Int);
	pMouths		->Add_Field("ELEVATION"		, SG_DATATYPE_Double);

	pVBasins	->Create(SHAPE_TYPE_Polygon	, _TL("Basins"));
	BASIN_ADD_FIELDS(pVBasins);

	pVSubBasins	->Create(SHAPE_TYPE_Polygon	, _TL("Subbasins"));
	BASIN_ADD_FIELDS(pVSubBasins);

	//-----------------------------------------------------
	Process_Set_Text(_TL("flow directions..."));

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			int	Direction	= -1;

			if( m_pDEM->is_InGrid(x, y) )
			{
				double	dMax		= 0.0;

				for(int i=0; i<8; i++)
				{
					int	ix	= Get_xTo(i, x);
					int	iy	= Get_yTo(i, y);

					if( m_pDEM->is_InGrid(ix, iy) && !m_pChannels->is_NoData(ix, iy) )
					{
						double	dz	= (m_pDEM->asDouble(x, y) - m_pDEM->asDouble(ix, iy)) / Get_Length(i);

						if( dMax < dz )
						{
							dMax		= dz;
							Direction	= i;
						}
					}
				}

				if( !m_pChannels->is_NoData(x, y) )
				{
					if( Direction >= 0 )
					{
						int	ix	= Get_xTo(Direction, x);
						int	iy	= Get_yTo(Direction, y);

						if( m_pDEM->is_InGrid(ix, iy) )
						{
							Inflows.Add_Value(ix, iy, 1);
						}
					}
				}
				else if( Direction < 0 )
				{
					Direction	= m_pDEM->Get_Gradient_NeighborDir(x, y);
				}
			}

			m_Direction.Set_Value(x, y, Direction);
		}
	}

	//-----------------------------------------------------
	Process_Set_Text(_TL("main basins..."));

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			if( m_pChannels->is_InGrid(x, y) && is_Outlet(x, y) )
			{
				Get_Basin(pBasins, pVBasins, x, y, -1);

				CSG_Shape	*pMouth	= pMouths->Add_Shape();

				pMouth->Add_Point(Get_System()->Get_Grid_to_World(x, y));

				pMouth->Set_Value(0, pVBasins->Get_Count());	// ID
				pMouth->Set_Value(1, pVBasins->Get_Count());	// MAIN_ID
				pMouth->Set_Value(2, m_pDEM->asDouble(x, y));	// ELEVATION
			}
		}
	}

	if( Parameters("DISTANCE")->asBool() )
	{
		m_Distance.Set_Name(_TL("Flow Distance"));

		DataObject_Add(SG_Create_Grid(m_Distance));
	}

	//-----------------------------------------------------
	Process_Set_Text(_TL("heads and mouths..."));

	for(y=0; y<Get_NY() && Set_Progress(y); y++)
	{
		for(x=0; x<Get_NX(); x++)
		{
			if( m_pChannels->is_InGrid(x, y) )
			{
				//-----------------------------------------
				if( Inflows.asInt(x, y) > 1 )		// mouth, linking channels of subcatchments
				{
					CSG_Shape	*pMouth	= pMouths->Add_Shape();

					pMouth->Add_Point(Get_System()->Get_Grid_to_World(x, y));

					pMouth->Set_Value(0, pMouths->Get_Count());		// ID
					pMouth->Set_Value(1, pBasins->asDouble(x, y));	// MAIN_ID
					pMouth->Set_Value(2, m_pDEM->asDouble(x, y));	// ELEVATION
				}

				//-----------------------------------------
				else if( Inflows.asInt(x, y) == 0 )	// head
				{
					CSG_Shape	*pHead	= pHeads->Add_Shape();

					pHead->Add_Point(Get_System()->Get_Grid_to_World(x, y));

					pHead->Set_Value(0, pHeads->Get_Count() + 1);
					pHead->Set_Value(1, m_Distance.asDouble(x, y));
				}
			}
		}
	}

	//-----------------------------------------------------
	Process_Set_Text(_TL("subbasins..."));

	pMouths->Set_Index(1, TABLE_INDEX_Ascending, 2, TABLE_INDEX_Descending);

	for(int iMouth=0; iMouth<pMouths->Get_Count() && Set_Progress(iMouth, pMouths->Get_Count()); iMouth++)
	{
		CSG_Shape	*pMouth	= pMouths->Get_Shape_byIndex(iMouth);

		if( Get_System()->Get_World_to_Grid(x, y, pMouth->Get_Point(0)) )
		{
			if( pMouth->asInt(0) == pMouth->asInt(1) )
			{
				Get_Basin(pSubBasins, pVSubBasins, x, y, pMouth->asInt(1));
			}
			else
			{
				for(int i=0; i<8; i++)
				{
					int	ix	= Get_xFrom(i, x);
					int	iy	= Get_yFrom(i, y);

					if( m_pChannels->is_InGrid(ix, iy) && m_Direction.asInt(ix, iy) == i )
					{
						Get_Basin(pSubBasins, pVSubBasins, ix, iy, pMouth->asInt(1));
					}
				}
			}
		}
	}

	if( Parameters("DISTANCE")->asBool() )
	{
		m_Distance.Set_Name(_TL("Subbasin Flow Distance"));

		DataObject_Add(SG_Create_Grid(m_Distance));
	}

	//-----------------------------------------------------
	m_Distance	.Destroy();
	m_Direction	.Destroy();

	return( true );
}