1 /**********************************************************
2 * Version $Id$
3 *********************************************************/
4 ///////////////////////////////////////////////////////////
5 // //
6 // SAGA //
7 // //
8 // System for Automated Geoscientific Analyses //
9 // //
10 // Tool Library //
11 // grid_analysis //
12 // //
13 //-------------------------------------------------------//
14 // //
15 // LeastCostPathProfile_Points.cpp //
16 // //
17 // Copyright (C) 2004-2010 by //
18 // Olaf Conrad, Victor Olaya & Volker Wichmann //
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 // e-mail: wichmann@laserdata //
42 // //
43 // contact: Volker Wichmann //
44 // LASERDATA GmbH //
45 // Management and analysis of //
46 // laserscanning data //
47 // Innsbruck, Austria //
48 // //
49 ///////////////////////////////////////////////////////////
50
51 //---------------------------------------------------------
52
53
54 ///////////////////////////////////////////////////////////
55 // //
56 // //
57 // //
58 ///////////////////////////////////////////////////////////
59
60 //---------------------------------------------------------
61 #include "LeastCostPathProfile_Points.h"
62
63
64 ///////////////////////////////////////////////////////////
65 // //
66 // //
67 // //
68 ///////////////////////////////////////////////////////////
69
70 //---------------------------------------------------------
71 #define VALUE_OFFSET 5
72
73
74 ///////////////////////////////////////////////////////////
75 // //
76 ///////////////////////////////////////////////////////////
77
78 //---------------------------------------------------------
CLeastCostPathProfile_Points(void)79 CLeastCostPathProfile_Points::CLeastCostPathProfile_Points(void)
80 {
81 Set_Name (_TL("Least Cost Paths"));
82
83 Set_Author ("O. Conrad, V. Olaya, V. Wichmann (c) 2004-2010");
84
85 Set_Description(_TW(
86 "This tool allows one to compute least cost path profile(s). It takes an "
87 "accumulated cost surface grid and a point shapefile as input. Each "
88 "point in the shapefile represents a source for which the least cost path "
89 "is calculated.\n"
90 "In case the point shapefile has more than one source point "
91 "defined, a separate least cost path is calculated for each point. "
92 "The tool outputs a point and a line shapefile for each least cost path.\n "
93 "The tool allows for optional input grids. The cell values of these grids "
94 "along the least cost path are written to the outputs as additional table fields.\n"
95 ));
96
97 Parameters.Add_Shapes(
98 NULL , "SOURCE" , _TL("Source Point(s)"),
99 _TL("Point shapefile with source point(s)"),
100 PARAMETER_INPUT, SHAPE_TYPE_Point
101 );
102
103 Parameters.Add_Grid(
104 NULL , "DEM" , _TL("Accumulated Cost Surface"),
105 _TL(""),
106 PARAMETER_INPUT
107 );
108
109 Parameters.Add_Grid_List(
110 NULL , "VALUES" , _TL("Values"),
111 _TL("Allows writing cell values from additional grids to the output"),
112 PARAMETER_INPUT_OPTIONAL
113 );
114
115 Parameters.Add_Shapes_List(
116 NULL , "POINTS" , _TL("Profile Points"),
117 _TL("Least cost path profile points"),
118 PARAMETER_OUTPUT, SHAPE_TYPE_Point
119 );
120
121 Parameters.Add_Shapes_List(
122 NULL , "LINE" , _TL("Profile Lines"),
123 _TL("Least cost path profile lines"),
124 PARAMETER_OUTPUT, SHAPE_TYPE_Line
125 );
126 }
127
128
129 ///////////////////////////////////////////////////////////
130 // //
131 ///////////////////////////////////////////////////////////
132
133 //---------------------------------------------------------
On_Execute(void)134 bool CLeastCostPathProfile_Points::On_Execute(void)
135 {
136 CSG_Shapes *pSources;
137 CSG_Parameter_Shapes_List *pList_Points, *pList_Lines;
138
139 m_pDEM = Parameters("DEM" )->asGrid();
140 m_pValues = Parameters("VALUES")->asGridList();
141 pSources = Parameters("SOURCE")->asShapes();
142 pList_Points = Parameters("POINTS")->asShapesList();
143 pList_Lines = Parameters("LINE" )->asShapesList();
144
145 //-----------------------------------------------------
146 pList_Points->Del_Items();
147 pList_Lines ->Del_Items();
148
149 //-----------------------------------------------------
150 for(int i=0, x, y; i<pSources->Get_Count(); i++)
151 {
152 CSG_Shape *pShape = pSources->Get_Shape(i);
153
154 if( Get_System().Get_World_to_Grid(x, y, pShape->Get_Point(0)) && m_pDEM->is_InGrid(x, y) )
155 {
156 //-----------------------------------------------------
157 m_pPoints = SG_Create_Shapes(SHAPE_TYPE_Point, CSG_String::Format("%s [%s] %d", _TL("Profile Points"), m_pDEM->Get_Name(), i + 1));
158
159 m_pPoints->Add_Field("ID", SG_DATATYPE_Int);
160 m_pPoints->Add_Field("D" , SG_DATATYPE_Double);
161 m_pPoints->Add_Field("X" , SG_DATATYPE_Double);
162 m_pPoints->Add_Field("Y" , SG_DATATYPE_Double);
163 m_pPoints->Add_Field("Z" , SG_DATATYPE_Double);
164
165 for(int j=0; j<m_pValues->Get_Grid_Count(); j++)
166 {
167 m_pPoints->Add_Field(m_pValues->Get_Grid(j)->Get_Name(), SG_DATATYPE_Double);
168 }
169
170 //-----------------------------------------------------
171 m_pLines = SG_Create_Shapes(SHAPE_TYPE_Line, CSG_String::Format("%s [%s] %d", _TL("Profile Line"), m_pDEM->Get_Name(), i + 1));
172
173 m_pLines->Add_Field("ID", SG_DATATYPE_Int);
174 m_pLines->Add_Shape()->Set_Value(0, 1);
175
176 //-----------------------------------------------------
177 int Direction;
178
179 while( Add_Point(x, y) && (Direction = m_pDEM->Get_Gradient_NeighborDir(x, y, true, false)) >= 0 )
180 {
181 x += Get_xTo(Direction);
182 y += Get_yTo(Direction);
183 }
184
185 //-----------------------------------------------------
186 if( m_pPoints->Get_Count() > 0 )
187 {
188 pList_Points->Add_Item(m_pPoints);
189 pList_Lines ->Add_Item(m_pLines );
190 }
191 else
192 {
193 delete(m_pPoints);
194 delete(m_pLines );
195 }
196 }
197 }
198
199 return( pList_Points->Get_Item_Count() > 0 );
200 }
201
202
203 ///////////////////////////////////////////////////////////
204 // //
205 ///////////////////////////////////////////////////////////
206
207 //---------------------------------------------------------
Add_Point(int x,int y)208 bool CLeastCostPathProfile_Points::Add_Point(int x, int y)
209 {
210 if( !m_pDEM->is_InGrid(x, y) )
211 {
212 return( false );
213 }
214
215 //-----------------------------------------------------
216 TSG_Point Point = Get_System().Get_Grid_to_World(x, y);
217
218 double Distance = 0.0;
219
220 if( m_pPoints->Get_Count() > 0 )
221 {
222 CSG_Shape *pLast = m_pPoints->Get_Shape(m_pPoints->Get_Count() - 1);
223
224 Distance = SG_Get_Distance(Point, pLast->Get_Point(0)) + pLast->asDouble(1);
225 }
226
227 //-----------------------------------------------------
228 CSG_Shape *pPoint = m_pPoints->Add_Shape();
229
230 pPoint->Add_Point(Point);
231
232 pPoint->Set_Value(0, m_pPoints->Get_Count());
233 pPoint->Set_Value(1, Distance);
234 pPoint->Set_Value(2, Point.x);
235 pPoint->Set_Value(3, Point.y);
236 pPoint->Set_Value(4, m_pDEM->asDouble(x, y));
237
238 for(int i=0; i<m_pValues->Get_Grid_Count(); i++)
239 {
240 pPoint->Set_Value(VALUE_OFFSET + i, m_pValues->Get_Grid(i)->asDouble(x, y));
241 }
242
243 m_pLines->Get_Shape(0)->Add_Point(Point);
244
245 return( true );
246 }
247
248
249 ///////////////////////////////////////////////////////////
250 // //
251 // //
252 // //
253 ///////////////////////////////////////////////////////////
254
255 //---------------------------------------------------------
256