1 
2 /*******************************************************************************
3     Image_VI_Distance.cpp
4     Copyright (C) Victor Olaya
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301, USA
19 *******************************************************************************/
20 
21 ///////////////////////////////////////////////////////////
22 //                                                       //
23 //                                                       //
24 //                                                       //
25 ///////////////////////////////////////////////////////////
26 
27 //---------------------------------------------------------
28 #include "Image_VI_Distance.h"
29 
30 
31 ///////////////////////////////////////////////////////////
32 //                                                       //
33 //                                                       //
34 //                                                       //
35 ///////////////////////////////////////////////////////////
36 
37 //---------------------------------------------------------
CImage_VI_Distance(void)38 CImage_VI_Distance::CImage_VI_Distance(void)
39 {
40 	Set_Name		(_TL("Vegetation Index (Distance Based)"));
41 
42 	Set_Author		("V.Olaya (c) 2004, O.Conrad (c) 2011");
43 
44 	Set_Description	(_TW(
45 		"Distance based vegetation indices."
46 	//	"\n<ul>"
47 	//	"<li>Transformed Soil Adjusted Vegetation Index (s. McCloy, 2006)\n"
48 	//	"    TSAVI = (NIR - Gain * R - Offset) * Gain / (Gain * NIR + R - Gain * Offset)</li>\n"
49 	//	"<li>Transformed Soil Adjusted Vegetation Index (s. McCloy, 2006)\n"
50 	//	"    ATSAVI = (NIR - Gain * R - Offset) / (Gain * NIR + R - gain * Offset + 0.8 * (1 + Gain^2))</li>\n"
51 	//	"</ul>(NIR = near infrared, R = red, S = soil adjustment factor)\n"
52 	));
53 
54 	Add_Reference("McCloy, K.R.", "2006",
55 		"Resource Management Information Systems: Remote Sensing, GIS and Modelling",
56 		"2nd Edition, CRC Taylor & Francis, 575pp."
57 	);
58 
59 	Add_Reference("Silleos, N.G., Alexandridis, T.K., Gitas, I.Z., Perakis, K.", "2006",
60 		"Vegetation Indices: Advances Made in Biomass Estimation and Vegetation Monitoring in the Last 30 Years",
61 		"Geocarto International, 21:4, 21-28.",
62 		SG_T("http://dx.doi.org/10.1080/10106040608542399")
63 	);
64 
65 	Parameters.Add_Grid(
66 		"", "RED"		, _TL("Red Reflectance"),
67 		_TL(""),
68 		PARAMETER_INPUT
69 	);
70 
71 	Parameters.Add_Grid(
72 		"", "NIR"		, _TL("Near Infrared Reflectance"),
73 		_TL(""),
74 		PARAMETER_INPUT
75 	);
76 
77 	Parameters.Add_Grid(
78 		"", "PVI0"		, _TL("Perpendicular Vegetation Index (Richardson and Wiegand, 1977)"),
79 		_TL(""),
80 		PARAMETER_OUTPUT_OPTIONAL
81 	);
82 
83 	Parameters.Add_Grid(
84 		"", "PVI1"		, _TL("Perpendicular Vegetation Index (Perry and Lautenschlager, 1984)"),
85 		_TL(""),
86 		PARAMETER_OUTPUT_OPTIONAL
87 	);
88 
89 	Parameters.Add_Grid(
90 		"", "PVI2"		, _TL("Perpendicular Vegetation Index (Walther and Shabaani)"),
91 		_TL(""),
92 		PARAMETER_OUTPUT_OPTIONAL
93 	);
94 
95 	Parameters.Add_Grid(
96 		"", "PVI3"		, _TL("Perpendicular Vegetation Index (Qi, et al., 1994)"),
97 		_TL(""),
98 		PARAMETER_OUTPUT_OPTIONAL
99 	);
100 
101 	Parameters.Add_Grid(
102 		"", "TSAVI"		, _TL("Transformed Soil Adjusted Vegetation Index (Baret et al. 1989)"),
103 		_TL(""),
104 		PARAMETER_OUTPUT_OPTIONAL
105 	);
106 
107 	Parameters.Add_Grid(
108 		"", "ATSAVI"	, _TL("Transformed Soil Adjusted Vegetation Index (Baret and Guyot, 1991)"),
109 		_TL(""),
110 		PARAMETER_OUTPUT_OPTIONAL
111 	);
112 
113 	Parameters.Add_Double(
114 		"", "INTERCEPT"	, _TL("Intercept of Soil Line"),
115 		_TL(""),
116 		0.0
117 	);
118 
119 	Parameters.Add_Double(
120 		"", "SLOPE"		, _TL("Slope of Soil Line"),
121 		_TL(""),
122 		0.5
123 	);
124 }
125 
126 
127 ///////////////////////////////////////////////////////////
128 //                                                       //
129 ///////////////////////////////////////////////////////////
130 
131 //---------------------------------------------------------
On_Execute(void)132 bool CImage_VI_Distance::On_Execute(void)
133 {
134 	CSG_Grid	*pRed		= Parameters("RED"   )->asGrid();
135 	CSG_Grid	*pNIR		= Parameters("NIR"   )->asGrid();
136 
137 	CSG_Grid	*pPVI0		= Parameters("PVI0"  )->asGrid();
138 	CSG_Grid	*pPVI1		= Parameters("PVI1"  )->asGrid();
139 	CSG_Grid	*pPVI2		= Parameters("PVI2"  )->asGrid();
140 	CSG_Grid	*pPVI3		= Parameters("PVI3"  )->asGrid();
141 	CSG_Grid	*pTSAVI		= Parameters("TSAVI" )->asGrid();
142 	CSG_Grid	*pATSAVI	= Parameters("ATSAVI")->asGrid();
143 
144 	DataObject_Set_Colors(pPVI0  , 11, SG_COLORS_RED_GREY_GREEN, false);
145 	DataObject_Set_Colors(pPVI1  , 11, SG_COLORS_RED_GREY_GREEN, false);
146 	DataObject_Set_Colors(pPVI2  , 11, SG_COLORS_RED_GREY_GREEN, false);
147 	DataObject_Set_Colors(pPVI3  , 11, SG_COLORS_RED_GREY_GREEN, false);
148 	DataObject_Set_Colors(pTSAVI , 11, SG_COLORS_RED_GREY_GREEN, false);
149 	DataObject_Set_Colors(pATSAVI, 11, SG_COLORS_RED_GREY_GREEN, false);
150 
151 	m_Slope		= Parameters("SLOPE"    )->asDouble();
152 	m_Intercept	= Parameters("INTERCEPT")->asDouble();
153 
154 	if( m_Slope <= 0.0 )
155 	{
156 		Error_Set(_TL("slope value has to be greater than zero"));
157 
158 		return( false );
159 	}
160 
161     for(int y=0; y<Get_NY() && Set_Progress(y); y++)
162 	{
163 		for(int x=0; x<Get_NX(); x++)
164 		{
165 			if( pRed->is_NoData(x, y) || pNIR->is_NoData(x, y) )
166 			{
167 				if( pPVI0   )	pPVI0  ->Set_NoData(x, y);
168 				if( pPVI1   )	pPVI1  ->Set_NoData(x, y);
169 				if( pPVI2   )	pPVI2  ->Set_NoData(x, y);
170 				if( pPVI3   )	pPVI3  ->Set_NoData(x, y);
171 				if( pTSAVI  )	pTSAVI ->Set_NoData(x, y);
172 				if( pATSAVI )	pATSAVI->Set_NoData(x, y);
173 			}
174 			else
175 			{
176 				double	R, NIR, Value;
177 
178 				R	= pRed->asDouble(x, y);
179 				NIR	= pNIR->asDouble(x, y);
180 
181 				if( pPVI0   ) { if( Get_PVI0  (R, NIR, Value) ) pPVI0  ->Set_Value(x, y, Value); else pPVI0  ->Set_NoData(x, y); }
182 				if( pPVI1   ) { if( Get_PVI1  (R, NIR, Value) ) pPVI1  ->Set_Value(x, y, Value); else pPVI1  ->Set_NoData(x, y); }
183 				if( pPVI2   ) { if( Get_PVI2  (R, NIR, Value) ) pPVI2  ->Set_Value(x, y, Value); else pPVI2  ->Set_NoData(x, y); }
184 				if( pPVI3   ) { if( Get_PVI3  (R, NIR, Value) ) pPVI3  ->Set_Value(x, y, Value); else pPVI3  ->Set_NoData(x, y); }
185 				if( pTSAVI  ) { if( Get_TSAVI (R, NIR, Value) ) pTSAVI ->Set_Value(x, y, Value); else pTSAVI ->Set_NoData(x, y); }
186 				if( pATSAVI ) { if( Get_ATSAVI(R, NIR, Value) ) pATSAVI->Set_Value(x, y, Value); else pATSAVI->Set_NoData(x, y); }
187 			}
188         }
189     }
190 
191 	return( true );
192 }
193 
194 
195 ///////////////////////////////////////////////////////////
196 //                                                       //
197 ///////////////////////////////////////////////////////////
198 
199 //---------------------------------------------------------
Get_PVI0(double R,double NIR,double & Value)200 inline bool CImage_VI_Distance::Get_PVI0(double R, double NIR, double &Value)	// Richardson & Wiegand, 1977
201 {
202 	double dB1	= 1.0 / m_Slope;
203 	double dB0	= R - NIR / m_Slope;
204 
205 	double Rgg5	= (dB1 * m_Intercept - dB0 * m_Slope) / (dB1 - m_Slope);
206 	double Rgg7	= (m_Intercept - dB0) / (dB1 - m_Slope);
207 
208 	Value	= sqrt(pow(Rgg5 - R, 2.0) + pow(Rgg7 - NIR, 3.0));
209 
210 	return( true );
211 }
212 
213 //---------------------------------------------------------
Get_PVI1(double R,double NIR,double & Value)214 inline bool CImage_VI_Distance::Get_PVI1(double R, double NIR, double &Value)	// Perry & Rautenschlager, 1984
215 {
216 	if( (Value = sqrt(1.0 + m_Slope * m_Slope)) != 0.0 )
217 	{
218 		Value	= ((m_Slope * NIR - R) + m_Intercept) / Value;
219 
220 		return( true );
221 	}
222 
223 	return( false );
224 }
225 
226 //---------------------------------------------------------
Get_PVI2(double R,double NIR,double & Value)227 inline bool CImage_VI_Distance::Get_PVI2(double R, double NIR, double &Value)
228 {
229 	if( (Value = sqrt(1.0 + m_Intercept)) != 0.0 )
230 	{
231 		Value	= (NIR - m_Intercept) * (R + m_Slope) / Value;
232 
233 		return( true );
234 	}
235 
236 	return( false );
237 }
238 
239 //---------------------------------------------------------
Get_PVI3(double R,double NIR,double & Value)240 inline bool CImage_VI_Distance::Get_PVI3(double R, double NIR, double &Value)	// Qi et al., 1994
241 {
242 	Value	= (NIR * m_Intercept) - (R * m_Slope);
243 
244 	return( true );
245 }
246 
247 //---------------------------------------------------------
Get_TSAVI(double R,double NIR,double & Value)248 inline bool CImage_VI_Distance::Get_TSAVI(double R, double NIR, double &Value)	// Baret et al., 1989
249 {
250 	if( (Value = R + m_Slope * NIR - m_Slope * m_Intercept) != 0.0 )
251 	{
252 		Value	= m_Slope * (NIR - m_Slope) * (R - m_Intercept) / Value;
253 
254 		return( true );
255 	}
256 
257 	return( false );
258 }
259 
260 //---------------------------------------------------------
Get_ATSAVI(double R,double NIR,double & Value)261 inline bool CImage_VI_Distance::Get_ATSAVI(double R, double NIR, double &Value)	// Baret & Guyot, 1991
262 {
263 	if( (Value = R + m_Slope * NIR - m_Slope * m_Intercept + 0.08 * (1.0 + m_Slope*m_Slope)) != 0.0 )
264 	{
265 		Value	= m_Slope * (NIR - m_Slope * R - m_Intercept) / Value;
266 
267 		return( true );
268 	}
269 
270 	return( false );
271 }
272 
273 
274 ///////////////////////////////////////////////////////////
275 //                                                       //
276 //                                                       //
277 //                                                       //
278 ///////////////////////////////////////////////////////////
279 
280 //---------------------------------------------------------
281