1 /**********************************************************
2  * Version $Id$
3  *********************************************************/
4 
5 ///////////////////////////////////////////////////////////
6 //                                                       //
7 //                         SAGA                          //
8 //                                                       //
9 //      System for Automated Geoscientific Analyses      //
10 //                                                       //
11 //                     Tool Library                      //
12 //                     Grid_Tools                        //
13 //                                                       //
14 //-------------------------------------------------------//
15 //                                                       //
16 //                   Grid_Proximity.cpp                  //
17 //                                                       //
18 //                 Copyright (C) 2010 by                 //
19 //                      Olaf Conrad                      //
20 //                                                       //
21 //-------------------------------------------------------//
22 //                                                       //
23 // This file is part of 'SAGA - System for Automated     //
24 // Geoscientific Analyses'. SAGA is free software; you   //
25 // can redistribute it and/or modify it under the terms  //
26 // of the GNU General Public License as published by the //
27 // Free Software Foundation, either version 2 of the     //
28 // License, or (at your option) any later version.       //
29 //                                                       //
30 // SAGA is distributed in the hope that it will be       //
31 // useful, but WITHOUT ANY WARRANTY; without even the    //
32 // implied warranty of MERCHANTABILITY or FITNESS FOR A  //
33 // PARTICULAR PURPOSE. See the GNU General Public        //
34 // License for more details.                             //
35 //                                                       //
36 // You should have received a copy of the GNU General    //
37 // Public License along with this program; if not, see   //
38 // <http://www.gnu.org/licenses/>.                       //
39 //                                                       //
40 //-------------------------------------------------------//
41 //                                                       //
42 //    e-mail:     oconrad@saga-gis.org                   //
43 //                                                       //
44 //    contact:    Olaf Conrad                            //
45 //                Institute of Geography                 //
46 //                University of Hamburg                  //
47 //                Germany                                //
48 //                                                       //
49 ///////////////////////////////////////////////////////////
50 
51 //---------------------------------------------------------
52 
53 
54 ///////////////////////////////////////////////////////////
55 //														 //
56 //														 //
57 //														 //
58 ///////////////////////////////////////////////////////////
59 
60 //---------------------------------------------------------
61 #include "Grid_Proximity.h"
62 
63 
64 ///////////////////////////////////////////////////////////
65 //														 //
66 //														 //
67 //														 //
68 ///////////////////////////////////////////////////////////
69 
70 //---------------------------------------------------------
CGrid_Proximity(void)71 CGrid_Proximity::CGrid_Proximity(void)
72 {
73 	//-----------------------------------------------------
74 	// 1. Info...
75 
76 	Set_Name		(_TL("Proximity Grid"));
77 
78 	Set_Author		(SG_T("O.Conrad (c) 2010"));
79 
80 	Set_Description	(_TW(
81 		"Calculates a grid with euclidean distance to feature cells (not no-data cells)."
82 	));
83 
84 
85 	//-----------------------------------------------------
86 	// 2. Standard in- and output...
87 
88 	Parameters.Add_Grid(
89 		NULL	, "FEATURES"		, _TL("Features"),
90 		_TL(""),
91 		PARAMETER_INPUT
92 	);
93 
94 	Parameters.Add_Grid(
95 		NULL	, "DISTANCE"		, _TL("Distance"),
96 		_TL(""),
97 		PARAMETER_OUTPUT
98 	);
99 
100 	Parameters.Add_Grid(
101 		NULL	, "DIRECTION"		, _TL("Direction"),
102 		_TL(""),
103 		PARAMETER_OUTPUT_OPTIONAL
104 	);
105 
106 	Parameters.Add_Grid(
107 		NULL	, "ALLOCATION"		, _TL("Allocation"),
108 		_TL(""),
109 		PARAMETER_OUTPUT_OPTIONAL
110 	);
111 }
112 
113 
114 ///////////////////////////////////////////////////////////
115 //														 //
116 //														 //
117 //														 //
118 ///////////////////////////////////////////////////////////
119 
120 //---------------------------------------------------------
On_Execute(void)121 bool CGrid_Proximity::On_Execute(void)
122 {
123 	int				x, y;
124 	double			z, d;
125 	TSG_Point		p;
126 	CSG_Grid		*pFeatures, *pDistance, *pDirection, *pAllocation;
127 	CSG_PRQuadTree	Search;
128 
129 	//-----------------------------------------------------
130 	pFeatures	= Parameters("FEATURES")	->asGrid();
131 	pDistance	= Parameters("DISTANCE")	->asGrid();
132 	pDirection	= Parameters("DIRECTION")	->asGrid();
133 	pAllocation	= Parameters("ALLOCATION")	->asGrid();
134 
135 	//-----------------------------------------------------
136 	Process_Set_Text(_TL("preparing distance calculation..."));
137 
138 	Search.Create(CSG_Rect(-1, -1, Get_NX(), Get_NY()));
139 
140 	for(y=0; y<Get_NY() && Set_Progress(y); y++)
141 	{
142 		for(x=0; x<Get_NX(); x++)
143 		{
144 			if( pFeatures->is_NoData(x, y) )
145 			{
146 				pDistance->Set_Value(x, y, -1.0);
147 			}
148 			else
149 			{
150 				pDistance->Set_Value(x, y,  0.0);
151 
152 				if( pDirection )
153 				{
154 					pDirection->Set_NoData(x, y);
155 				}
156 
157 				if( pAllocation )
158 				{
159 					pAllocation->Set_Value(x, y, pFeatures->asDouble(x, y));
160 				}
161 
162 				//-----------------------------------------
163 				bool	bBorder	= false;
164 
165 				for(int i=0; i<8 && !bBorder; i++)
166 				{
167 					int	ix	= Get_xTo(i, x);
168 					int	iy	= Get_yTo(i, y);
169 
170 					if( is_InGrid(ix, iy) && pFeatures->is_NoData(ix, iy) )
171 					{
172 						bBorder	= true;
173 					}
174 				}
175 
176 				if( bBorder )
177 				{
178 					Search.Add_Point(x, y, pFeatures->asDouble(x, y));
179 				}
180 			}
181 		}
182 	}
183 
184 	if( !Search.is_Okay() || Search.Get_Point_Count() <= 0 || Search.Get_Point_Count() >= Get_NCells() )
185 	{
186 		Message_Add(_TL("no features to buffer."));
187 
188 		return( false );
189 	}
190 
191 	//-----------------------------------------------------
192 	Process_Set_Text(_TL("performing distance calculation..."));
193 
194 	for(y=0; y<Get_NY() && Set_Progress(y); y++)
195 	{
196 		for(x=0; x<Get_NX(); x++)
197 		{
198 			if( pDistance->asDouble(x, y) < 0.0 && Search.Get_Nearest_Point(x, y, p, z, d) )
199 			{
200 				pDistance->Set_Value(x, y, d * Get_Cellsize());
201 
202 				if( pDirection )
203 				{
204 					if( d > 0.0 )
205 					{
206 						pDirection->Set_Value(x, y, SG_Get_Angle_Of_Direction(x, y, p.x, p.y) * M_RAD_TO_DEG);
207 					}
208 					else
209 					{
210 						pDirection->Set_NoData(x, y);
211 					}
212 				}
213 
214 				if( pAllocation )
215 				{
216 					pAllocation->Set_Value(x, y, z);
217 				}
218 			}
219 		}
220 	}
221 
222 	//-----------------------------------------------------
223 	return( true );
224 }
225 
226 
227 ///////////////////////////////////////////////////////////
228 //														 //
229 //														 //
230 //														 //
231 ///////////////////////////////////////////////////////////
232 
233 //---------------------------------------------------------
234