TeTheme.cpp

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 You should have received a copy of the GNU Lesser General Public
00011 License along with this library.
00012 
00013 The authors reassure the license terms regarding the warranties.
00014 They specifically disclaim any warranties, including, but not limited to,
00015 the implied warranties of merchantability and fitness for a particular purpose.
00016 The library provided hereunder is on an "as is" basis, and the authors have no
00017 obligation to provide maintenance, support, updates, enhancements, or modifications.
00018 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
00019 indirect, special, incidental, or consequential damages arising out of the use
00020 of this library and its documentation.
00021 *************************************************************************************/
00022 
00023 #include "TeTheme.h"
00024 #include "TeDatabase.h"
00025 #include "TeGroupingAlgorithms.h"
00026 #include "TeRasterTransform.h"
00027 #include "TeQuerier.h"
00028 #include "TeQuerierParams.h"
00029 
00030 extern int  yyparse(string& sqlOut);
00031 extern int  initParse(const string& strIn, TeDatabase* db);
00032 
00033 static TeThemeFactory themeFactory;
00034 
00035 TeTheme::TeTheme( const string& name, TeLayer* layer, TeViewNode* parent, const int& view, const int& id)
00036                 : TeAbstractTheme(name, parent, view, id, TeTHEME),
00037                 layer_(layer),
00038         useCollection_(true)
00039 {
00040         //layer id
00041         if(layer)
00042         {
00043                 layerId_ = layer->id();
00044                 if (layer_->database())
00045                         themeBox_ = layer_->box();
00046         }
00047         else
00048                 layerId_ = -1;
00049 
00050         isEditable_ = true;
00051 }
00052 
00053 TeTheme::TeTheme(const TeViewNodeParams& params) : TeAbstractTheme(params),     layer_(0), layerId_(-1),
00054 useCollection_(true)
00055 {
00056         isEditable_ = true;
00057 }
00058 
00059 
00060 // Copy constructor
00061 TeTheme::TeTheme (const TeTheme& other) :
00062         TeAbstractTheme(other)
00063 {
00064         layerId_ = other.layerId_;
00065         layer_ = other.layer_;      //the same layer pointer
00066         collectionTable_ = other.collectionTable_;
00067         collectionAuxTable_ = other.collectionAuxTable_;
00068 
00069         attTableVector_ = other.attTableVector_;
00070         sqlFrom_ =  other.sqlFrom_;
00071         sqlJoin_ = other.sqlGridJoin_;
00072         sqlGridFrom_ = other.sqlGridFrom_;
00073         sqlGridJoin_ = other.sqlGridJoin_;
00074         aliasVector_ = other.aliasVector_;
00075         sqlAttList_ = other.sqlAttList_;
00076         sqlNumAttList_ = other.sqlNumAttList_;
00077 
00078     useCollection_ = other.useCollection_;
00079 
00080     isEditable_ = true;
00081 }
00082 
00083 
00084 // Destructor
00085 TeTheme::~TeTheme ()
00086 {
00087         clearAttTableVector();
00088         clearAttList();
00089         collectionTable_.clear();
00090         collectionAuxTable_.clear();
00091         sqlFrom_.clear();
00092         sqlJoin_.clear();
00093         sqlGridFrom_.clear();
00094         sqlGridJoin_.clear();
00095         aliasVector_.clear();
00096         sqlAttList_.clear();
00097         sqlNumAttList_.clear();
00098 }
00099 
00100 TeTheme&
00101 TeTheme::operator= (const TeTheme& other)
00102 {
00103         if ( this != &other )
00104         {
00105                 TeAbstractTheme* absTheme = (TeAbstractTheme*)this;
00106                 absTheme->operator=(other);
00107                 layerId_ = other.layerId_;
00108                 layer_ = other.layer_;      //the same layer pointer
00109 
00110                 collectionTable_ = other.collectionTable_;
00111                 collectionAuxTable_ = other.collectionAuxTable_;
00112 
00113                 attTableVector_ = other.attTableVector_;
00114                 sqlFrom_ =  other.sqlFrom_;
00115                 sqlJoin_ = other.sqlGridJoin_;
00116                 sqlGridFrom_ = other.sqlGridFrom_;
00117                 sqlGridJoin_ = other.sqlGridJoin_;
00118                 aliasVector_ = other.aliasVector_;
00119                 sqlAttList_ = other.sqlAttList_;
00120                 sqlNumAttList_ = other.sqlNumAttList_;
00121 
00122         useCollection_ = other.useCollection_;
00123         }
00124         return *this;
00125 }
00126 
00127 TeViewNode* TeTheme::clone()
00128 {
00129         TeTheme* theme = new TeTheme();
00130         *theme = *this;
00131         return theme;
00132 }
00133 
00134 
00135 void TeTheme::layer(TeLayer* layer)
00136 {
00137         layer_ = layer;
00138         if (layer)
00139         {
00140                 layerId_ = layer->id();
00141 //              themeBox_ = layer_->box();
00142         }
00143 }
00144 
00145 void
00146 TeTheme::setSpatialRest(TeBox& box, TeGeomRep rep, TeSpatialRelation relation)
00147 {
00148         hasSpatialRes_ = true;
00149         boxRest_ = box;
00150         spatialRelation_ = relation;
00151 
00152         if(rep==TeGEOMETRYNONE)
00153                 geomRepRest_ = layer()->vectRepres()[0]->geomRep_;
00154         else
00155                 geomRepRest_ = rep;
00156 
00157         geomRest_ = 0;
00158 }
00159 
00160 void
00161 TeTheme::setSpatialRest(TeGeometry* geom, TeGeomRep rep, TeSpatialRelation relation)
00162 {
00163         hasSpatialRes_ = true;
00164         geomRest_ = geom;
00165         spatialRelation_ = relation;
00166 
00167         if(rep==TeGEOMETRYNONE)
00168                 geomRepRest_ = layer()->vectRepres()[0]->geomRep_;
00169         else
00170                 geomRepRest_ = rep;
00171 
00172         boxRest_ = TeBox();
00173 }
00174 
00175 string
00176 TeTheme::sqlWhereRestrictions(TeRepresentation* rep)
00177 {
00178         TeKeys objs;
00179         string whereClause= " 1 = 1 ";
00180         TeDatabase* db = layer()->database();
00181 
00182         // load the first representation
00183         if(!rep)
00184                 rep = (layer()->vectRepres())[0];
00185 
00186         // temporal restrictions are applied only to temporal tables
00187         if(hasTemporalRest())
00188         {
00189                 string result = "";
00190 
00191                 initParse(temporalRest(), db);
00192 
00193                 if(!yyparse(result))  //0: accept  1: reject
00194                         whereClause += " AND "+ result;
00195                 else
00196                         return "";
00197         }
00198 
00199         // we should test if the attribute restriction is valid
00200         if (hasAttrRest())
00201                 whereClause += " AND "+ attributeRest();
00202 
00203         // spatial restriction with other geometry representation
00204         if (hasSpatialRest() && rep)
00205         {
00206                 if(boxRestriction().isValid())
00207                 {
00208             TeBox b =  boxRestriction();
00209             TeGeomRep gRep = rep->geomRep_;
00210 //                      whereClause += " AND "+ db->getSQLBoxWhere(boxRestriction(), rep->geomRep_);
00211                         string geomTableRest = layer()->tableName(geomRepRestriction());
00212                         whereClause += " AND "+ db->getSQLBoxWhere(b, gRep, geomTableRest);
00213                 }
00214                 else if(geomRestriction())
00215                 {
00216                         string geomTableRest = layer()->tableName(geomRepRestriction());
00217                         TePrecision::instance().setPrecision(TeGetPrecision(layer()->projection()));
00218 
00219                         if(db->spatialRelation(geomTableRest, geomRepRestriction(), geomRestriction(),
00220                                                            objs, spatialRelation()))
00221                         {
00222                                 string obs;
00223                                 for(unsigned int i=0; i<objs.size(); i++)
00224                                 {
00225                                         if(i!=0)
00226                                                 obs += ",";
00227                                         obs += "'"+ objs[i] +"'";
00228                                 }
00229 
00230                                 whereClause += " AND "+ rep->tableName_ +".object_id IN ("+ obs +")";
00231                         }
00232                 }
00233         }
00234         return whereClause;
00235 }
00236 
00237 void TeTheme::createRasterVisual(TeRaster* rst)
00238 {
00239         if (rasterVisual_)
00240                 delete rasterVisual_;
00241 
00242         if (!rst)
00243                 rst = layer_->raster();
00244 
00245         if (!rst)
00246                 return;
00247 
00248         rasterVisual_ = new TeRasterTransform();
00249 
00250         if (rst->params().photometric_[0] == TeRasterParams::TePallete)  // raster palette -> uses its palette
00251         {
00252                 rasterVisual_->setTransfFunction(&TeRasterTransform::Pallete2ThreeBand);
00253                 rasterVisual_->setLutSize(rst->params().lutr_.size());
00254                 return;
00255         }
00256 
00257         if (visibleRep_ & 0x40000000  &&                // sliced raster -> generate the
00258                 grouping_.groupMode_ == TeRasterSlicing)        // appropriate palette
00259         {
00260                 int band = atoi(grouping_.groupAttribute_.name_.c_str());
00261                 rasterVisual_->setSrcBand(band);
00262                 if (rst->params().dataType_[band] != TeUNSIGNEDCHAR)
00263                         rasterVisual_->generateLUT(legend_, 1024, defaultLegend_.visual(TePOLYGONS)->color());
00264                 else
00265                         rasterVisual_->generateLUT(legend_, 256, defaultLegend_.visual(TePOLYGONS)->color());
00266                 rasterVisual_->setTransfFunction(&TeRasterTransform::LUT2ThreeBand);
00267                 return;
00268         }
00269 
00270         if (rst->params().dataType_[0] != TeUNSIGNEDCHAR)// non unsigned char -> generate linear transformation
00271         {
00272                 std::vector<double>::const_iterator minIt = min_element(rst->params().vmin_.begin(), rst->params().vmin_.end());
00273                 std::vector<double>::const_iterator maxIt = max_element(rst->params().vmax_.begin(), rst->params().vmax_.end());
00274 
00275                 rasterVisual_->setLinearTransfParameters(*minIt, *maxIt , 0, 255);
00276         }
00277 
00278         if (rst->params().nBands() == 1)
00279                 rasterVisual_->setTransfFunction(&TeRasterTransform::Mono2ThreeBand);
00280         else if (rst->params().nBands() == 3)
00281                 rasterVisual_->setTransfFunction(&TeRasterTransform::ThreeBand2RGB);
00282         else
00283                 rasterVisual_->setTransfFunction(&TeRasterTransform::Band2Band);
00284 }
00285 
00286 
00287 
00288 bool
00289 TeTheme::buildCollection(std::string objectId, const bool& sincronize)
00290 {
00291         if(id()==0)
00292                 return false;
00293 
00294         if(!populateCollection(objectId, sincronize))
00295                 return false;
00296 
00297         if(!populateCollectionAux(objectId))
00298                 return false;
00299 
00300         return true;
00301 }
00302 
00303 bool
00304 TeTheme::buildGrouping(const TeGrouping& g, TeSelectedObjects selectedObjects,
00305                                                  vector<double>* dValuesVec)
00306 {
00307         return buildGrouping(layer_->database(), g, selectedObjects, dValuesVec);
00308 }
00309 
00310 bool
00311 TeTheme::buildGrouping(TeDatabase* db, const TeGrouping& g, TeSelectedObjects selectedObjects, vector<double>* dValuesVec)
00312 {
00313         if(!db)
00314                 return false;
00315         grouping_ = g;
00316         unsigned int i;
00317         vector<TeSlice> slices;
00318         int     nullValues = 0;
00319         if (grouping_.groupMode_ == TeRasterSlicing)
00320         {
00321                 int b = atoi(grouping_.groupAttribute_.name_.c_str());
00322                 if (!layer_->raster() ||
00323                         b < 0 ||
00324                         b > layer_->raster()->params().nBands() ||
00325                         grouping_.groupNumSlices_ <= 0)
00326                         return false;
00327 
00328                 if (grouping_.groupMaxVal_ == TeMINFLOAT)
00329                         grouping_.groupMaxVal_ = layer_->raster()->params().vmax_[b];
00330 
00331                 if (grouping_.groupMinVal_ == TeMAXFLOAT)
00332                         grouping_.groupMinVal_ = layer_->raster()->params().vmin_[b];
00333 
00334                 TeGroupByEqualStep(grouping_.groupMinVal_, grouping_.groupMaxVal_,
00335                         grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00336         }
00337         else
00338         {
00339         if(grouping_.groupAttribute_.name_.empty())
00340                         return false;
00341 
00342                 //verify what the objects will be considered
00343                 string  input;
00344                 if(selectedObjects == TeSelectedByPointing)
00345                 {
00346                         input = " WHERE (grid_status = 1 OR grid_status = 3";
00347                         input += " OR (grid_status is null AND (c_object_status = 1 OR c_object_status = 3)))";
00348                 }
00349                 else if(selectedObjects == TeNotSelectedByPointing)
00350                 {
00351                         input = " WHERE (grid_status = 0 OR grid_status = 2";
00352                         input += " OR (grid_status is null AND (c_object_status = 0 OR c_object_status = 2)))";
00353                 }
00354                 else if(selectedObjects == TeSelectedByQuery)
00355                 {
00356                         input = " WHERE (grid_status = 2 OR grid_status = 3";
00357                         input += " OR (grid_status is null AND (c_object_status = 2 OR c_object_status = 3)))";
00358                 }
00359                 else if(selectedObjects == TeNotSelectedByQuery)
00360                 {
00361                         input = " WHERE (grid_status = 0 OR grid_status = 1";
00362                         input += " OR (grid_status is null AND (c_object_status = 0 OR c_object_status = 1)))";
00363                 }
00364                 else if(selectedObjects == TeGrouped)
00365                 {
00366                         input = " WHERE c_legend_id <> 0";
00367                 }
00368                 else if(selectedObjects == TeNotGrouped)
00369                 {
00370                         input = " WHERE c_legend_id = 0";
00371                 }
00372 
00373                 TeDatabasePortal* portal = db->getPortal();
00374                 string query;
00375                 bool normal = false;
00376                 string aggrFunc = "";
00377                 if(grouping_.groupFunction_.empty())
00378                         aggrFunc = " MIN";
00379                 else
00380                         aggrFunc = grouping_.groupFunction_;
00381 
00382                 if(grouping_.groupNormAttribute_.empty())
00383                 {
00384                         query = " SELECT "+ aggrFunc +"("+ grouping_.groupAttribute_.name_ +")";
00385                 }
00386                 else
00387                 {
00388                         query = " SELECT "+ aggrFunc +"("+ grouping_.groupAttribute_.name_ +") / "+ aggrFunc +"("+ grouping_.groupNormAttribute_ + ")";
00389                         normal = true;
00390                 }
00391                 query += sqlGridFrom();
00392 
00393                 if(selectedObjects != TeAll)
00394                         query += input;
00395                 query += " GROUP BY " + collectionTable() + ".c_object_id";
00396                 if(!portal->query(query) || !portal->fetchRow())
00397                 {
00398                         delete portal;
00399                         return false;
00400                 }
00401                 vector<double> dValues;  //inputvect
00402                 vector<string> sValues; //svec
00403                 double mean, sum;
00404                 mean = sum = 0.;
00405                 do
00406                 {
00407                         string val = portal->getData(0);
00408                         string valNorm = Te2String(atof(val.c_str()), grouping_.groupPrecision_);
00409 
00410                         if (!val.empty())
00411                         {
00412                                 if(grouping_.groupMode_== TeUniqueValue)
00413                                 {
00414                                         if(normal)
00415                                                 sValues.push_back(valNorm);
00416                                         else
00417                                                 sValues.push_back(val);
00418                                 }
00419                                 else
00420                                 {
00421                                         dValues.push_back(atof(valNorm.c_str()));
00422                                         sum += atof(valNorm.c_str());
00423                                 }
00424 
00425                         }
00426                         else
00427                                 nullValues++;
00428                 }while(portal->fetchRow());
00429 
00430                 delete portal;
00431 
00432                 if(dValues.empty() && sValues.empty())
00433                         return false;
00434 
00435                 if(grouping_.groupMode_== TeEqualSteps)
00436                         TeGroupByEqualStep(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00437                 else if(grouping_.groupMode_== TeQuantil)
00438                         TeGroupByQuantil(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00439                 else if(grouping_.groupMode_== TeStdDeviation)
00440                 {
00441                         string m = Te2String(mean);
00442                         TeGroupByStdDev(dValues.begin(), dValues.end(), grouping_.groupStdDev_, slices, m, grouping_.groupPrecision_);
00443                 }
00444                 else if(grouping_.groupMode_== TeUniqueValue)
00445                 {
00446                         if(grouping_.groupFunction_ == "COUNT")
00447                                 TeGroupByUniqueValue(sValues, TeINT, slices, grouping_.groupPrecision_);
00448                         else
00449                                 TeGroupByUniqueValue(sValues, grouping_.groupAttribute_.type_, slices, grouping_.groupPrecision_);
00450                 }
00451 
00452                 if (dValuesVec)
00453                 {
00454                         for (i = 0; i < dValues.size(); ++i)
00455                                 dValuesVec->push_back(dValues[i]);
00456                 }
00457         }
00458         if(grouping_.groupNullAttr_ && nullValues > 0)
00459         {
00460                 TeSlice ps;
00461                 ps.count_ = nullValues;
00462                 ps.from_ = "Missing Data";
00463                 slices.push_back(ps);
00464                 grouping_.groupNumSlices_ = slices.size() - 1;
00465         }
00466         else
00467                 grouping_.groupNumSlices_ = slices.size();
00468 
00469         legend_.clear();
00470         for(i=0; i<slices.size(); ++i)
00471         {
00472                 TeLegendEntry legend(slices[i]);
00473                 legend.group(i);
00474                 legend.theme(id());
00475                 legend_.push_back(legend);
00476         }
00477         return true;
00478 }
00479 
00480 bool
00481 TeTheme::buildGrouping(const TeGrouping& g, TeChronon chr, vector<map<string, string> >& mapObjValVec)
00482 {
00483         return buildGrouping(layer_->database(), g, chr, mapObjValVec);
00484 }
00485 
00486 bool
00487 TeTheme::buildGrouping(TeDatabase* db, const TeGrouping& g, TeChronon chr, vector<map<string, string> >& mapObjValVec)
00488 {
00489         if(!db || chr == TeNOCHRONON)
00490                 return false;
00491 
00492         grouping_ = g;
00493 
00494         unsigned int i;
00495         vector<TeSlice> slices;
00496         vector<double> dValues;  //inputvect
00497         vector<string> sValues; //svec
00498         double mean, sum;
00499         mean = sum = 0.;
00500         int     nullValues = 0;
00501         string val;
00502 
00503         if (grouping_.groupMode_ == TeRasterSlicing)
00504         {
00505                 int b = atoi(grouping_.groupAttribute_.name_.c_str());
00506                 if (!layer_->raster() ||
00507                         b < 0 ||
00508                         b > layer_->raster()->params().nBands() ||
00509                         grouping_.groupNumSlices_ <= 0)
00510                         return false;
00511 
00512                 if (grouping_.groupMaxVal_ == TeMINFLOAT)
00513                         grouping_.groupMaxVal_ = layer_->raster()->params().vmax_[b];
00514 
00515                 if (grouping_.groupMinVal_ == TeMAXFLOAT)
00516                         grouping_.groupMinVal_ = layer_->raster()->params().vmin_[b];
00517 
00518                 TeGroupByEqualStep(grouping_.groupMinVal_, grouping_.groupMaxVal_,
00519                         grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00520         }
00521         else
00522         {
00523                 string func;
00524                 TeStatisticType statType = TeNOSTATISTIC;
00525                 if (grouping_.groupMode_ == TeUniqueValue && grouping_.groupAttribute_.type_ == TeSTRING)
00526                         func = "MIN";
00527                 else
00528                         func = grouping_.groupFunction_;
00529 
00530                 if (func == "MIN")
00531                         statType = TeMINVALUE;
00532                 else if (func == "MAX")
00533                         statType = TeMAXVALUE;
00534                 else if (func == "MEAN")
00535                         statType = TeMEAN;
00536                 else if (func == "SUM")
00537                         statType = TeSUM;
00538                 else if (func == "COUNT")
00539                         statType = TeCOUNT;
00540 
00541                 // Set the flag that indicates the geometries must not be loaded
00542                 bool loadGeometries = false;
00543 
00544                 // Insert the attributes in a multimap that relates the attribute
00545                 // representation and its statistic type
00546                 TeGroupingAttr attrMMap;
00547                 pair<TeAttributeRep, TeStatisticType> attr1 (
00548                         TeAttributeRep(grouping_.groupAttribute_), statType);
00549                 attrMMap.push_back(attr1);
00550 
00551                 // Set querier parameters
00552                 TeQuerierParams querierParams(loadGeometries, attrMMap);
00553                 querierParams.setParams(this, chr);
00554 
00555                 TeQuerier querier(querierParams);
00556 
00557                 // Load instances based on the querier parameters given
00558                 int numFrames = querier.getNumTimeFrames();
00559                 TeSTInstance sti;
00560                 string objId;
00561                 TePropertyVector vec;
00562                 mapObjValVec.resize(numFrames);
00563 
00564                 for (int frame = 0; frame < numFrames; ++frame)
00565                 {
00566                         if (querier.loadInstances(frame) == false)
00567                                 continue;
00568 
00569                         // Traverse all the instances
00570                         while(querier.fetchInstance(sti))
00571                         {
00572                                 objId = sti.objectId();
00573                                 sti.getPropertyValue(val, 0);
00574 
00575                                 dValues.push_back(atof(val.c_str()));
00576                                 sValues.push_back(val);
00577                                 map<string, string>& objValMap = mapObjValVec[frame];
00578                                 objValMap.insert(make_pair(objId, val));
00579                         }
00580                 }
00581 
00582                 if(grouping_.groupMode_== TeEqualSteps)
00583                         TeGroupByEqualStep(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00584                 else if(grouping_.groupMode_== TeQuantil)
00585                         TeGroupByQuantil(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00586                 else if(grouping_.groupMode_== TeStdDeviation)
00587                 {
00588                         string m = Te2String(mean);
00589                         TeGroupByStdDev(dValues.begin(), dValues.end(), grouping_.groupStdDev_, slices, m, grouping_.groupPrecision_);
00590                 }
00591                 else if(grouping_.groupMode_== TeUniqueValue)
00592                 {
00593                         if(grouping_.groupFunction_ == "COUNT")
00594                                 TeGroupByUniqueValue(sValues, TeINT, slices, grouping_.groupPrecision_);
00595                         else
00596                                 TeGroupByUniqueValue(sValues, grouping_.groupAttribute_.type_, slices, grouping_.groupPrecision_);
00597                 }
00598         }
00599 
00600         if(grouping_.groupNullAttr_ && nullValues > 0)
00601         {
00602                 TeSlice ps;
00603                 ps.count_ = nullValues;
00604                 ps.from_ = "Missing Data";
00605                 slices.push_back(ps);
00606                 grouping_.groupNumSlices_ = slices.size() - 1;
00607         }
00608         else
00609                 grouping_.groupNumSlices_ = slices.size();
00610 
00611         legend_.clear();
00612         for(i=0; i<slices.size(); ++i)
00613         {
00614                 TeLegendEntry legend(slices[i]);
00615                 legend.group(i);
00616                 legend.theme(id());
00617                 legend_.push_back(legend);
00618         }
00619 
00620         return true;
00621 }
00622 
00623 bool
00624 TeTheme::getAttTables(TeAttrTableVector& attrs, TeAttrTableType attType)
00625 {
00626         TeAttrTableVector::iterator it = attTableVector_.begin();
00627         while (it != attTableVector_.end())
00628         {
00629                 if ((attType == TeAllAttrTypes) || ((*it).tableType() == attType))
00630                         attrs.push_back((*it));
00631                 ++it;
00632         }
00633         return (!attrs.empty());
00634 }
00635 
00636 bool
00637 TeTheme::getTable(TeTable& table, const string tableName)
00638 {
00639         unsigned int i;
00640         for (i = 0; i < attTableVector_.size(); ++i)
00641         {
00642                 if (attTableVector_[i].name() == tableName)
00643                 {
00644                         table = attTableVector_[i];
00645                         return true;
00646                 }
00647         }
00648         return false;
00649 }
00650 
00651 bool
00652 TeTheme::getTemporalTable(TeTable& table)
00653 {
00654         TeAttrTableVector::iterator it = attTableVector_.begin();
00655         while (it != attTableVector_.end())
00656         {
00657                 if (((*it).tableType() == TeAttrEvent) || ((*it).tableType() == TeFixedGeomDynAttr))
00658                 {
00659                         table = (*it);
00660                         return true;
00661                 }
00662                 ++it;
00663         }
00664         return false;
00665 }
00666 
00667 bool
00668 TeTheme::saveGrouping(TeSelectedObjects selectedObjects)
00669 {
00670         return saveGrouping(layer_->database(), selectedObjects);
00671 }
00672 
00673 bool
00674 TeTheme::saveGrouping(TeDatabase* db, TeSelectedObjects)
00675 {
00676         if(!db)
00677                 return false;
00678 
00679         vector<TeLegendEntry> legVec = legend_;
00680 
00681         // Delete the theme grouping(if any) from the database
00682         if(db->deleteLegend(id()) == false)
00683                 return false;
00684 
00685         if(grouping_.groupMode_ == TeNoGrouping)
00686                 return true;
00687 
00688         // Insert the new grouping
00689         if(db->insertGrouping(id(), grouping_) == false)
00690                 return false;
00691 
00692         legend_ = legVec;
00693         // Update (insert) the new legends
00694         if (db->updateLegend(legend_) == false)
00695                 return false;
00696 
00697         setLegendsForObjects();
00698 
00699         if(legend_.size())
00700                 visibleRep_ = visibleRep_ | 0x40000000;
00701         else
00702                 visibleRep_ = visibleRep_ | 0xbfffffff;
00703         string upVis = "UPDATE te_theme SET visible_rep=" + Te2String(visibleRep_) + " WHERE theme_id=" + Te2String(id());
00704         return (db->execute(upVis));
00705 
00706         return true;
00707 }
00708 
00709 bool
00710 TeTheme::loadThemeTables()
00711 {
00712         clearAttTableVector();
00713         TeDatabase* db = this->layer()->database();
00714         if(!db)
00715                 return false;
00716         return (db->loadThemeTable(this));
00717 }
00718 
00719 bool
00720 TeTheme::addThemeTable(TeTable& inputTable)
00721 {
00722         bool result = true;
00723         TeAttrTableType type = inputTable.tableType();
00724 
00725         if(inputTable.name() == collectionAuxTable_)
00726         {
00727                 loadTablesJoin();
00728                 return false;
00729         }
00730 
00731         if (type == TeAttrMedia)
00732                 return false;
00733 
00734         if(type != TeAttrStatic)
00735         {
00736                 bool hasTemporal = false;
00737                 bool hasExtern = false;
00738 
00739                 TeAttrTableVector::iterator it = attTableVector_.begin();
00740                 while(it!=attTableVector_.end())
00741                 {
00742                         //temporal
00743                         if( (it->tableType()==TeAttrEvent) ||
00744                                 (it->tableType()==TeFixedGeomDynAttr) ||
00745                                 (it->tableType()==TeDynGeomDynAttr))
00746                                 hasTemporal = true;
00747 
00748                         //extern
00749                         if((it->tableType())==TeAttrExternal)
00750                                 hasExtern = true;
00751 
00752                         ++it;
00753                 }
00754 
00755                 if( ((type==TeAttrEvent) ||
00756                         (type==TeFixedGeomDynAttr) ||
00757                         (type==TeDynGeomDynAttr)) && (hasTemporal || hasExtern))
00758                         result = false;
00759                 else if ((type==TeAttrExternal) && hasTemporal)
00760                         result = false;
00761         }
00762 
00763         if(!result)
00764                 return false;
00765 
00766         attTableVector_.push_back(inputTable);
00767         loadAliasVector();
00768         loadAttrLists();
00769         loadTablesJoin();
00770         return true;
00771 }
00772 
00773 void
00774 TeTheme::addThemeTable(string tableName)
00775 {
00776         TeTable table(tableName);
00777         addThemeTable(table);
00778 }
00779 
00780 bool
00781 TeTheme::setAttTables(TeAttrTableVector& attrs)
00782 {
00783         attTableVector_.clear();
00784         int countTemporal = 0;
00785         int countExtern = 0;
00786         bool result = true;
00787 
00788         TeAttrTableVector::iterator it = attrs.begin();
00789         while(it!=attrs.end())
00790         {
00791                 //temporal
00792                 if( (it->tableType()==TeAttrEvent) ||
00793                         (it->tableType()==TeFixedGeomDynAttr) ||
00794                         (it->tableType()==TeDynGeomDynAttr))
00795                         ++countTemporal;
00796 
00797                 //extern
00798                 if(it->tableType()==TeAttrExternal)
00799                         ++countExtern;
00800 
00801                 if( (it->tableType()==TeAttrMedia)     ||
00802                         (countTemporal>0 && countExtern>0) ||
00803                         (countTemporal>1) ||
00804                         (it->name() == collectionAuxTable_) )
00805                 {
00806                         result = false;
00807                 }
00808                 else
00809                 {
00810                         attTableVector_.push_back(*it);
00811                         loadAliasVector();
00812                         loadAttrLists();
00813                         loadTablesJoin();
00814                 }
00815                 ++it;
00816         }
00817         return result;
00818 }
00819 
00820 bool
00821 TeTheme::removeThemeTable(unsigned int index)
00822 {
00823         if (index > (attTableVector_.size() - 1))
00824                 return false;
00825 
00826         TeAttrTableVector::iterator it;
00827         it = attTableVector_.begin() + index;
00828 
00829         attTableVector_.erase(it);
00830         loadAliasVector();
00831         loadAttrLists();
00832         loadTablesJoin();
00833         return true;
00834 }
00835 
00836 string
00837 TeTheme::getAttribute(unsigned int pos)
00838 {
00839         unsigned int i;
00840         unsigned int sumCols = 0, tableCol;
00841         bool found = false;
00842         for (i = 0; i < attTableVector_.size(); ++i)
00843         {
00844                 TeAttributeList& attrList = attTableVector_[i].attributeList();
00845                 if (pos < (sumCols + attrList.size()))
00846                 {
00847                         if (i == 0)
00848                                 tableCol = pos;
00849                         else
00850                                 tableCol = pos - sumCols;
00851                         found = true;
00852                         break;
00853                 }
00854                 sumCols += attrList.size();
00855         }
00856 
00857         if (found == false)
00858                 return "";
00859 
00860         TeAttributeList& attrList = attTableVector_[i].attributeList();
00861         string attrName = attTableVector_[i].name() + "." + attrList[tableCol].rep_.name_;
00862         return attrName;
00863 }
00864 
00865 bool
00866 TeTheme::isIndex(unsigned int pos)
00867 {
00868         string fullAttrName = getAttribute(pos);
00869         if (fullAttrName.empty() == true)
00870                 return false;
00871 
00872         size_t idx = fullAttrName.find(".");
00873         string tableName = fullAttrName.substr(0, idx);
00874         string attrName = fullAttrName.substr(idx+1);
00875 
00876         // Get the representation of a table given an attribute name
00877         TeTable table;
00878         if (getTable(table, tableName) == false)
00879                 return false;
00880 
00881         // Check if the attribute is index or not
00882         if(table.uniqueName() == attrName)
00883                 return true;
00884 
00885         return false;
00886 }
00887 
00888 bool
00889 TeTheme::isThemeTable(int tableId)
00890 {
00891         bool isThemeTable = false;
00892         unsigned int i;
00893         for (i = 0; i < attTableVector_.size(); ++i)
00894         {
00895                 if (attTableVector_[i].id() == tableId)
00896                 {
00897                         isThemeTable = true;
00898                         break;
00899                 }
00900         }
00901         return isThemeTable;
00902 }
00903 
00904 bool
00905 TeTheme::isThemeTable(string tableName)
00906 {
00907         bool isThemeTable = false;
00908         for (unsigned int i = 0; i < attTableVector_.size(); ++i)
00909         {
00910                 if (attTableVector_[i].name() == tableName)
00911                 {
00912                         isThemeTable = true;
00913                         break;
00914                 }
00915         }
00916         return isThemeTable;
00917 }
00918 
00919 string
00920 TeTheme::getTableName(const string& attrName)
00921 {
00922         string tableName;
00923         size_t pos = attrName.find(".");
00924 
00925         if (pos != string::npos)
00926                 return tableName = attrName.substr(0, pos);
00927 
00928         for (unsigned int i = 0; i < attTableVector_.size(); ++i)
00929         {
00930                 TeAttributeList& attrList = attTableVector_[i].attributeList();
00931                 for (unsigned j = 0; j < attrList.size(); ++j)
00932                 {
00933                         if (attrList[j].rep_.name_ == attrName)
00934                         {
00935                                 tableName = attTableVector_[i].name();
00936                                 return tableName;
00937                         }
00938                 }
00939         }
00940 
00941         return tableName;
00942 }
00943 
00944 
00945 bool
00946 TeTheme::deleteGrouping()
00947 {
00948         TeDatabase* db = layer_->database();
00949         if(!db)
00950                 return false;
00951 
00952         resetGrouping();
00953 
00954         //delete te_legend table
00955         if(!db->deleteLegend (this->id()))
00956                 return false;
00957 
00958         //delete te_grouping table
00959         string sql = "DELETE FROM te_grouping WHERE theme_id= "+ Te2String(this->id());
00960         db->execute (sql);
00961 
00962         return true;
00963 }
00964 
00965 bool
00966 TeTheme::createCollectionAuxTable()
00967 {
00968         return createCollectionAuxTable(layer_->database());
00969 }
00970 
00971 bool
00972 TeTheme::createCollectionAuxTable(TeDatabase* db)
00973 {
00974         unsigned int i, j;
00975         bool status;
00976         vector<string> indexes;
00977 
00978         if(!db)
00979                 return false;
00980 
00981         if(!db->tableExist(collectionTable_))
00982                 return false;
00983 
00984         if(db->tableExist(collectionAuxTable_))
00985         {
00986                 status = db->execute("DROP TABLE " + collectionAuxTable_);
00987                 if(db->tableExist(collectionAuxTable_))
00988                 {
00989                         if(!status)
00990                                 return false;
00991                 }
00992         }
00993 
00994         TeAttributeList attList;
00995 
00996         TeAttribute at;
00997         at.rep_.type_ = TeSTRING;
00998         at.rep_.numChar_ = 50;
00999         at.rep_.name_ = "object_id";
01000         attList.push_back(at);
01001 
01002         j = 0;
01003         for (i = 0; i < attTableVector_.size(); ++i)
01004         {
01005                 if (attTableVector_[i].tableType() == TeAttrExternal ||
01006                         attTableVector_[i].tableType() == TeFixedGeomDynAttr)
01007                 {
01008 //descobre o tipo do dado que sera linkado
01009                         for(unsigned int k = 0; k < attTableVector_[i].attributeList().size(); ++k)
01010                         {
01011                                 if(attTableVector_[i].attributeList()[k].rep_.name_ == attTableVector_[i].uniqueName())
01012                                 {
01013                                         at.rep_.type_ = attTableVector_[i].attributeList()[k].rep_.type_;
01014                                         at.rep_.numChar_ = attTableVector_[i].attributeList()[k].rep_.numChar_;
01015                                         break;
01016                                 }
01017                         }
01018 
01019                         at.rep_.name_ = "aux" + Te2String(j++);
01020                         attList.push_back(at);
01021                         indexes.push_back(at.rep_.name_);
01022                 }
01023         }
01024 
01025         at.rep_.isPrimaryKey_ = true;
01026         at.rep_.numChar_ = 0;
01027         at.rep_.name_ = "unique_id";
01028         at.rep_.isAutoNumber_ = true;
01029         at.rep_.type_ = TeINT;
01030         attList.push_back(at);
01031 
01032         at.rep_.name_ = "grid_status";
01033         at.rep_.isPrimaryKey_ = false;
01034         at.rep_.isAutoNumber_ = false;
01035         at.rep_.numChar_ = 0;
01036         attList.push_back(at);
01037 
01038         status = db->createTable(collectionAuxTable_, attList);
01039         if(!status)
01040                 return false;
01041 
01042         string idxName = "te_idx_caux"+ Te2String(this->id());
01043 
01044         //create index to object_id
01045         db->createIndex(collectionAuxTable_, idxName+"_objId", "object_id");
01046 
01047         for(unsigned int i=0; i<indexes.size(); ++i)
01048                 db->createIndex(collectionAuxTable_, idxName+"_"+indexes[i], indexes[i]);
01049 
01050         return true;
01051 }
01052 
01053 bool TeTheme::isUpdated()
01054 {
01055         if(layer() == NULL)
01056         {
01057                 return false;
01058         }
01059         layer()->reloadLayerEditionTime();
01060 
01061         if(this->getCreationTime() < layer()->getEditionTime())
01062         {
01063                 return false;
01064         }
01065         return true;
01066 }
01067 
01068 bool
01069 TeTheme::populateCollectionAux(std::string objectId)
01070 {
01071         TeDatabase* db = layer_->database();
01072         if((!db) || (collectionTable_.empty()) || (collectionAuxTable_.empty()))
01073                 return false;
01074 
01075         string whereClause;
01076 
01077         whereClause = " WHERE 1=1 ";
01078 
01079         // Populate the collection auxiliary table
01080         string ins = "INSERT INTO " + collectionAuxTable_ + " (object_id";
01081     unsigned int i, j;
01082         j = 0;
01083         for (i = 0; i < attTableVector_.size(); ++i)
01084         {
01085                 if (attTableVector_[i].tableType() == TeAttrExternal ||
01086                         attTableVector_[i].tableType() == TeFixedGeomDynAttr)
01087                         ins += ", aux" + Te2String(j++);
01088         }
01089 
01090         ins += ", grid_status) SELECT c_object_id";
01091         for (i = 0; i < attTableVector_.size(); ++i)
01092         {
01093                 if (attTableVector_[i].tableType() == TeAttrExternal ||
01094                         attTableVector_[i].tableType() == TeFixedGeomDynAttr)
01095                         ins += "," + aliasVector()[i] + "." + attTableVector_[i].uniqueName();
01096         }
01097 
01098         ins += ",c_object_status";
01099 
01100         //attribute restriction
01101         if(!generateAttributeRest_.empty())
01102                 whereClause += " AND "+ generateAttributeRest_;
01103 
01104         //temporal restriction
01105         if(!generateTemporalRest_.empty())
01106         {
01107                 string sqlTemp;
01108                 initParse(generateTemporalRest_, db);
01109 
01110                 if(!yyparse(sqlTemp))  //0: accept  1: reject
01111                         whereClause += " AND "+ sqlTemp;
01112                 else
01113                         return false;
01114         }
01115 
01116         //spatial restriction is already stored in the collection table
01117 
01118         bool usaTemporal = false;
01119         for (i = 0; i < attTableVector_.size(); ++i)
01120         {
01121                 if (attTableVector_[i].tableType() == TeFixedGeomDynAttr ||
01122                         attTableVector_[i].tableType() == TeDynGeomDynAttr)
01123                         usaTemporal = true;
01124         }
01125         loadThemeTablesJoin();
01126         string result = "";
01127         if(!generateAttributeRest_.empty() || !generateTemporalRest_.empty() || attTableVector_.size() > 1)
01128         {
01129                 result = ins + sqlFrom() + whereClause + " ";
01130         }
01131         else
01132         {
01133                 result = ins + " FROM " + collectionTable() + " " + whereClause + " ";
01134         }
01135         if (!objectId.empty() && !whereClause.empty())
01136                 result += " AND c_object_id = '"+objectId+"'";
01137         if (!db->execute(result))
01138                 return false;
01139 
01140         if(usaTemporal) // filter collection table
01141         {
01142                 string s = "DELETE FROM " + collectionTable_ + " WHERE c_object_id NOT IN";
01143                 s += " (SELECT DISTINCT object_id FROM " + collectionAuxTable_ + ")";
01144                 return(db->execute(s));
01145         }
01146         return true;
01147 }
01148 
01149 
01150 bool
01151 TeTheme::locatePolygon (TeCoord2D &pt, TePolygon &polygon, const double& tol)
01152 {
01153         if (!layer()->database() || collectionTable().empty())
01154                 return false;
01155 
01156         string geomTable = layer()->tableName(TePOLYGONS);
01157         string sqlFrom = " "+ geomTable +" INNER JOIN " + collectionTable();
01158         sqlFrom += " ON "+ collectionTable() +".c_object_id = "+ geomTable +".object_id ";
01159 
01160         if(!layer()->database()->locatePolygon(sqlFrom, pt, polygon, tol))
01161                 return false;
01162 
01163         return true;
01164 }
01165 
01166 
01167 bool
01168 TeTheme::locatePolygonSet (TeCoord2D &pt, double tol, TePolygonSet &polygons)
01169 {
01170         if (!layer()->database() || collectionTable().empty())
01171                 return false;
01172 
01173         string geomTable = layer()->tableName(TePOLYGONS);
01174         string sqlFrom = " "+ geomTable +" INNER JOIN " + collectionTable();
01175         sqlFrom += " ON "+ collectionTable() +".c_object_id = "+ geomTable +".object_id ";
01176 
01177         if(!layer()->database()->locatePolygonSet(sqlFrom, pt, tol, polygons))
01178                 return false;
01179 
01180         return true;
01181 }
01182 
01183 bool
01184 TeTheme::locateLine (TeCoord2D &pt, TeLine2D &line, const double& tol)
01185 {
01186         if (!layer()->database() || collectionTable().empty())
01187                 return false;
01188 
01189         string geomTable = layer()->tableName(TeLINES);
01190         string sqlFrom = " "+ geomTable +" INNER JOIN " + collectionTable();
01191         sqlFrom += " ON "+ collectionTable() +".c_object_id = "+ geomTable +".object_id ";
01192 
01193         if(!layer()->database()->locateLine(sqlFrom, pt, line, tol))
01194                 return false;
01195 
01196         return true;
01197 }
01198 
01199 bool
01200 TeTheme::locatePoint (TeCoord2D &pt, TePoint &point, const double& tol)
01201 {
01202         if (!layer()->database() || collectionTable().empty())
01203                 return false;
01204 
01205         string geomTable = layer()->tableName(TePOINTS);
01206         string sqlFrom = " "+ geomTable +" INNER JOIN " + collectionTable();
01207         sqlFrom += " ON "+ collectionTable() +".c_object_id = "+ geomTable +".object_id ";
01208 
01209         if(!layer()->database()->locatePoint(sqlFrom, pt, point, tol))
01210                 return false;
01211 
01212         return true;
01213 }
01214 
01215 bool
01216 TeTheme::locateCell (TeCoord2D &pt, TeCell &cell, const double&  tol)
01217 {
01218         if (!layer()->database() || collectionTable().empty())
01219                 return false;
01220 
01221         string geomTable = layer()->tableName(TeCELLS);
01222         string sqlFrom = " "+ geomTable +" INNER JOIN " + collectionTable();
01223         sqlFrom += " ON "+ collectionTable() +".c_object_id = "+ geomTable +".object_id ";
01224 
01225         if(!layer()->database()->locateCell(sqlFrom, pt, cell, tol))
01226                 return false;
01227 
01228         return true;
01229 }
01230 
01231 //------------------------------ protected methods
01232 void
01233 TeTheme::loadAliasVector()
01234 {
01235         unsigned int i, count;
01236         TeTable table;
01237         multimap<string, int> tableMMap;
01238 
01239         aliasVector_.clear();
01240 
01241         for (i = 0; i < attTableVector_.size(); ++i)
01242         {
01243                 table = attTableVector_[i];
01244 
01245                 if (table.tableType() != TeAttrExternal)
01246                         aliasVector_.push_back(table.name());
01247                 else
01248                 {
01249                         count = tableMMap.count(table.name());
01250                         if (count == 0)
01251                                 aliasVector_.push_back(table.name());
01252                         else
01253                                 aliasVector_.push_back(table.name() + "_" + Te2String(count));
01254 
01255                         tableMMap.insert(multimap<string,int>::value_type(table.name(), ++count));
01256                 }
01257         }
01258 }
01259 
01260 string
01261 TeTheme::sqlGridFrom(const string& geomTable)
01262 {
01263         if(geomTable.empty())
01264                 return sqlGridFrom_;
01265 
01266         string result;
01267         loadTablesJoin(geomTable);
01268         result = sqlGridFrom_;
01269         loadTablesJoin();
01270         return result;
01271 }
01272 
01273 bool
01274 TeTheme::generateLabelPositions(const std::string& objectId)
01275 {
01276         TeDatabase* db = layer()->database();
01277         if(!db)
01278                 return false;
01279 
01280         return (db->generateLabelPositions(this, objectId));
01281 }
01282 
01283 void
01284 TeTheme::loadTablesJoin(const string& geomTable)  //sqlGridFrom and sqlGridJoin
01285 {
01286         unsigned int i, count;
01287         multimap<string, int> tableMMap;
01288     TeTable table;
01289     bool hasExternalTable = false;
01290 
01291     // Set the new sqlGridFrom_ clause and the new sqlGridJoin_ string
01292     sqlGridFrom_.clear();
01293     sqlGridJoin_.clear();
01294 
01295     TeAttrTableVector tableVec;
01296     vector<string>    aliasVec;
01297 
01298     if(!geomTable.empty())
01299     {
01300         TeTable table;
01301         table.name(geomTable);
01302         table.setLinkName("object_id");
01303         table.setUniqueName("object_id");
01304         table.setTableType(TeAttrStatic);
01305         tableVec.push_back(table);
01306 
01307         for(i=0; i<attTableVector_.size(); ++i)
01308             tableVec.push_back(attTableVector_[i]);
01309 
01310         aliasVec.push_back(geomTable);
01311         for(i=0; i<aliasVector_.size(); ++i)
01312             aliasVec.push_back(aliasVector_[i]);
01313     }
01314     else
01315     {
01316         tableVec = attTableVector_;
01317         aliasVec = aliasVector_;
01318     }
01319 
01320     //verify if there is external table
01321     for (i = 0; i < tableVec.size(); ++i)
01322     {
01323         if (tableVec[i].tableType() == TeAttrExternal)
01324         {
01325             hasExternalTable = true;
01326             break;
01327         }
01328     }
01329 
01330     if(!collectionAuxTable_.empty())
01331     {
01332         sqlGridFrom_ = " FROM ";
01333 
01334         for (i = 0; i <= tableVec.size(); ++i)
01335             sqlGridFrom_ += "(";
01336 
01337         sqlGridFrom_ += collectionAuxTable_;
01338         sqlGridJoin_ = "SELECT ";
01339 
01340         if(hasExternalTable)
01341             sqlGridFrom_ += " RIGHT JOIN "+ collectionTable_;
01342         else
01343             sqlGridFrom_ += " LEFT JOIN "+ collectionTable_;
01344 
01345         sqlGridFrom_ += " ON "+ collectionAuxTable_ +".object_id = "+ collectionTable_ +".c_object_id )";
01346 
01347         int numAux = 0;
01348         for (i = 0; i < tableVec.size(); ++i)
01349         {
01350             table = tableVec[i];
01351             if ((table.tableType()==TeAttrStatic) || (table.tableType()==TeAttrMedia) || (table.tableType()==TeAttrEvent))
01352             {
01353                 sqlGridFrom_ += " LEFT JOIN " + aliasVec[i];
01354                 sqlGridFrom_ += " ON " + collectionTable_ +".c_object_id = " + aliasVec[i] + "." + table.linkName() +")";
01355             }
01356             else if (table.tableType() == TeAttrExternal)
01357             {
01358                                 count = tableMMap.count(table.name());
01359                                 if (count == 0)
01360                                         sqlGridFrom_ += " LEFT JOIN " + aliasVec[i];
01361                                 else
01362                                         sqlGridFrom_ += " LEFT JOIN " + table.name() + " AS " + aliasVec[i];
01363 
01364                                 tableMMap.insert(multimap<string,int>::value_type(table.name(), ++count));
01365                 sqlGridFrom_ += " ON " + collectionAuxTable_ + ".aux" + Te2String(numAux++) +" = "+ aliasVec[i] +"."+ table.uniqueName() +")";
01366             }
01367             else
01368             {
01369                 sqlGridFrom_ += " LEFT JOIN " + aliasVec[i];
01370                 sqlGridFrom_ += " ON " + collectionAuxTable_ + ".aux" + Te2String(numAux++) +" = "+ aliasVec[i] +"."+ table.uniqueName() +")";
01371             }
01372 
01373             sqlGridJoin_ += aliasVec[i] + ".*,";
01374         }
01375 
01376         sqlGridJoin_ += collectionTable_ + ".*, " +  collectionAuxTable_ + ".* " + sqlGridFrom_;
01377     }
01378 
01379         loadThemeTablesJoin();
01380  }
01381 
01382 void TeTheme::loadThemeTablesJoin()  ////sqlJoin and sqlFrom
01383 {
01384         unsigned int i, count;
01385         multimap<string, int> tableMMap;
01386         TeTable table;
01387 
01388         // Set the new from clause and the new join string
01389         sqlFrom_.clear();
01390         sqlJoin_.clear();
01391 
01392         sqlFrom_ = " FROM ";
01393         sqlJoin_ = "SELECT ";
01394 
01395         if (collectionTable_.empty() == false)
01396         {
01397                 for (i = 0; i < attTableVector_.size(); ++i)
01398                         sqlFrom_ += "(";
01399                 sqlFrom_ += collectionTable_;
01400 
01401                 for (i = 0; i < attTableVector_.size(); ++i)
01402                 {
01403                         table = attTableVector_[i];
01404                         if (table.tableType() != TeAttrExternal)
01405                         {
01406                                 sqlFrom_ += " LEFT JOIN " + aliasVector_[i];
01407                                 sqlFrom_ += " ON " + collectionTable_ + ".c_object_id = " + aliasVector_[i] + "." + table.linkName() + ")";
01408                         }
01409                         else
01410                         {
01411                                 count = tableMMap.count(table.name());
01412                                 if (count == 0)
01413                                         sqlFrom_ += " LEFT JOIN " + aliasVector_[i];
01414                                 else
01415                                         sqlFrom_ += " LEFT JOIN " + table.name() + " AS " + aliasVector_[i];
01416 
01417                                 tableMMap.insert(multimap<string,int>::value_type(table.name(), ++count));
01418 
01419                                 sqlFrom_ += " ON " + table.relatedTableName() + "." + table.relatedAttribute() + " = ";
01420                                 sqlFrom_ +=  aliasVector_[i] + "." + table.linkName() + ")";
01421                         }
01422 
01423                         sqlJoin_ += aliasVector_[i] + ".*,";
01424                 }
01425 
01426                 sqlJoin_ += collectionTable_ + ".*" + sqlFrom_;
01427         }
01428         else
01429         {
01430                 if (attTableVector_.size() == 1)
01431                 {
01432                         table = attTableVector_[0];
01433                         sqlFrom_ += table.name();
01434                         sqlJoin_ = "SELECT " + table.name() + ".*" + sqlFrom_;
01435                 }
01436                 else
01437                 {
01438                         for (i = 0; i < attTableVector_.size() - 1; ++i)
01439                                 sqlFrom_ += "(";
01440 
01441                         TeTable firstTable = attTableVector_[0];
01442                         sqlFrom_ += firstTable.name();
01443                         sqlJoin_ += firstTable.name() + ".*,";
01444                         for (i = 1; i < attTableVector_.size(); ++i)
01445                         {
01446                                 table = attTableVector_[i];
01447                                 sqlFrom_ += " LEFT JOIN " + aliasVector_[i];
01448                                 sqlFrom_ += " ON " + firstTable.name() + "." + firstTable.linkName() + " = " + aliasVector_[i] + "." + table.linkName() + ")";
01449 
01450                                 if (i == attTableVector_.size() - 1)
01451                                         sqlJoin_ += aliasVector_[i] + ".*";
01452                                 else
01453                                         sqlJoin_ += aliasVector_[i] + ".*,";
01454                         }
01455 
01456                         sqlJoin_ += sqlFrom_;
01457                 }
01458         }
01459         return;
01460 }
01461 
01462 void
01463 TeTheme::loadAttrLists()
01464 {
01465         // Set the new list of attributes of all the theme tables and its new numerical list,
01466         unsigned int i, j, count;
01467         TeTable table;
01468         multimap<string, int> attrMMap;
01469         string attrName;
01470 
01471         sqlAttList_.clear();
01472         sqlNumAttList_.clear();
01473 
01474         if (layer() == 0)
01475                 return;
01476         TeDatabase *db = layer()->database();
01477 
01478         for (i = 0; i < attTableVector_.size(); ++i)
01479         {
01480                 table = attTableVector_[i];
01481                 // Set the map of attribute names
01482                 if(table.attributeList().empty())
01483                         db->getAttributeList(table.name(), table.attributeList());
01484 
01485                 for (j = 0; j < table.attributeList().size(); ++j)
01486                 {
01487                         attrName = table.attributeList()[j].rep_.name_;
01488                         count = attrMMap.count(attrName);
01489                         attrMMap.insert(multimap<string,int>::value_type(attrName, ++count));
01490                 }
01491         }
01492 
01493         // Set the list of attribute names that contains all the attribute names
01494         // of the theme tables
01495         for (i = 0; i < attTableVector_.size(); ++i)
01496         {
01497                 table = attTableVector_[i];
01498                 TeAttributeList attrList=table.attributeList();
01499                 if(attrList.empty())
01500                         db->getAttributeList(table.name(), attrList);
01501                 for (j = 0; j < attrList.size(); ++j)
01502                 {
01503                         attrName = attrList[j].rep_.name_;
01504                         count = attrMMap.count(attrName);
01505                         if (count == 1)
01506                                 attrList[j].rep_.name_ = attrName;
01507                         else
01508                                 attrList[j].rep_.name_ = aliasVector_[i] + "." + attrName;
01509 
01510                         sqlAttList_.push_back(attrList[j]);
01511                 }
01512         }
01513 
01514         // Set the list of attribute names that contains all the numeric attribute names
01515         // of the theme tables
01516         for(i = 0; i < sqlAttList_.size(); ++i)
01517         {
01518                 if(sqlAttList_[i].rep_.type_ == TeREAL || sqlAttList_[i].rep_.type_ == TeINT)
01519                         sqlNumAttList_.push_back(sqlAttList_[i]);
01520         }
01521 }
01522 
01523 void
01524 TeTheme::setLegendsForObjects()
01525 {
01526         if(grouping_.groupMode_ == TeNoGrouping || attTableVector_.empty())
01527                 return;
01528 
01529         unsigned int i, j;
01530         string func, query, oid, val;
01531 
01532         TeDatabase *db = layer_->database();
01533         TeDatabasePortal* portal = db->getPortal();
01534 
01535         TeAttrDataType type = grouping_.groupAttribute_.type_;
01536         string  groupingAttr = grouping_.groupAttribute_.name_;
01537 
01538         vector<string> oidVec;
01539         vector<string> oidWithNullValVec;
01540         vector<string> valVec;
01541         map<int, set<string> > legObjSetMap;
01542 
01543         objLegendMap_.clear();
01544 
01545         if(grouping_.groupFunction_.empty())
01546                 func = "MIN";
01547         else
01548                 func = grouping_.groupFunction_;
01549 
01550         if(grouping_.groupFunction_ == "COUNT")
01551                 type = TeINT;
01552 
01553         query = "SELECT MIN(" + attTableVector_[0].uniqueName() + ")";
01554         query += ", " + func + "(" + groupingAttr + ")" + sqlFrom_;
01555         query += " GROUP BY " + attTableVector_[0].uniqueName();
01556 
01557         if(portal->query(query) == false)
01558         {
01559                 delete portal;
01560                 return;
01561         }
01562 
01563         while(portal->fetchRow())
01564         {
01565                 oid = portal->getData(0);
01566                 val = portal->getData(1);
01567                 if (val.empty() == false)
01568                 {
01569                         oidVec.push_back(oid);
01570                         valVec.push_back(val);
01571                 }
01572                 else
01573                         oidWithNullValVec.push_back(oid);
01574         }
01575 
01576         unsigned int legSize = legend_.size();
01577         if(grouping_.groupNullAttr_ && oidWithNullValVec.size() > 0)
01578                 --legSize;
01579 
01580         if (grouping_.groupMode_ == TeUniqueValue)
01581         {
01582                 for (i = 0; i < oidVec.size(); ++i)
01583                 {
01584                         oid = oidVec[i];
01585                         val = valVec[i];
01586 
01587                         if(type == TeREAL)
01588                                 val = Te2String(atof(val.c_str()), grouping_.groupPrecision_);
01589                         else if(type == TeINT)
01590                                 val = Te2String(atoi(val.c_str()));
01591 
01592                         for(j = 0; j < legSize; ++j)
01593                         {
01594                                 TeLegendEntry& leg = legend_[j];
01595                                 if(val == leg.from())
01596                                 {
01597                                         objLegendMap_[oid] = leg.id();
01598                                         set<string>& oidSet = legObjSetMap[leg.id()];
01599                                         oidSet.insert(oid);
01600                                         break;
01601                                 }
01602                         }
01603                 }
01604         }
01605         else
01606         {
01607                 for (i = 0; i < oidVec.size(); ++i)
01608                 {
01609                         double dVal, dFrom, dTo;
01610                         oid = oidVec[i];
01611                         val = valVec[i];
01612 
01613                         if (type == TeREAL)
01614                                 val = Te2String(atof(val.c_str()), grouping_.groupPrecision_);
01615 
01616                         for (j = 0; j < legSize; ++j)
01617                         {
01618                                 TeLegendEntry& leg = legend_[j];
01619                                 if (leg.from().find("mean") != string::npos)
01620                                         continue;
01621 
01622                                 dVal  = atof(val.c_str());
01623                                 dFrom = atof(leg.from().c_str());
01624                                 dTo = atof(leg.to().c_str());
01625 
01626                                 if (j < (legSize - 1))
01627                                 {
01628                                         if(dVal >= dFrom && dVal < dTo)
01629                                         {
01630                                                 objLegendMap_[oid] = leg.id();
01631                                                 set<string>& oidSet = legObjSetMap[leg.id()];
01632                                                 oidSet.insert(oid);
01633                                                 break;
01634                                         }
01635                                 }
01636                                 else
01637                                 {
01638                                         if(dVal >= dFrom && dVal <= dTo)
01639                                         {
01640                                                 objLegendMap_[oid] = leg.id();
01641                                                 set<string>& oidSet = legObjSetMap[leg.id()];
01642                                                 oidSet.insert(oid);
01643                                                 break;
01644                                         }
01645                                 }
01646                         }
01647                 }
01648         }
01649         delete portal;
01650 
01651         // Set the leg id for the objects with null values
01652         int legId = defaultLegend_.id();
01653         if (grouping_.groupNullAttr_)
01654                 legId = legend_[legend_.size() - 1].id();
01655 
01656         for (i = 0; i < oidWithNullValVec.size(); ++i)
01657         {
01658                 oid = oidWithNullValVec[i];
01659                 objLegendMap_[oid] = legId;
01660                 set<string>& oidSet = legObjSetMap[legId];
01661                 oidSet.insert(oid);
01662         }
01663 
01664 /*
01665         // Insert the legends in the te_legend table
01666         map<int, set<string> >::iterator mapIt;
01667         set<string>::iterator setIt;
01668         unsigned char *data;
01669         string where = " theme_id = " + Te2String(id());
01670         for (mapIt = legObjSetMap.begin(); mapIt != legObjSetMap.end(); ++mapIt)
01671         {
01672                 legId = mapIt->first;
01673                 set<string>& oidSet = mapIt->second;
01674                 string whereClause = where;
01675                 whereClause +=  " AND legend_id = " + Te2String(legId);
01676                 string objStr;
01677                 for (setIt = oidSet.begin(); setIt != oidSet.end(); ++setIt)
01678                         objStr += *setIt + ';';
01679                 data = (unsigned char*)objStr.c_str();
01680                 db->insertBlob("te_legend", "object_list", whereClause, data, objStr.size());
01681         }
01682 */
01683 }
01684 
01685 void
01686 TeTheme::setOwnLegendsForObjects()
01687 {
01688 
01689 }
01690 
01691 bool
01692 TeTheme::saveLegendInCollection(TeSelectedObjects selectedObjects, std::string objectId)
01693 {
01694         return saveLegendInCollection(layer()->database(), selectedObjects, objectId);
01695 }
01696 
01697 bool
01698 TeTheme::saveLegendInCollection(TeDatabase* db, TeSelectedObjects selectedObjects, std::string objectId)
01699 {
01700         unsigned int i;
01701         if(!db || grouping_.groupMode_ == TeNoGrouping)
01702                 return false;
01703 
01704         TeAttrDataType          type = grouping_.groupAttribute_.type_;
01705         TeLegendEntryVector legVec = legend_;
01706         string                  groupingAttr = grouping_.groupAttribute_.name_;
01707 
01708         string input;
01709         if(selectedObjects == TeSelectedByPointing)
01710         {
01711                 input = " WHERE (grid_status = 1 OR grid_status = 3";
01712                 input += " OR (grid_status IS NULL AND (c_object_status = 1 OR c_object_status = 3)))";
01713         }
01714         else if(selectedObjects == TeNotSelectedByPointing)
01715         {
01716                 input = " WHERE (grid_status = 0 OR grid_status = 2";
01717                 input += " OR (grid_status is null AND (c_object_status = 0 OR c_object_status = 2)))";
01718         }
01719         else if(selectedObjects == TeSelectedByQuery)
01720         {
01721                 input = " WHERE (grid_status = 2 OR grid_status = 3";
01722                 input += " OR (grid_status is null AND (c_object_status = 2 OR c_object_status = 3)))";
01723         }
01724         else if(selectedObjects == TeNotSelectedByQuery)
01725         {
01726                 input = " WHERE (grid_status = 0 OR grid_status = 1";
01727                 input += " OR (grid_status is null AND (c_object_status = 0 OR c_object_status = 1)))";
01728         }
01729         else if(selectedObjects == TeGrouped)
01730                 input = " WHERE c_legend_id <> 0";
01731         else if(selectedObjects == TeNotGrouped)
01732                 input = " WHERE c_legend_id = 0";
01733 
01734 
01735         string func;
01736         if(grouping_.groupFunction_.empty())
01737                 func = " MIN";
01738         else
01739                 func = grouping_.groupFunction_;
01740 
01741         if(grouping_.groupFunction_ == "COUNT")
01742                 type = TeINT;
01743 
01744         string query = "SELECT MIN(" + collectionTable_ + ".c_object_id)";
01745         if(grouping_.groupNormAttribute_.empty())
01746                 query += ", "+ func +"(" + groupingAttr + ")" + sqlGridFrom();
01747         else
01748                 query += ", "+ func +"(" + groupingAttr + ") / "+ func +"(" + grouping_.groupNormAttribute_ + ")" + sqlGridFrom();
01749 
01750         if(selectedObjects != TeAll)
01751                 query += input;
01752 
01753         query += " GROUP BY " + collectionTable_ + ".c_object_id";
01754 
01755         map<int, vector<string> > legMap;
01756 
01757         TeDatabasePortal* portal = db->getPortal();
01758         if(portal->query(query) == false)
01759         {
01760                 delete portal;
01761                 return false;
01762         }
01763 
01764         vector<string> idVec;
01765         vector<string> nullIdVec;
01766         vector<string> valVec;
01767         while(portal->fetchRow())
01768         {
01769                 string val = portal->getData(1);
01770                 string oid = portal->getData(0);
01771                 if (val.empty() == false)
01772                 {
01773                         idVec.push_back(oid);
01774                         valVec.push_back(val);
01775                 }
01776                 else
01777                         nullIdVec.push_back(oid);
01778         }
01779         if (grouping_.groupMode_ == TeUniqueValue)
01780         {
01781                 unsigned int j = 0;
01782                 while( j < idVec.size())
01783                 {
01784                         string val = valVec[j];
01785                         string oid = idVec[j];
01786                         if(type == TeREAL)
01787                         {
01788                                 double a = atof(val.c_str());
01789                                 val = Te2String(a, grouping_.groupPrecision_);
01790                         }
01791                         else if(type == TeINT)
01792                         {
01793                                 int a = atoi(val.c_str());
01794                                 val = Te2String(a);
01795                         }
01796 
01797                         unsigned int siz = legend_.size();
01798                         if(grouping_.groupNullAttr_ && nullIdVec.size() > 0)
01799                                 --siz;
01800                         for(i=0; i < siz; i++)
01801                         {
01802                                 TeLegendEntry& leg = legend_[i];
01803                                 if(val == leg.from())
01804                                 {
01805                                         legMap[leg.id()].push_back(oid);
01806                                         break;
01807                                 }
01808                         }
01809                         j++;
01810                 }
01811         }
01812         else
01813         {
01814                 unsigned int j = 0;
01815                 while(j < idVec.size())
01816                 {
01817                         string val = valVec[j];
01818                         string oid = idVec[j];
01819                         if(type == TeREAL)
01820                         {
01821                                 double a = atof(val.c_str());
01822                                 val = Te2String(a, grouping_.groupPrecision_);
01823                         }
01824 
01825                         unsigned int siz = legend_.size();
01826                         if(grouping_.groupNullAttr_ && !nullIdVec.empty())
01827                --siz;
01828                         for(i=0; i < siz; i++)
01829                         {
01830                                 TeLegendEntry& leg = legend_[i];
01831                                 int f = leg.from().find("mean");
01832                                 if(f >= 0)
01833                                         continue;
01834                                 double dval = atof(val.c_str());
01835                                 double dfrom = atof(leg.from().c_str());
01836                                 double dto = atof(leg.to().c_str());
01837                                 if(i < legend_.size()-1)
01838                                 {
01839                                         if(dval >= dfrom && dval < dto)
01840                                         {
01841                                                 legMap[leg.id()].push_back(oid);
01842                                                 break;
01843                                         }
01844                                 }
01845                                 else
01846                                 {
01847                                         if(dval >= dfrom && dval <= dto)
01848                                         {
01849                                                 legMap[leg.id()].push_back(oid);
01850                                                 break;
01851                                         }
01852                                 }
01853                         }
01854                         j++;
01855                 }
01856         }
01857         delete portal;
01858 
01859         int legId = defaultLegend_.id();
01860         if (grouping_.groupNullAttr_)
01861                 legId = legend_[legend_.size()-1].id();
01862         for(i = 0; i < nullIdVec.size(); ++i)
01863         {
01864                 string oid = nullIdVec[i];
01865                 legMap[legId].push_back(oid);
01866         }
01867 
01868         vector<string> svec;
01869         map<int, vector<string> > :: iterator it = legMap.begin();
01870         while(it != legMap.end())
01871         {
01872         // --- Generate In Clauses ----
01873                 unsigned int i, j, k, size, chunkSize = 200, nChunks;
01874                 string inClause;
01875                 size = it->second.size();
01876                 if (size % chunkSize)
01877                         nChunks = size / chunkSize + 1;
01878                 else
01879                         nChunks = size / chunkSize;
01880 
01881                 j = 0;
01882                 for (k = 0; k < nChunks; ++k)
01883                 {
01884                         i = 0;
01885                         inClause = "(";
01886                         while (j < size && i < chunkSize)
01887                         {
01888                                 inClause += "'" + db->escapeSequence(it->second[j]) + "',";
01889                                 i++;
01890                                 j++;
01891                         }
01892                         inClause[inClause.size() - 1] = ')';
01893                         svec.push_back(inClause);
01894                 }
01895 
01896                 //--- generateInClause
01897 
01898                 for(i=0; i<svec.size(); ++i)
01899                 {
01900                         string up = "UPDATE " + collectionTable_ + " SET c_legend_id = " + Te2String(it->first);
01901                         up += " WHERE c_object_id IN " + svec[i];
01902                         if (!objectId.empty())
01903                                 up += " AND c_object_id='"+objectId+"'";
01904                         if(db->execute(up) == false)
01905                                 continue;
01906                 }
01907                 it++;
01908                 svec.clear();
01909         }
01910         if(legend_.size())
01911                 visibleRep_ = visibleRep_ | 0x40000000;
01912         else
01913                 visibleRep_ = visibleRep_ | 0xbfffffff;
01914         string upVis = "UPDATE te_theme SET visible_rep=" + Te2String(visibleRep_) + " WHERE theme_id=" + Te2String(id());
01915         return (db->execute(upVis));
01916 }
01917 
01918 bool
01919 TeTheme::populateCollection(std::string objectId, const bool& sincronize)
01920 {
01921         TeDatabase* db = layer_->database();
01922         if(!db || collectionTable_.empty())
01923                 return false;
01924 
01925         if(attTableVector_.empty())
01926                 attTableVector_ = layer_->attrTables();
01927 
01928         bool useSincronize = sincronize;
01929 
01930         TeRepresPointerVector& represVec = layer_->vectRepres();
01931         for (unsigned int i = 0; i < represVec.size(); ++i)
01932         {
01933                 TeRepresentation* rep = represVec[i];
01934                 if(rep->geomRep_ == TeTEXT)
01935                         continue;
01936 
01937                 string geomTable = layer_->tableName(rep->geomRep_);
01938 
01939                 string sqlSelect, sqlFrom, sqlWhere;
01940 
01941                 sqlSelect = " SELECT DISTINCT "+ geomTable +".object_id ";
01942                 if(!generateAttributeRest_.empty() || !generateTemporalRest_.empty())
01943                 {
01944                         sqlFrom = tableJoin(attTableVector_, geomTable, "object_id");
01945                 }
01946                 else
01947                 {
01948                         sqlFrom = " " + geomTable;
01949                 }
01950 
01951                 if(useSincronize == true)
01952                 {
01953                         sqlWhere  = " WHERE NOT EXISTS (SELECT * FROM " + collectionTable_;
01954                         sqlWhere += " WHERE "+ collectionTable_ +".c_object_id = "+ geomTable +".object_id )";
01955                         sqlWhere += " AND " + geomTable + ".object_id IS NOT NULL ";
01956                 }
01957                 else
01958                 {
01959                         sqlWhere += " WHERE " + geomTable + ".object_id IS NOT NULL ";
01960                         useSincronize = true; //se tiver mais de uma representacao, o segundo join nao pode repetir valores ja inseridos
01961                 }
01962 
01963                 //attribute restriction
01964                 if(!generateAttributeRest_.empty())
01965                         sqlWhere += " AND ("+ generateAttributeRest_ +" )";
01966 
01967                 //temporal restriction
01968                 if(!generateTemporalRest_.empty())
01969                 {
01970                         string sqlTemp;
01971                         initParse(generateTemporalRest_, db);
01972 
01973                         if(!yyparse(sqlTemp))  //0: accept  1: reject
01974                                 sqlWhere += " AND "+ sqlTemp;
01975                         else
01976                                 return false;
01977                 }
01978 
01979                 TeKeys objs;
01980 
01981                 //spatial restriction
01982                 if(hasSpatialRes_)
01983                 {
01984                         if(boxRest_.isValid())
01985                         {
01986                                 TeBox box = boxRest_;
01987                                 sqlWhere += " AND "+ db->getSQLBoxWhere(box, geomRepRest_, geomTable);
01988                         }
01989                         else if (geomRest_)
01990                         {
01991                                 TePrecision::instance().setPrecision(TeGetPrecision(layer()->projection()));
01992 
01993                                 if(db->spatialRelation(geomTable, geomRepRest_, geomRest_, objs, spatialRelation_))
01994                                 {
01995                                         string obs;
01996                                         for(unsigned int i=0; i<objs.size(); i++)
01997                                         {
01998                                                 if(i!=0)
01999                                                         obs += ",";
02000                                                 obs += "'"+ objs[i] +"'";
02001                                         }
02002 
02003                                         sqlWhere += " AND "+ geomTable +".object_id IN ("+ obs +")";
02004                                 }
02005                         }
02006                 }
02007 
02008                 //populate the collection table
02009                 string popule;
02010                 popule = " INSERT INTO "+ collectionTable_ +" (c_object_id) ";
02011                 popule += sqlSelect +" FROM "+ sqlFrom + sqlWhere;
02012                 if (!objectId.empty())
02013                 {
02014                         if (sqlWhere.length())
02015                                 popule += " AND ";
02016                         popule += geomTable +".object_id='" +objectId+ "'";
02017                 }
02018 
02019                 if (!db->execute(popule))
02020                 {
02021                         //Treats an error in the MySQL database system
02022                         //Error: 1062 SQLSTATE: 23000 (ER_DUP_ENTRY)
02023                         //Message: Duplicate entry '%s' for key %d
02024                         if(db->dbmsName() != "MySQL" || db->errorNum()!=1062)
02025                 return false;
02026                 }
02027         }
02028 
02029 //      int defaultLegend = defaultLegend_.id();
02030         string popule = "UPDATE " + collectionTable_;
02031         popule += " SET c_legend_id=0, c_legend_own=0, c_object_status=0 ";
02032 
02033         if (!objectId.empty())
02034                 popule += " WHERE c_object_id='"+objectId+"'";
02035 
02036         if (!db->execute(popule))
02037                 return false;
02038 
02039         themeBox_= getThemeBox();
02040         return true;
02041 }
02042 
02043 bool TeTheme::hasObjectsWithoutGeometries(TeGeomRep geomRep)
02044 {
02045         if(!layer() || !layer()->database())
02046                 return true;
02047 
02048         //get the geometry table
02049         string geomTable = layer()->tableName(geomRep);
02050         if(geomTable.empty())
02051                 return true;
02052 
02053         TeDatabasePortal* portal = layer()->database()->getPortal();
02054         if(!portal)
02055                 return true;
02056 
02057         //Verify the collection table or attribute tables
02058         if(layer()->database()->tableExist(collectionTable()))
02059         {
02060                 string s = " SELECT COUNT(*) ";
02061                 s+= " FROM "+  collectionTable();
02062                 s+= " WHERE NOT EXISTS ";
02063                 s+= " (SELECT * FROM "+ geomTable;
02064                 s+= " WHERE "+ collectionTable() +".c_object_id ";
02065                 s+= " = "+ geomTable +".object_id ) ";
02066 
02067                 if(!portal->query(s) || !portal->fetchRow())
02068                 {
02069                         delete portal;
02070                         return true;
02071                 }
02072 
02073                 int numObjs = atoi(portal->getData(0));
02074                 if(numObjs>0)
02075                 {
02076                         delete portal;
02077                         return true;
02078                 }
02079         }
02080         else
02081         {
02082                 //for each static table
02083                 for(unsigned int i=0; i<this->attrTables().size(); ++i)
02084                 {
02085                         if(     this->attrTables()[i].tableType() == TeAttrExternal ||
02086                                 this->attrTables()[i].tableType() == TeAttrMedia ||
02087                                 this->attrTables()[i].tableType() == TeGeocodingData)
02088                                 continue;
02089 
02090                         string s = " SELECT COUNT(*) ";
02091                         s+= " FROM "+  attrTables()[i].name();
02092                         s+= " WHERE NOT EXISTS ";
02093                         s+= " (SELECT * FROM "+ geomTable;
02094                         s+= " WHERE "+ attrTables()[i].name() +"."+ attrTables()[i].linkName();
02095                         s+= " = "+ geomTable +".object_id ) ";
02096 
02097                         if(!portal->query(s) || !portal->fetchRow())
02098                         {
02099                                 delete portal;
02100                                 return true;
02101                         }
02102 
02103                         int numObjs = atoi(portal->getData(0));
02104                         if(numObjs>0)
02105                         {
02106                                 delete portal;
02107                                 return true;
02108                         }
02109                 }
02110         }
02111 
02112         delete portal;
02113         return false;
02114 }
02115 
02116 bool TeTheme::removeObjectsWithoutGeometries(TeGeomRep geomRep)
02117 {
02118         if(!layer() || !layer()->database() || !layer()->database()->tableExist(collectionTable()))
02119                 return true;
02120 
02121         //get the geometry table
02122         string geomTable = layer()->tableName(geomRep);
02123         if(geomTable.empty())
02124                 return true;
02125 
02126         string del = " DELETE FROM "+ collectionTable();
02127         del += " WHERE NOT EXISTS ";
02128         del += " (SELECT * FROM "+ geomTable;
02129         del += " WHERE "+ collectionTable() +".c_object_id = ";
02130         del += geomTable +".object_id) ";
02131 
02132         if(!layer()->database()->execute(del))
02133                 return false;
02134 
02135         del = " DELETE FROM "+ collectionAuxTable();
02136         del += " WHERE NOT EXISTS ";
02137         del += " (SELECT * FROM "+ geomTable;
02138         del += " WHERE "+ collectionAuxTable() +".object_id = ";
02139         del += geomTable +".object_id) ";
02140 
02141         if(!layer()->database()->execute(del))
02142                 return false;
02143 
02144         return true;
02145 }
02146 
02147 bool
02148 TeTheme::save()
02149 {
02150         TeDatabase* db = layer()->database();
02151         if(!db)
02152                 return false;
02153 
02154         //insert theme in database
02155         if(id()==0)
02156         {
02157                 if(!db->insertTheme(this)) //updateThemeTable
02158                 {
02159                         db->deleteTheme(this->id());
02160                         return false;
02161                 }
02162         }
02163 
02164     if(useCollection_)
02165     {
02166             //collection table
02167             if(collectionTable().empty())
02168                     collectionTable("te_collection_"+ Te2String(id()));
02169 
02170             if(!db->createCollectionTable(collectionTable_))
02171             {
02172                     db->deleteTheme(this->id());
02173                     return false;
02174             }
02175 
02176             //collection aux table
02177             collectionAuxTable(collectionTable() + "_aux");
02178             addThemeTable(collectionAuxTable());
02179 
02180             if(!createCollectionAuxTable())
02181             {
02182                     db->deleteTheme(this->id());
02183                     return false;
02184             }
02185     }
02186 
02187         return true;
02188 }
02189 
02190 set<string> TeTheme::getObjects(TeSelectedObjects selectedObjects)
02191 {
02192         if (selectedObjects == TeAll)
02193         {
02194                 if (objectSet_.empty() == false)
02195                         return objectSet_;
02196                 else
02197                 {
02198                         if (attTableVector_.empty())
02199                                 return set<string>();
02200 
02201                         // Set the new set of objects
02202                         if (layer_->hasGeometry(TeRASTER) == false)
02203                         {
02204                                 TeDatabase *db = layer_->database();
02205                                 TeDatabasePortal* portal = db->getPortal();
02206 
02207                                 string q = "SELECT " + attTableVector_[0].name() + "." + attTableVector_[0].uniqueName() + sqlFrom();
02208                                 if (portal->query(q) == false)
02209                                 {
02210                                         delete portal;
02211                                         return set<string>();
02212                                 }
02213 
02214                                 while (portal->fetchRow())
02215                                         objectSet_.insert(portal->getData(0));
02216 
02217                                 delete portal;
02218                                 return objectSet_;
02219                         }
02220                 }
02221         }
02222 
02223         set<string> oidSet;
02224         map<string, int>::iterator it;
02225         string oid;
02226 
02227         if (selectedObjects == TeSelectedByPointing)
02228         {
02229                 for (it = objStatusMap_.begin(); it != objStatusMap_.end(); ++it)
02230                 {
02231                         oid = it->first;
02232                         if (objStatusMap_[oid] == TePOINTED || objStatusMap_[oid] == TePOINTED_QUERIED)
02233                                 oidSet.insert(oid);
02234                 }
02235         }
02236         else if (selectedObjects == TeNotSelectedByPointing)
02237         {
02238                 oidSet = getObjects();
02239                 for (it = objStatusMap_.begin(); it != objStatusMap_.end(); ++it)
02240                 {
02241                         oid = it->first;
02242                         if (objStatusMap_[oid] == TePOINTED || objStatusMap_[oid] == TePOINTED_QUERIED)
02243                                 oidSet.erase(oid);
02244                 }
02245         }
02246         else if (selectedObjects == TeSelectedByQuery)
02247         {
02248                 for (it = objStatusMap_.begin(); it != objStatusMap_.end(); ++it)
02249                 {
02250                         oid = it->first;
02251                         if (objStatusMap_[oid] == TeQUERIED || objStatusMap_[oid] == TePOINTED_QUERIED)
02252                                 oidSet.insert(oid);
02253                 }
02254         }
02255         else if (selectedObjects == TeNotSelectedByQuery)
02256         {
02257                 oidSet = getObjects();
02258                 for (it = objStatusMap_.begin(); it != objStatusMap_.end(); ++it)
02259                 {
02260                         oid = it->first;
02261                         if (objStatusMap_[oid] == TeQUERIED || objStatusMap_[oid] == TePOINTED_QUERIED)
02262                                 oidSet.erase(oid);
02263                 }
02264         }
02265         else if(selectedObjects == TeGrouped)
02266         {
02267                 map<string, int>& objLegendMap = getObjLegendMap();
02268                 for (it = objLegendMap.begin(); it != objLegendMap.end(); ++it)
02269                 {
02270                         string oid = it->first;
02271                         if (objLegendMap[oid] != 0)
02272                                 oidSet.insert(oid);
02273                 }
02274         }
02275         else if(selectedObjects == TeNotGrouped)
02276         {
02277                 oidSet = getObjects();
02278                 map<string, int>& objLegendMap = getObjLegendMap();
02279                 for (it = objLegendMap.begin(); it != objLegendMap.end(); ++it)
02280                         oidSet.erase(it->first);
02281         }
02282         else if(selectedObjects == TeSelectedByPointingOrQuery)
02283         {
02284                 oidSet = getObjects();
02285                 for (it = objStatusMap_.begin(); it != objStatusMap_.end(); ++it)
02286                 {
02287                         oid = it->first;
02288                         if (objStatusMap_[oid] == TeQUERIED || objStatusMap_[oid] == TePOINTED)
02289                                 oidSet.insert(oid);
02290                 }
02291         }
02292         else if(selectedObjects == TeSelectedByPointingAndQuery )
02293         {
02294                 oidSet = getObjects();
02295                 for (it = objStatusMap_.begin(); it != objStatusMap_.end(); ++it)
02296                 {
02297                         oid = it->first;
02298                         if (objStatusMap_[oid] == TePOINTED_QUERIED )
02299                                 oidSet.insert(oid);
02300                 }
02301         }
02302 
02303         return oidSet;
02304 }
02305 
02306 vector<string> TeTheme::getItemVector(TeSelectedObjects selectedObjects)
02307 {
02308         vector<string> itemVec;
02309 
02310         //======================================================================================
02311         //Get all the items
02312         vector<string> allItemVec;
02313         string item;
02314         unsigned int i;
02315 
02316         if (selectedObjects == TeAll || selectedObjects == TeNotSelectedByPointing ||
02317                 selectedObjects == TeNotSelectedByQuery)
02318         {
02319                 vector<TeTable> tableVec;
02320                 getAttTables(tableVec);
02321 
02322                 string q = "SELECT ";
02323                 for (i = 0; i < tableVec.size(); ++i)
02324                 {
02325                         if (i != 0)
02326                                 q += ",";
02327                         q += tableVec[i].uniqueName();
02328                 }
02329                 q += sqlFrom();
02330 
02331                 TeDatabase* db = layer()->database();
02332                 TeDatabasePortal* portal = db->getPortal();
02333 
02334                 if (portal->query(q) == false)
02335                 {
02336                         delete portal;
02337                         return itemVec;
02338                 }
02339 
02340                 while(portal->fetchRow())
02341                 {
02342                         item = portal->getData(tableVec[0].uniqueName());
02343                         for (i = 1; i < tableVec.size(); ++i)
02344                                 item += portal->getData(tableVec[i].uniqueName());
02345                         allItemVec.push_back(item);
02346                 }
02347 
02348                 delete portal;
02349         }
02350 
02351         //======================================================================================
02352         // Get the items according to the selectedObjects variable
02353         map<string, int>& itemStatusMap = getItemStatusMap();
02354         map<string, int>::iterator it;
02355 
02356         if (selectedObjects == TeAll)
02357                 return allItemVec;
02358         else if(selectedObjects == TeSelectedByPointing)
02359         {
02360                 for (it = itemStatusMap.begin(); it != itemStatusMap.end(); ++it)
02361                 {
02362                         item = it->first;
02363                         if (itemStatusMap[item] == TePOINTED || itemStatusMap[item] == TePOINTED_QUERIED)
02364                                 itemVec.push_back(item);
02365                 }
02366         }
02367         else if(selectedObjects == TeNotSelectedByPointing)
02368         {
02369                 for (i = 0; i < allItemVec.size(); ++i)
02370                 {
02371                         item = allItemVec[i];
02372                         if (itemStatusMap[item] == TeDEFAULT || itemStatusMap[item] == TeQUERIED)
02373                                 itemVec.push_back(item);
02374 
02375                         if (itemStatusMap[item] == TeDEFAULT)
02376                                 itemStatusMap.erase(item);
02377                 }
02378         }
02379         else if(selectedObjects == TeSelectedByQuery)
02380         {
02381                 for (it = itemStatusMap.begin(); it != itemStatusMap.end(); ++it)
02382                 {
02383                         item = it->first;
02384                         if (itemStatusMap[item] == TeQUERIED || itemStatusMap[item] == TePOINTED_QUERIED)
02385                                 itemVec.push_back(item);
02386                 }
02387         }
02388         else if(selectedObjects == TeNotSelectedByQuery)
02389         {
02390                 for (i = 0; i < allItemVec.size(); ++i)
02391                 {
02392                         item = allItemVec[i];
02393                         if (itemStatusMap[item] == TeDEFAULT || itemStatusMap[item] == TePOINTED)
02394                                 itemVec.push_back(item);
02395 
02396                         if (itemStatusMap[item] == TeDEFAULT)
02397                                 itemStatusMap.erase(item);
02398                 }
02399         }
02400         else if(selectedObjects == TeGrouped)
02401         {
02402                 set<string> oidSet;
02403                 map<string, int>& objLegendMap = getObjLegendMap();
02404                 for (it = objLegendMap.begin(); it != objLegendMap.end(); ++it)
02405                 {
02406                         string oid = it->first;
02407                         if (objLegendMap[oid] != 0)
02408                                 oidSet.insert(oid);
02409                 }
02410 
02411                 itemVec = getItemVector(oidSet);
02412         }
02413         else if(selectedObjects == TeNotGrouped)
02414         {
02415                 set<string> oidSet = getObjects();
02416                 map<string, int>& objLegendMap = getObjLegendMap();
02417                 for (it = objLegendMap.begin(); it != objLegendMap.end(); ++it)
02418                         oidSet.erase(it->first);
02419 
02420                 itemVec = getItemVector(oidSet);
02421         }
02422         else if(selectedObjects == TeSelectedByPointingOrQuery )
02423         {
02424                 for (it = itemStatusMap.begin(); it != itemStatusMap.end(); ++it)
02425                 {
02426                         item = it->first;
02427                         if( (itemStatusMap[item] == TePOINTED ) ||
02428                           (itemStatusMap[item] == TeQUERIED ) ) {
02429 
02430                                 itemVec.push_back(item);
02431                         }
02432                 }
02433         }
02434 
02435         return itemVec;
02436 }
02437 
02438 vector<string> TeTheme::getItemVector(const set<string>& oidSet)
02439 {
02440         vector<string> itemVec;
02441         vector<TeTable> tableVec = attrTables();
02442         set<string>::const_iterator it;
02443         unsigned int i;
02444 
02445         if (tableVec.size() == 1)
02446         {
02447                 for (it = oidSet.begin(); it != oidSet.end(); ++it)
02448                         itemVec.push_back(*it);
02449                 return itemVec;
02450         }
02451 
02452         // Set the expression that represents the concatenation
02453         // of the unique names of each theme table
02454         string concatIndexStr;
02455         vector<string> indexVec;
02456         TeDatabase* db = layer()->database();
02457         for (i = 0; i < tableVec.size(); ++i)
02458                 indexVec.push_back(tableVec[i].name() + "." + tableVec[i].uniqueName());
02459 
02460         concatIndexStr = db->getConcatFieldsExpression(indexVec);
02461 
02462         vector<string> queryVec;
02463         string query;
02464 
02465 
02466         set<string>::const_iterator itB = oidSet.begin();
02467         set<string>::const_iterator itE = oidSet.end();
02468         vector<string> inClauseVec = generateInClauses(itB, itE, db);
02469         for (i = 0; i < inClauseVec.size(); ++i)
02470         {
02471                 query = "SELECT " + tableVec[i].name() + "." + tableVec[i].uniqueName();
02472                 query += ", " + concatIndexStr + sqlFrom() + " WHERE ";
02473                 query += tableVec[i].name() + "." + tableVec[i].uniqueName() + " IN " + inClauseVec[i];
02474                 queryVec.push_back(query);
02475         }
02476 
02477         TeDatabasePortal* portal = db->getPortal();
02478         for (i = 0; i < queryVec.size(); ++i)
02479         {
02480                 if (i != 0)
02481                         portal->freeResult();
02482 
02483                 if(portal->query(queryVec[i]) == false)
02484                 {
02485                         delete portal;
02486                         return itemVec;
02487                 }
02488 
02489                 while(portal->fetchRow())
02490                         itemVec.push_back(portal->getData(1));
02491         }
02492 
02493         delete portal;
02494         return itemVec;
02495 }
02496 
02497 
02498 set<string> TeTheme::getObjects(const vector<string>& itemVec)
02499 {
02500         set<string> oidSet;
02501 
02502         unsigned int i;
02503         TeDatabase* db = layer()->database();
02504 
02505         // Get the vector of tables of the theme
02506         vector<TeTable> tableVec;
02507         getAttTables(tableVec);
02508 
02509         vector<string> indexVec;
02510         for (i = 0; i < tableVec.size(); ++i)
02511                 indexVec.push_back(tableVec[i].name() + "." + tableVec[i].uniqueName());
02512 
02513         string concatIndexStr = db->getConcatFieldsExpression(indexVec);
02514 
02515         std::vector<string>::const_iterator itemVec_it_begin( itemVec.begin() );
02516         std::vector<string>::const_iterator itemVec_it_end( itemVec.end() );
02517 
02518         vector<string> inClauseVec = generateInClauses( itemVec_it_begin,
02519     itemVec_it_end, db);
02520 
02521         vector<string> queryVec;
02522         string selectClause = "SELECT " + concatIndexStr + ", ";
02523         selectClause += tableVec[0].name() + "." + tableVec[0].uniqueName() + " " + sqlFrom();
02524 
02525         for (i = 0; i < inClauseVec.size(); ++i)
02526         {
02527                 string query = selectClause + " WHERE " + concatIndexStr + " IN " + inClauseVec[i];
02528                 queryVec.push_back(query);
02529         }
02530 
02531         TeDatabasePortal *portal = db->getPortal();
02532         for (i = 0; i < queryVec.size(); ++i)
02533         {
02534                 if (i != 0)
02535                         portal->freeResult();
02536 
02537                 if (portal->query(queryVec[i]))
02538                 {
02539                         while (portal->fetchRow())
02540                                 oidSet.insert(portal->getData(1));
02541                 }
02542         }
02543         delete portal;
02544 
02545         return oidSet;
02546 }
02547 
02548 unsigned int
02549 TeTheme::getNumberOfObjects()
02550 {
02551         int numRows = 0;
02552         string s = "SELECT COUNT(*) " + this->sqlFrom();
02553         TeDatabasePortal* portal = this->layer()->database()->getPortal();
02554         if(portal->query(s) && portal->fetchRow() )
02555         {
02556                 numRows = atoi(portal->getData(0));
02557         }
02558         delete portal;
02559         return numRows;
02560 }
02561 
02562 
02563 void TeTheme::setUsingCollection(const bool& usingCollection)
02564 {
02565     useCollection_ = usingCollection;
02566 }
02567 
02568 TeProjection*
02569 TeTheme::getThemeProjection()
02570 {
02571         if (layer_)
02572                 return layer_->projection();
02573         else
02574                 return 0;
02575 }
02576 
02577 bool TeTheme::beforeCopyThemeTo(TeAbstractTheme* absThemeCopy, TeDatabase* outputDatabase)
02578 {
02579         if(TeAbstractTheme::beforeCopyThemeTo(absThemeCopy, outputDatabase) == false)
02580         {
02581                 return false;
02582         }
02583 
02584         TeTheme* themeCopy = dynamic_cast<TeTheme*>(absThemeCopy);
02585         if(themeCopy == 0)
02586         {
02587                 return false;
02588         }
02589 
02590         themeCopy->collectionTable("");
02591         themeCopy->collectionAuxTable("");
02592 
02593         TeLayerMap& layerMap = outputDatabase->layerMap();
02594         TeLayerMap::iterator it = layerMap.begin();
02595         while(it != layerMap.end())
02596         {
02597                 if(themeCopy->name() == it->second->name())
02598                 {
02599                         themeCopy->layer(it->second);
02600                         break;
02601                 }
02602                 ++it;
02603         }
02604 
02605         return true;
02606 }
02607 
02608 bool TeTheme::afterCopyThemeTo(TeAbstractTheme* absThemeCopy, TeDatabase* outputDatabase)
02609 {
02610 //Chama a funcao de copia da classe pai
02611         if(TeAbstractTheme::afterCopyThemeTo(absThemeCopy, outputDatabase) == false)
02612         {
02613                 return false;
02614         }
02615 
02616 //Teste se o tema eh realmente um TeTheme
02617         TeTheme* themeCopy = dynamic_cast<TeTheme*>(absThemeCopy);
02618         if(themeCopy == 0)
02619         {
02620                 return false;
02621         }
02622 
02623 //Preenche as tabelas de colecao
02624         TeDatabase* inputDatabase = this->layer()->database();
02625 
02626         if(inputDatabase->tableExist(this->collectionTable()) && outputDatabase->tableExist(themeCopy->collectionTable()))
02627         {
02628                 /*if(!TeCopyTable(inputDatabase, this->collectionTable(), outputDatabase, themeCopy->collectionTable()))
02629                 {
02630                         return false;
02631                 }*/
02632                 if(themeCopy->populateCollection("", false) == false)
02633                 {
02634                         return false;
02635                 }
02636         }
02637         if(inputDatabase->tableExist(this->collectionAuxTable()) && outputDatabase->tableExist(themeCopy->collectionAuxTable()))
02638         {
02639                 if(themeCopy->populateCollectionAux() == false)
02640                 {
02641                         return false;
02642                 }
02643         }
02644 
02645 //Salva a legenda na colecao
02646         if(this->grouping().groupMode_ != TeNoGrouping)
02647         {
02648                 if(!themeCopy->saveLegendInCollection())
02649                 {
02650                         return false;
02651                 }
02652         }
02653 
02654         return true;
02655 }

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