| TerraLib 4.1

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Examples

- File List
- File Members

E:/Projetos_Primeiro_Semestre_2012/TerraView/terralib/src/terralib/kernel/TeGridIndex.h
Go to the documentation of this file.

    00001 /************************************************************************************
    00002 TerraLib - a library for developing GIS applications.
    00003 Copyright © 2001-2007 INPE and Tecgraf/PUC-Rio.
    00004
    00005 This code is part of the TerraLib library.
    00006 This library is free software; you can redistribute it and/or
    00007 modify it under the terms of the GNU Lesser General Public
    00008 License as published by the Free Software Foundation; either
    00009 version 2.1 of the License, or (at your option) any later version.
    00010
    00011 You should have received a copy of the GNU Lesser General Public
    00012 License along with this library.
    00013
    00014 The authors reassure the license terms regarding the warranties.
    00015 They specifically disclaim any warranties, including, but not limited to,
    00016 the implied warranties of merchantability and fitness for a particular purpose.
    00017 The library provided hereunder is on an "as is" basis, and the authors have no
    00018 obligation to provide maintenance, support, updates, enhancements, or modifications.
    00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
    00020 indirect, special, incidental, or consequential damages arising out of the use
    00021 of this library and its documentation.
    00022 *************************************************************************************/
    00027 #ifndef  __TERRALIB_INTERNAL_GRIDINDEX_H
    00028 #define  __TERRALIB_INTERNAL_GRIDINDEX_H
    00029
    00030 #include "TeGeometry.h"
    00031 #include "TeIntersector.h"
    00032
    00033 #include <map>
    00034
    00035 /*
    00036  * WARNING:
    00037  *
    00038  *       1. This module IS UNDER DEVELOPMENT!
    00039  *
    00040  *       2. These data structures means to be used only in TerraLib kernel and should not be used by anyone because
    00041  *          the support and interfaces can be changed in future.
    00042  *
    00043  */
    00044
    00045 namespace TeSAM
    00046 {
    00053
    00054
    00066 class TL_DLL TeGridIndex
    00067 {
    00068            public:
    00069
    00071                       typedef pair<int, int> gridKey;
    00072
    00074                       typedef multimap<gridKey, unsigned int> gridType;                 // em cada linha e coluna podemos associar uma lista de outros objetos
    00075
    00076                       double dx_;
    00077                       double dy_;
    00078                       int npartsX_;
    00079                       int npartsY_;
    00080                       double xi_;
    00081                       double yi_;
    00082                       double xf_;
    00083                       double yf_;
    00084                       gridType grid_;
    00085                       unsigned int size_;
    00086
    00087            public:
    00088
    00090                       TeGridIndex()
    00091                                  : dx_(0.0), dy_(0.0), npartsX_(0), npartsY_(0), xi_(0.0), yi_(0.0), xf_(0.0), yf_(0.0), size_(0u)
    00092                       {
    00093                       }
    00094
    00096                       TeGridIndex(const TeBox& b, const double& resX, const double& resY)
    00097                                  : size_(0u)
    00098                       {
    00099                                  setBox(b);
    00100
    00101                                  setResolution(resX, resY);
    00102                       }
    00103
    00105                       void setBox(const TeBox& b)
    00106                       {
    00107                                  xi_ = b.x1_;
    00108                                  yi_ = b.y1_;
    00109
    00110                                  xf_ = b.x2_;
    00111                                  yf_ = b.y2_;
    00112                       }
    00113
    00115                       unsigned int size() const
    00116                       {
    00117                                  return size_;
    00118                       }
    00119
    00121                       void setResolution(const double& resX, const double& resY)
    00122                       {
    00123                                  dx_ = resX;
    00124                                  dy_ = resY;
    00125
    00126                                  if((dx_ <= 0.0) || (dy_ <= 0.0))
    00127                                  {
    00128                                             npartsX_ = 0;
    00129                                             npartsY_ = 0;
    00130                                  }
    00131                                  else
    00132                                  {
    00133                                             npartsX_ = TeRound((xf_ - xi_) / dx_) + 1;
    00134                                             npartsY_ = TeRound((yf_ - yi_) / dy_) + 1;
    00135                                  }
    00136                       }
    00137
    00139                       int getNumCols() const
    00140                       {
    00141                                  return npartsX_;
    00142                       }
    00143
    00145                       int getNumLines() const
    00146                       {
    00147                                  return npartsY_;
    00148                       }
    00149
    00151                       bool isValid() const
    00152                       {
    00153                                  return (npartsX_ != 0 && npartsY_ != 0);
    00154                       }
    00155
    00156
    00158                       void insert(const TeCoord2D& c, const unsigned int& itemId)
    00159                       {
    00160                                  int col = int((c.x_ - xi_) / dx_);
    00161                                  int line = int((c.y_ - yi_) / dy_);
    00162
    00163                                  gridKey key(col, line);
    00164
    00165                                  grid_.insert(gridType::value_type(key, itemId));
    00166
    00167                                  ++size_;
    00168                       }
    00169
    00171                       void getIndex(const TeCoord2D& c1, const TeCoord2D& c2, int& col1, int& line1, int& col2, int& line2)
    00172                       {
    00173                                  double lowerX = ((c1.x_ < c2.x_) ? c1.x_ : c2.x_);
    00174                                  double lowerY = ((c1.y_ < c2.y_) ? c1.y_ : c2.y_);
    00175                                  double upperX = ((c1.x_ > c2.x_) ? c1.x_ : c2.x_);
    00176                                  double upperY = ((c1.y_ > c2.y_) ? c1.y_ : c2.y_);
    00177
    00178                                  col1 = int((lowerX - xi_) / dx_);
    00179                                  line1 = int((lowerY - yi_) / dy_);
    00180                                  col2 = int((upperX - xi_) / dx_) + 1;
    00181                                  line2 = int((upperY - yi_) / dy_) + 1;
    00182                       }
    00183
    00185                       void insert(const TeCoord2D& c1, const TeCoord2D& c2, const unsigned int& itemId)
    00186                       {
    00187                                  gridKey key(0, 0);
    00188
    00189                                  int col1;
    00190                                  int line1;
    00191                                  int col2;
    00192                                  int line2;
    00193
    00194                                  getIndex(c1, c2, col1, line1, col2, line2);
    00195
    00196                                  for(int i = col1; i <= col2; ++i)
    00197                                  {
    00198                                             key.first  = i;
    00199
    00200                                             for(int j = line1; j <= line2; ++j)
    00201                                             {
    00202
    00203                                                        key.second = j;
    00204
    00205                                                        grid_.insert(gridType::value_type(key, itemId));
    00206
    00207                                                        ++size_;
    00208                                             }
    00209                                  }
    00210                       }
    00211
    00213                       void indexLine(const TeLine2D& l)
    00214                       {
    00215                                  unsigned int nstep = l.size() - 1;
    00216
    00217                                  for(unsigned int i = 0; i < nstep; ++i)
    00218                                             insert(l[i], l[i+1], i);
    00219                       }
    00220
    00222                       gridType& getGrid()
    00223                       {
    00224                                  return grid_;
    00225                       }
    00226
    00228                       void getLines(TeLineSet& lset)
    00229                       {
    00230                                  for(int i = 0; i <= npartsX_; ++i)
    00231                                  {
    00232                                             TeCoord2D c1, c2;
    00233                                             c1.x_ = xi_ + dx_ * i;
    00234                                             c1.y_ = yi_;
    00235
    00236                                             c2.x_ = xi_ + dx_ * i;
    00237                                             c2.y_ = yi_ + npartsY_ * dy_;
    00238
    00239                                             TeLine2D l;
    00240
    00241                                             l.add(c1); l.add(c2);
    00242
    00243                                             lset.add(l);
    00244                                  }
    00245
    00246                                  for(int j = 0; j <= npartsY_; ++j)
    00247                                  {
    00248                                             TeCoord2D c1, c2;
    00249                                             c1.x_ = xi_;
    00250                                             c1.y_ = yi_ + dy_ * j;
    00251
    00252                                             c2.x_ = xi_ + npartsX_ * dx_;
    00253                                             c2.y_ = yi_ + dy_ * j;
    00254
    00255                                             TeLine2D l;
    00256
    00257                                             l.add(c1); l.add(c2);
    00258
    00259                                             lset.add(l);
    00260                                  }
    00261                       }
    00262
    00263            private:
    00264
    00266                       TeGridIndex(const TeGridIndex& rhs);
    00267
    00269                       TeGridIndex& operator=(const TeGridIndex& rhs);
    00270
    00271 };         // end of class TeGridIndex
    00272
    00274 TL_DLL inline void getAverage(const TeLine2D& l, double& dx, double& dy)
    00275 {
    00276            unsigned int nstep = l.size() - 1;
    00277
    00278            double sumX = 0.0;
    00279            double sumY = 0.0;
    00280
    00281            for(unsigned int i = 0; i < nstep; ++i)
    00282            {
    00283                       sumX += fabs(l[i + 1].x_ - l[i].x_);
    00284                       sumY += fabs(l[i + 1].y_ - l[i].y_);
    00285            }
    00286
    00287            dx = (sumX / double(nstep)) * 8.0;
    00288            dy = (sumY / double(nstep)) * 8.0;
    00289
    00290            return;
    00291 }
    00292
    00294 TL_DLL inline bool TeSafeIntersectionsGrid(const TeLine2D& redLine, const TeLine2D& blueLine, TeINTERSECTOR2::TeVectorBoundaryIP& report, const unsigned int& redObjId = 0, const unsigned int& blueObjId = 0)
    00295 {
    00296            double dx = 0.0;
    00297            double dy = 0.0;
    00298
    00299            getAverage(redLine, dx, dy);
    00300
    00301            TeGridIndex redGrid(redLine.box(), dx, dy);
    00302
    00303            redGrid.indexLine(redLine);
    00304
    00305     TeGridIndex::gridKey key(0, 0);
    00306
    00307            int colmax = redGrid.getNumCols();
    00308            int colmin = 0;
    00309            int linemax = redGrid.getNumLines();
    00310            int linemin = 0;
    00311
    00312            int col1 = 0;
    00313            int col2 = 0;
    00314            int line1 = 0;
    00315            int line2 = 0;
    00316
    00317            bool hasIntersections = false;
    00318
    00319            TeSegmentIntersectionType t = TeImproperIntersection;
    00320
    00321 // Para cada segmento azul, verificar os quadrantes interceptados
    00322            unsigned int nStep = blueLine.size() - 1;
    00323
    00324            for(unsigned int k = 0; k < nStep; ++k)
    00325            {
    00326                       redGrid.getIndex(blueLine[k], blueLine[k+1], col1, line1, col2, line2);
    00327
    00328                       if((col2 < colmin) || (line2 < linemin) || (col1 > colmax) || (line1 > linemax))
    00329                                  continue;
    00330
    00331                       //if(((col1 > colmax) && (col2 > colmax)) || ((line1 > linemax) && (line2 > linemax)))
    00332                       //         continue;
    00333
    00334                       if(col1 < colmin)
    00335                                  col1 = colmin;
    00336
    00337                       if(col2 > colmax)
    00338                                  col2 = colmax;
    00339
    00340                       if(line1 < linemin)
    00341                                  line1 = linemin;
    00342
    00343         if(line2 > linemax)
    00344                                  line2 = linemax;
    00345
    00346                       for(int col = col1; col <= col2; ++col)
    00347                                  for(int lin = line1; lin <= line2; ++lin)
    00348                                  {
    00349                                             key.first  = col;
    00350                                             key.second = lin;
    00351
    00352                                             pair<TeGridIndex::gridType::iterator, TeGridIndex::gridType::iterator> its = redGrid.getGrid().equal_range(key);
    00353
    00354                                             while(its.first != its.second)
    00355                                             {
    00356                                                        TeINTERSECTOR2::TeBoundaryIP ip;
    00357
    00358                                                        if(TeINTERSECTOR2::TeIntersection(redLine[its.first->second], redLine[its.first->second + 1], blueLine[k], blueLine[k+1], ip, t))
    00359                                                        {
    00360                                                                   hasIntersections = true;
    00361
    00362                                                                   ip.redPartNum_ = redObjId;
    00363                                                                   ip.redSegNum_ = its.first->second;
    00364                                                                   ip.bluePartNum_ = blueObjId;
    00365                                                                   ip.blueSegNum_ = k;
    00366
    00367                                                                   if(ip.coords_.size() == 2)       //overlap
    00368                                                                   {
    00369                                                                              // Verificar se os pontos estão em ordem crescente
    00370                                                                              if(ip.coords_[0].x_ < ip.coords_[1].x_)
    00371                                                                              {
    00372                                                                                         report.push_back(ip);
    00373                                                                              }
    00374                                                                              else if(ip.coords_[0].x_ > ip.coords_[1].x_)
    00375                                                                              {
    00376                                                                                         swap(ip.coords_[0], ip.coords_[1]);
    00377                                                                                         report.push_back(ip);
    00378                                                                              }
    00379                                                                              else if(ip.coords_[0].y_ < ip.coords_[1].y_)
    00380                                                                              {
    00381                                                                                         report.push_back(ip);
    00382                                                                              }
    00383                                                                              else
    00384                                                                              {
    00385                                                                                         swap(ip.coords_[0], ip.coords_[1]);
    00386
    00387                                                                                         report.push_back(ip);
    00388                                                                              }
    00389                                                                   }
    00390                                                                   else
    00391                                                                   {
    00392                                                                              report.push_back(ip);
    00393                                                                   }
    00394                                                        }
    00395
    00396                                                        ++(its.first);
    00397                                             }
    00398                                  }
    00399            }
    00400
    00401            return hasIntersections;
    00402 }
    00403
    00406 };         // end namespace TeSAM
    00407
    00408
    00409 #endif     // __TERRALIB_INTERNAL_GRIDINDEX_H
    00410
    00411
    00412
    00413

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines