
///////////////////////////////////////////////////////////
//                                                       //
//                         SAGA                          //
//                                                       //
//      System for Automated Geoscientific Analyses      //
//                                                       //
//                     Tool Library                      //
//                     Shapes_Tools                      //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//                  Shapes_Extents.cpp                   //
//                                                       //
//                 Copyright (C) 2008 by                 //
//                      Olaf Conrad                      //
//                                                       //
//-------------------------------------------------------//
//                                                       //
// This file is part of 'SAGA - System for Automated     //
// Geoscientific Analyses'. SAGA is free software; you   //
// can redistribute it and/or modify it under the terms  //
// of the GNU General Public License as published by the //
// Free Software Foundation, either version 2 of the     //
// License, or (at your option) any later version.       //
//                                                       //
// SAGA is distributed in the hope that it will be       //
// useful, but WITHOUT ANY WARRANTY; without even the    //
// implied warranty of MERCHANTABILITY or FITNESS FOR A  //
// PARTICULAR PURPOSE. See the GNU General Public        //
// License for more details.                             //
//                                                       //
// You should have received a copy of the GNU General    //
// Public License along with this program; if not, see   //
// <http://www.gnu.org/licenses/>.                       //
//                                                       //
//-------------------------------------------------------//
//                                                       //
//    e-mail:     oconrad@saga-gis.org                   //
//                                                       //
//    contact:    Olaf Conrad                            //
//                Institute of Geography                 //
//                University of Goettingen               //
//                Goldschmidtstr. 5                      //
//                37077 Goettingen                       //
//                Germany                                //
//                                                       //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
#include "shapes_extents.h"


///////////////////////////////////////////////////////////
//                                                       //
//                                                       //
//                                                       //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
CShapes_Extents::CShapes_Extents(void)
{
	Set_Name		(_TL("Get Shapes Extents"));

	Set_Author		("O.Conrad (c) 2008");

	Set_Description	(_TW(
		""
	));

	//-----------------------------------------------------
	Parameters.Add_Shapes("", "SHAPES" , _TL("Shapes" ), _TL(""), PARAMETER_INPUT);

	Parameters.Add_Shapes("", "EXTENTS", _TL("Extents"), _TL(""), PARAMETER_OUTPUT, SHAPE_TYPE_Polygon);

	Parameters.Add_Choice("", "OUTPUT" , _TL("Get Extent for ..."), _TL(""), CSG_String::Format("%s|%s|%s",
		_TL("all shapes"),
		_TL("each shape"),
		_TL("each shape's part")), 1
	);

	Parameters.Add_Double("", "BUFFER" , _TL("Add Buffer"), _TL(""), 0., 0., true);
}


///////////////////////////////////////////////////////////
//                                                       //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
bool CShapes_Extents::On_Execute(void)
{
	CSG_Shapes &Shapes = *Parameters("SHAPES")->asShapes();

	if( !Shapes.is_Valid() )
	{
		Message_Add(_TL("empty or invalid input layer"));

		return( false );
	}

	int	   Output = Parameters("OUTPUT")->asInt   ();
	double Buffer = Parameters("BUFFER")->asDouble();

	if( Shapes.Get_Type() == SHAPE_TYPE_Point && Buffer <= 0. )
	{
		Message_Add(_TL("no 'get extents' support for single points"));

		return( false );
	}

	CSG_Shapes &Extents = *Parameters("EXTENTS")->asShapes();

	//-----------------------------------------------------
	if( Output == 0 ) // all shapes
	{
		Extents.Create(SHAPE_TYPE_Polygon);
		Extents.Fmt_Name("%s [%s]", Shapes.Get_Name(), _TL("Extent"));
		Extents.Add_Field("ID", SG_DATATYPE_Int);

		CSG_Rect r = Shapes.Get_Extent(); if( Buffer > 0. ) { r.Inflate(Buffer, false); }

		CSG_Shape &Extent = *Extents.Add_Shape();

		Extent.Set_Value(0, 1);

		Extent.Add_Point(r.xMin, r.yMin);
		Extent.Add_Point(r.xMin, r.yMax);
		Extent.Add_Point(r.xMax, r.yMax);
		Extent.Add_Point(r.xMax, r.yMin);

		return( true );
	}

	//-----------------------------------------------------
	Extents.Create(SHAPE_TYPE_Polygon, NULL, &Shapes);
	Extents.Fmt_Name("%s [%s]", Shapes.Get_Name(), _TL("Extents"));

	for(sLong i=0; i<Shapes.Get_Count() && Set_Progress(i, Shapes.Get_Count()); i++)
	{
		CSG_Shape &Shape = *Shapes.Get_Shape(i);

		if( Output == 1 ) // each shape
		{
			CSG_Rect r = Shape.Get_Extent(); if( Buffer > 0. ) { r.Inflate(Buffer, false); }

			CSG_Shape &Extent = *Extents.Add_Shape(&Shape, SHAPE_COPY_ATTR);

			Extent.Add_Point(r.xMin, r.yMin);
			Extent.Add_Point(r.xMin, r.yMax);
			Extent.Add_Point(r.xMax, r.yMax);
			Extent.Add_Point(r.xMax, r.yMin);
		}
		else for(int iPart=0; iPart<Shape.Get_Part_Count(); iPart++) // if( Output == 2 ) // each shape's part
		{
			CSG_Rect r = Shape.Get_Extent(iPart); if( Buffer > 0. ) { r.Inflate(Buffer, false); }

			CSG_Shape &Extent = *Extents.Add_Shape(&Shape, SHAPE_COPY_ATTR);

			Extent.Add_Point(r.xMin, r.yMin);
			Extent.Add_Point(r.xMin, r.yMax);
			Extent.Add_Point(r.xMax, r.yMax);
			Extent.Add_Point(r.xMax, r.yMin);
		}
	}

	//-----------------------------------------------------
	return( Extents.is_Valid() );
}


///////////////////////////////////////////////////////////
//                                                       //
//                                                       //
//                                                       //
///////////////////////////////////////////////////////////

//---------------------------------------------------------
