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 //---------------------------------------------------------