00001 #include "TeExternalTheme.h"
00002 #include "TeLayer.h"
00003 #include "TeDatabase.h"
00004 #include "TeDatabaseFactoryParams.h"
00005 #include "TeDBConnectionsPool.h"
00006 #include "TeGroupingAlgorithms.h"
00007 #include "TeQuerier.h"
00008 #include "TeQuerierParams.h"
00009 #include "TeRasterTransform.h"
00010
00011
00012 TeExternalTheme::TeExternalTheme(TeDatabase* sourceDb, TeTheme* remoteTheme, const int& viewId,
00013 const string& name) :
00014 TeTheme(name, 0, 0, viewId),
00015 remoteTheme_(NULL),
00016 sourceDB_(sourceDb),
00017 remoteDbId_(-1)
00018 {
00019 type(TeEXTERNALTHEME);
00020
00021 if(remoteTheme != NULL)
00022 {
00023 setRemoteTheme(remoteTheme);
00024 }
00025
00026 isEditable_ = false;
00027 }
00028
00029 TeExternalTheme::~TeExternalTheme()
00030 {
00031 if(remoteTheme_ != NULL)
00032 {
00033 delete remoteTheme_;
00034 }
00035 }
00036
00037 TeExternalTheme& TeExternalTheme::operator=(TeExternalTheme& rhs)
00038 {
00039 if ( this != &rhs )
00040 {
00041 *(TeTheme*)this = rhs;
00042
00043 this->remoteTheme_ = rhs.remoteTheme_;
00044 this->sourceDB_ = rhs.sourceDB_;
00045 }
00046
00047 return *this;
00048 }
00049
00050 TeViewNode* TeExternalTheme::clone()
00051 {
00052 TeExternalTheme* extTheme = new TeExternalTheme(this->sourceDB_, this->remoteTheme_, this->view(), this->name());
00053 *extTheme = *this;
00054
00055 extTheme->remoteTheme_ = (TeTheme*)this->remoteTheme_->clone();
00056
00057 return extTheme;
00058 }
00059
00060 TeTheme*
00061 TeExternalTheme::getRemoteTheme() const
00062 {
00063 return remoteTheme_;
00064 }
00065
00066 void TeExternalTheme::setRemoteTheme(TeTheme* theme)
00067 {
00068 remoteTheme_ = new TeTheme(*theme);
00069 TeLayer* remoteLayer = new TeLayer(*theme->layer());
00070
00071 remoteTheme_->layer(remoteLayer);
00072 remoteDbId_ = TeDBConnectionsPool::instance().getDatabaseIdx(remoteLayer->database());
00073 }
00074
00075 TeDatabase* TeExternalTheme::getSourceDatabase()
00076 {
00077 return sourceDB_;
00078 }
00079
00080 void TeExternalTheme::setSourceDatabase(TeDatabase* srcDB)
00081 {
00082 sourceDB_ = srcDB;
00083 }
00084
00085 string
00086 TeExternalTheme::getRemoteThemeName()
00087 {
00088 return remoteTheme_->name();
00089 }
00090
00091 void
00092 TeExternalTheme::loadObjectLegendMap()
00093 {
00094 objLegendMap_.clear();
00095 objOwnLegendMap_.clear();
00096 objStatusMap_.clear();
00097 itemStatusMap_.clear();
00098
00099 TeDatabasePortal* portal = sourceDB_->getPortal();
00100
00101 if(!portal->query("SELECT c_object_id, c_legend_id, c_legend_own, c_object_status FROM " + collectionTable()))
00102 return;
00103
00104 while(portal->fetchRow())
00105 {
00106 string objId = portal->getData(0);
00107 int status = portal->getInt(3);
00108 if(portal->getInt(1) != 0)
00109 objLegendMap_[portal->getData(0)] = portal->getInt(1);
00110 if(portal->getInt(2) != 0)
00111 objOwnLegendMap_[portal->getData(0)] = portal->getInt(2);
00112 if(status != 0)
00113 objStatusMap_[objId] = status;
00114 }
00115
00116 portal->freeResult();
00117
00118 if(!portal->query("SELECT object_id, unique_id, grid_status FROM " + collectionAuxTable()))
00119 return;
00120
00121 while(portal->fetchRow())
00122 {
00123 if(portal->getInt(2) != 0)
00124 {
00125 itemStatusMap_[portal->getData(1)] = portal->getInt(2);
00126 }
00127 }
00128
00129 portal->freeResult();
00130 delete portal;
00131 }
00132
00133 int
00134 TeExternalTheme::getGridStatus(const int uniqueId, const std::string )
00135 {
00136 string aux = Te2String(uniqueId);
00137 std::map<std::string, int >::iterator itGridStatus = itemStatusMap_.find(aux);
00138 if(itGridStatus == itemStatusMap_.end())
00139 return 0;
00140 return itGridStatus->second;
00141 }
00142
00143 int
00144 TeExternalTheme::getObjectStatus(const std::string objectId)
00145 {
00146 std::map<std::string, int>::iterator it = objStatusMap_.find(objectId);
00147 if(it == objStatusMap_.end())
00148 return 0;
00149
00150 return it->second;
00151 }
00152
00153 bool
00154 TeExternalTheme::setObjectLegendStatusMap(const std::string objId, const int status)
00155 {
00156 if(objId.empty())
00157 return false;
00158
00159 if( status == 0)
00160 {
00161 map<std::string, int>::iterator itLegStatus = objStatusMap_.find(objId);
00162
00163 if(itLegStatus != objStatusMap_.end())
00164 {
00165 objStatusMap_.erase(itLegStatus);
00166 return true;
00167 }
00168 return false;
00169 }
00170
00171 objStatusMap_[objId] = status;
00172
00173 return true;
00174 }
00175
00176 bool
00177 TeExternalTheme::setObjectGridStatusMap(const std::string objId, const int uniqueId, const int status)
00178 {
00179 string aux = Te2String(uniqueId);
00180 if(objId.empty() || aux.empty())
00181 return false;
00182
00183 if( status == 0 )
00184 {
00185 std::map<std::string, int >::iterator itGridStatus = itemStatusMap_.find(aux);
00186
00187 if(itGridStatus != itemStatusMap_.end())
00188 {
00189 itemStatusMap_.erase(itGridStatus);
00190 return true;
00191 }
00192 return false;
00193 }
00194
00195 itemStatusMap_[aux] = status;
00196
00197 return true;
00198 }
00199
00200 int
00201 TeExternalTheme::layerId()
00202 {
00203 return -1;
00204 }
00205
00206 void
00207 TeExternalTheme::layerId(int)
00208 {
00209 }
00210
00211 void
00212 TeExternalTheme::layer(TeLayer* layer)
00213 {
00214 if(remoteTheme_)
00215 remoteTheme_->layer(layer);
00216 }
00217
00218 TeLayer*
00219 TeExternalTheme::layer()
00220 {
00221 if(remoteTheme_)
00222 return remoteTheme_->layer();
00223 return 0;
00224 }
00225
00226 TeProjection*
00227 TeExternalTheme::getThemeProjection()
00228 {
00229 if(remoteTheme_ && remoteTheme_->layer())
00230 return remoteTheme_->layer()->projection();
00231 return 0;
00232 }
00233
00234 bool
00235 TeExternalTheme::hasRestriction()
00236 {
00237 return false;
00238 }
00239
00240 bool TeExternalTheme::hasAttrRest()
00241 {
00242 return false;
00243 }
00244
00245 bool TeExternalTheme::hasTemporalRest()
00246 {
00247 return false;
00248 }
00249
00250 bool TeExternalTheme::hasSpatialRest()
00251 {
00252 return false;
00253 }
00254
00255 string TeExternalTheme::sqlWhereRestrictions(TeRepresentation* )
00256 {
00257 return string("");
00258 }
00259
00260 void TeExternalTheme::loadTablesJoin(const string& geomTable)
00261 {
00262 remoteTheme_->loadTablesJoin(geomTable);
00263 }
00264
00265 string TeExternalTheme::sqlGridJoin()
00266 {
00267 return remoteTheme_->sqlGridJoin();
00268 }
00269
00270 string TeExternalTheme::sqlGridFrom(const string& geomTable)
00271 {
00272 return remoteTheme_->sqlGridFrom(geomTable);
00273 }
00274
00275 bool TeExternalTheme::save()
00276 {
00277 return save(sourceDB_, useCollection_);
00278 }
00279
00280 bool TeExternalTheme::save(TeDatabase* db, const bool& copyExternalCollection)
00281 {
00282 if(!db)
00283 return false;
00284
00285
00286
00287 if(id()==0)
00288 {
00289 if(!db->insertTheme(this))
00290 {
00291 db->deleteTheme(this->id());
00292 return false;
00293 }
00294 }
00295 else
00296 {
00297 if(!db->updateTheme(this))
00298 {
00299 db->deleteTheme(this->id());
00300 return false;
00301 }
00302 }
00303
00304 if(copyExternalCollection)
00305 {
00306
00307 if(collectionTable().empty())
00308 collectionTable("te_collection_"+ Te2String(id()));
00309
00310 if(!db->createCollectionTable(collectionTable_))
00311 {
00312 db->deleteTheme(this->id());
00313 return false;
00314 }
00315
00316
00317 collectionAuxTable(collectionTable() + "_aux");
00318
00319 if(!TeTheme::createCollectionAuxTable(db))
00320 {
00321 db->deleteTheme(this->id());
00322 return false;
00323 }
00324 }
00325
00326 return true;
00327 }
00328
00329 bool TeExternalTheme::save(const bool& copyExternalCollection)
00330 {
00331 if(!save(sourceDB_, copyExternalCollection))
00332 return false;
00333
00334
00335 std::map<int, int> mapIdLegend;
00336
00337 if(copyExternalCollection)
00338 {
00339 createLegendMapId(mapIdLegend);
00340
00341 if(!mapIdLegend.empty())
00342 copyRemoteCollection(mapIdLegend);
00343
00344 mapIdLegend.clear();
00345
00346 loadObjectLegendMap();
00347 }
00348
00349 return true;
00350 }
00351
00352 bool TeExternalTheme::createCollectionAuxTable()
00353 {
00354 return TeTheme::createCollectionAuxTable(sourceDB_);
00355 }
00356
00357 bool TeExternalTheme::populateCollectionAux(std::string )
00358 {
00359 return true;
00360 }
00361
00362 bool TeExternalTheme::buildGrouping(const TeGrouping& g, TeSelectedObjects ,
00363 vector<double>* dValuesVec)
00364 {
00365 TeDatabase* db = remoteTheme_->layer()->database();
00366 if(!db)
00367 return false;
00368
00369 grouping_ = g;
00370 unsigned int i;
00371 vector<TeSlice> slices;
00372 int nullValues = 0;
00373 if (grouping_.groupMode_ == TeRasterSlicing)
00374 {
00375 int b = atoi(grouping_.groupAttribute_.name_.c_str());
00376 if (!remoteTheme_->layer()->raster() ||
00377 b < 0 ||
00378 b > remoteTheme_->layer()->raster()->params().nBands() ||
00379 grouping_.groupNumSlices_ <= 0)
00380 return false;
00381
00382 if (grouping_.groupMaxVal_ == TeMINFLOAT)
00383 grouping_.groupMaxVal_ = remoteTheme_->layer()->raster()->params().vmax_[b];
00384
00385 if (grouping_.groupMinVal_ == TeMAXFLOAT)
00386 grouping_.groupMinVal_ = remoteTheme_->layer()->raster()->params().vmin_[b];
00387
00388 TeGroupByEqualStep(grouping_.groupMinVal_, grouping_.groupMaxVal_,
00389 grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00390 }
00391 else
00392 {
00393 if(grouping_.groupAttribute_.name_.empty())
00394 return false;
00395
00396 TeDatabasePortal* portal = db->getPortal();
00397 string query;
00398 bool normal = false;
00399 string aggrFunc = "";
00400 if(grouping_.groupFunction_.empty())
00401 aggrFunc = " MIN";
00402 else
00403 aggrFunc = grouping_.groupFunction_;
00404
00405 if(grouping_.groupNormAttribute_.empty())
00406 {
00407 query = " SELECT "+ aggrFunc +"("+ grouping_.groupAttribute_.name_ +")";
00408 }
00409 else
00410 {
00411 query = " SELECT "+ aggrFunc +"("+ grouping_.groupAttribute_.name_ +") / "+ aggrFunc +"("+ grouping_.groupNormAttribute_ + ")";
00412 normal = true;
00413 }
00414 query += sqlGridFrom();
00415 query += " GROUP BY " + remoteTheme_->collectionTable() + ".c_object_id";
00416 if(!portal->query(query) || !portal->fetchRow())
00417 {
00418 delete portal;
00419 return false;
00420 }
00421 vector<double> dValues;
00422 vector<string> sValues;
00423 double mean, sum;
00424 mean = sum = 0.;
00425 do
00426 {
00427 string val = portal->getData(0);
00428 string valNorm = Te2String(atof(val.c_str()), grouping_.groupPrecision_);
00429
00430 if (!val.empty())
00431 {
00432 if(grouping_.groupMode_== TeUniqueValue)
00433 {
00434 if(normal)
00435 sValues.push_back(valNorm);
00436 else
00437 sValues.push_back(val);
00438 }
00439 else
00440 {
00441 dValues.push_back(atof(valNorm.c_str()));
00442 sum += atof(valNorm.c_str());
00443 }
00444
00445 }
00446 else
00447 nullValues++;
00448 }while(portal->fetchRow());
00449
00450 delete portal;
00451
00452 if(dValues.empty() && sValues.empty())
00453 return false;
00454
00455 if(grouping_.groupMode_== TeEqualSteps)
00456 TeGroupByEqualStep(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00457 else if(grouping_.groupMode_== TeQuantil)
00458 TeGroupByQuantil(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00459 else if(grouping_.groupMode_== TeStdDeviation)
00460 {
00461 string m = Te2String(mean);
00462 TeGroupByStdDev(dValues.begin(), dValues.end(), grouping_.groupStdDev_, slices, m, grouping_.groupPrecision_);
00463 }
00464 else if(grouping_.groupMode_== TeUniqueValue)
00465 {
00466 if(grouping_.groupFunction_ == "COUNT")
00467 TeGroupByUniqueValue(sValues, TeINT, slices, grouping_.groupPrecision_);
00468 else
00469 TeGroupByUniqueValue(sValues, grouping_.groupAttribute_.type_, slices, grouping_.groupPrecision_);
00470 }
00471
00472 if (dValuesVec)
00473 {
00474 for (i = 0; i < dValues.size(); ++i)
00475 dValuesVec->push_back(dValues[i]);
00476 }
00477 }
00478 if(grouping_.groupNullAttr_ && nullValues > 0)
00479 {
00480 TeSlice ps;
00481 ps.count_ = nullValues;
00482 ps.from_ = "Missing Data";
00483 slices.push_back(ps);
00484 grouping_.groupNumSlices_ = slices.size() - 1;
00485 }
00486 else
00487 grouping_.groupNumSlices_ = slices.size();
00488
00489 legend_.clear();
00490 for(i=0; i<slices.size(); ++i)
00491 {
00492 TeLegendEntry legend(slices[i]);
00493 legend.group(i);
00494 legend.theme(id());
00495 legend_.push_back(legend);
00496 }
00497 return true;
00498 }
00499
00500 bool TeExternalTheme::buildGrouping(const TeGrouping& g, TeChronon chr, vector<map<string, string> >& mapObjValVec)
00501 {
00502 TeDatabase* db = remoteTheme_->layer()->database();
00503
00504 if(!db || chr == TeNOCHRONON)
00505 return false;
00506
00507 grouping_ = g;
00508
00509 unsigned int i;
00510 vector<TeSlice> slices;
00511 vector<double> dValues;
00512 vector<string> sValues;
00513 double mean, sum;
00514 mean = sum = 0.;
00515 int nullValues = 0;
00516 string val;
00517
00518 if (grouping_.groupMode_ == TeRasterSlicing)
00519 {
00520 int b = atoi(grouping_.groupAttribute_.name_.c_str());
00521 if (!remoteTheme_->layer()->raster() ||
00522 b < 0 ||
00523 b > remoteTheme_->layer()->raster()->params().nBands() ||
00524 grouping_.groupNumSlices_ <= 0)
00525 return false;
00526
00527 if (grouping_.groupMaxVal_ == TeMINFLOAT)
00528 grouping_.groupMaxVal_ = remoteTheme_->layer()->raster()->params().vmax_[b];
00529
00530 if (grouping_.groupMinVal_ == TeMAXFLOAT)
00531 grouping_.groupMinVal_ = remoteTheme_->layer()->raster()->params().vmin_[b];
00532
00533 TeGroupByEqualStep(grouping_.groupMinVal_, grouping_.groupMaxVal_,
00534 grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00535 }
00536 else
00537 {
00538 string func;
00539 TeStatisticType statType = TeNOSTATISTIC;
00540 if (grouping_.groupMode_ == TeUniqueValue && grouping_.groupAttribute_.type_ == TeSTRING)
00541 func = "MIN";
00542 else
00543 func = grouping_.groupFunction_;
00544
00545 if (func == "MIN")
00546 statType = TeMINVALUE;
00547 else if (func == "MAX")
00548 statType = TeMAXVALUE;
00549 else if (func == "MEAN")
00550 statType = TeMEAN;
00551 else if (func == "SUM")
00552 statType = TeSUM;
00553 else if (func == "COUNT")
00554 statType = TeCOUNT;
00555
00556
00557 bool loadGeometries = false;
00558
00559
00560
00561 TeGroupingAttr attrMMap;
00562 pair<TeAttributeRep, TeStatisticType> attr1 (
00563 TeAttributeRep(grouping_.groupAttribute_), statType);
00564 attrMMap.push_back(attr1);
00565
00566
00567 TeQuerierParams querierParams(loadGeometries, attrMMap);
00568 querierParams.setParams(this, chr);
00569
00570 TeQuerier querier(querierParams);
00571
00572
00573 int numFrames = querier.getNumTimeFrames();
00574 TeSTInstance sti;
00575 string objId;
00576 TePropertyVector vec;
00577 mapObjValVec.resize(numFrames);
00578
00579 for (int frame = 0; frame < numFrames; ++frame)
00580 {
00581 if (querier.loadInstances(frame) == false)
00582 continue;
00583
00584
00585 while(querier.fetchInstance(sti))
00586 {
00587 objId = sti.objectId();
00588 vec = sti.getPropertyVector();
00589 val = vec[0].value_;
00590 dValues.push_back(atof(val.c_str()));
00591 sValues.push_back(val);
00592 map<string, string>& objValMap = mapObjValVec[frame];
00593 objValMap.insert(make_pair(objId, val));
00594 }
00595 }
00596
00597 if(grouping_.groupMode_== TeEqualSteps)
00598 TeGroupByEqualStep(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00599 else if(grouping_.groupMode_== TeQuantil)
00600 TeGroupByQuantil(dValues.begin(), dValues.end(), grouping_.groupNumSlices_, slices, grouping_.groupPrecision_);
00601 else if(grouping_.groupMode_== TeStdDeviation)
00602 {
00603 string m = Te2String(mean);
00604 TeGroupByStdDev(dValues.begin(), dValues.end(), grouping_.groupStdDev_, slices, m, grouping_.groupPrecision_);
00605 }
00606 else if(grouping_.groupMode_== TeUniqueValue)
00607 {
00608 if(grouping_.groupFunction_ == "COUNT")
00609 TeGroupByUniqueValue(sValues, TeINT, slices, grouping_.groupPrecision_);
00610 else
00611 TeGroupByUniqueValue(sValues, grouping_.groupAttribute_.type_, slices, grouping_.groupPrecision_);
00612 }
00613 }
00614
00615 if(grouping_.groupNullAttr_ && nullValues > 0)
00616 {
00617 TeSlice ps;
00618 ps.count_ = nullValues;
00619 ps.from_ = "Missing Data";
00620 slices.push_back(ps);
00621 grouping_.groupNumSlices_ = slices.size() - 1;
00622 }
00623 else
00624 grouping_.groupNumSlices_ = slices.size();
00625
00626 legend_.clear();
00627 for(i=0; i<slices.size(); ++i)
00628 {
00629 TeLegendEntry legend(slices[i]);
00630 legend.group(i);
00631 legend.theme(id());
00632 legend_.push_back(legend);
00633 }
00634
00635 return true;
00636 }
00637
00638 bool TeExternalTheme::saveGrouping(TeSelectedObjects selectedObjects)
00639 {
00640 return TeTheme::saveGrouping(sourceDB_, selectedObjects);
00641 }
00642
00643 bool TeExternalTheme::saveLegendInCollection(TeSelectedObjects selectedObjects, std::string objectId)
00644 {
00645 return saveLegendInCollection(sourceDB_, selectedObjects, objectId);
00646 }
00647
00648 bool TeExternalTheme::saveLegendInCollection(TeDatabase* db, TeSelectedObjects , std::string objectId)
00649 {
00650 unsigned int i;
00651 if(grouping_.groupMode_ == TeNoGrouping)
00652 return false;
00653
00654 TeAttrDataType type = grouping_.groupAttribute_.type_;
00655 TeLegendEntryVector legVec = legend_;
00656 string groupingAttr = grouping_.groupAttribute_.name_;
00657
00658 string collectionTableRemote = remoteTheme_->collectionTable();
00659 string func;
00660
00661 if(grouping_.groupFunction_.empty())
00662 func = " MIN";
00663 else
00664 func = grouping_.groupFunction_;
00665
00666 if(grouping_.groupFunction_ == "COUNT")
00667 type = TeINT;
00668
00669 string query = "SELECT MIN(" + collectionTableRemote + ".c_object_id)";
00670 if(grouping_.groupNormAttribute_.empty())
00671 query += ", "+ func +"(" + groupingAttr + ")" + remoteTheme_->sqlGridFrom();
00672 else
00673 query += ", "+ func +"(" + groupingAttr + ") / "+ func +"(" + grouping_.groupNormAttribute_ + ")" + remoteTheme_->sqlGridFrom();
00674
00675 query += " GROUP BY " + collectionTableRemote + ".c_object_id";
00676
00677 map<int, vector<string> > legMap;
00678
00679 TeDatabasePortal* portal = remoteTheme_->layer()->database()->getPortal();
00680 if(portal->query(query) == false)
00681 {
00682 delete portal;
00683 return false;
00684 }
00685
00686 vector<string> idVec;
00687 vector<string> nullIdVec;
00688 vector<string> valVec;
00689 while(portal->fetchRow())
00690 {
00691
00692 string val = portal->getData(1);
00693 string oid = portal->getData(0);
00694 if (val.empty() == false)
00695 {
00696 idVec.push_back(oid);
00697 valVec.push_back(val);
00698 }
00699 else
00700 nullIdVec.push_back(oid);
00701 }
00702 if (grouping_.groupMode_ == TeUniqueValue)
00703 {
00704 unsigned int j = 0;
00705 while( j < idVec.size())
00706 {
00707 string val = valVec[j];
00708 string oid = idVec[j];
00709 if(type == TeREAL)
00710 {
00711 double a = atof(val.c_str());
00712 val = Te2String(a, grouping_.groupPrecision_);
00713 }
00714 else if(type == TeINT)
00715 {
00716 int a = atoi(val.c_str());
00717 val = Te2String(a);
00718 }
00719
00720 unsigned int siz = legend_.size();
00721 if(grouping_.groupNullAttr_ && nullIdVec.size() > 0)
00722 --siz;
00723 for(i=0; i < siz; i++)
00724 {
00725 TeLegendEntry& leg = legend_[i];
00726 if(val == leg.from())
00727 {
00728 legMap[leg.id()].push_back(oid);
00729 break;
00730 }
00731 }
00732 j++;
00733 }
00734 }
00735 else
00736 {
00737 unsigned int j = 0;
00738 while(j < idVec.size())
00739 {
00740 string val = valVec[j];
00741 string oid = idVec[j];
00742 if(type == TeREAL)
00743 {
00744 double a = atof(val.c_str());
00745 val = Te2String(a, grouping_.groupPrecision_);
00746 }
00747
00748 unsigned int siz = legend_.size();
00749 if(grouping_.groupNullAttr_ && !nullIdVec.empty())
00750 --siz;
00751 for(i=0; i < siz; i++)
00752 {
00753 TeLegendEntry& leg = legend_[i];
00754 int f = leg.from().find("mean");
00755 if(f >= 0)
00756 continue;
00757 double dval = atof(val.c_str());
00758 double dfrom = atof(leg.from().c_str());
00759 double dto = atof(leg.to().c_str());
00760 if(i < legend_.size()-1)
00761 {
00762 if(dval >= dfrom && dval < dto)
00763 {
00764 legMap[leg.id()].push_back(oid);
00765 break;
00766 }
00767 }
00768 else
00769 {
00770 if(dval >= dfrom && dval <= dto)
00771 {
00772 legMap[leg.id()].push_back(oid);
00773 break;
00774 }
00775 }
00776 }
00777 j++;
00778 }
00779 }
00780 delete portal;
00781
00782 int legId = defaultLegend_.id();
00783 if (grouping_.groupNullAttr_)
00784 legId = legend_[legend_.size()-1].id();
00785 for(i = 0; i < nullIdVec.size(); ++i)
00786 {
00787 string oid = nullIdVec[i];
00788 legMap[legId].push_back(oid);
00789 }
00790
00791 vector<string> svec;
00792 map<int, vector<string> > :: iterator it = legMap.begin();
00793 while(it != legMap.end())
00794 {
00795
00796 unsigned int i, j, k, size, chunkSize = 200, nChunks;
00797 string inClause;
00798 size = it->second.size();
00799 if (size % chunkSize)
00800 nChunks = size / chunkSize + 1;
00801 else
00802 nChunks = size / chunkSize;
00803
00804 j = 0;
00805 for (k = 0; k < nChunks; ++k)
00806 {
00807 i = 0;
00808 inClause = "(";
00809 while (j < size && i < chunkSize)
00810 {
00811 inClause += "'" + db->escapeSequence(it->second[j]) + "',";
00812 i++;
00813 j++;
00814 }
00815 inClause[inClause.size() - 1] = ')';
00816 svec.push_back(inClause);
00817 }
00818
00819
00820
00821 for(i=0; i<svec.size(); ++i)
00822 {
00823 string up = "UPDATE " + collectionTable_ + " SET c_legend_id = " + Te2String(it->first);
00824 up += " WHERE c_object_id IN " + svec[i];
00825 if (!objectId.empty())
00826 up += " AND c_object_id='"+objectId+"'";
00827 if(db->execute(up) == false)
00828 continue;
00829 }
00830 it++;
00831 svec.clear();
00832 }
00833 if(legend_.size())
00834 visibleRep_ = visibleRep_ | 0x40000000;
00835 else
00836 visibleRep_ = visibleRep_ | 0xbfffffff;
00837 string upVis = "UPDATE te_theme SET visible_rep=" + Te2String(visibleRep_) + " WHERE theme_id=" + Te2String(id());
00838
00839 if(!db->execute(upVis))
00840 return false;
00841
00842 loadObjectLegendMap();
00843
00844 return true;
00845 }
00846
00847 void TeExternalTheme::setLegendsForObjects()
00848 {
00849 }
00850
00851 bool TeExternalTheme::generateLabelPositions(const std::string& )
00852 {
00853 throw;
00854 return false;
00855 }
00856
00857 bool TeExternalTheme::deleteGrouping()
00858 {
00859 if(!sourceDB_)
00860 return false;
00861
00862 resetGrouping();
00863
00864
00865 if(!sourceDB_->deleteLegend (this->id()))
00866 return false;
00867
00868
00869 string sql = "DELETE FROM te_grouping WHERE theme_id= "+ Te2String(this->id());
00870 sourceDB_->execute (sql);
00871
00872 return true;
00873 }
00874
00875 void TeExternalTheme::createRasterVisual(TeRaster* rst)
00876 {
00877 if (rasterVisual_)
00878 delete rasterVisual_;
00879
00880 if (!rst)
00881 rst = remoteTheme_->layer()->raster();
00882
00883 if (!rst)
00884 return;
00885
00886 rasterVisual_ = new TeRasterTransform();
00887
00888 if (rst->params().photometric_[0] == TeRasterParams::TePallete)
00889 {
00890 rasterVisual_->setTransfFunction(&TeRasterTransform::Pallete2ThreeBand);
00891 rasterVisual_->setLutSize(rst->params().lutr_.size());
00892 return;
00893 }
00894
00895 if (visibleRep_ & 0x40000000 &&
00896 grouping_.groupMode_ == TeRasterSlicing)
00897 {
00898 int band = atoi(grouping_.groupAttribute_.name_.c_str());
00899 rasterVisual_->setSrcBand(band);
00900 if (rst->params().dataType_[band] != TeUNSIGNEDCHAR)
00901 rasterVisual_->generateLUT(legend_, 1024, defaultLegend_.visual(TePOLYGONS)->color());
00902 else
00903 rasterVisual_->generateLUT(legend_, 256, defaultLegend_.visual(TePOLYGONS)->color());
00904 rasterVisual_->setTransfFunction(&TeRasterTransform::LUT2ThreeBand);
00905 return;
00906 }
00907
00908 if (rst->params().dataType_[0] != TeUNSIGNEDCHAR)
00909 rasterVisual_->setLinearTransfParameters(rst->params().vmin_[0],rst->params().vmax_[0], 0, 255);
00910
00911 if (rst->params().nBands() == 1)
00912 rasterVisual_->setTransfFunction(&TeRasterTransform::Mono2ThreeBand);
00913 else if (rst->params().nBands() == 3)
00914 rasterVisual_->setTransfFunction(&TeRasterTransform::ThreeBand2RGB);
00915 else
00916 rasterVisual_->setTransfFunction(&TeRasterTransform::Band2Band);
00917 }
00918
00919 bool TeExternalTheme::addThemeTable(TeTable& table)
00920 {
00921 if( remoteTheme_ )
00922 return remoteTheme_->addThemeTable(table);
00923
00924 return false;
00925 }
00926
00927 void TeExternalTheme::addThemeTable(string tableName)
00928 {
00929 if( remoteTheme_ )
00930 return remoteTheme_->addThemeTable(tableName);
00931
00932 return;
00933 }
00934
00935 bool TeExternalTheme::isThemeTable(int tableId)
00936 {
00937 if( remoteTheme_ )
00938 return remoteTheme_->isThemeTable(tableId);
00939
00940 return false;
00941 }
00942
00943 bool TeExternalTheme::isThemeTable(string tableName)
00944 {
00945 if( remoteTheme_ )
00946 return remoteTheme_->isThemeTable(tableName);
00947
00948 return false;
00949 }
00950
00951 TeAttrTableVector& TeExternalTheme::attrTables()
00952 {
00953 if( remoteTheme_ )
00954 return remoteTheme_->attrTables();
00955 attTableVector_.clear();
00956 return attTableVector_;
00957 }
00958
00959 bool TeExternalTheme::setAttTables(TeAttrTableVector& attrs)
00960 {
00961 if( remoteTheme_ )
00962 return remoteTheme_->setAttTables(attrs);
00963
00964 return false;
00965 }
00966
00967 bool TeExternalTheme::getAttTables(TeAttrTableVector& attrs, TeAttrTableType attType)
00968 {
00969 if(remoteTheme_)
00970 return remoteTheme_->getAttTables(attrs, attType);
00971
00972 return false;
00973 }
00974
00975 bool TeExternalTheme::getTable(TeTable& table, const string tableName)
00976 {
00977 if(remoteTheme_)
00978 return remoteTheme_->getTable(table, tableName);
00979
00980 return false;
00981 }
00982
00983 void TeExternalTheme::clearAttTableVector()
00984 {
00985 if(remoteTheme_)
00986 remoteTheme_->clearAttTableVector();
00987 }
00988
00989 bool TeExternalTheme::getTemporalTable(TeTable& table)
00990 {
00991 if(remoteTheme_)
00992 return remoteTheme_->getTemporalTable(table);
00993
00994 return false;
00995 }
00996
00997 bool TeExternalTheme::removeThemeTable(unsigned int index)
00998 {
00999 if(remoteTheme_)
01000 return remoteTheme_->removeThemeTable(index);
01001
01002 return false;
01003 }
01004
01005 string TeExternalTheme::getTableName(const string& attrName)
01006 {
01007 if(remoteTheme_)
01008 return remoteTheme_->getTableName(attrName);
01009
01010 return "";
01011 }
01012
01013 string TeExternalTheme::getAttribute(unsigned int index)
01014 {
01015 if(remoteTheme_)
01016 return remoteTheme_->getAttribute(index);
01017
01018 return "";
01019 }
01020
01021
01022 bool TeExternalTheme::loadThemeTables()
01023 {
01024 if(!remoteTheme_)
01025 return false;
01026
01027 bool result = remoteTheme_->loadThemeTables();
01028
01029 if(result)
01030 {
01031 clearAttTableVector();
01032 attrTables() = remoteTheme_->attrTables();
01033 }
01034
01035 return result;
01036 }
01037
01038
01039 TeAttributeList TeExternalTheme::sqlAttList()
01040 {
01041 if(remoteTheme_)
01042 return remoteTheme_->sqlAttList();
01043
01044 return TeAttributeList();
01045 }
01046
01047 void TeExternalTheme::clearAttList()
01048 {
01049 if(remoteTheme_)
01050 return remoteTheme_->clearAttList();
01051 }
01052
01053 TeAttributeList TeExternalTheme::sqlNumAttList()
01054 {
01055 if(remoteTheme_)
01056 return remoteTheme_->sqlNumAttList();
01057
01058 return TeAttributeList();
01059 }
01060
01061 void TeExternalTheme::clearNumAttList()
01062 {
01063 if(remoteTheme_)
01064 remoteTheme_->clearNumAttList();
01065 }
01066
01067 string TeExternalTheme::sqlJoin()
01068 {
01069 if(remoteTheme_)
01070 return remoteTheme_->sqlJoin();
01071
01072 return "";
01073 }
01074
01075 string TeExternalTheme::sqlFrom()
01076 {
01077 if(remoteTheme_)
01078 return remoteTheme_->sqlFrom();
01079
01080 return "";
01081 }
01082
01083 vector<string>& TeExternalTheme::aliasVector()
01084 {
01085 if(remoteTheme_)
01086 return remoteTheme_->aliasVector();
01087 aliasVector_.clear();
01088 return aliasVector_;
01089 }
01090
01091 void TeExternalTheme::loadAliasVector()
01092 {
01093 if(remoteTheme_)
01094 return remoteTheme_->loadAliasVector();
01095
01096 return;
01097 }
01098
01099 void TeExternalTheme::loadAttrLists()
01100 {
01101 if(!remoteTheme_)
01102 return;
01103
01104 remoteTheme_->loadAttrLists();
01105
01106 sqlAttList_.clear();
01107 sqlNumAttList_.clear();
01108
01109 sqlAttList_ = remoteTheme_->sqlAttList();
01110 sqlNumAttList_ = remoteTheme_->sqlNumAttList();
01111
01112 }
01113
01114 bool TeExternalTheme::locatePolygon(TeCoord2D &pt, TePolygon &polygon, const double& tol)
01115 {
01116 if(!remoteTheme_)
01117 return false;
01118
01119 return remoteTheme_->locatePolygon(pt, polygon, tol);
01120 }
01121
01122 bool TeExternalTheme::locatePolygonSet(TeCoord2D &pt, double tol, TePolygonSet &polygons)
01123 {
01124 if(!remoteTheme_)
01125 return false;
01126
01127 return remoteTheme_->locatePolygonSet(pt, tol, polygons);
01128 }
01129
01130 bool TeExternalTheme::locateLine(TeCoord2D &pt, TeLine2D &line, const double& tol)
01131 {
01132 if(!remoteTheme_)
01133 return false;
01134
01135 return remoteTheme_->locateLine(pt, line, tol);
01136 }
01137
01138 bool TeExternalTheme::locatePoint(TeCoord2D &pt, TePoint &point, const double& tol)
01139 {
01140 if(!remoteTheme_)
01141 return false;
01142
01143 return remoteTheme_->locatePoint(pt, point, tol);
01144 }
01145
01146 bool TeExternalTheme::locateCell(TeCoord2D &pt, TeCell &c, const double& tol)
01147 {
01148 if(!remoteTheme_)
01149 return false;
01150
01151 return remoteTheme_->locateCell(pt, c, tol);
01152 }
01153
01154 bool TeExternalTheme::hasObjectsWithoutGeometries(TeGeomRep geomRep)
01155 {
01156 if(!remoteTheme_)
01157 return false;
01158
01159 return remoteTheme_->hasObjectsWithoutGeometries(geomRep);
01160 }
01161
01162 bool TeExternalTheme::removeObjectsWithoutGeometries(TeGeomRep geomRep)
01163 {
01164 if(!remoteTheme_)
01165 return false;
01166
01167 return remoteTheme_->removeObjectsWithoutGeometries(geomRep);
01168 }
01169
01170 int TeExternalTheme::createExternalThemeTable(TeDatabase* sourceDB)
01171 {
01172 if(!sourceDB)
01173 return 0;
01174
01175 if(sourceDB->tableExist("te_external_theme"))
01176 return -1;
01177
01178 TeAttributeList attList;
01179
01180 TeAttribute att1;
01181 att1.rep_.name_ = "theme_id";
01182 att1.rep_.isAutoNumber_ = false;
01183 att1.rep_.isPrimaryKey_ = true;
01184 att1.rep_.null_ = false;
01185 att1.rep_.type_ = TeINT;
01186 att1.rep_.numChar_ = 0;
01187 attList.push_back(att1);
01188
01189 TeAttribute att2;
01190 att2.rep_.name_ = "database_id";
01191 att2.rep_.isAutoNumber_ = false;
01192 att2.rep_.isPrimaryKey_ = false;
01193 att2.rep_.null_ = false;
01194 att2.rep_.type_ = TeINT;
01195 att2.rep_.numChar_ = 0;
01196 attList.push_back(att2);
01197
01198 TeAttribute att3;
01199 att3.rep_.name_ = "external_theme_id";
01200 att3.rep_.isAutoNumber_ = false;
01201 att3.rep_.isPrimaryKey_ = false;
01202 att3.rep_.null_ = false;
01203 att3.rep_.type_ = TeINT;
01204 att3.rep_.numChar_ = 0;
01205 attList.push_back(att3);
01206
01207 if(!sourceDB->createTable("te_external_theme", attList))
01208 return 0;
01209
01210 return 1;
01211 }
01212
01213 bool TeExternalTheme::populateCollection(std::string , const bool& )
01214 {
01215 return true;
01216 }
01217
01218 void TeExternalTheme::createLegendMapId(std::map<int, int>& mapIdLegend)
01219 {
01220 mapIdLegend.clear();
01221
01222 mapIdLegend[remoteTheme_->outOfCollectionLegend().id()] = outOfCollectionLegend().id();
01223 mapIdLegend[remoteTheme_->withoutDataConnectionLegend().id()] = withoutDataConnectionLegend().id();
01224 mapIdLegend[remoteTheme_->defaultLegend().id()] = defaultLegend().id();
01225 mapIdLegend[remoteTheme_->pointingLegend().id()] = pointingLegend().id();
01226 mapIdLegend[remoteTheme_->queryLegend().id()] = queryLegend().id();
01227 mapIdLegend[remoteTheme_->queryAndPointingLegend().id()] = queryAndPointingLegend().id();
01228
01229 for (int i = 0; i < remoteTheme_->grouping().groupNumSlices_; ++i)
01230 {
01231 mapIdLegend[remoteTheme_->legend()[i].id()] = legend()[i].id();
01232 }
01233
01234 return;
01235 }
01236
01237 bool TeExternalTheme::copyRemoteCollection(std::map<int, int>& mapIdLegend)
01238 {
01239 if(mapIdLegend.empty())
01240 return false;
01241
01242 if(remoteTheme_->collectionTable().empty())
01243 {
01244 return false;
01245 }
01246
01247 if(!remoteTheme_->layer()->database()->tableExist(remoteTheme_->collectionTable()))
01248 {
01249 return false;
01250 }
01251
01252
01253 TeDatabasePortal* remotePortal = remoteTheme_->layer()->database()->getPortal();
01254 string strSQL = "SELECT * from ";
01255 strSQL += remoteTheme_->collectionTable();
01256
01257 if(remotePortal->query(strSQL))
01258 {
01259 while(remotePortal->fetchRow())
01260 {
01261 string c_obj_id = remotePortal->getData(0);
01262 int c_leg_id = atoi(remotePortal->getData(1));
01263 string lab_x = remotePortal->getData(2);
01264 string lab_y = remotePortal->getData(3);
01265
01266 string c_leg_own = "0";
01267 string c_obj_stat = remotePortal->getData(5);
01268
01269 int new_c_leg_id = mapIdLegend[c_leg_id];
01270
01271 string strINS = "INSERT INTO ";
01272 strINS += this->collectionTable();
01273 strINS += " (c_object_id, c_legend_id, label_x, label_y, c_legend_own, c_object_status) ";
01274 strINS += "VALUES (";
01275 strINS += (c_obj_id.empty() ? "''" : "'" + c_obj_id + "'");
01276 strINS += ", ";
01277 strINS += Te2String(new_c_leg_id);
01278 strINS += ", ";
01279 strINS += (lab_x.empty() ? "''" : lab_x);
01280 strINS += ", ";
01281 strINS += (lab_y.empty() ? "''" : lab_y);
01282 strINS += ", ";
01283 strINS += (c_leg_own.empty() ? "''" : c_leg_own);
01284 strINS += ", ";
01285 strINS += (c_obj_stat.empty() ? "''" : c_obj_stat);
01286 strINS += ")";
01287
01288 if(!sourceDB_->execute(strINS))
01289 return false;
01290 }
01291 }
01292 else
01293 return false;
01294
01295 remotePortal->freeResult();
01296
01297
01298 string strSQLAux = "SELECT * from ";
01299 strSQLAux += remoteTheme_->collectionAuxTable();
01300
01301 if(remotePortal->query(strSQLAux))
01302 {
01303 while(remotePortal->fetchRow())
01304 {
01305 string c_obj_id = remotePortal->getData(0);
01306 string unique_id = remotePortal->getData(1);
01307 string grid_status = remotePortal->getData(2);
01308
01309 string strINSAux = "INSERT INTO ";
01310 strINSAux +=collectionAuxTable();
01311 strINSAux += " (object_id, unique_id, grid_status) ";
01312 strINSAux += "VALUES (";
01313 strINSAux += (c_obj_id.empty() ? "''" : "'" + c_obj_id + "'");
01314 strINSAux += ", ";
01315 strINSAux += (unique_id.empty() ? "''" : unique_id);
01316 strINSAux += ", ";
01317 strINSAux += (grid_status.empty() ? "''" : grid_status);
01318 strINSAux += ")";
01319
01320 if(!sourceDB_->execute(strINSAux))
01321 return false;
01322 }
01323 }
01324 else
01325 return false;
01326
01327 remotePortal->freeResult();
01328 delete remotePortal;
01329
01330 return true;
01331 }
01332
01333
01334
01335 bool TeExternalTheme::getRemoteThemeInfo(int& remoteThemeId, int& databaseId)
01336 {
01337 if(!sourceDB_)
01338 return false;
01339
01340 try
01341 {
01342 TeDatabasePortal* dbPortal = sourceDB_->getPortal();
01343
01344 if(!dbPortal)
01345 {
01346 return false;
01347 }
01348
01349 std::string strSQL = "SELECT external_theme_id, database_id FROM te_external_theme ";
01350 strSQL += "WHERE theme_id = " + Te2String(id());
01351
01352 if(!dbPortal->query(strSQL) || !dbPortal->fetchRow())
01353 {
01354 dbPortal->freeResult();
01355 delete dbPortal;
01356 return false;
01357 }
01358
01359 remoteThemeId = dbPortal->getInt("external_theme_id");
01360 databaseId = dbPortal->getInt("database_id");
01361
01362 dbPortal->freeResult();
01363 delete dbPortal;
01364 }
01365 catch(TeException&)
01366 {
01367 }
01368
01369 return true;
01370 }
01371
01372 void TeExternalTheme::setRemoteDbId(const int& removeDbId)
01373 {
01374 remoteDbId_ = removeDbId;
01375 }
01376
01377 bool
01378 TeExternalTheme::loadMetadata(TeDatabase* db)
01379 {
01380 if(remoteTheme_ || !db)
01381 return false;
01382
01383 int remoteThemeId = -1;
01384 int remoteDBId = -1;
01385
01386 setSourceDatabase(db);
01387
01388 if(!getRemoteThemeInfo(remoteThemeId, remoteDBId))
01389 return false;
01390
01391 TeDatabase* remotedb = TeDBConnectionsPool::instance().getDatabase(remoteDBId);
01392 if(remotedb == NULL)
01393 {
01394 std::string hostName, dbmsName, dbName, userName, password;
01395 int port = 0;
01396 if(!TeDBConnectionsPool::instance().getConnectionInfo(db, remoteDBId, hostName, dbmsName, dbName, userName, password, port))
01397 {
01398 return false;
01399 }
01400
01401 remotedb = TeDBConnectionsPool::instance().getDatabase(dbmsName, dbName, hostName, userName, password, port);
01402
01403 if(remotedb != NULL)
01404 {
01405 TeDBConnectionsPool::instance().saveExternalDBConnection(db, remotedb);
01406 }
01407 }
01408
01409 if(!remotedb || !remotedb->isConnected())
01410 return false;
01411
01412 TeThemeMap::iterator itTheme = remotedb->themeMap().find(remoteThemeId);
01413
01414 TeTheme* remoteTheme = NULL;
01415
01416 if(itTheme != remotedb->themeMap().end())
01417 {
01418
01419 if(itTheme->second->getProductId()!=TeTHEME)
01420 return false;
01421
01422 remoteTheme = dynamic_cast<TeTheme*>(itTheme->second);
01423 }
01424 else
01425 {
01426
01427 remoteTheme = new TeTheme();
01428 remoteTheme->id(remoteThemeId);
01429 try
01430 {
01431 if(!remotedb->loadTheme(remoteTheme))
01432 return false;
01433 }
01434 catch(...)
01435 {
01436 return false;
01437 }
01438 }
01439
01440 if(remoteTheme == NULL)
01441 {
01442 return false;
01443 }
01444 if(remoteTheme->layer() == NULL)
01445 {
01446 return false;
01447 }
01448
01449 setRemoteTheme(remoteTheme);
01450
01451 remotedb->clear();
01452
01453 loadObjectLegendMap();
01454 return true;
01455 }
01456
01457 bool TeExternalTheme::saveMetadata(TeDatabase* dstDB)
01458 {
01459 if(!remoteTheme_ || !remoteTheme_->layer() || !remoteTheme_->layer()->database())
01460 return false;
01461
01462 int themeId = id();
01463 int remoteThemeId = remoteTheme_->id();
01464
01465 TeDatabasePortal* portal = dstDB->getPortal();
01466 if(!portal)
01467 return false;
01468
01469 string sql = "SELECT * FROM te_external_theme WHERE theme_id = "+ Te2String(themeId);
01470 bool isUpdate = false;
01471 if(!portal->query(sql))
01472 {
01473 delete portal;
01474 return false;
01475 }
01476 if(portal->fetchRow())
01477 isUpdate = true;
01478 delete portal;
01479
01480 string strSQL;
01481 if(isUpdate)
01482 {
01483 strSQL = "UPDATE te_external_theme SET ";
01484 strSQL += " theme_id = "+ Te2String(themeId);
01485 strSQL += ", ";
01486 strSQL += " database_id = "+ Te2String(remoteDbId_);
01487 strSQL += ", ";
01488 strSQL += " external_theme_id = "+ Te2String(remoteThemeId);
01489 strSQL += " WHERE theme_id = "+ Te2String(themeId);
01490 }
01491 else
01492 {
01493 strSQL = "INSERT INTO te_external_theme (theme_id, database_id, external_theme_id) VALUES (";
01494 strSQL += Te2String(themeId);
01495 strSQL += ", ";
01496 strSQL += Te2String(remoteDbId_);
01497 strSQL += ", ";
01498 strSQL += Te2String(remoteThemeId);
01499 strSQL += ")";
01500 }
01501
01502 if(!dstDB->execute(strSQL))
01503 return false;
01504
01505 return true;
01506 }
01507
01508 bool TeExternalTheme::eraseMetadata(TeDatabase* db)
01509 {
01510 int themeId = id();
01511
01512 std::string strSQL = " DELETE FROM te_external_theme ";
01513 strSQL += " WHERE theme_id = "+ Te2String(themeId);
01514
01515 if(!db->execute(strSQL))
01516 return false;
01517
01518 return true;
01519 }
01520
01521 bool TeExternalTheme::beforeCopyThemeTo(TeAbstractTheme* absThemeCopy, TeDatabase* outputDatabase)
01522 {
01523 if(TeTheme::beforeCopyThemeTo(absThemeCopy, outputDatabase) == false)
01524 {
01525 return false;
01526 }
01527
01528
01529 TeExternalTheme* themeCopy = dynamic_cast<TeExternalTheme*>(absThemeCopy);
01530 if(themeCopy == 0)
01531 {
01532 return false;
01533 }
01534
01535 TeDBConnectionsPool::createDBConnectionTable(outputDatabase);
01536 if(themeCopy->createExternalThemeTable(outputDatabase) == 0)
01537 {
01538 return false;
01539 }
01540
01541 TeDatabase* remoteDb = themeCopy->getRemoteTheme()->layer()->database();
01542 TeDBConnectionsPool::instance().saveExternalDBConnection(outputDatabase, remoteDb);
01543 int dbId = TeDBConnectionsPool::instance().getDatabaseIdx(remoteDb);
01544
01545 themeCopy->setSourceDatabase(outputDatabase);
01546 themeCopy->setRemoteDbId(dbId);
01547
01548 return true;
01549 }