1
2 /*******************************************************************************
3 Grid_CVA.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 "Grid_CVA.h"
29
30
31 ///////////////////////////////////////////////////////////
32 // //
33 // //
34 // //
35 ///////////////////////////////////////////////////////////
36
37 //---------------------------------------------------------
CGrid_CVA(void)38 CGrid_CVA::CGrid_CVA(void)
39 {
40 Set_Name (_TL("Change Vector Analysis"));
41
42 Set_Author ("V.Olaya (c) 2004, O.Conrad (c) 2012");
43
44 Set_Description (_TW(
45 "This tool performs a change vector analysis (CVA) for the given input features. "
46 "Input features are supplied as grid lists for initial and final state. "
47 "In both lists features have to be given in the same order. "
48 "Distance is measured as Euclidean distance in features space. When analyzing two features "
49 "direction is calculated as angle (radians) by default. Otherwise direction is coded as "
50 "the quadrant it points to in terms of feature space. "
51 ));
52
53 Parameters.Add_Grid_List("",
54 "A" , _TL("Initial State"),
55 _TL(""),
56 PARAMETER_INPUT
57 );
58
59 Parameters.Add_Grid_List("",
60 "B" , _TL("Final State"),
61 _TL(""),
62 PARAMETER_INPUT
63 );
64
65 Parameters.Add_Grid("",
66 "DIST" , _TL("Distance"),
67 _TL(""),
68 PARAMETER_OUTPUT
69 );
70
71 Parameters.Add_Grid("",
72 "DIR" , _TL("Angle"),
73 _TL(""),
74 PARAMETER_OUTPUT_OPTIONAL
75 );
76
77 Parameters.Add_Grids("",
78 "C" , _TL("Change Vector"),
79 _TL(""),
80 PARAMETER_OUTPUT_OPTIONAL
81 );
82 }
83
84
85 ///////////////////////////////////////////////////////////
86 // //
87 ///////////////////////////////////////////////////////////
88
89 //---------------------------------------------------------
On_Parameters_Enable(CSG_Parameters * pParameters,CSG_Parameter * pParameter)90 int CGrid_CVA::On_Parameters_Enable(CSG_Parameters *pParameters, CSG_Parameter *pParameter)
91 {
92 if( pParameter->Cmp_Identifier("A")
93 || pParameter->Cmp_Identifier("B") )
94 {
95 pParameters->Set_Enabled("ANGLE",
96 (*pParameters)("A")->asInt() == 2
97 && (*pParameters)("B")->asInt() == 2
98 );
99 }
100
101 return( CSG_Tool_Grid::On_Parameters_Enable(pParameters, pParameter) );
102 }
103
104
105 ///////////////////////////////////////////////////////////
106 // //
107 ///////////////////////////////////////////////////////////
108
109 //---------------------------------------------------------
On_Execute(void)110 bool CGrid_CVA::On_Execute(void)
111 {
112 CSG_Parameter_Grid_List *pA = Parameters("A")->asGridList();
113 CSG_Parameter_Grid_List *pB = Parameters("B")->asGridList();
114
115 int nFeatures = pA->Get_Grid_Count();
116
117 if( nFeatures != pB->Get_Grid_Count() )
118 {
119 Error_Set(_TL("number of initial and final state grids differs"));
120
121 return( false );
122 }
123
124 if( nFeatures == 0 )
125 {
126 Error_Set(_TL("no grids in list"));
127
128 return( false );
129 }
130
131 //-----------------------------------------------------
132 CSG_Grids *pC = Parameters("C")->asGrids();
133
134 if( pC )
135 {
136 if( !pC->Create(Get_System(), nFeatures) || !pC->is_Valid() || pC->Get_NZ() < nFeatures )
137 {
138 pC = NULL;
139 }
140 else
141 {
142 pC->Set_Name(_TL("Change Vector"));
143
144 pC->Add_Attribute("A", SG_DATATYPE_String);
145 pC->Add_Attribute("B", SG_DATATYPE_String);
146
147 for(int i=0; i<nFeatures; i++)
148 {
149 pC->Set_Z(i, i + 1);
150
151 pC->Get_Attributes()[i].Set_Value(1, pA->Get_Grid(i)->Get_Name());
152 pC->Get_Attributes()[i].Set_Value(2, pB->Get_Grid(i)->Get_Name());
153 }
154
155 pC->Get_Attributes_Ptr()->Set_Field_Type(0, SG_DATATYPE_Word);
156 }
157 }
158
159 //-----------------------------------------------------
160 CSG_Colors Colors;
161 Colors.Set_Ramp(SG_GET_RGB(255, 255, 255), SG_GET_RGB( 0, 127, 127), 0, Colors.Get_Count() / 2);
162 Colors.Set_Ramp(SG_GET_RGB( 0, 127, 127), SG_GET_RGB(255, 0, 0), Colors.Get_Count() / 2, Colors.Get_Count());
163
164 CSG_Grid *pLength = Parameters("DIST")->asGrid();
165 CSG_Grid *pAngle = Parameters("DIR" )->asGrid();
166
167 DataObject_Set_Colors(pLength, Colors);
168 DataObject_Set_Colors(pAngle , Colors);
169
170 //-----------------------------------------------------
171 for(int y=0; y<Get_NY() && Set_Progress(y); y++)
172 {
173 #pragma omp parallel for
174 for(int x=0; x<Get_NX(); x++)
175 {
176 bool bOkay = true; CSG_Vector a(nFeatures), b(nFeatures);
177
178 for(int i=0; bOkay && i<nFeatures; i++)
179 {
180 if( (bOkay = !pA->Get_Grid(i)->is_NoData(x, y) && !pB->Get_Grid(i)->is_NoData(x, y)) == true )
181 {
182 a[i] = pA->Get_Grid(i)->asDouble(x, y);
183 b[i] = pB->Get_Grid(i)->asDouble(x, y);
184 }
185 }
186
187 //---------------------------------------------
188 if( bOkay == false )
189 {
190 if( pLength ) pLength->Set_NoData(x, y);
191 if( pAngle ) pAngle ->Set_NoData(x, y);
192
193 for(int i=0; pC && i<nFeatures; i++)
194 {
195 pC->Set_NoData(x, y, i);
196 }
197 }
198 else
199 {
200 CSG_Vector c = b - a;
201
202 if( pLength ) pLength->Set_Value(x, y, c.Get_Length());
203 if( pAngle ) pAngle ->Set_Value(x, y, a.Get_Angle(b) * M_RAD_TO_DEG);
204
205 for(int i=0; pC && i<nFeatures; i++)
206 {
207 pC->Set_Value(x, y, i, c[i]);
208 }
209 }
210 }
211 }
212
213 //-----------------------------------------------------
214 return( true );
215 }
216
217
218 ///////////////////////////////////////////////////////////
219 // //
220 // //
221 // //
222 ///////////////////////////////////////////////////////////
223
224 //---------------------------------------------------------
225