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