SAGA API v2.0.8
H:/saga/saga_svn/saga-gis/src/saga_core/saga_api/grid_system.cpp
Go to the documentation of this file.
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 //---------------------------------------------------------