//---------------------------------------------------------
bool CLines_From_Polygons::On_Execute(void)
{
	CSG_Shapes	*pLines, *pPolygons;

	pPolygons	= Parameters("POLYGONS")	->asShapes();
	pLines		= Parameters("LINES")		->asShapes();

	//-----------------------------------------------------
	if(	pPolygons->Get_Count() <= 0 )
	{
		Error_Set(_TL("no polygons in input"));

		return( false );
	}

	//-----------------------------------------------------
	pLines->Create(SHAPE_TYPE_Line, pPolygons->Get_Name(), pPolygons, pPolygons->Get_Vertex_Type());

	for(int iPolygon=0; iPolygon<pPolygons->Get_Count(); iPolygon++)
	{
		CSG_Shape	*pPolygon	= pPolygons	->Get_Shape(iPolygon);
		CSG_Shape	*pLine		= pLines	->Add_Shape(pPolygon, SHAPE_COPY_ATTR);

		for(int iPart=0; iPart<pPolygon->Get_Part_Count(); iPart++)
		{
			for(int iPoint=0; iPoint<pPolygon->Get_Point_Count(iPart); iPoint++)
			{
				pLine->Add_Point(pPolygon->Get_Point(iPoint, iPart), iPart);

				if( pPolygons->Get_Vertex_Type() != SG_VERTEX_TYPE_XY )
				{
					pLine->Set_Z(pPolygon->Get_Z(iPoint, iPart), iPoint, iPart);

					if( pPolygons->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
					{
						pLine->Set_M(pPolygon->Get_M(iPoint, iPart), iPoint, iPart);
					}
				}
			}

			if( !CSG_Point(pPolygon->Get_Point(0, iPart)).is_Equal(pPolygon->Get_Point(pPolygon->Get_Point_Count(iPart) - 1, iPart)) )
			{
				pLine->Add_Point(pPolygon->Get_Point(0, iPart), iPart);

				if( pPolygons->Get_Vertex_Type() != SG_VERTEX_TYPE_XY )
				{
					pLine->Set_Z(pPolygon->Get_Z(0, iPart), pLine->Get_Point_Count(iPart) - 1, iPart);

					if( pPolygons->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
					{
						pLine->Set_M(pPolygon->Get_M(0, iPart), pLine->Get_Point_Count(iPart) - 1, iPart);
					}
				}
			}
		}
	}

	return( true );
}
//---------------------------------------------------------
void CD8_Flow_Analysis::Get_Segment(int x, int y)
{
	int		i	= m_pDir->asInt(x, y);

	if( i >= 0 )
	{
		CSG_Shape	*pSegment	= m_pSegments->Add_Shape();

		pSegment->Set_Value(0, m_pSegments->Get_Count());					// SEGMENT_ID
		pSegment->Set_Value(1, m_Nodes.asInt(x, y));						// NODE_A
		pSegment->Set_Value(3, m_pBasins->asInt(x, y));						// BASIN
		pSegment->Set_Value(4, m_pOrder->asInt(x, y) + 1 - m_Threshold);	// ORDER
		pSegment->Set_Value(5, m_pOrder->asInt(x, y));						// ORDER_CELL

		pSegment->Add_Point(Get_System()->Get_Grid_to_World(x, y));
		pSegment->Set_Z(m_pDEM->asDouble(x, y), pSegment->Get_Point_Count() - 1);

		do
		{
			x	+= Get_xTo(i);
			y	+= Get_yTo(i);

			pSegment->Add_Point(Get_System()->Get_Grid_to_World(x, y));
			pSegment->Set_Z(m_pDEM->asDouble(x, y), pSegment->Get_Point_Count() - 1);

			if( m_Nodes.asInt(x, y) )
			{
				pSegment->Set_Value(2, m_Nodes.asInt(x, y));						// NODE_B
				pSegment->Set_Value(6, ((CSG_Shape_Line *)pSegment)->Get_Length());	// LENGTH

				return;
			}
		}
		while( (i = m_pDir->asInt(x, y)) >= 0 );
	}
}
//---------------------------------------------------------
bool CPoints_From_MultiPoints::On_Execute(void)
{
	//-----------------------------------------------------
	CSG_Shapes	*pMultipoints	= Parameters("MULTIPOINTS")	->asShapes();
	CSG_Shapes	*pPoints		= Parameters("POINTS")		->asShapes();

	pPoints->Create(SHAPE_TYPE_Point, pMultipoints->Get_Name(), pMultipoints, pMultipoints->Get_Vertex_Type());

	//-----------------------------------------------------
	for(int iMultipoint=0; iMultipoint<pMultipoints->Get_Count() && Set_Progress(iMultipoint, pMultipoints->Get_Count()); iMultipoint++)
	{
		CSG_Shape	*pMultipoint	= pMultipoints->Get_Shape(iMultipoint);

		for(int iPart=0; iPart<pMultipoint->Get_Part_Count(); iPart++)
		{
			for(int iPoint=0; iPoint<pMultipoint->Get_Point_Count(iPart); iPoint++)
			{
				CSG_Shape	*pPoint	= pPoints->Add_Shape(pMultipoint, SHAPE_COPY_ATTR);

				pPoint->Add_Point(pMultipoint->Get_Point(iPoint, iPart));

				if( pMultipoints->Get_Vertex_Type() != SG_VERTEX_TYPE_XY )
				{
					pPoint->Set_Z(pMultipoint->Get_Z(iPoint, iPart), 0);

					if( pMultipoints->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
					{
						pPoint->Set_M(pMultipoint->Get_M(iPoint, iPart), 0);
					}
				}
			}
		}
	}

	return( true );
}
//---------------------------------------------------------
bool CShapes_Convert_Vertex_Type::On_Execute(void)
{
	CSG_Shapes		*pInput, *pOutput;
	int				iFieldZ, iFieldM;

	pInput		= Parameters("INPUT")->asShapes();
	iFieldZ		= Parameters("FIELD_Z")->asInt();
	iFieldM		= Parameters("FIELD_M")->asInt();
	pOutput		= Parameters("OUTPUT")->asShapes();
	
	
	if( pInput->Get_Count() < 1 )
	{
		SG_UI_Msg_Add_Error(_TL("Input shape is empty!"));
		return (false);
	}

	//-----------------------------------------------------
	if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XY )
	{
		if( iFieldZ < 0 )
		{
			SG_UI_Msg_Add_Error(_TL("Please provide an attribute field with z-information!"));
			return( false );
		}

		if( iFieldM < 0 )
		{
			pOutput->Create(pInput->Get_Type(), CSG_String::Format(SG_T("%s_Z"), pInput->Get_Name()), pInput, SG_VERTEX_TYPE_XYZ);
		}
		else
		{
			pOutput->Create(pInput->Get_Type(), CSG_String::Format(SG_T("%s_ZM"), pInput->Get_Name()), pInput, SG_VERTEX_TYPE_XYZM);
		}
	}
	else
	{
		pOutput->Create(pInput->Get_Type(), CSG_String::Format(SG_T("%s_XY"), pInput->Get_Name()), pInput, SG_VERTEX_TYPE_XY);

		pOutput->Add_Field(SG_T("Z"), SG_DATATYPE_Double);

		if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
		{
			pOutput->Add_Field(SG_T("M"), SG_DATATYPE_Double);
		}
	}


	//-----------------------------------------------------
	for(int iShape=0; iShape<pInput->Get_Count(); iShape++)
	{
		CSG_Shape	*pShapeIn	= pInput	->Get_Shape(iShape);
		CSG_Shape	*pShapeOut	= pOutput	->Add_Shape(pShapeIn, SHAPE_COPY_ATTR);

		for(int iPart=0; iPart<pShapeIn->Get_Part_Count(); iPart++)
		{
			for(int iPoint=0; iPoint<pShapeIn->Get_Point_Count(iPart); iPoint++)
			{
				pShapeOut->Add_Point(pShapeIn->Get_Point(iPoint, iPart), iPart);

				if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XY )
				{
					pShapeOut->Set_Z(pShapeIn->asDouble(iFieldZ), iPoint, iPart);

					if( pOutput->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
					{
						pShapeOut->Set_M(pShapeIn->asDouble(iFieldM), iPoint, iPart);
					}
				}
				else
				{
					if( pInput->Get_Vertex_Type() == SG_VERTEX_TYPE_XYZM )
					{
						pShapeOut->Set_Value(pOutput->Get_Field_Count() - 1, pShapeIn->Get_M(iPoint, iPart));
						pShapeOut->Set_Value(pOutput->Get_Field_Count() - 2, pShapeIn->Get_Z(iPoint, iPart));
					}
					else
					{
						pShapeOut->Set_Value(pOutput->Get_Field_Count() - 1, pShapeIn->Get_Z(iPoint, iPart));
					}
				}
			}
		}
	}

	//-----------------------------------------------------
	return( true );
}
//---------------------------------------------------------
CSG_Shape * CSG_PointCloud::_Set_Shape(int iPoint)
{
    SG_UI_Progress_Lock(true);

    CSG_Shape	*pShape	= m_Shapes.Get_Shape(0);

    if( pShape->is_Modified() && m_Shapes_Index >= 0 && m_Shapes_Index < Get_Count() )
    {
        m_Cursor	= m_Points[m_Shapes_Index];

        for(int i=0; i<Get_Field_Count(); i++)
        {
            switch( Get_Field_Type(i) )
            {
            default:
                Set_Value(i, pShape->asDouble(i));
                break;

            case SG_DATATYPE_Date:
            case SG_DATATYPE_String:
                Set_Value(i, pShape->asString(i));
                break;
            }
        }

        Set_Value(0, pShape->Get_Point(0).x);
        Set_Value(1, pShape->Get_Point(0).y);
        Set_Value(2, pShape->Get_Z    (0)  );
    }

    if( iPoint >= 0 && iPoint < Get_Count() )
    {
        if(1|| iPoint != m_Shapes_Index )
        {
            m_Cursor	= m_Points[iPoint];

            pShape->Set_Point(Get_X(), Get_Y(), 0, 0);
            pShape->Set_Z    (Get_Z()         , 0, 0);

            for(int i=0; i<Get_Field_Count(); i++)
            {
                switch( Get_Field_Type(i) )
                {
                default:
                    pShape->Set_Value(i, Get_Value(i));
                    break;

                case SG_DATATYPE_Date:
                case SG_DATATYPE_String:
                {
                    CSG_String	s;

                    Get_Value(i, s);

                    pShape->Set_Value(i, s);
                }
                break;
                }
            }

            m_Shapes_Index	= iPoint;
            pShape->m_Index	= iPoint;
            pShape->Set_Selected(is_Selected(iPoint));
        }

        m_Shapes.Set_Modified(false);

        SG_UI_Progress_Lock(false);

        return( pShape );
    }

    m_Shapes_Index	= -1;

    SG_UI_Progress_Lock(false);

    return( NULL );
}
//---------------------------------------------------------
bool CLines_From_Points::On_Execute(void)
{
	int			Order, Separate, Elevation;
	CSG_String	s;
	CSG_Shape	*pLine , *pPoint;
	CSG_Shapes	*pLines, *pPoints;

	pPoints		= Parameters("POINTS"   )->asShapes();
	pLines		= Parameters("LINES"    )->asShapes();
	Order		= Parameters("ORDER"    )->asInt();
	Separate	= Parameters("SEPARATE" )->asInt();
	Elevation	= Parameters("ELEVATION")->asInt();

	//-------------------------------------------------
	if(	pPoints->Get_Count() < 1 )
	{
		return( false );
	}

	//-------------------------------------------------
	pLines->Create(SHAPE_TYPE_Line, pPoints->Get_Name(), NULL, Elevation >= 0 ? SG_VERTEX_TYPE_XYZ : SG_VERTEX_TYPE_XY);

	pLines->Add_Field(SG_T("ID"), SG_DATATYPE_Int);

	if( Separate >= 0 )
	{
		pLines->Add_Field(pPoints->Get_Field_Name(Separate), pPoints->Get_Field_Type(Separate));

		pPoints->Set_Index(Separate, TABLE_INDEX_Ascending, Order, TABLE_INDEX_Ascending);
	}
	else
	{
		pPoints->Set_Index(Order, TABLE_INDEX_Ascending);
	}

	//-------------------------------------------------
	for(int iPoint=0; iPoint<pPoints->Get_Count(); iPoint++)
	{
		pPoint	= pPoints->Get_Shape_byIndex(iPoint);

		if( pLines->Get_Count() == 0 || (Separate >= 0 && s.Cmp(pPoint->asString(Separate))) )
		{
			pLine	= pLines->Add_Shape();

			pLine->Set_Value(0, pLines->Get_Count());

			if( Separate >= 0 )
			{
				pLine->Set_Value(1, s = pPoint->asString(Separate));
			}
		}

		pLine->Add_Point(pPoint->Get_Point(0));

		if( Elevation >= 0 )
		{
			pLine->Set_Z(pPoint->asDouble(Elevation), iPoint);
		}
	}

	return( true );
}