TeCoverageDecoderDatabase.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 *************************************************************************************/
00023 /*!
00024   \file TeCoverageDecoderDatabase.h
00025 
00026   \par This file contains definitions and algorithms for accessing a
00027        generic Coverage from a TerraLib database.
00028 */
00029 #ifndef  __TERRALIB_INTERNAL_COVERAGEDECODERDATABASE_H
00030 #define  __TERRALIB_INTERNAL_COVERAGEDECODERDATABASE_H
00031 
00032 #include "TeCoverageDecoder.h"
00033 
00034 /*!
00035   \class TeCoverageDecoderDatabase
00036   \brief Class to decode a generic Coverage from a TerraLib database.
00037 */
00038 template <class T>
00039 class TeCoverageDecoderDatabase : public TeCoverageDecoder<T>
00040 {
00041 public:
00042 
00043     //! Constructor from parameters
00044     TeCoverageDecoderDatabase(TeCoverageParams& params) :
00045         TeCoverageDecoder<T>(params)
00046     {
00047     }
00048 
00049     //! Initialize internal structures
00050     /*!
00051       Instantiate internal structures, must be called before any
00052       attempt to access the coverage data.
00053     */
00054     virtual void init()
00055     {
00056         TeLayer* layer = TeRetrieveLayer(params_.getDatabase(), params_.getLayerId());
00057 
00058         // Check if the coverage ID is specified
00059         if (params_.getCoverageId().empty())
00060         {
00061             // Otherwise, get the first coverage (if any)
00062             std::vector<std::string> coverageIds;
00063             TeRetrieveCoverageIds(layer, coverageIds);
00064             if (coverageIds.empty())
00065             {
00066                 std::string errorMsg = "No coverage defined on layer " + Te2String(layer->id()) + ".";
00067                 throw TeException(UNKNOWN_ERROR_TYPE, errorMsg, false);
00068             }
00069             // New coverage ID is the first coverage found on layer
00070             params_.setCoverageId(coverageIds.at(0));
00071         }
00072 
00073         // Set coverage table name
00074         params_.setCoverageTable(TeRetrieveCoverageTable(layer, params_.getCoverageId()));
00075 
00076         // Retrieve coverage dimensions information from the database
00077         std::vector<TeCoverageDimension> dimensions;
00078         TeRetrieveDimensions(layer, params_.getCoverageId(), dimensions);
00079         params_.setDimensions(dimensions);
00080 
00081         // Set coverage projection
00082         params_.setProjection(layer->projection());
00083 
00084         // Set coverage bounding box
00085         params_.setBoundingBox(TeRetrieveCoverageBox(layer, params_.getCoverageId()));
00086 
00087         // Set number of elements of the coverage
00088         params_.setNumElements(TeRetrieveCoverageNumElements(layer, params_.getCoverageId()));
00089     }
00090 
00091     //! Select generic coverage blocks from the database.
00092     /*!
00093       \par Select generic coverage blocks from a TerraLib database. Uses
00094            a TeBlockLoader object for retrieving blocks from the database.
00095       \par The polygon parameter defines a selection area and the relation
00096            parameter specifies the kind of relation (e.g. intersection,
00097            crossing, overlapping) that holds between the selection area and
00098            at least one geometry in each block to be selected.
00099       \param poly an instance of TePolygon representing a selection area
00100       \param relation a spatial relation
00101       \param dontSelect list IDs of blocks that must not be retrieved
00102       \sa TeCoverageBlock TeSpatialRelation TeBlockLoader
00103     */
00104     void selectBlocks(const TePolygon& poly, const TeSpatialRelation relation, std::vector<TeCoverageBlock<T> >& selected, std::set<int>& dontSelect)
00105     {
00106         selected.clear();
00107 
00108         TeBox queryBox = poly.box();
00109 
00110         // Set block loader parameters.
00111         TeBlockLoaderParams loaderParams;
00112         loaderParams.db = params_.getDatabase();
00113         loaderParams.table_name = params_.getCoverageTable();
00114         loaderParams.selection_box = queryBox;
00115         loaderParams.load_all_attrs = true;
00116         loaderParams.dont_load_ids = dontSelect;
00117 
00118         // Construct loader and load blocks.
00119         TeBlockLoader loader(loaderParams);
00120         loader.loadBlocks();
00121 
00122         // Iterate over blocks loaded
00123         while (loader.fetchNext()) {
00124 
00125             TeBox blockBox(loader.getDouble("lower_x"),
00126                         loader.getDouble("lower_y"),
00127                         loader.getDouble("upper_x"),
00128                         loader.getDouble("upper_y"));
00129 
00130             TePolygon& blockPoly = polygonFromBox(blockBox);
00131 
00132             // If the spatial relation doesn't hold, proceed to the next block
00133             if (!TeTopologicalRelation(&blockPoly, &poly, relation))
00134             {
00135                 continue;
00136             }
00137 
00138             // Extract block contents.
00139             long blockSize = 0;
00140             unsigned char* data = NULL;
00141             loader.getSpatialData(data, blockSize);
00142             
00143             // Decode block contents.
00144             TeCoverageBlock<T>& block = decodeCoverageBlock(data, blockSize, params_.getDimensions());
00145 
00146             // Set other block attributes
00147             block.id = loader.getID();
00148             block.box = blockBox;
00149 
00150             // Add block to result
00151             selected.push_back(block);
00152         }
00153     }
00154 
00155 protected:
00156 
00157     //! Decode a generic geometry-value pair
00158     /*!
00159       \par Decode a generic geometry-value pair from a block of raw data.
00160            As a side effect, the pointer to the data is moved forward to the
00161            end of the decoded chunk.
00162         \param data pointer to the memory location where the raw data starts
00163         \param dimensions information about the coverage dimensions
00164         \return a generic geometry-value pair
00165     */
00166     TeGeomValuePair<T> decodeGeomValuePair(unsigned char*& data, std::vector<TeCoverageDimension>& dimensions);
00167 
00168     //! Decode a generic coverage block
00169     /*!
00170         \par Decode coverage block contents that are stored in the database
00171              as raw binary data. As a side effect, the pointer to the data
00172              is moved forward to the end of the decoded chunk.
00173         \param data pointer to the memory location where the raw data starts
00174         \param dataSize size of the raw data block to be decoded
00175         \param dimensions information about the coverage dimensions
00176         \return a generic coverage block
00177     */
00178     TeCoverageBlock<T> decodeCoverageBlock(unsigned char*& data, const long dataSize, std::vector<TeCoverageDimension>& dimensions)
00179     {
00180         TeCoverageBlock<T> block;
00181 
00182         unsigned char* dataEnd = data + dataSize;
00183 
00184         // Decode geom-value pairs from chunks of the block
00185         unsigned int count = 0;
00186         while (data < dataEnd)
00187         {
00188             TeGeomValuePair<T>& gvPair = decodeGeomValuePair(data, dimensions);
00189             gvPair.geom.objectId(Te2String(count++));
00190 
00191             block.pairs.push_back(gvPair); // Insert geom-value pair in block
00192         }
00193         return block;
00194     }
00195 };
00196 
00197 //! Specialization for decoding a TePoint instead of a generic geometry
00198 TeGeomValuePair<TePoint>
00199 TeCoverageDecoderDatabase<TePoint>::decodeGeomValuePair(unsigned char*& data, std::vector<TeCoverageDimension>& dimensions)
00200 {
00201     TeGeomValuePair<TePoint> gvPair = TeGeomValuePair<TePoint>();
00202 
00203     // Set coordinates
00204     double x = READ(data, double);
00205     double y = READ(data, double);
00206 
00207     gvPair.geom = TePoint(x, y);
00208     
00209     // Set values
00210     gvPair.value = std::vector<double>();
00211     std::vector<TeCoverageDimension>::iterator it = dimensions.begin();
00212     std::vector<TeCoverageDimension>::iterator end = dimensions.end();
00213     while (it != end)
00214     {
00215         double val = 0;
00216 
00217         switch (it->type)
00218         {
00219         case (TeUNSIGNEDSHORT):
00220             val = READ(data, unsigned short);
00221             break;
00222         case (TeSHORT):
00223             val = READ(data, short);
00224             break;
00225         case (TeINTEGER):
00226             val = READ(data, int);
00227             break;                
00228         case (TeUNSIGNEDLONG):
00229             val = READ(data, unsigned long);
00230             break;
00231         case (TeLONG):
00232             val = READ(data, long);
00233             break;
00234         case (TeFLOAT):
00235             val = READ(data, float);
00236             break;
00237         case (TeDOUBLE):
00238             val = READ(data, double);
00239             break;
00240         default:
00241             // Exception (invalid type)
00242             break;
00243         }
00244 
00245         gvPair.value.push_back(val);
00246         it++;
00247     }
00248 
00249     return gvPair;
00250 }
00251 
00252 //! Specialization for decoding a TeLine2D instead of a generic geometry
00253 TeGeomValuePair<TeLine2D>
00254 TeCoverageDecoderDatabase<TeLine2D>::decodeGeomValuePair(unsigned char*& data, std::vector<TeCoverageDimension>& dimensions)
00255 {
00256     TeGeomValuePair<TeLine2D> gvPair = TeGeomValuePair<TeLine2D>();
00257 
00258     TeLine2D line = TeLine2D();
00259 
00260     // Check number of points in the line
00261     unsigned int numPoints = READ(data, unsigned int);
00262 
00263     // Decode points and add to the line
00264     for (unsigned int i = 0; i < numPoints; ++i)
00265     {
00266         double x = READ(data, double);
00267         double y = READ(data, double);
00268 
00269         line.add(TeCoord2D(x, y));
00270     }
00271 
00272     gvPair.geom = line;
00273     
00274     // Set values
00275     gvPair.value = std::vector<double>();
00276     std::vector<TeCoverageDimension>::iterator it = dimensions.begin();
00277     std::vector<TeCoverageDimension>::iterator end = dimensions.end();
00278     while (it != end)
00279     {
00280         double val = 0;
00281 
00282         switch (it->type)
00283         {
00284         case (TeUNSIGNEDSHORT):
00285             val = READ(data, unsigned short);
00286             break;
00287         case (TeSHORT):
00288             val = READ(data, short);
00289             break;
00290         case (TeINTEGER):
00291             val = READ(data, int);
00292             break;                
00293         case (TeUNSIGNEDLONG):
00294             val = READ(data, unsigned long);
00295             break;
00296         case (TeLONG):
00297             val = READ(data, long);
00298             break;
00299         case (TeFLOAT):
00300             val = READ(data, float);
00301             break;
00302         case (TeDOUBLE):
00303             val = READ(data, double);
00304             break;
00305         default:
00306             // Exception (invalid type)
00307             break;
00308         }
00309 
00310         gvPair.value.push_back(val);
00311         it++;
00312     }
00313 
00314     return gvPair;
00315 }
00316 
00317 //! Specialization for decoding a TePolygon instead of a generic geometry
00318 TeGeomValuePair<TePolygon>
00319 TeCoverageDecoderDatabase<TePolygon>::decodeGeomValuePair(unsigned char*& data, std::vector<TeCoverageDimension>& dimensions)
00320 {
00321     TeGeomValuePair<TePolygon> gvPair = TeGeomValuePair<TePolygon>();
00322 
00323     TePolygon poly = TePolygon();
00324     // Check number of linear rings in the polygon
00325     unsigned int numLines = READ(data, unsigned int);
00326 
00327     for (unsigned int i = 0; i < numLines; ++i)
00328     {
00329         TeLine2D line = TeLine2D();
00330 
00331         // Check number of points in the line
00332         unsigned int numPoints = READ(data, unsigned int);
00333 
00334         // Decode points and add to the line
00335         for (unsigned int i = 0; i < numPoints; ++i)
00336         {
00337             double x = READ(data, double);
00338             double y = READ(data, double);
00339 
00340             line.add(TeCoord2D(x, y));
00341         }
00342 
00343         TeLinearRing ring = TeLinearRing(line);
00344         poly.add(ring);
00345     }
00346     gvPair.geom = poly;
00347     
00348     // Set values
00349     gvPair.value = std::vector<double>();
00350     std::vector<TeCoverageDimension>::iterator it = dimensions.begin();
00351     std::vector<TeCoverageDimension>::iterator end = dimensions.end();
00352     while (it != end)
00353     {
00354         double val = 0;
00355 
00356         switch (it->type)
00357         {
00358         case (TeUNSIGNEDSHORT):
00359             val = READ(data, unsigned short);
00360             break;
00361         case (TeSHORT):
00362             val = READ(data, short);
00363             break;
00364         case (TeINTEGER):
00365             val = READ(data, int);
00366             break;                
00367         case (TeUNSIGNEDLONG):
00368             val = READ(data, unsigned long);
00369             break;
00370         case (TeLONG):
00371             val = READ(data, long);
00372             break;
00373         case (TeFLOAT):
00374             val = READ(data, float);
00375             break;
00376         case (TeDOUBLE):
00377             val = READ(data, double);
00378             break;
00379         default:
00380             // Exception (invalid type)
00381             break;
00382         }
00383 
00384         gvPair.value.push_back(val);
00385         it++;
00386     }
00387 
00388     return gvPair;
00389 }
00390 
00391 #endif // __TERRALIB_INTERNAL_COVERAGEDECODERDATABASE_H

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