TeInterpolation.cpp

Go to the documentation of this file.
00001 /************************************************************************************
00002 TerraLib - a library for developing GIS applications.
00003 Copyright © 2001-2004 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 *************************************************************************************/
00023 
00024 #include "TeInterpolation.h"
00025 
00026 #include "TeKdTree.h"
00027 #include "TeSTElementSet.h"
00028 #include "TeSTEFunctionsDB.h"
00029 #include "TeQuerierParams.h"
00030 #include "TeQuerier.h"
00031 #include "TeVectorRemap.h"
00032 
00033 
00034 //! Builds a KDTree from a theme with samples: the theme must have a point representation
00035 /*
00036                 \param sampleTheme          The theme with samples
00037                 \param sampleAttrTableName  Theme table with samples
00038                 \param sampleColumnName     Table column with sample values
00039                 \param tree                                 The tree to store samples
00040                 \param destProjection           Destination projection
00041                 \return TRUE if the tree is built correct, otherwise returns FALSE
00042  */
00043 template<class KDTREE> bool TeBuildKDTree(TeTheme* sampleTheme, const string& sampleAttrTableName,
00044                                                                                   const string& sampleColumnName, KDTREE& tree, TeProjection* destProjection)
00045 {
00046 // verifies if we need to reproject the samples
00047         bool doReprojection = false;
00048 
00049         TeProjection* sampleProj = sampleTheme->layer()->projection();
00050 
00051         if(sampleProj && destProjection && (!((*sampleProj) == (*destProjection))))
00052                 doReprojection = true;
00053 
00054 // if it is necessary to reproject, reproject the tree's box first
00055     if(doReprojection)
00056         {
00057                 TeBox baux = tree.getBox();
00058                 TeBox b = TeRemapBox(baux, sampleProj, destProjection);
00059 
00060                 tree.setBox(b);
00061         }
00062 
00063 
00064         vector<pair<TeCoord2D, TeSample> > dataSet;
00065 
00066 // load sample points
00067         bool loadGeometries = true;
00068 
00069     vector<string> attributes;
00070 
00071         string attName = sampleAttrTableName + "." + sampleColumnName;
00072 
00073     attributes.push_back(attName);
00074 
00075         TeQuerierParams querierParams(loadGeometries, attributes);
00076 
00077         querierParams.setParams(sampleTheme);
00078 
00079         TeQuerier querier(querierParams);
00080 
00081 // load instances from theme based in the querier parameters
00082         if(!querier.loadInstances())
00083                 return false;
00084         
00085         TeSTInstance sti;       
00086 
00087 // traverse all the instances
00088         while(querier.fetchInstance(sti))       
00089         {
00090                 TeProperty prop;
00091 
00092 // retrieves sample values
00093                 sti.getProperty(prop, attName);    
00094                 
00095                 if(sti.hasPoints())
00096                 {
00097                         TePointSet pointSet;
00098 
00099                         sti.getGeometry(pointSet);
00100 
00101                         TeCoord2D c = pointSet[0].location();
00102 
00103 // if it is necessary, do reprojection
00104                         if(doReprojection)
00105                         {
00106                                 TeCoord2D caux;
00107                                 TeVectorRemap(c, sampleProj, caux, destProjection);
00108                                 c = caux;
00109                         }
00110 
00111                         TeSample sample(c, atof(prop.value_.c_str()));
00112 
00113 // put samples into auxiliary vector to build the tree
00114                         dataSet.push_back(pair<TeCoord2D, TeSample>(sample.location(), sample));
00115                 }
00116         }
00117 
00118         tree.build(dataSet);
00119 
00120         return true;
00121 }
00122 
00123 bool TeCellInterpolate(TeTheme* inputTheme, const string& inputAttrTableName, const string& sampleColumnName,
00124                        TeTheme* outputTheme, const string& outputAttrTableName, const string& outputColumnName,
00125                                        const TeInterpolationAlgorithm& algorithm,
00126                        const unsigned int& numberOfNeighbors, const int& powValue, const double& boxRatio)
00127 {
00128         if((inputTheme == 0) || (outputTheme == 0))
00129                 return false;
00130 
00131         if(inputAttrTableName.empty() || outputAttrTableName.empty())
00132                 return false;
00133 
00134         if(sampleColumnName.empty() || outputColumnName.empty())
00135                 return false;   
00136 
00137 // load the tree with samples
00138         typedef TeSAM::TeAdaptativeKdTreeNode<TeCoord2D, vector<TeSample>, TeSample> KDNODE;
00139         typedef TeSAM::TeAdaptativeKdTree<KDNODE> KDTREE;
00140 
00141         unsigned int bucketSize = 2 * numberOfNeighbors;
00142 
00143         TeBox mbr = inputTheme->layer()->box();
00144 
00145         KDTREE tree(mbr, bucketSize);
00146 
00147         if(!TeBuildKDTree(inputTheme, inputAttrTableName, sampleColumnName, tree, outputTheme->layer()->projection()))
00148                 return false;
00149 
00150         if(tree.size() == 0)
00151                 return false;
00152         
00153         else if(outputTheme->visibleRep() & TeCELLS)
00154         {
00155                 TeInterpolationAlgorithms<KDTREE> interpolationObj(tree);
00156 
00157 // load cells to be interpolated
00158 
00159                 bool loadGeometries = true;
00160 
00161                 vector<string> attributes;
00162 
00163                 TeQuerierParams querierParams(loadGeometries);
00164 
00165                 querierParams.setParams(outputTheme);
00166 
00167                 TeQuerier querier(querierParams);
00168 
00169 // load theme instances
00170                 querier.loadInstances();        
00171                 
00172                 TeSTInstance sti;       
00173 
00174                 TeSTElementSet elemSet(outputTheme);    
00175 
00176 // traverse all the instances
00177                 while(querier.fetchInstance(sti))       
00178                 {
00179                         TeProperty prop;
00180 
00181                         if(sti.hasCells())
00182                         {
00183                                 TeCellSet cellSet;
00184 
00185                                 sti.getGeometry(cellSet);
00186 
00187                                 double value = -TeMAXFLOAT;
00188 
00189 // if the cell has more than one geometry, so emit an error!!!!!!
00190                                 if((cellSet.size() > 1) || (cellSet.size() == 0))
00191                                         return false;
00192 
00193 // do interpolation with the informed algorithm
00194                                 if(algorithm == TeNNInterpolation)
00195                                 {
00196                                         value = interpolationObj.nearestNeighbor(cellSet[0].box().center());
00197                                 }
00198                                 else if(algorithm == TeAvgInterpolation)
00199                                 {
00200                                         value = interpolationObj.avgNearestNeighbor(cellSet[0].box().center(), numberOfNeighbors);
00201                                 }
00202                                 else if(algorithm == TeDistWeightAvgInterpolation)
00203                                 {
00204                                         value = interpolationObj.distWeightAvgNearestNeighbor(cellSet[0].box().center(), numberOfNeighbors, powValue);
00205                                 }
00206                                 else if(algorithm == TeAvgInBoxInterpolation)
00207                                 {
00208                                         TeCoord2D center = cellSet[0].box().center();
00209 
00210                                         TeBox b(center.x_ - boxRatio, center.y_ - boxRatio, center.x_ + boxRatio, center.y_ + boxRatio);
00211 
00212                                         value = interpolationObj.boxAvg(b);
00213                                 }
00214                                 else if(algorithm == TeDistWeightAvgInBoxInterpolation)
00215                                 {
00216                                         TeCoord2D center = cellSet[0].box().center();
00217 
00218                                         TeBox b(center.x_ - boxRatio, center.y_ - boxRatio, center.x_ + boxRatio, center.y_ + boxRatio);
00219 
00220                                         value = interpolationObj.boxDistWeightAvg(center, b, powValue);
00221                                 }
00222                                 else
00223                                         return false;
00224 
00225 // stores the interpolated values
00226                                 TeSTInstance inst;
00227 
00228                                 inst.objectId(sti.objectId());
00229                                 inst.uniqueId(sti.uniqueId());
00230                                 inst.theme(outputTheme);
00231 
00232                                 TeProperty prop;
00233                                 prop.attr_.rep_.name_ = outputColumnName;
00234                                 prop.attr_.rep_.type_ = TeREAL;
00235                                 prop.value_ = Te2String(value, 15);
00236 
00237                                 inst.addProperty(prop);
00238 
00239                                 elemSet.insertSTInstance(inst);
00240                         }
00241                 }
00242 
00243 // store the interpolated values
00244                 return TeUpdateDBFromSet(&elemSet, outputAttrTableName);        
00245         }       
00246         
00247         return false;
00248 }
00249 
00250 bool TeRasterInterpolate(TeTheme* inputTheme, const string& inputAttrTableName, const string& sampleColumnName,
00251                          TeRaster* outputRaster, const int& band,
00252                                          const TeInterpolationAlgorithm& algorithm,
00253                          const unsigned int& numberOfNeighbors, const int& powValue, const double& boxRatio)
00254 {
00255         if((inputTheme == 0) || (outputRaster == 0))
00256                 return false;
00257 
00258         if(inputAttrTableName.empty())
00259                 return false;
00260 
00261         if(sampleColumnName.empty())
00262                 return false;   
00263 
00264 // load tree with samaples
00265         typedef TeSAM::TeAdaptativeKdTreeNode<TeCoord2D, vector<TeSample>, TeSample> KDNODE;
00266         typedef TeSAM::TeAdaptativeKdTree<KDNODE> KDTREE;
00267 
00268 // A minimum of MINBUCKETSIZE elements in each bucket
00269         unsigned int bucketSize = 2 * numberOfNeighbors;
00270 
00271         TeBox mbr = inputTheme->layer()->box();
00272 
00273         KDTREE tree(mbr, bucketSize);
00274 
00275         if(!TeBuildKDTree(inputTheme, inputAttrTableName, sampleColumnName, tree, outputRaster->projection()))
00276                 return false;
00277 
00278         if(tree.size() == 0)
00279                 return false;
00280 
00281         TeInterpolationAlgorithms<KDTREE> interpolationObj(tree);
00282         
00283         int nLines = outputRaster->params().nlines_;
00284         int nCols = outputRaster->params().ncols_;
00285 
00286         double value = -TeMAXFLOAT;
00287 
00288         if(algorithm == TeNNInterpolation)
00289         {
00290                 for(int i = 0; i < nLines; ++i)
00291                         for(int j = 0; j < nCols; ++j)
00292                         {
00293                                 TeCoord2D cl(j, i);
00294 
00295                                 TeCoord2D c = outputRaster->index2Coord(cl);
00296 
00297                                 value = interpolationObj.nearestNeighbor(c);
00298 
00299                 outputRaster->setElement(j, i, value, band);
00300                         }               
00301         }
00302         else if(algorithm == TeAvgInterpolation)
00303         {
00304                 for(int i = 0; i < nLines; ++i)
00305                 {
00306                         for(int j = 0; j < nCols; ++j)
00307                         {
00308                                 TeCoord2D cl(j, i);
00309 
00310                                 TeCoord2D c = outputRaster->index2Coord(cl);
00311 
00312                                 value = interpolationObj.avgNearestNeighbor(c, numberOfNeighbors);
00313 
00314                 outputRaster->setElement(j, i, value, band);
00315                         }       
00316                 }
00317         }
00318         else if(algorithm == TeDistWeightAvgInterpolation)
00319         {
00320                 for(int i = 0; i < nLines; ++i)
00321                         for(int j = 0; j < nCols; ++j)
00322                         {
00323                                 TeCoord2D cl(j, i);
00324 
00325                                 TeCoord2D c = outputRaster->index2Coord(cl);
00326 
00327                                 value = interpolationObj.distWeightAvgNearestNeighbor(c, numberOfNeighbors, powValue);
00328 
00329                 outputRaster->setElement(j, i, value, band);
00330                         }
00331         }
00332         else if(algorithm == TeAvgInBoxInterpolation)
00333         {
00334                 for(int i = 0; i < nLines; ++i)
00335                         for(int j = 0; j < nCols; ++j)
00336                         {
00337                                 TeCoord2D cl(j, i);
00338 
00339                                 TeCoord2D c = outputRaster->index2Coord(cl);
00340 
00341                                 TeBox b(c.x_ - boxRatio, c.y_ - boxRatio, c.x_ + boxRatio, c.y_ + boxRatio);
00342 
00343                                 value = interpolationObj.boxAvg(b);
00344 
00345                 outputRaster->setElement(j, i, value, band);
00346                         }
00347         }
00348         else if(algorithm == TeDistWeightAvgInBoxInterpolation)
00349         {
00350                 for(int i = 0; i < nLines; ++i)
00351                         for(int j = 0; j < nCols; ++j)
00352                         {
00353                                 TeCoord2D cl(j, i);
00354 
00355                                 TeCoord2D c = outputRaster->index2Coord(cl);
00356 
00357                                 TeBox b(c.x_ - boxRatio, c.y_ - boxRatio, c.x_ + boxRatio, c.y_ + boxRatio);
00358 
00359                                 value = interpolationObj.boxDistWeightAvg(c, b, powValue);
00360 
00361                 outputRaster->setElement(j, i, value, band);
00362                         }
00363         }
00364         else
00365                 return false;
00366 
00367 
00368     return true;
00369 }

Generated on Sun Jul 29 04:01:22 2012 for TerraLib - Development Source by  doxygen 1.5.3