1 /**********************************************************
2 * Version $Id$
3 *********************************************************/
4 ///////////////////////////////////////////////////////////
5 // //
6 // SAGA //
7 // //
8 // System for Automated Geoscientific Analyses //
9 // //
10 // Tool Library //
11 // Cost Analysis //
12 // //
13 //-------------------------------------------------------//
14 // //
15 // LeastCostPathProfile.cpp //
16 // //
17 // Copyright (C) 2004 by //
18 // Olaf Conrad & Victor Olaya //
19 // //
20 //-------------------------------------------------------//
21 // //
22 // This file is part of 'SAGA - System for Automated //
23 // Geoscientific Analyses'. SAGA is free software; you //
24 // can redistribute it and/or modify it under the terms //
25 // of the GNU General Public License as published by the //
26 // Free Software Foundation, either version 2 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // SAGA is distributed in the hope that it will be //
30 // useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU General //
36 // Public License along with this program; if not, see //
37 // <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
50 ///////////////////////////////////////////////////////////
51
52 //---------------------------------------------------------
53
54
55 ///////////////////////////////////////////////////////////
56 // //
57 // //
58 // //
59 ///////////////////////////////////////////////////////////
60
61 //---------------------------------------------------------
62 #include "LeastCostPathProfile.h"
63
64
65 ///////////////////////////////////////////////////////////
66 // //
67 // //
68 // //
69 ///////////////////////////////////////////////////////////
70
71 //---------------------------------------------------------
72 #define VALUE_OFFSET 5
73
74
75 ///////////////////////////////////////////////////////////
76 // //
77 ///////////////////////////////////////////////////////////
78
79 //---------------------------------------------------------
CLeastCostPathProfile(void)80 CLeastCostPathProfile::CLeastCostPathProfile(void)
81 {
82 Set_Name (_TL("Least Cost Path"));
83
84 Set_Author ("Victor Olaya (c) 2004");
85
86 Set_Description (_TW(
87 "Creates a least cost past profile using an accumulated cost surface."
88 ));
89
90 Parameters.Add_Grid(
91 NULL , "DEM" , _TL("Accumulated cost"),
92 _TL(""),
93 PARAMETER_INPUT
94 );
95
96 Parameters.Add_Grid_List(
97 NULL , "VALUES" , _TL("Values"),
98 _TL(""),
99 PARAMETER_INPUT_OPTIONAL
100 );
101
102 Parameters.Add_Shapes(
103 NULL , "POINTS" , _TL("Profile Points"),
104 _TL(""),
105 PARAMETER_OUTPUT, SHAPE_TYPE_Point
106 );
107
108 Parameters.Add_Shapes(
109 NULL , "LINE" , _TL("Profile Line"),
110 _TL(""),
111 PARAMETER_OUTPUT, SHAPE_TYPE_Line
112 );
113 }
114
115
116 ///////////////////////////////////////////////////////////
117 // //
118 ///////////////////////////////////////////////////////////
119
120 //---------------------------------------------------------
On_Execute(void)121 bool CLeastCostPathProfile::On_Execute(void)
122 {
123 m_pDEM = Parameters("DEM" )->asGrid ();
124 m_pValues = Parameters("VALUES")->asGridList();
125 m_pPoints = Parameters("POINTS")->asShapes ();
126 m_pLines = Parameters("LINE" )->asShapes ();
127
128 //-----------------------------------------------------
129 m_pPoints->Create(SHAPE_TYPE_Point, CSG_String::Format("%s [%s]", _TL("Profile"), m_pDEM->Get_Name()));
130
131 m_pPoints->Add_Field("ID", SG_DATATYPE_Int );
132 m_pPoints->Add_Field("D" , SG_DATATYPE_Double);
133 m_pPoints->Add_Field("X" , SG_DATATYPE_Double);
134 m_pPoints->Add_Field("Y" , SG_DATATYPE_Double);
135 m_pPoints->Add_Field("Z" , SG_DATATYPE_Double);
136
137 for(int i=0; i<m_pValues->Get_Grid_Count(); i++)
138 {
139 m_pPoints->Add_Field(m_pValues->Get_Grid(i)->Get_Name(), SG_DATATYPE_Double);
140 }
141
142 //-----------------------------------------------------
143 m_pLines->Create(SHAPE_TYPE_Line, CSG_String::Format("%s [%s]", _TL("Profile"), m_pDEM->Get_Name()));
144 m_pLines->Add_Field("ID", SG_DATATYPE_Int);
145 m_pLine = m_pLines->Add_Shape();
146 m_pLine->Set_Value(0, 1);
147
148 //-----------------------------------------------------
149 // DataObject_Update(m_pDEM, true);
150
151 Set_Drag_Mode(TOOL_INTERACTIVE_DRAG_NONE);
152
153 return( true );
154 }
155
156
157 ///////////////////////////////////////////////////////////
158 // //
159 ///////////////////////////////////////////////////////////
160
161 //---------------------------------------------------------
On_Execute_Position(CSG_Point ptWorld,TSG_Tool_Interactive_Mode Mode)162 bool CLeastCostPathProfile::On_Execute_Position(CSG_Point ptWorld, TSG_Tool_Interactive_Mode Mode)
163 {
164 switch( Mode )
165 {
166 case TOOL_INTERACTIVE_LDOWN:
167 case TOOL_INTERACTIVE_MOVE_LDOWN:
168 return( Set_Profile(Get_System().Fit_to_Grid_System(ptWorld)) );
169
170 default:
171 return( false );
172 }
173 }
174
175
176 ///////////////////////////////////////////////////////////
177 // //
178 ///////////////////////////////////////////////////////////
179
180 //---------------------------------------------------------
Set_Profile(TSG_Point ptWorld)181 bool CLeastCostPathProfile::Set_Profile(TSG_Point ptWorld)
182 {
183 m_pPoints->Del_Shapes();
184 m_pLine ->Del_Parts();
185
186 //-----------------------------------------------------
187 int x, y, Direction;
188
189 if( Get_Grid_Pos(x, y) )
190 {
191 while( Add_Point(x, y) && (Direction = m_pDEM->Get_Gradient_NeighborDir(x, y, true, false)) >= 0 )
192 {
193 x += Get_xTo(Direction);
194 y += Get_yTo(Direction);
195 }
196 }
197
198 //-----------------------------------------------------
199 DataObject_Update(m_pLines , false);
200 DataObject_Update(m_pPoints, false);
201
202 return( m_pPoints->Get_Count() > 0 );
203 }
204
205 //---------------------------------------------------------
Add_Point(int x,int y)206 bool CLeastCostPathProfile::Add_Point(int x, int y)
207 {
208 if( !m_pDEM->is_InGrid(x, y) )
209 {
210 return( false );
211 }
212
213 //-----------------------------------------------------
214 TSG_Point Point = Get_System().Get_Grid_to_World(x, y);
215
216 double Distance = 0.0;
217
218 if( m_pPoints->Get_Count() > 0 )
219 {
220 CSG_Shape *pLast = m_pPoints->Get_Shape(m_pPoints->Get_Count() - 1);
221
222 Distance = SG_Get_Distance(Point, pLast->Get_Point(0)) + pLast->asDouble(1);
223 }
224
225 //-----------------------------------------------------
226 CSG_Shape *pPoint = m_pPoints->Add_Shape();
227
228 pPoint->Add_Point(Point);
229
230 pPoint->Set_Value(0, m_pPoints->Get_Count());
231 pPoint->Set_Value(1, Distance);
232 pPoint->Set_Value(2, Point.x);
233 pPoint->Set_Value(3, Point.y);
234 pPoint->Set_Value(4, m_pDEM->asDouble(x, y));
235
236 for(int i=0; i<m_pValues->Get_Grid_Count(); i++)
237 {
238 pPoint->Set_Value(VALUE_OFFSET + i, m_pValues->Get_Grid(i)->asDouble(x, y));
239 }
240
241 m_pLine->Add_Point(Point);
242
243 return( true );
244 }
245
246
247 ///////////////////////////////////////////////////////////
248 // //
249 // //
250 // //
251 ///////////////////////////////////////////////////////////
252
253 //---------------------------------------------------------