1 /**********************************************************
2  * Version $Id$
3  *********************************************************/
4 /*******************************************************************************
5     AggregationIndex.cpp
6     Copyright (C) Victor Olaya
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12 
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17 
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301, USA
21 *******************************************************************************/
22 
23 #include "Grid_AggregationIndex.h"
24 
25 
CAggregationIndex(void)26 CAggregationIndex::CAggregationIndex(void){
27 
28 	Set_Name		(_TL("Aggregation Index"));
29 
30 	Set_Description	(_TW(
31 		"(c) 2004 by Victor Olaya. Aggregation Index\r\n"
32 		"References:\r\n"
33 		"1. Hong S. He, et al. An aggregation index to quantify spatial patterns of landscapes, Landscape Ecology 15, 591-601,2000\r\n"
34 	));
35 
36 	Parameters.Add_Grid(NULL,
37 						"INPUT",
38 						_TL("Input Grid"),
39 						_TL(""),
40 						PARAMETER_INPUT);
41 
42 	Parameters.Add_Value(NULL,
43 						"MAXNUMCLASS",
44 						_TL("Max. Number of Classes"),
45 						_TL("Maximum number of classes in the entire grid."),
46 						PARAMETER_TYPE_Int,
47 						10);
48 
49 	Parameters.Add_Table(NULL,
50 						"RESULT",
51 						_TL("Result"),
52 						_TL(""),
53 						PARAMETER_OUTPUT);
54 
55 }//constructor
56 
57 
~CAggregationIndex(void)58 CAggregationIndex::~CAggregationIndex(void){}
59 
On_Execute(void)60 bool CAggregationIndex::On_Execute(void){
61 
62 	int i;
63 	int iClass;
64 	int iXOffset[] = {-1,0,0,1};
65 	int iYOffset[] = {0,-1,1,0};
66 	int iTotalArea = 0;
67 	int iLargestInt;
68 	int iMaxEii;
69 	int iRemainder;
70 	int iNumClasses = Parameters("MAXNUMCLASS")->asInt();
71 	CSG_Grid* pInput = Parameters("INPUT")->asGrid();
72 	CSG_Table* pTable = Parameters("RESULT")->asTable();
73 	CSG_Table_Record* pRecord;
74 
75 	float** pData = new float*[iNumClasses];
76 	for (i = 0; i < iNumClasses; i++){
77 		pData[i] = new float[2];
78 		pData[i][0] = 0;
79 		pData[i][1] = 0;
80 	}//for
81 
82 	pTable->Create((CSG_Table*)NULL);
83 	pTable->Set_Name(_TL("Aggregation Index"));
84 	pTable->Add_Field(_TL("Class"), SG_DATATYPE_Int);
85 	pTable->Add_Field(_TL("Area"), SG_DATATYPE_Double);
86 	pTable->Add_Field(_TL("Area(%)"), SG_DATATYPE_Double);
87 	pTable->Add_Field(_TL("Aggregation Index"), SG_DATATYPE_Double);
88 
89 	for(int y=1; y<Get_NY()-1 && Set_Progress(y); y++){
90 		for(int x=1; x<Get_NX()-1; x++){
91 			if (!pInput->is_NoData(x,y)){
92 				iClass = pInput->asInt(x,y);
93 				if (iClass <= iNumClasses && iClass > 0){
94 					iTotalArea++;
95 					pData[iClass-1][0]++;
96 					for (i=0; i<4; i++){
97 						if (pInput->asInt(x + iXOffset[i],y + iYOffset[i]) == iClass){
98 							pData[iClass-1][1]++;
99 						}//if
100 					}//for
101 				}//if
102 			}//if
103 		}//for
104 	}//for
105 
106 	for(i=0; i<iNumClasses; i++){
107 		pRecord	= pTable->Add_Record();
108 		pRecord->Set_Value(0, i + 1);
109 		pRecord->Set_Value(1, pData[i][0]);
110 		if (pData[i][0]){
111 			pRecord->Set_Value(2, (float) pData[i][0] / (float) iTotalArea * 100.0);
112 			iLargestInt = (int) floor(sqrt(pData[i][0]));
113 			iRemainder = (int) (pData[i][0] - (iLargestInt * iLargestInt));
114 			if (iRemainder){
115 				if (iRemainder < iLargestInt){
116 					iMaxEii = 2 * iLargestInt * (iLargestInt - 1) + 2 * iRemainder - 1;
117 				}//if
118 				else{
119 					iMaxEii = 2 * iLargestInt * (iLargestInt - 1) + 2 * iRemainder - 2;
120 				}//else
121 			}//if
122 			else{
123 				iMaxEii = 2 * iLargestInt * (iLargestInt - 1);
124 			}//else
125 			pRecord->Set_Value(3, (float) pData[i][1] / (float) iMaxEii / 2.0);
126 		}//if
127 		else{
128 			pRecord->Set_Value(2, 0.0);
129 			pRecord->Set_Value(3, 0.0);
130 		}//else
131 	}//for
132 
133 	for (i = 0; i < iNumClasses; i++){
134 		delete [] pData[i];
135 	}//for
136 
137 	delete [] pData;
138 
139 	return true;
140 
141 }//method
142