Example #1
0
//---------------------------------------------------------
bool CShape_Index::On_Execute(void)
{
	CSG_Shapes	*pShapes, *pIndex;

	//-----------------------------------------------------
	pShapes	= Parameters("SHAPES")	->asShapes();
	pIndex	= Parameters("INDEX")	->asShapes();

	//-----------------------------------------------------
	if( pShapes->is_Valid() )
	{
		int		iField	= pShapes->Get_Field_Count();

		if( pIndex == NULL )
		{
			pIndex	= pShapes;
		}

		if( pIndex != pShapes )
		{
			pIndex->Create(SHAPE_TYPE_Polygon, _TL("Shape Index"), pShapes);
		}

		pIndex->Add_Field(_TL("Area")			, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("Perimenter")		, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("P/A")			, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("P/sqrt(A)")		, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("Max.Distance")	, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("D/A")			, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("D/sqrt(A)")		, SG_DATATYPE_Double);
		pIndex->Add_Field(_TL("Shape Index")	, SG_DATATYPE_Double);

		for(int iShape=0; iShape<pShapes->Get_Count() && Set_Progress(iShape, pShapes->Get_Count()); iShape++)
		{
			CSG_Shape_Polygon	*pShape	= (CSG_Shape_Polygon *)pShapes->Get_Shape(iShape);

			double	Area		= pShape->Get_Area();
			double	Perimeter	= pShape->Get_Perimeter();
			double	Distance	= Get_Distance(pShape);

			if( Perimeter > 0.0 && Distance > 0.0 )
			{
				if( pIndex != pShapes )
				{
					pShape		= (CSG_Shape_Polygon *)pIndex->Add_Shape(pShape, SHAPE_COPY_ATTR);
				}

				pShape->Set_Value(iField + 0, Area);
				pShape->Set_Value(iField + 1, Perimeter);
				pShape->Set_Value(iField + 2, Perimeter / Area);
				pShape->Set_Value(iField + 3, Perimeter / sqrt(Area));
				pShape->Set_Value(iField + 4, Distance);
				pShape->Set_Value(iField + 5, Distance / Area);
				pShape->Set_Value(iField + 6, Distance / sqrt(Area));
				pShape->Set_Value(iField + 7, Perimeter / (2.0 * sqrt(M_PI * Area)));
			}
		}

		if( pIndex == pShapes )
		{
			DataObject_Update(pShapes);
		}

		return( pIndex->is_Valid() );
	}

	//-----------------------------------------------------
	return( false );
}
//---------------------------------------------------------
bool CShape_Index::On_Execute(void)
{
	//-----------------------------------------------------
	CSG_Shapes	*pPolygons = Parameters("SHAPES")->asShapes();

	if( !pPolygons->is_Valid() )
	{
		Error_Set(_TL("invalid polygons layer"));

		return( false );
	}

	//-----------------------------------------------------
	if( Parameters("INDEX")->asShapes() && Parameters("INDEX")->asShapes() != pPolygons )
	{
		CSG_Shapes	*pTarget   = Parameters("INDEX")->asShapes();

		pTarget->Create(SHAPE_TYPE_Polygon, CSG_String::Format("%s [%s]", pPolygons->Get_Name(), _TL("Shape Indices")));

		pTarget->Add_Field("ID", SG_DATATYPE_Int);

		for(int iPolygon=0; iPolygon<pPolygons->Get_Count() && Set_Progress(iPolygon, pPolygons->Get_Count()); iPolygon++)
		{
			pTarget->Add_Shape(pPolygons->Get_Shape(iPolygon), SHAPE_COPY)->Set_Value(0, iPolygon);
		}

		pPolygons	= pTarget;
	}

	//-----------------------------------------------------
	int	offIndices	= pPolygons->Get_Field_Count();

	pPolygons->Add_Field(_TL("A"           ), SG_DATATYPE_Double);	//  0
	pPolygons->Add_Field(_TL("P"           ), SG_DATATYPE_Double);	//  1
	pPolygons->Add_Field(_TL("P/A"         ), SG_DATATYPE_Double);	//  2
	pPolygons->Add_Field(_TL("P/sqrt(A)"   ), SG_DATATYPE_Double);	//  3
	pPolygons->Add_Field(_TL("Depqc"       ), SG_DATATYPE_Double);	//  4
	pPolygons->Add_Field(_TL("Sphericity"  ), SG_DATATYPE_Double);	//  5
	pPolygons->Add_Field(_TL("Shape Index" ), SG_DATATYPE_Double);	//  6
	pPolygons->Add_Field(_TL("Dmax"        ), SG_DATATYPE_Double);	//  7
	pPolygons->Add_Field(_TL("DmaxDir"     ), SG_DATATYPE_Double);	//  8
	pPolygons->Add_Field(_TL("Dmax/A"      ), SG_DATATYPE_Double);	//  9
	pPolygons->Add_Field(_TL("Dmax/sqrt(A)"), SG_DATATYPE_Double);	// 10

	bool	bGyros	= Parameters("GYROS")->asBool();

	if( bGyros )
	{
		pPolygons->Add_Field(_TL("Dgyros"  ), SG_DATATYPE_Double);	// 11
	}

	int	offFeret	= pPolygons->Get_Field_Count();

	double	dFeret	= 0.0;

	if( Parameters("FERET")->asBool() )
	{
		dFeret	= M_DEG_TO_RAD * (180. / (1. + Parameters("FERET_DIRS")->asInt()));

		pPolygons->Add_Field(_TL("Fmax"    ), SG_DATATYPE_Double);	//  0
		pPolygons->Add_Field(_TL("FmaxDir" ), SG_DATATYPE_Double);	//  1
		pPolygons->Add_Field(_TL("Fmin"    ), SG_DATATYPE_Double);	//  2
		pPolygons->Add_Field(_TL("FminDir" ), SG_DATATYPE_Double);	//  3
		pPolygons->Add_Field(_TL("Fmean"   ), SG_DATATYPE_Double);	//  4
		pPolygons->Add_Field(_TL("Fmax90"  ), SG_DATATYPE_Double);	//  5
		pPolygons->Add_Field(_TL("Fmin90"  ), SG_DATATYPE_Double);	//  6
		pPolygons->Add_Field(_TL("Fvol"    ), SG_DATATYPE_Double);	//  7
	}

	//-----------------------------------------------------
	CSG_Shapes	*pDmax	= Parameters("DMAX")->asShapes();

	if( pDmax )
	{
		pDmax->Create(SHAPE_TYPE_Line, CSG_String::Format("%s [%s]", pPolygons->Get_Name(), _TL("Maximum Diameter")));

		pDmax->Add_Field("ID", SG_DATATYPE_Int   );
		pDmax->Add_Field("D" , SG_DATATYPE_Double);
	}

	//-----------------------------------------------------
	for(int iPolygon=0; iPolygon<pPolygons->Get_Count() && Set_Progress(iPolygon, pPolygons->Get_Count()); iPolygon++)
	{
		CSG_Shape_Polygon	*pPolygon	= (CSG_Shape_Polygon *)pPolygons->Get_Shape(iPolygon);

		double	A	= pPolygon->Get_Area     ();
		double	P	= pPolygon->Get_Perimeter();

		if( A > 0.0 && P > 0.0 )
		{
			pPolygon->Set_Value(offIndices + 0, A);
			pPolygon->Set_Value(offIndices + 1, P);
			pPolygon->Set_Value(offIndices + 2, P / A);
			pPolygon->Set_Value(offIndices + 3, P / sqrt(A));
			pPolygon->Set_Value(offIndices + 4, 2 * sqrt(A / M_PI));
			pPolygon->Set_Value(offIndices + 5, (2 * sqrt(A * M_PI)) / P);
			pPolygon->Set_Value(offIndices + 6, P / (2 * sqrt(A * M_PI)));

			double	Dmax;	TSG_Point	Pmax[2];

			if( Get_Diameter_Max(pPolygon, Dmax, Pmax) )
			{
				double	DmaxDir	= SG_Get_Angle_Of_Direction(Pmax[0], Pmax[1]); if( DmaxDir > M_PI_180 ) DmaxDir -= M_PI_180;

				pPolygon->Set_Value(offIndices +  7, Dmax);
				pPolygon->Set_Value(offIndices +  8, DmaxDir * M_RAD_TO_DEG);
				pPolygon->Set_Value(offIndices +  9, Dmax / A);
				pPolygon->Set_Value(offIndices + 10, Dmax / sqrt(A));

				if( pDmax )
				{
					CSG_Shape	*pLine	= pDmax->Add_Shape();

					pLine->Add_Point(Pmax[0]);
					pLine->Add_Point(Pmax[1]);

					pLine->Set_Value(0, iPolygon);
					pLine->Set_Value(1, Dmax);
				}

				if( bGyros )
				{
					Get_Diameter_Gyros(pPolygon, offIndices + 11);
				}

				if( dFeret > 0.0 )
				{
					Get_Diameters_Feret(pPolygon, offFeret, dFeret);
				}
			}
			else
			{
				for(int iField=offIndices+7; iField<pPolygons->Get_Field_Count(); iField++)
				{
					pPolygon->Set_NoData(iField);
				}
			}
		}
		else
		{
			for(int iField=offIndices; iField<pPolygons->Get_Field_Count(); iField++)
			{
				pPolygon->Set_NoData(iField);
			}
		}
	}

	//-----------------------------------------------------
	if( pPolygons == Parameters("SHAPES")->asShapes() )
	{	// output is always updated automatically - but if input has been modified, this needs a manual update!
		DataObject_Update(pPolygons);
	}

	return( pPolygons->is_Valid() );
}