|
SAGA API v2.0.8
|
00001 /********************************************************** 00002 * Version $Id: grid_system.cpp 1105 2011-06-21 14:11:47Z oconrad $ 00003 *********************************************************/ 00004 00006 // // 00007 // SAGA // 00008 // // 00009 // System for Automated Geoscientific Analyses // 00010 // // 00011 // Application Programming Interface // 00012 // // 00013 // Library: SAGA_API // 00014 // // 00015 //-------------------------------------------------------// 00016 // // 00017 // grid_system.cpp // 00018 // // 00019 // Copyright (C) 2005 by Olaf Conrad // 00020 // // 00021 //-------------------------------------------------------// 00022 // // 00023 // This file is part of 'SAGA - System for Automated // 00024 // Geoscientific Analyses'. // 00025 // // 00026 // This library is free software; you can redistribute // 00027 // it and/or modify it under the terms of the GNU Lesser // 00028 // General Public License as published by the Free // 00029 // Software Foundation, version 2.1 of the License. // 00030 // // 00031 // This library is distributed in the hope that it will // 00032 // be useful, but WITHOUT ANY WARRANTY; without even the // 00033 // implied warranty of MERCHANTABILITY or FITNESS FOR A // 00034 // PARTICULAR PURPOSE. See the GNU Lesser General Public // 00035 // License for more details. // 00036 // // 00037 // You should have received a copy of the GNU Lesser // 00038 // General Public License along with this program; if // 00039 // not, write to the Free Software Foundation, Inc., // 00040 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, // 00041 // USA. // 00042 // // 00043 //-------------------------------------------------------// 00044 // // 00045 // contact: Olaf Conrad // 00046 // Institute of Geography // 00047 // University Hamburg // 00048 // Germany // 00049 // // 00050 // e-mail: oconrad@saga-gis.org // 00051 // // 00053 00054 //--------------------------------------------------------- 00055 00056 00058 // // 00059 // // 00060 // // 00062 00063 //--------------------------------------------------------- 00064 #include "grid.h" 00065 #include "shapes.h" 00066 00067 00069 // // 00070 // // 00071 // // 00073 00074 //--------------------------------------------------------- 00075 CSG_Grid_System::CSG_Grid_System(void) 00076 { 00077 m_Cellsize = -1.0; 00078 00079 m_NX = m_NY = 0; 00080 } 00081 00082 //--------------------------------------------------------- 00083 CSG_Grid_System::CSG_Grid_System(const CSG_Grid_System &System) 00084 { 00085 m_Cellsize = -1.0; 00086 00087 Assign(System); 00088 } 00089 00090 //--------------------------------------------------------- 00091 CSG_Grid_System::CSG_Grid_System(double Cellsize, const CSG_Rect &Extent) 00092 { 00093 m_Cellsize = -1.0; 00094 00095 Assign(Cellsize, Extent); 00096 } 00097 00098 //--------------------------------------------------------- 00099 CSG_Grid_System::CSG_Grid_System(double Cellsize, double xMin, double yMin, double xMax, double yMax) 00100 { 00101 m_Cellsize = -1.0; 00102 00103 Assign(Cellsize, xMin, yMin, xMax, yMax); 00104 } 00105 00106 //--------------------------------------------------------- 00107 CSG_Grid_System::CSG_Grid_System(double Cellsize, double xMin, double yMin, int NX, int NY) 00108 { 00109 m_Cellsize = -1.0; 00110 00111 Assign(Cellsize, xMin, yMin, NX, NY); 00112 } 00113 00114 //--------------------------------------------------------- 00115 CSG_Grid_System::~CSG_Grid_System(void) 00116 { 00117 } 00118 00119 00121 // // 00122 // // 00123 // // 00125 00126 //--------------------------------------------------------- 00127 bool CSG_Grid_System::is_Valid(void) const 00128 { 00129 return( m_Cellsize > 0.0 ); 00130 } 00131 00132 //--------------------------------------------------------- 00133 const SG_Char * CSG_Grid_System::Get_Name(bool bShort) 00134 { 00135 if( is_Valid() ) 00136 { 00137 if( bShort ) 00138 { 00139 m_Name.Printf(SG_T("%.*f; %dx %dy; %.*fx %.*fy"), 00140 SG_Get_Significant_Decimals(Get_Cellsize()), 00141 Get_Cellsize(), 00142 Get_NX(), 00143 Get_NY(), 00144 SG_Get_Significant_Decimals(Get_XMin()), Get_XMin(), 00145 SG_Get_Significant_Decimals(Get_YMin()), Get_YMin() 00146 ); 00147 } 00148 else 00149 { 00150 m_Name.Printf(SG_T("%s: %f, %s: %dx/%dy, %s: %fx/%fy"), 00151 LNG("[DAT] Cell size"), 00152 Get_Cellsize(), 00153 LNG("[DAT] Number of cells"), 00154 Get_NX(), 00155 Get_NY(), 00156 LNG("[DAT] Lower left corner"), 00157 Get_XMin(), 00158 Get_YMin() 00159 ); 00160 } 00161 00162 return( m_Name ); 00163 } 00164 00165 return( LNG("[DAT] [not set]") ); 00166 } 00167 00168 00170 // // 00171 // // 00172 // // 00174 00175 //--------------------------------------------------------- 00176 bool CSG_Grid_System::operator == (const CSG_Grid_System &System) const 00177 { 00178 return( is_Equal(System) ); 00179 } 00180 00181 //--------------------------------------------------------- 00182 void CSG_Grid_System::operator = (const CSG_Grid_System &System) 00183 { 00184 Assign(System); 00185 } 00186 00187 00189 // // 00190 // // 00191 // // 00193 00194 //--------------------------------------------------------- 00195 bool CSG_Grid_System::Assign(const CSG_Grid_System &System) 00196 { 00197 return( Assign(System.m_Cellsize, System.m_Extent) ); 00198 } 00199 00200 //--------------------------------------------------------- 00201 bool CSG_Grid_System::Assign(double Cellsize, const CSG_Rect &Extent) 00202 { 00203 return( Assign(Cellsize, Extent.m_rect.xMin, Extent.m_rect.yMin, Extent.m_rect.xMax, Extent.m_rect.yMax) ); 00204 } 00205 00206 //--------------------------------------------------------- 00207 bool CSG_Grid_System::Assign(double Cellsize, double xMin, double yMin, double xMax, double yMax) 00208 { 00209 if( Cellsize > 0.0 && xMin < xMax && yMin < yMax ) 00210 { 00211 return( Assign(Cellsize, xMin, yMin, 1 + (int)(0.5 + (xMax - xMin) / Cellsize), 1 + (int)(0.5 + (yMax - yMin) / Cellsize)) ); 00212 } 00213 00214 return( Assign(0.0, 0.0, 0.0, 0, 0) ); 00215 } 00216 00217 //--------------------------------------------------------- 00218 bool CSG_Grid_System::Assign(double Cellsize, double xMin, double yMin, int NX, int NY) 00219 { 00220 if( Cellsize > 0.0 && NX > 0 && NY > 0 ) 00221 { 00222 m_NX = NX; 00223 m_NY = NY; 00224 m_NCells = (long) NY * NX; 00225 00226 m_Cellsize = Cellsize; 00227 m_Cellarea = Cellsize * Cellsize; 00228 00229 m_Extent .Assign( 00230 xMin, 00231 yMin, 00232 xMin + (NX - 1.0) * Cellsize, 00233 yMin + (NY - 1.0) * Cellsize 00234 ); 00235 00236 m_Extent_Cells .Assign( 00237 xMin - 0.5 * Cellsize, 00238 yMin - 0.5 * Cellsize, 00239 xMin + (NX - 0.5) * Cellsize, 00240 yMin + (NY - 0.5) * Cellsize 00241 ); 00242 00243 m_Diagonal = Cellsize * sqrt(2.0); 00244 00245 return( true ); 00246 } 00247 00248 m_Cellsize = -1.0; 00249 m_NX = 0; 00250 m_NY = 0; 00251 m_NCells = 0; 00252 m_Cellsize = 0.0; 00253 m_Cellarea = 0.0; 00254 m_Diagonal = 0.0; 00255 m_Extent .Assign(0.0, 0.0, 0.0, 0.0); 00256 m_Extent_Cells .Assign(0.0, 0.0, 0.0, 0.0); 00257 00258 return( false ); 00259 } 00260 00261 00263 // // 00264 // // 00265 // // 00267 00268 //--------------------------------------------------------- 00269 bool CSG_Grid_System::is_Equal(const CSG_Grid_System &System) const 00270 { 00271 return( is_Equal(System.m_Cellsize, System.m_Extent.m_rect) ); 00272 } 00273 00274 //--------------------------------------------------------- 00275 bool CSG_Grid_System::is_Equal(double Cellsize, const TSG_Rect &Extent) const 00276 { 00277 return( m_Cellsize == Cellsize && m_Extent == Extent ); 00278 } 00279 00280 00282 // // 00283 // // 00284 // // 00286 00287 //--------------------------------------------------------- 00288 CSG_Grid_Cell_Addressor::CSG_Grid_Cell_Addressor(void) 00289 { 00290 m_Cells.Add_Field(SG_T("X"), SG_DATATYPE_Int); 00291 m_Cells.Add_Field(SG_T("Y"), SG_DATATYPE_Int); 00292 m_Cells.Add_Field(SG_T("D"), SG_DATATYPE_Double); 00293 m_Cells.Add_Field(SG_T("W"), SG_DATATYPE_Double); 00294 } 00295 00296 //--------------------------------------------------------- 00297 bool CSG_Grid_Cell_Addressor::Destroy(void) 00298 { 00299 m_Cells.Del_Records(); 00300 00301 return( true ); 00302 } 00303 00304 00306 // // 00308 00309 //--------------------------------------------------------- 00310 #define ADD_CELL(x, y, d) {\ 00311 CSG_Table_Record *pRecord = m_Cells.Add_Record();\ 00312 pRecord->Set_Value(0, x);\ 00313 pRecord->Set_Value(1, y);\ 00314 pRecord->Set_Value(2, d);\ 00315 pRecord->Set_Value(3, m_Weighting.Get_Weight(d));\ 00316 } 00317 00318 //--------------------------------------------------------- 00319 bool CSG_Grid_Cell_Addressor::Set_Radius(double Radius) 00320 { 00321 Destroy(); 00322 00323 //----------------------------------------------------- 00324 if( Radius > 0.0 ) 00325 { 00326 ADD_CELL(0.0, 0.0, 0.0); 00327 00328 for(double y=1.0; y<=Radius; y++) 00329 { 00330 for(double x=0.0; x<=Radius; x++) 00331 { 00332 double d = SG_Get_Length(x, y); 00333 00334 if( d <= Radius ) 00335 { 00336 ADD_CELL( x, y, d); 00337 ADD_CELL( y, -x, d); 00338 ADD_CELL(-x, -y, d); 00339 ADD_CELL(-y, x, d); 00340 } 00341 } 00342 } 00343 00344 //------------------------------------------------- 00345 if( m_Cells.Get_Count() > 0 ) 00346 { 00347 m_Cells.Set_Index(2, TABLE_INDEX_Ascending); 00348 00349 return( true ); 00350 } 00351 } 00352 00353 return( false ); 00354 } 00355 00356 //--------------------------------------------------------- 00357 bool CSG_Grid_Cell_Addressor::Set_Annulus(double inner_Radius, double outer_Radius) 00358 { 00359 Destroy(); 00360 00361 //----------------------------------------------------- 00362 if( inner_Radius <= outer_Radius ) 00363 { 00364 if( inner_Radius <= 0.0 ) 00365 { 00366 ADD_CELL(0.0, 0.0, 0.0); 00367 } 00368 00369 for(double y=1.0; y<=outer_Radius; y++) 00370 { 00371 for(double x=0.0; x<=outer_Radius; x++) 00372 { 00373 double d = SG_Get_Length(x, y); 00374 00375 if( inner_Radius <= d && d <= outer_Radius ) 00376 { 00377 ADD_CELL( x, y, d); 00378 ADD_CELL( y, -x, d); 00379 ADD_CELL(-x, -y, d); 00380 ADD_CELL(-y, x, d); 00381 } 00382 } 00383 } 00384 00385 //------------------------------------------------- 00386 if( m_Cells.Get_Count() > 0 ) 00387 { 00388 m_Cells.Set_Index(2, TABLE_INDEX_Ascending); 00389 00390 return( true ); 00391 } 00392 } 00393 00394 return( false ); 00395 } 00396 00397 //--------------------------------------------------------- 00398 bool CSG_Grid_Cell_Addressor::Set_Sector(double Radius, double Direction, double Tolerance) 00399 { 00400 Destroy(); 00401 00402 //----------------------------------------------------- 00403 if( Radius > 0.0 ) 00404 { 00405 TSG_Point a, b; 00406 CSG_Shapes Polygons(SHAPE_TYPE_Polygon); // Polygons.Add_Field(SG_T("ID"), SG_DATATYPE_Int); 00407 CSG_Shape_Polygon *pPolygon = (CSG_Shape_Polygon *)Polygons.Add_Shape(); 00408 00409 Direction = fmod(Direction, M_PI_360); if( Direction < 0.0 ) Direction += M_PI_360; 00410 00411 if( Direction < M_PI_090 ) 00412 { 00413 a.x = -0.5; b.x = 0.5; 00414 a.y = 0.5; b.y = -0.5; 00415 } 00416 else if( Direction < M_PI_180 ) 00417 { 00418 a.x = 0.5; b.x = -0.5; 00419 a.y = 0.5; b.y = -0.5; 00420 } 00421 else if( Direction < M_PI_270 ) 00422 { 00423 a.x = 0.5; b.x = -0.5; 00424 a.y = -0.5; b.y = 0.5; 00425 } 00426 else // if( Direction < M_PI_360 ) 00427 { 00428 a.x = -0.5; b.x = 0.5; 00429 a.y = -0.5; b.y = 0.5; 00430 } 00431 00432 double d = 10.0 * SG_Get_Length(Radius, Radius); 00433 00434 pPolygon->Add_Point(b.x, b.y); 00435 pPolygon->Add_Point(a.x, a.y); 00436 pPolygon->Add_Point(a.x + d * sin(Direction - Tolerance), a.y + d * cos(Direction - Tolerance)); 00437 pPolygon->Add_Point( d * sin(Direction) , d * cos(Direction)); 00438 pPolygon->Add_Point(b.x + d * sin(Direction + Tolerance), a.y + d * cos(Direction + Tolerance)); 00439 00440 //------------------------------------------------- 00441 for(double y=1.0; y<=Radius; y++) 00442 { 00443 for(double x=0.0; x<=Radius; x++) 00444 { 00445 if( (d = SG_Get_Length(x, y)) <= Radius ) 00446 { 00447 if( pPolygon->Contains( x, y) ) ADD_CELL( x, y, d); 00448 if( pPolygon->Contains( y, -x) ) ADD_CELL( y, -x, d); 00449 if( pPolygon->Contains(-x, -y) ) ADD_CELL(-x, -y, d); 00450 if( pPolygon->Contains(-y, x) ) ADD_CELL(-y, x, d); 00451 } 00452 } 00453 } 00454 00455 //------------------------------------------------- 00456 if( m_Cells.Get_Count() > 0 ) 00457 { 00458 m_Cells.Set_Index(2, TABLE_INDEX_Ascending); 00459 00460 return( true ); 00461 } 00462 } 00463 00464 return( false ); 00465 } 00466 00467 00469 // // 00470 // // 00471 // // 00473 00474 //---------------------------------------------------------