00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "TePostGIS.h"
00025 #include "TePGUtils.h"
00026 #include "TePGInterface.h"
00027
00028 #define BUFFSIZE 1024
00029
00030 TePostGIS::TePostGIS()
00031 {
00032 dbmsName_ = "PostGIS";
00033 }
00034
00035 bool TePostGIS::newDatabase(const string& database, const string& user, const string& password, const string& host, const int& port, bool terralibModel, const std::string& characterSet)
00036 {
00037 errorMessage_ = "";
00038
00039 string createDB = "CREATE DATABASE ";
00040 createDB += "\"" + database + "\"";
00041 createDB += " TEMPLATE = template_postgis";
00042
00043 if(!characterSet.empty())
00044 {
00045 createDB += " ENCODING = '" + characterSet + "'";
00046 }
00047
00048 if(!connect(host, user, password, "template_postgis", port))
00049 {
00050 close();
00051 return false;
00052 }
00053
00054 bool connected = false;
00055
00056 if(execute(createDB))
00057 {
00058 connected = connect(host, user, password, database, port);
00059 }
00060 else
00061 {
00062 std::string errMessage = errorMessage();
00063 close();
00064 errorMessage_ = errMessage;
00065 return false;
00066 }
00067
00068 if(terralibModel)
00069 {
00070
00071 if(connected)
00072 {
00073 if(!createConceptualModel())
00074 {
00075 close();
00076 return false;
00077 }
00078 }
00079 else
00080 {
00081 close();
00082 return false;
00083 }
00084 }
00085
00086 return true;
00087 }
00088
00089 bool TePostGIS::connect(const string& host, const string& user, const string& password, const string& database, int port)
00090 {
00091 if(!realConnect(host, user, password, database, port))
00092 return false;
00093
00094
00095 TePGRecordset rec;
00096
00097 string sql = "SELECT postgis_version()";
00098
00099 if(!rec.open(sql.c_str(), tepg_connection_) || rec.recordCount() <= 0)
00100 {
00101 rec.close();
00102
00103 this->close();
00104
00105 errorMessage_ = "Couldn't find PostGIS extension! You may use the PostgreSQL driver!";
00106
00107 return false;
00108 }
00109
00110
00111 int version = PQserverVersion(tepg_connection_->c_ptr());
00112 if(version >= 80100)
00113 {
00114 gistBoxOps_ = "box_ops";
00115 if(version >= 90000)
00116 {
00117
00118 execute("set bytea_output = 'escape'");
00119 }
00120 return true;
00121 }
00122
00123 sql = "SELECT opcname FROM pg_opclass WHERE (opcname = 'gist_box_ops') ORDER BY opcname DESC";
00124
00125 if(rec.open(sql.c_str(), tepg_connection_) && rec.recordCount() > 0)
00126 {
00127 TePostgreSQL::gistBoxOps_ = rec.value(0);
00128 rec.close();
00129
00130 return true;
00131 }
00132
00133 rec.close();
00134
00135 this->close();
00136
00137 errorMessage_ = "GiST extension not found! Please, install R-Tree GiST in your database and try again!";
00138
00139 return false;
00140 }
00141
00142 bool TePostGIS::showDatabases(const string& host, const string& user, const string& password, vector<string>& dbNames, int port)
00143 {
00144 errorMessage_ = "";
00145
00146 if(TePostgreSQL::realConnect(host, user, password, "template1", port))
00147 {
00148 string sql = "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1') ORDER BY datname";
00149
00150 TePostGISPortal p(this);
00151
00152 if(p.query(sql) && p.fetchRow())
00153 {
00154 do
00155 {
00156 dbNames.push_back(p.getData("datname"));
00157 }while(p.fetchRow());
00158
00159 return true;
00160 }
00161 else
00162 errorMessage_ = "Didn't find any database!";
00163 }
00164
00165 return false;
00166 }
00167
00168 TeDatabasePortal* TePostGIS::getPortal()
00169 {
00170 errorMessage_ = "";
00171
00172 TeDatabasePortal *portal = new TePostGISPortal(this);
00173
00174 return portal;
00175 }
00176
00177 bool TePostGIS::createTable(const string& table, TeAttributeList &attr)
00178 {
00179 errorMessage_ = "";
00180
00181 bool first = true;
00182
00183 TeAttributeList::iterator it = attr.begin();
00184
00185 string createTable ="CREATE TABLE " + table +" (";
00186
00187 string type;
00188 char size[8];
00189
00190 string pkeys;
00191
00192 vector<string> addGeomColumnsSQL;
00193 string addGeomSQL = "";
00194
00195 while(it != attr.end())
00196 {
00197 switch ((*it).rep_.type_)
00198 {
00199 case TeSTRING: if((*it).rep_.numChar_ > 0)
00200 {
00201 type = "VARCHAR(" + Te2String((*it).rep_.numChar_) + ")";
00202 }
00203 else
00204 {
00205 type = "TEXT";
00206 }
00207 break;
00208
00209 case TeREAL: type = "FLOAT8";
00210 break;
00211
00212 case TeINT:
00213 case TeUNSIGNEDINT:
00214 type = ((*it).rep_.isAutoNumber_) ? "SERIAL" : "INTEGER";
00215 break;
00216
00217 case TeBLOB:
00218 type = "BYTEA";
00219 break;
00220
00221 case TeDATETIME: type = "TIMESTAMP(0)";
00222 break;
00223
00224 case TeCHARACTER: type = "CHAR ";
00225 sprintf (size, "(%d)", (*it).rep_.numChar_);
00226 type += string (size);
00227 break;
00228
00229 case TeBOOLEAN: type = "BOOLEAN";
00230 break;
00231
00232 case TePOINTTYPE:
00233 case TePOINTSETTYPE:
00234 addGeomSQL = "SELECT AddGeometryColumn('";
00235 addGeomSQL += TeConvertToLowerCase(table);
00236 addGeomSQL += "', 'spatial_data', ";
00237 addGeomSQL += Te2String(it->rep_.epsgCode_) + ", 'POINT', 2)";
00238
00239 addGeomColumnsSQL.push_back(addGeomSQL);
00240
00241 ++it;
00242 continue;
00243
00244 case TeLINE2DTYPE:
00245 case TeLINESETTYPE:
00246 addGeomSQL = "SELECT AddGeometryColumn('";
00247 addGeomSQL += TeConvertToLowerCase(table);
00248 addGeomSQL += "', 'spatial_data',";
00249 addGeomSQL += Te2String(it->rep_.epsgCode_) + ", 'LINESTRING', 2)";
00250
00251 addGeomColumnsSQL.push_back(addGeomSQL);
00252
00253 ++it;
00254 continue;
00255
00256 case TePOLYGONTYPE:
00257 case TePOLYGONSETTYPE:
00258 addGeomSQL = "SELECT AddGeometryColumn('";
00259 addGeomSQL += TeConvertToLowerCase(table);
00260 addGeomSQL += "', 'spatial_data',";
00261 addGeomSQL += Te2String(it->rep_.epsgCode_) + ", 'POLYGON', 2)";
00262
00263 addGeomColumnsSQL.push_back(addGeomSQL);
00264
00265 ++it;
00266 continue;
00267
00268 case TeCELLTYPE:
00269 case TeCELLSETTYPE:
00270 if(!first)
00271 createTable += ", ";
00272 else
00273 first = false;
00274
00275 addGeomSQL = "SELECT AddGeometryColumn('";
00276 addGeomSQL += TeConvertToLowerCase(table);
00277 addGeomSQL += "', 'spatial_data',";
00278 addGeomSQL += Te2String(it->rep_.epsgCode_) + ", 'POLYGON', 2)";
00279
00280 addGeomColumnsSQL.push_back(addGeomSQL);
00281
00282 createTable += " col_number INTEGER NOT NULL,";
00283 createTable += " row_number INTEGER NOT NULL ";
00284 ++it;
00285 continue;
00286
00287 case TeRASTERTYPE:
00288 if(!first)
00289 createTable += ", ";
00290 else
00291 first = false;
00292
00293 createTable += " block_box BOX NOT NULL,";
00294 createTable += " band_id INTEGER NOT NULL,";
00295 createTable += " resolution_factor INTEGER NOT NULL,";
00296 createTable += " subband INTEGER NOT NULL,";
00297 createTable += " spatial_data BYTEA,";
00298 createTable += " block_size INTEGER NOT NULL ";
00299 ++it;
00300 continue;
00301
00302 case TeNODETYPE:
00303 case TeNODESETTYPE:
00304 addGeomSQL = "SELECT AddGeometryColumn('";
00305 addGeomSQL += TeConvertToLowerCase(table);
00306 addGeomSQL += "', 'spatial_data', ";
00307 addGeomSQL += Te2String(it->rep_.epsgCode_) + ", 'POINT', 2)";
00308
00309 addGeomColumnsSQL.push_back(addGeomSQL);
00310
00311 ++it;
00312 continue;
00313
00314 case TeTEXTTYPE:
00315 case TeTEXTSETTYPE:
00316
00317 default: type = "VARCHAR ";
00318 sprintf (size, "(%d)", (*it).rep_.numChar_);
00319 type += string (size);
00320 break;
00321 }
00322
00323 if(!((*it).rep_.defaultValue_.empty()))
00324 type += " DEFAULT '" + (*it).rep_.defaultValue_ + "' ";
00325
00326 if(!((*it).rep_.null_))
00327 type += " NOT NULL ";
00328
00329 if(!first)
00330 createTable += ", ";
00331 else
00332 first = false;
00333
00334 createTable += (*it).rep_.name_ + " ";
00335 createTable += type;
00336
00337
00338 if((*it).rep_.isPrimaryKey_ && (*it).rep_.type_ != TeBLOB )
00339 {
00340 if(!pkeys.empty())
00341 pkeys += ", ";
00342
00343 pkeys += (*it).rep_.name_;
00344 }
00345
00346
00347 ++it;
00348 }
00349
00350 if(!pkeys.empty())
00351 { string pk = ", PRIMARY KEY(";
00352 pk += pkeys;
00353 pk += ")";
00354
00355 createTable += pk;
00356 }
00357
00358
00359 createTable += ");";
00360
00361 if(!execute(createTable))
00362 return false;
00363
00364 for(unsigned int i = 0; i < addGeomColumnsSQL.size(); ++i)
00365 {
00366 if(!execute(addGeomColumnsSQL[i]))
00367 return false;
00368 }
00369
00370 return true;
00371 }
00372
00373 bool TePostGIS::generateLabelPositions(TeTheme *theme, const std::string& objectId)
00374 {
00375 string geomTable, upd;
00376 string collTable = theme->collectionTable();
00377
00378 if((collTable.empty()) || (!tableExist(collTable)))
00379 return false;
00380
00381 if(theme->layer()->hasGeometry(TeCELLS) ||
00382 theme->layer()->hasGeometry(TePOLYGONS) ||
00383 theme->layer()->hasGeometry(TeLINES) ||
00384 theme->layer()->hasGeometry(TePOINTS))
00385 {
00386 geomTable = theme->layer()->tableName(TeCELLS);
00387
00388 if(geomTable.empty())
00389 {
00390 geomTable = theme->layer()->tableName(TePOLYGONS);
00391 if(geomTable.empty())
00392 {
00393 geomTable = theme->layer()->tableName(TeLINES);
00394
00395 if(geomTable.empty())
00396 geomTable = theme->layer()->tableName(TePOINTS);
00397 }
00398 }
00399
00400 upd= " UPDATE " + collTable + " SET ";
00401 upd += " label_x = (SELECT MAX(xmin(spatial_data::box3d) + (xmax(spatial_data::box3d)";
00402 upd += " - xmin(spatial_data::box3d)) / 2.0) ";
00403 upd += "FROM " + geomTable + " WHERE object_id = c_object_id), ";
00404
00405 upd += " label_y = (SELECT MAX(ymin(spatial_data::box3d) + (ymax(spatial_data::box3d)";
00406 upd += " - ymin(spatial_data::box3d)) / 2.0) ";
00407 upd += "FROM " + geomTable + " WHERE object_id = c_object_id) ";
00408
00409 upd += " WHERE (label_x IS NULL) OR (label_y IS NULL)";
00410 }
00411
00412 if (!objectId.empty())
00413 upd += " AND c_object_id='"+objectId+"'";
00414
00415 return execute(upd);
00416 }
00417
00418
00419 bool TePostGIS::selectPolygonSet(const string& table, const string& criteria, TePolygonSet& ps)
00420 {
00421 TeDatabasePortal *portal = this->getPortal();
00422
00423 string sql ="SELECT * FROM " + table;
00424
00425 if(!criteria.empty())
00426 sql += " WHERE " + criteria;
00427
00428 if(!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00429 {
00430 delete portal;
00431 return false;
00432 }
00433
00434 bool flag = true;
00435
00436 do
00437 {
00438 TePolygon poly;
00439 flag = portal->fetchGeometry(poly);
00440 ps.add(poly);
00441 }
00442 while(flag);
00443
00444 delete portal;
00445
00446 return true;
00447 }
00448
00449 bool TePostGIS::loadPolygonSet(TeTheme* theme, TePolygonSet& ps)
00450 {
00451 string collTable = theme->collectionTable();
00452
00453 if(collTable.empty())
00454 return false;
00455
00456 TeLayer* themeLayer = theme->layer();
00457
00458 if(!themeLayer->hasGeometry(TePOLYGONS))
00459 return false;
00460
00461 string polygonTable = themeLayer->tableName(TePOLYGONS);
00462
00463 if(polygonTable.empty())
00464 return false;
00465
00466 string sql = "SELECT * FROM (" + polygonTable + " RIGHT JOIN " + collTable;
00467 sql += " ON " + polygonTable + ".object_id = " + collTable + ".c_object_id)";
00468
00469 TeDatabasePortal *portal = this->getPortal();
00470
00471 if(!portal)
00472 return false;
00473
00474 if(!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00475 {
00476 delete portal;
00477 return false;
00478 }
00479
00480 bool flag = true;
00481
00482 do
00483 {
00484 TePolygon poly;
00485 flag = portal->fetchGeometry(poly);
00486 ps.add ( poly );
00487 }
00488 while(flag);
00489
00490 delete portal;
00491
00492 return true;
00493 }
00494
00495 bool TePostGIS::loadPolygonSet(const string& table, const string& geoid, TePolygonSet& ps)
00496 {
00497 TeDatabasePortal *portal = this->getPortal();
00498
00499 string q ="SELECT * FROM " + table;
00500
00501 if (!geoid.empty())
00502 q += " WHERE object_id = '" + geoid +"'";
00503
00504 if (!portal->query(q, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00505 {
00506 delete portal;
00507 return false;
00508 }
00509
00510 bool flag = true;
00511
00512 do
00513 {
00514 TePolygon poly;
00515 flag = portal->fetchGeometry(poly);
00516 ps.add(poly);
00517 }
00518 while (flag);
00519
00520 delete portal;
00521
00522 return true;
00523 }
00524
00525 bool TePostGIS::loadPolygonSet(const string& table, TeBox& box, TePolygonSet& ps)
00526 {
00527 TeDatabasePortal *portal = this->getPortal();
00528
00529 if(!portal)
00530 return false;
00531
00532 string q = "SELECT * FROM " + table + " WHERE ";
00533 q += this->getSQLBoxWhere (box, TePOLYGONS, table);
00534
00535 if(!portal->query(q, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00536 {
00537 delete portal;
00538 return false;
00539 }
00540
00541 bool flag = true;
00542
00543 do
00544 {
00545 TePolygon poly;
00546 flag = portal->fetchGeometry(poly);
00547 ps.add(poly);
00548 }
00549 while (flag);
00550
00551 delete portal;
00552
00553 return true;
00554 }
00555
00556 TeDatabasePortal* TePostGIS::loadPolygonSet(const string& table, TeBox& box)
00557 {
00558 TeDatabasePortal *portal = this->getPortal();
00559
00560 if(!portal)
00561 return 0;
00562
00563 string q = "SELECT * FROM " + table + " WHERE ";
00564 q += this->getSQLBoxWhere(box, TePOLYGONS, table);
00565
00566 if(!portal->query(q, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00567 {
00568 delete portal;
00569 return 0;
00570 }
00571 else
00572 return portal;
00573 }
00574
00575 bool TePostGIS::locatePolygon(const string& table, TeCoord2D& pt, TePolygon& polygon, const double& tol)
00576 {
00577 TeDatabasePortal *portal = this->getPortal();
00578
00579 if (!portal)
00580 return false;
00581
00582 TeBox box (pt.x()-tol,pt.y()-tol,pt.x()+tol,pt.y()+tol);
00583
00584
00585 std::string tableName = table;
00586
00587 size_t found = tableName.find(" ");
00588 if(found != tableName.npos)
00589 {
00590 std::vector<std::string> vecValues;
00591 TeSplitString(tableName, " ", vecValues);
00592
00593 tableName = vecValues[0];
00594 }
00595
00596 string sql = "SELECT * FROM ";
00597 sql += table;
00598 sql += " WHERE ";
00599 sql += getSQLBoxWhere(box, TePOLYGONS, tableName);
00600
00601 if(!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00602 {
00603 delete portal;
00604 return false;
00605 }
00606
00607 bool flag = true;
00608
00609 do
00610 {
00611 TePolygon poly;
00612
00613 flag = portal->fetchGeometry(poly);
00614
00615 if(TeWithin(TePoint(pt), poly))
00616 {
00617 polygon = poly;
00618 delete portal;
00619 return true;
00620 }
00621 }
00622 while(flag);
00623
00624 delete portal;
00625
00626 return false;
00627 }
00628
00629 bool TePostGIS::locatePolygonSet(const string& table, TeCoord2D &pt, double tol, TePolygonSet &polygons)
00630 {
00631 TeDatabasePortal *portal = this->getPortal();
00632
00633 if (!portal)
00634 return false;
00635
00636 TeBox box (pt.x()-tol,pt.y()-tol,pt.x()+tol,pt.y()+tol);
00637
00638
00639 string sql = "SELECT * FROM ";
00640 sql += table;
00641 sql += " WHERE ";
00642 sql += getSQLBoxWhere(box, TePOLYGONS, table);
00643
00644 if (!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00645 {
00646 delete portal;
00647 return false;
00648 }
00649 bool flag = true;
00650
00651 polygons.clear();
00652
00653 do
00654 {
00655 TePolygon poly;
00656
00657 flag = portal->fetchGeometry(poly);
00658
00659 if(TeWithin(TePoint(pt), poly))
00660 polygons.add(poly);
00661 }
00662 while (flag);
00663
00664 delete portal;
00665
00666 if(polygons.size())
00667 return (true);
00668
00669 return false;
00670 }
00671
00672 bool TePostGIS::insertPolygon(const string& table, TePolygon &p)
00673 {
00674 errorMessage_ = "";
00675
00676 unsigned int sizeBinaryPolygon = 0;
00677 char* binaryPolygon = TePolygonToWKBPolygon(p, sizeBinaryPolygon);
00678
00679 int nParams = 2;
00680 Oid paramTypes[2];
00681 const char *paramValues[2];
00682 int paramLengths[2];
00683 int paramFormats[2];
00684
00685
00686 paramTypes[0] = PG_VARCHAR_TYPE;
00687 paramTypes[1] = 0;
00688
00689 string strOid = escapeSequence(p.objectId());
00690 paramValues[0] = strOid.c_str();
00691 paramValues[1] = binaryPolygon;
00692
00693 paramLengths[0] = 0;
00694 paramLengths[1] = sizeBinaryPolygon;
00695
00696 paramFormats[0] = 0;
00697 paramFormats[1] = 1;
00698
00699
00700 string command = "INSERT INTO ";
00701 command += table;
00702 command += " (object_id, spatial_data)";
00703 command += " VALUES ($1, $2::geometry)";
00704
00705 int result = tepg_connection_->exec_cmd_params(command.c_str(),
00706 nParams,
00707 paramTypes,
00708 paramValues,
00709 paramLengths,
00710 paramFormats,
00711 0);
00712
00713 delete [] binaryPolygon;
00714
00715 if(result == 1)
00716 {
00717 string sql = "SELECT currval('" + table + "_geom_id_seq')";
00718
00719 TePGRecordset rec;
00720 rec.open(sql.c_str(), tepg_connection_);
00721 if(rec.recordCount() > 0)
00722 {
00723 p.geomId(rec.getInt(0));
00724 for(register unsigned int i = 0; i < p.size(); ++i)
00725 {
00726 p[i].geomId(rec.getInt(0));
00727 }
00728 }
00729
00730 rec.close();
00731 }
00732 else
00733 return false;
00734
00735 return true;
00736 }
00737
00738 bool TePostGIS::updatePolygon(const string& table, TePolygon &p)
00739 {
00740 errorMessage_ = "";
00741
00742 unsigned int sizeBinaryPolygon = 0;
00743 char* binaryPolygon = TePolygonToWKBPolygon(p, sizeBinaryPolygon);
00744
00745 int nParams = 2;
00746 Oid paramTypes[2];
00747 const char *paramValues[2];
00748 int paramLengths[2];
00749 int paramFormats[2];
00750
00751
00752 paramTypes[0] = PG_VARCHAR_TYPE;
00753 paramTypes[1] = 0;
00754
00755 string strOid = escapeSequence(p.objectId());
00756 paramValues[0] = strOid.c_str();
00757 paramValues[1] = binaryPolygon;
00758
00759 paramLengths[0] = 0;
00760 paramLengths[1] = sizeBinaryPolygon;
00761
00762 paramFormats[0] = 0;
00763 paramFormats[1] = 1;
00764
00765 string command = "UPDATE " + table + " SET";
00766 command += " object_id = $1";
00767 command += ", spatial_data = $2::geometry";
00768 command += " WHERE geom_id = ";
00769 command += Te2String(p.geomId());
00770
00771 int result = tepg_connection_->exec_cmd_params(command.c_str(),
00772 nParams,
00773 paramTypes,
00774 paramValues,
00775 paramLengths,
00776 paramFormats,
00777 0);
00778
00779 delete [] binaryPolygon;
00780
00781 return (result == 1);
00782 }
00783
00784 bool TePostGIS::loadLineSet(const string& table, const string& geoid, TeLineSet& ls)
00785 {
00786 TeDatabasePortal *portal = this->getPortal();
00787
00788 string q ="SELECT * FROM " + table;
00789
00790 if(!geoid.empty())
00791 q += " WHERE object_id = '" + geoid +"'";
00792
00793 if(!portal->query(q, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00794 {
00795 delete portal;
00796 return false;
00797 }
00798
00799 bool flag = true;
00800
00801 do
00802 {
00803 TeLine2D line;
00804 flag = portal->fetchGeometry(line);
00805 ls.add (line);
00806 }while(flag);
00807
00808 delete portal;
00809
00810 return true;
00811 }
00812
00813 bool TePostGIS::loadLineSet(const string& table, TeBox& box, TeLineSet& linSet)
00814 {
00815 TeDatabasePortal *portal = this->getPortal();
00816
00817 if(!portal)
00818 return false;
00819
00820 string q = "SELECT * FROM " + table + " WHERE ";
00821 q += this->getSQLBoxWhere (box, TeLINES, table);
00822
00823 if(!portal->query(q, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00824 {
00825 delete portal;
00826 return false;
00827 }
00828
00829 bool flag = true;
00830
00831 do
00832 {
00833 TeLine2D lin;
00834 flag = portal->fetchGeometry(lin);
00835 linSet.add(lin);
00836 }
00837 while (flag);
00838
00839 delete portal;
00840
00841 return true;
00842 }
00843
00844 TeDatabasePortal* TePostGIS::loadLineSet(const string& table, TeBox& box)
00845 {
00846 TeDatabasePortal *portal = this->getPortal();
00847
00848 if(!portal)
00849 return 0;
00850
00851 string q = "SELECT * FROM " + table + " WHERE ";
00852 q += this->getSQLBoxWhere (box, TeLINES, table);
00853
00854
00855 if(!portal->query(q, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00856 {
00857 delete portal;
00858
00859 return 0;
00860 }
00861
00862 return portal;
00863 }
00864
00865 bool TePostGIS::insertLine(const string& table, TeLine2D& l)
00866 {
00867 errorMessage_ = "";
00868
00869 unsigned int sizeBinaryRing = 0;
00870 char* binaryRing = TeLine2DToWKBLineString(l, sizeBinaryRing);
00871
00872 int nParams = 2;
00873 Oid paramTypes[2];
00874 const char *paramValues[2];
00875 int paramLengths[2];
00876 int paramFormats[2];
00877
00878
00879 paramTypes[0] = PG_VARCHAR_TYPE;
00880 paramTypes[1] = 0;
00881
00882 string strOid = escapeSequence(l.objectId());
00883 paramValues[0] = strOid.c_str();
00884 paramValues[1] = binaryRing;
00885
00886 paramLengths[0] = 0;
00887 paramLengths[1] = sizeBinaryRing;
00888
00889 paramFormats[0] = 0;
00890 paramFormats[1] = 1;
00891
00892
00893 string command = "INSERT INTO ";
00894 command += table;
00895 command += " (object_id, spatial_data)";
00896 command += " VALUES ($1, $2::geometry)";
00897
00898 int result = tepg_connection_->exec_cmd_params(command.c_str(),
00899 nParams,
00900 paramTypes,
00901 paramValues,
00902 paramLengths,
00903 paramFormats,
00904 0);
00905
00906 delete [] binaryRing;
00907
00908 if(result == 1)
00909 {
00910 string sql = "SELECT currval('" + table + "_geom_id_seq')";
00911
00912 TePGRecordset rec;
00913 rec.open(sql.c_str(), tepg_connection_);
00914
00915 if(rec.recordCount() > 0)
00916 l.geomId(rec.getInt(0));
00917
00918 rec.close();
00919 }
00920 else
00921 return false;
00922
00923 return true;
00924 }
00925
00926 bool TePostGIS::updateLine(const string& table, TeLine2D& l)
00927 {
00928 errorMessage_ = "";
00929
00930 unsigned int sizeBinaryRing = 0;
00931 char* binaryRing = TeLine2DToWKBLineString(l, sizeBinaryRing);
00932
00933 int nParams = 2;
00934 Oid paramTypes[2];
00935 const char *paramValues[2];
00936 int paramLengths[2];
00937 int paramFormats[2];
00938
00939
00940 paramTypes[0] = PG_VARCHAR_TYPE;
00941 paramTypes[1] = 0;
00942
00943 string strOid = escapeSequence(l.objectId());
00944 paramValues[0] = strOid.c_str();
00945 paramValues[1] = binaryRing;
00946
00947 paramLengths[0] = 0;
00948 paramLengths[1] = sizeBinaryRing;
00949
00950 paramFormats[0] = 0;
00951 paramFormats[1] = 1;
00952
00953 string command = "UPDATE " + table + " SET";
00954 command += " obejct_id = $1";
00955 command += ", spatial_data = $2::geometry";
00956 command += " WHERE geom_id = ";
00957 command += Te2String(l.geomId());
00958
00959 int result = tepg_connection_->exec_cmd_params(command.c_str(),
00960 nParams,
00961 paramTypes,
00962 paramValues,
00963 paramLengths,
00964 paramFormats,
00965 0);
00966
00967 delete [] binaryRing;
00968
00969 return (result == 1);
00970 }
00971
00972 bool TePostGIS::locateLine(const string& table, TeCoord2D &pt, TeLine2D &line, const double& tol)
00973 {
00974 TeDatabasePortal* portal = this->getPortal();
00975
00976 TeBox box (pt.x()-tol,pt.y()-tol,pt.x()+tol,pt.y()+tol);
00977
00978 string sql = "SELECT * FROM ";
00979 sql += table;
00980 sql += " WHERE ";
00981 sql += this->getSQLBoxWhere(box, TeLINES, table);
00982
00983 if(!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
00984 {
00985 delete portal;
00986 return false;
00987 }
00988
00989
00990 TeLineSet ls;
00991 int k;
00992 bool flag = true;
00993 do
00994 {
00995 TeLine2D l;
00996 flag = portal->fetchGeometry( l );
00997 ls.add ( l );
00998 } while(flag);
00999
01000 delete portal;
01001
01002 TeCoord2D paux;
01003
01004 if(TeNearest(pt, ls, k, paux, tol))
01005 {
01006 line = ls[k];
01007 return true;
01008 }
01009
01010 return false;
01011 }
01012
01013 bool TePostGIS::insertPoint(const string& table, TePoint &p)
01014 {
01015 errorMessage_ = "";
01016
01017 unsigned int sizeBinaryPoint = 2 * sizeof(double);
01018 char* binaryPoint = TePointToWKBPoint(p, sizeBinaryPoint);
01019
01020 int nParams = 2;
01021 Oid paramTypes[2];
01022 const char *paramValues[2];
01023 int paramLengths[2];
01024 int paramFormats[2];
01025
01026
01027 paramTypes[0] = PG_VARCHAR_TYPE;
01028 paramTypes[1] = 0;
01029
01030 string strOid = escapeSequence(p.objectId());
01031 paramValues[0] = strOid.c_str();
01032 paramValues[1] = binaryPoint;
01033
01034 paramLengths[0] = 0;
01035 paramLengths[1] = sizeBinaryPoint;
01036
01037 paramFormats[0] = 0;
01038 paramFormats[1] = 1;
01039
01040
01041 string command = "INSERT INTO ";
01042 command += table;
01043 command += " (object_id, spatial_data)";
01044 command += " VALUES ($1, $2::geometry)";
01045
01046 int result = tepg_connection_->exec_cmd_params(command.c_str(),
01047 nParams,
01048 paramTypes,
01049 paramValues,
01050 paramLengths,
01051 paramFormats,
01052 0);
01053
01054 delete [] binaryPoint;
01055
01056 if(result == 1)
01057 {
01058 string sql = "SELECT currval('" + table + "_geom_id_seq')";
01059 TePGRecordset rec;
01060 rec.open(sql.c_str(), tepg_connection_);
01061 if(rec.recordCount() > 0)
01062 p.geomId(rec.getInt(0));
01063
01064 rec.close();
01065 }
01066 else
01067 return false;
01068
01069 return true;
01070 }
01071
01072 bool TePostGIS::updatePoint(const string& table, TePoint &p)
01073 {
01074 errorMessage_ = "";
01075
01076 unsigned int sizeBinaryPoint = 2 * sizeof(double);
01077 char* binaryPoint = TePointToWKBPoint(p, sizeBinaryPoint);
01078
01079 int nParams = 2;
01080 Oid paramTypes[2];
01081 const char *paramValues[2];
01082 int paramLengths[2];
01083 int paramFormats[2];
01084
01085
01086 paramTypes[0] = PG_VARCHAR_TYPE;
01087 paramTypes[1] = 0;
01088
01089 string strOid = escapeSequence(p.objectId());
01090 paramValues[0] = strOid.c_str();
01091 paramValues[1] = binaryPoint;
01092
01093 paramLengths[0] = 0;
01094 paramLengths[1] = sizeBinaryPoint;
01095
01096 paramFormats[0] = 0;
01097 paramFormats[1] = 1;
01098
01099 string command = "UPDATE " + table + " SET";
01100 command += " object_id = $1";
01101 command += ", spatial_data = $2::geometry";
01102 command += " WHERE geom_id = ";
01103 command += Te2String(p.geomId());
01104
01105 int result = tepg_connection_->exec_cmd_params(command.c_str(),
01106 nParams,
01107 paramTypes,
01108 paramValues,
01109 paramLengths,
01110 paramFormats,
01111 0);
01112
01113 delete [] binaryPoint;
01114
01115 return (result == 1);
01116 }
01117
01118 bool TePostGIS::locatePoint(const string& table, TeCoord2D& pt, TePoint& point, const double& tol)
01119 {
01120 TeDatabasePortal* portal = this->getPortal();
01121
01122 TeBox bbox(pt.x() - tol, pt.y() - tol, pt.x() + tol, pt.y() + tol);
01123
01124 string sql = "SELECT * FROM ";
01125 sql += table;
01126 sql += " WHERE ";
01127 sql += this->getSQLBoxWhere(bbox, TePOINTS, table);
01128
01129 if(!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
01130 {
01131 delete portal;
01132 return false;
01133 }
01134
01135 TePointSet ps;
01136
01137 bool flag = true;
01138
01139 do
01140 {
01141 TePoint point;
01142 flag = portal->fetchGeometry(point);
01143 ps.add(point);
01144 }while(flag);
01145
01146 delete portal;
01147 int k;
01148 if(TeNearest(pt, ps, k, tol))
01149 {
01150 point = ps[k];
01151 return true;
01152 }
01153 return false;
01154 }
01155
01156 bool TePostGIS::insertNode(const string& table, TeNode& node)
01157 {
01158 errorMessage_ = "";
01159
01160 TePoint p;
01161 TeCoord2D nodeCoord(node.location().x(), node.location().y());
01162 p.add(nodeCoord);
01163
01164 unsigned int sizeBinaryPoint = 2 * sizeof(double);
01165 char* binaryPoint = TePointToWKBPoint(p, sizeBinaryPoint);
01166
01167 int nParams = 2;
01168 Oid paramTypes[2];
01169 const char *paramValues[2];
01170 int paramLengths[2];
01171 int paramFormats[2];
01172
01173
01174 paramTypes[0] = PG_VARCHAR_TYPE;
01175 paramTypes[1] = 0;
01176
01177 string strOid = escapeSequence(node.objectId());
01178 paramValues[0] = strOid.c_str();
01179 paramValues[1] = binaryPoint;
01180
01181 paramLengths[0] = 0;
01182 paramLengths[1] = sizeBinaryPoint;
01183
01184 paramFormats[0] = 0;
01185 paramFormats[1] = 1;
01186
01187
01188 string command = "INSERT INTO ";
01189 command += table;
01190 command += " (object_id, spatial_data)";
01191 command += " VALUES ($1, $2::geometry)";
01192
01193 int result = tepg_connection_->exec_cmd_params(command.c_str(),
01194 nParams,
01195 paramTypes,
01196 paramValues,
01197 paramLengths,
01198 paramFormats,
01199 0);
01200
01201 delete [] binaryPoint;
01202
01203 if(result != 1)
01204 return false;
01205
01206 string sql = "SELECT currval('" + table + "_geom_id_seq')";
01207 TePGRecordset rec;
01208 rec.open(sql.c_str(), tepg_connection_);
01209 if(rec.recordCount() > 0)
01210 node.geomId(rec.getInt(0));
01211
01212 rec.close();
01213
01214 return true;
01215 }
01216
01217 bool TePostGIS::updateNode(const string& table, TeNode& node)
01218 {
01219 errorMessage_ = "";
01220
01221 TePoint p;
01222 TeCoord2D nodeCoord(node.location().x(), node.location().y());
01223 p.add(nodeCoord);
01224
01225 unsigned int sizeBinaryPoint = 2 * sizeof(double);
01226 char* binaryPoint = TePointToWKBPoint(p, sizeBinaryPoint);
01227
01228 int nParams = 2;
01229 Oid paramTypes[2];
01230 const char *paramValues[2];
01231 int paramLengths[2];
01232 int paramFormats[2];
01233
01234
01235 paramTypes[0] = PG_VARCHAR_TYPE;
01236 paramTypes[1] = 0;
01237
01238 string strOid = escapeSequence(node.objectId());
01239 paramValues[0] = strOid.c_str();
01240 paramValues[1] = binaryPoint;
01241
01242 paramLengths[0] = 0;
01243 paramLengths[1] = sizeBinaryPoint;
01244
01245 paramFormats[0] = 0;
01246 paramFormats[1] = 1;
01247
01248 string command = "UPDATE " + table + " SET";
01249 command += " object_id = $1";
01250 command += ", spatial_data = $2::geometry";
01251 command += " WHERE geom_id = ";
01252 command += Te2String(node.geomId());
01253
01254 int result = tepg_connection_->exec_cmd_params(command.c_str(),
01255 nParams,
01256 paramTypes,
01257 paramValues,
01258 paramLengths,
01259 paramFormats,
01260 0);
01261
01262 delete [] binaryPoint;
01263
01264 return (result == 1);
01265 }
01266
01267 bool TePostGIS::insertCell(const string& table, TeCell &c)
01268 {
01269 errorMessage_ = "";
01270
01271 TePolygon p;
01272 TeLinearRing ring;
01273 ring.add(TeCoord2D(c.box().x1(), c.box().y1()));
01274 ring.add(TeCoord2D(c.box().x2(), c.box().y1()));
01275 ring.add(TeCoord2D(c.box().x2(), c.box().y2()));
01276 ring.add(TeCoord2D(c.box().x1(), c.box().y2()));
01277 ring.add(TeCoord2D(c.box().x1(), c.box().y1()));
01278
01279 p.add(ring);
01280 p.srid(c.srid());
01281
01282 unsigned int sizeBinaryPolygon = 0;
01283 char* binaryPolygon = TePolygonToWKBPolygon(p, sizeBinaryPolygon);
01284
01285 int nParams = 4;
01286 Oid paramTypes[4];
01287 const char *paramValues[4];
01288 int paramLengths[4];
01289 int paramFormats[4];
01290
01291
01292 paramTypes[0] = PG_VARCHAR_TYPE;
01293 paramTypes[1] = 0;
01294 paramTypes[2] = PG_INT4_TYPE;
01295 paramTypes[3] = PG_INT4_TYPE;
01296
01297 string strOid = escapeSequence(c.objectId());
01298 paramValues[0] = strOid.c_str();
01299 paramValues[1] = binaryPolygon;
01300
01301 string strCol = Te2String(c.column());
01302 paramValues[2] = strCol.c_str();
01303
01304 string strRow = Te2String(c.line());
01305 paramValues[3] = strRow.c_str();
01306
01307 paramLengths[0] = 0;
01308 paramLengths[1] = sizeBinaryPolygon;
01309 paramLengths[2] = 0;
01310 paramLengths[3] = 0;
01311
01312 paramFormats[0] = 0;
01313 paramFormats[1] = 1;
01314 paramFormats[2] = 0;
01315 paramFormats[3] = 0;
01316
01317 string command = "INSERT INTO ";
01318 command += table;
01319 command += " (object_id, spatial_data, col_number, row_number)";
01320 command += " VALUES ($1, $2::geometry, $3, $4)";
01321
01322 int result = tepg_connection_->exec_cmd_params(command.c_str(),
01323 nParams,
01324 paramTypes,
01325 paramValues,
01326 paramLengths,
01327 paramFormats,
01328 0);
01329
01330 delete [] binaryPolygon;
01331
01332 if(result != 1)
01333 return false;
01334
01335
01336 string sql = "SELECT currval('" + table + "_geom_id_seq')";
01337 TePGRecordset rec;
01338 rec.open(sql.c_str(), tepg_connection_);
01339 if(rec.recordCount() > 0)
01340 c.geomId(rec.getInt(0));
01341
01342 rec.close();
01343
01344 return true;
01345 }
01346
01347 bool TePostGIS::updateCell(const string& table, TeCell &c)
01348 {
01349 errorMessage_ = "";
01350
01351 TePolygon p;
01352 TeLinearRing ring;
01353 ring.add(TeCoord2D(c.box().x1(), c.box().y1()));
01354 ring.add(TeCoord2D(c.box().x2(), c.box().y1()));
01355 ring.add(TeCoord2D(c.box().x2(), c.box().y2()));
01356 ring.add(TeCoord2D(c.box().x1(), c.box().y2()));
01357 ring.add(TeCoord2D(c.box().x1(), c.box().y1()));
01358
01359 p.add(ring);
01360
01361 unsigned int sizeBinaryPolygon = 0;
01362 char* binaryPolygon = TePolygonToWKBPolygon(p, sizeBinaryPolygon);
01363
01364 int nParams = 4;
01365 Oid paramTypes[4];
01366 const char *paramValues[4];
01367 int paramLengths[4];
01368 int paramFormats[4];
01369
01370
01371 paramTypes[0] = PG_VARCHAR_TYPE;
01372 paramTypes[1] = 0;
01373 paramTypes[2] = PG_INT4_TYPE;
01374 paramTypes[3] = PG_INT4_TYPE;
01375
01376 string strOid = escapeSequence(c.objectId());
01377 paramValues[0] = strOid.c_str();
01378 paramValues[1] = binaryPolygon;
01379
01380 string strCol = Te2String(c.column());
01381 paramValues[2] = strCol.c_str();
01382
01383 string strRow = Te2String(c.line());
01384 paramValues[3] = strRow.c_str();
01385
01386 paramLengths[0] = 0;
01387 paramLengths[1] = sizeBinaryPolygon;
01388 paramLengths[2] = 0;
01389 paramLengths[3] = 0;
01390
01391 paramFormats[0] = 0;
01392 paramFormats[1] = 1;
01393 paramFormats[2] = 0;
01394 paramFormats[3] = 0;
01395
01396 string command = "UPDATE " + table + " SET";
01397 command += " object_id = $1";
01398 command += ", spatial_data = $2::geometry";
01399 command += ", col_number = $3";
01400 command += ", row_number = $4";
01401 command += " WHERE geom_id = ";
01402 command += Te2String(c.geomId());
01403
01404 int result = tepg_connection_->exec_cmd_params(command.c_str(),
01405 nParams,
01406 paramTypes,
01407 paramValues,
01408 paramLengths,
01409 paramFormats,
01410 0);
01411
01412 delete [] binaryPolygon;
01413
01414 return (result == 1);
01415 }
01416
01417 bool TePostGIS::locateCell(const string& table, TeCoord2D& pt, TeCell& c, const double& tol)
01418 {
01419 TeDatabasePortal* portal = this->getPortal();
01420
01421 TeBox box (pt.x()-tol,pt.y()-tol,pt.x()+tol,pt.y()+tol);
01422
01423
01424 string sql ="SELECT * FROM ";
01425 sql += table;
01426 sql += " WHERE ";
01427 sql += this->getSQLBoxWhere(box, TeCELLS, table);
01428
01429 if(!portal->query(sql, TeSERVERSIDE, TeUNIDIRECTIONAL, TeREADONLY, TeBINARYCURSOR) || !portal->fetchRow())
01430 {
01431 delete portal;
01432 return false;
01433 }
01434
01435 portal->fetchGeometry(c);
01436
01437 delete portal;
01438
01439 return true;
01440 }
01441
01442 bool TePostGIS::removeGeometry(const string& tableName, const TeGeomRep& rep, const int& geomId)
01443 {
01444 if(tableName.empty())
01445 {
01446 return false;
01447 }
01448
01449 std::string remove = "DELETE FROM " + tableName;
01450 remove += " WHERE geom_id = " + geomId;
01451
01452 return this->execute(remove);
01453 }
01454
01455 bool TePostGIS::createSpatialIndex(const string& table, const string& column, TeSpatialIndexType , short , short )
01456 {
01457
01458 string sql = "SELECT " + column + " FROM " + table + " WHERE 1 = 2";
01459
01460 TePGRecordset rec;
01461
01462 if(!rec.open(sql, (TePostgreSQL::tepg_connection_)))
01463 {
01464 rec.close();
01465 return false;
01466 }
01467
01468 string create = "";
01469
01470 if(rec.fieldType(0) == PG_BOX_TYPE)
01471 {
01472 create = "CREATE INDEX sp_idx_" + table + " ON " + table + " USING GIST (" + column + " " + TePostgreSQL::gistBoxOps_ + ")";
01473 }
01474 else
01475 {
01476 create = "CREATE INDEX sp_idx_" + table + " ON " + table + " USING GIST (" + column + " GIST_GEOMETRY_OPS)";
01477 }
01478
01479 rec.close();
01480
01481 return this->execute(create);
01482 }
01483
01484 string TePostGIS::getSQLBoxWhere(const TeBox& box, const TeGeomRep rep, const std::string& tableName)
01485 {
01486 if(rep == TeTEXT)
01487 return TeDatabase::getSQLBoxWhere(box, rep, tableName);
01488
01489 string colname = "spatial_data";
01490
01491 if(rep & TeRASTER)
01492 return TePostgreSQL::getSQLBoxWhere(box, rep, tableName);
01493
01494
01495 std::string strProj = "";
01496 if(!tableName.empty())
01497 {
01498 TeDatabasePortal* portal = getPortal();
01499
01500 std::string sql = "select SRID from geometry_columns where " + toUpper("f_table_name") + " = " + toUpper("'" + tableName + "'");
01501 if(portal->query(sql) && portal->fetchRow())
01502 {
01503 strProj = portal->getData(0);
01504 if(strProj.empty() || strProj == "-1")
01505 {
01506 strProj = "";
01507 }
01508 }
01509 else
01510 {
01511 TeLayerMap& layerMap = this->layerMap();
01512 TeLayerMap::iterator it = layerMap.begin();
01513 while(it != layerMap.end())
01514 {
01515 if(it->second->tableName(rep) == tableName)
01516 {
01517 strProj = Te2String(it->second->projection()->epsgCode());
01518 break;
01519 }
01520 ++it;
01521 }
01522 }
01523
01524 delete portal;
01525 }
01526
01527 std::string whereBox = "";
01528 if(tableName.empty() == false && strProj.empty() == false)
01529 {
01530 whereBox = "(SetSRID('" + PGBox_encode(box) + "'::box3d, " + strProj + ") && " + colname + ")";
01531 }
01532 else
01533 {
01534 whereBox = "('" + PGBox_encode(box) + "'::box3d && " + colname + ")";
01535 }
01536
01537 return whereBox;
01538 }
01539
01540 std::string TePostGIS::getSQLOrderBy(const TeGeomRep& rep) const
01541 {
01542 std::string orderBy = "object_id ASC";
01543 return orderBy;
01544 }
01545
01546 string TePostGIS::getSQLBoxWhere(const string& table1, const string& table2, TeGeomRep rep2, TeGeomRep rep1)
01547 {
01548 if((rep1 == TeTEXT) || (rep2 == TeTEXT))
01549 {
01550 return TeDatabase::getSQLBoxWhere(table1, table2, rep2, rep1);
01551 }
01552
01553 string col1name = "spatial_data";
01554 string col2name = "spatial_data";;
01555
01556 if(rep1 & TeRASTER)
01557 col1name = "block_box";
01558
01559 if(rep2 & TeRASTER)
01560 col2name = "block_box";
01561
01562 string wherebox = "(";
01563 wherebox += table1;
01564 wherebox += "." + col1name + " && ";
01565 wherebox += table2;
01566 wherebox += "." + col2name + ")";
01567
01568 return wherebox;
01569 }
01570
01571 string TePostGIS::getSQLBoxSelect (const string& tableName, TeGeomRep rep)
01572 {
01573 if(rep == TeTEXT)
01574 return TeDatabase::getSQLBoxSelect(tableName, rep);
01575
01576 string colname = "spatial_data";
01577
01578 if(rep & TeRASTER)
01579 return TePostgreSQL::getSQLBoxSelect(tableName, rep);
01580
01581
01582 string select = "";
01583 select += "xmin(" + tableName + "." + colname + ") as lower_x, ";
01584 select += "ymin(" + tableName + "." + colname + ") as lower_y, ";
01585 select += "xmax(" + tableName + "." + colname + ") as upper_x, ";
01586 select += "ymax(" + tableName + "." + colname + ") as upper_y ";
01587
01588 return select;
01589 }
01590
01591 bool TePostGIS::getMBRGeom(string tableGeom, string object_id, TeBox& box, string colGeom)
01592 {
01593
01594 string sql = "SELECT " + colGeom + " FROM " + tableGeom + " WHERE 1 = 2";
01595
01596 TePGRecordset rec;
01597
01598 if(!rec.open(sql, (TePostgreSQL::tepg_connection_)))
01599 {
01600 rec.close();
01601 return false;
01602 }
01603
01604 if(rec.fieldType(0) == PG_BOX_TYPE)
01605 {
01606 rec.close();
01607
01608 return TePostgreSQL::getMBRGeom(tableGeom, object_id, box, colGeom);
01609 }
01610
01611 rec.close();
01612
01613
01614
01615 TeDatabasePortal* portal = getPortal();
01616 if(!portal)
01617 return false;
01618
01619 string sel = "SELECT extent(" + colGeom + ") FROM " + tableGeom;
01620 sel += " WHERE object_id = '" + object_id + "'";
01621
01622 if(!portal->query(sel)|| !portal->fetchRow())
01623 {
01624 delete portal;
01625 return false;
01626 }
01627
01628 box = PGBox_decode(portal->getData(0));
01629
01630 delete portal;
01631 return true;
01632 }
01633
01634 bool TePostGIS::getMBRSelectedObjects(string geomTable, string colGeom, string fromClause, string whereClause, string afterWhereClause, TeGeomRep repType, TeBox& bout, const double& tol)
01635 {
01636 if(repType == TeTEXT)
01637 return TeDatabase::getMBRSelectedObjects(geomTable, colGeom, fromClause, whereClause, afterWhereClause, repType, bout, tol);
01638
01639 if(repType == TeRASTER)
01640 return TePostgreSQL::getMBRSelectedObjects(geomTable, colGeom, fromClause, whereClause, afterWhereClause, repType, bout, tol);
01641
01642 TeDatabasePortal* portal = getPortal();
01643
01644 if (!portal)
01645 return false;
01646
01647 string fields = "extent(" + geomTable + "." + colGeom + ")::BOX3D";
01648 string query = " SELECT " + fields;
01649 query += " FROM " + fromClause;
01650
01651 if(!whereClause.empty())
01652 query += " WHERE " + whereClause;
01653
01654 if(portal->query(query) && portal->fetchRow())
01655
01656
01657 {
01658 TeBox aux(PGBox_decode(portal->getData(0)));
01659 bout = aux;
01660
01661 delete portal;
01662 return true;
01663 }
01664
01665 delete portal;
01666
01667 return false;
01668 }
01669
01670 string TePostGIS::getSpatialIdxColumn(TeGeomRep rep)
01671 {
01672 if (rep == TeRASTER)
01673 return "block_box";
01674
01675 return "spatial_data";
01676 }
01677
01678
01679 bool TePostGIS::getEncodingList(const std::string& host, const std::string& user, const std::string& password, const int& port, std::vector<std::string>& vecEncodingList)
01680 {
01681 if(!connect(host, user, password, "template_postgis", port))
01682 {
01683 close();
01684 return false;
01685 }
01686
01687 bool returnValue = TePostgreSQL::getEncodingList(vecEncodingList);
01688
01689 close();
01690
01691 return returnValue;
01692 }
01693
01694
01695 TePostGISPortal::TePostGISPortal(TeDatabase *pDatabase)
01696 {
01697 db_ = pDatabase;
01698 con_ = ((static_cast<TePostGIS*>(pDatabase))->tepg_connection_);
01699 }
01700
01701 bool TePostGISPortal::fetchGeometry(TePolygon& pol)
01702 {
01703 errorMessage_ = "";
01704
01705 if(_multiPolygonBuffer.empty() == false)
01706 {
01707 pol = *_multiPolygonBuffer.begin();
01708 _multiPolygonBuffer.erase(_multiPolygonBuffer.begin());
01709 return true;
01710 }
01711
01712 int geomId = tepg_recordset_->getInt("geom_id");
01713 std::string objectId = tepg_recordset_->getData("object_id");
01714
01715 TePolygonSet ps;
01716 tepg_recordset_->getPGISMultiPolygon("spatial_data", ps);
01717
01718
01719 for(unsigned int i = 0; i < ps.size(); ++i)
01720 {
01721 ps[i].geomId(geomId);
01722 ps[i].objectId(objectId);
01723 if(i == 0)
01724 {
01725 pol = ps[i];
01726 }
01727 else
01728 {
01729 _multiPolygonBuffer.add(ps[i]);
01730 }
01731 }
01732
01733 if(_multiPolygonBuffer.empty())
01734 {
01735 return fetchRow();
01736 }
01737
01738 return true;
01739 }
01740
01741 bool TePostGISPortal::fetchGeometry(TePolygon& pol, const unsigned int& initIndex)
01742 {
01743 errorMessage_ = "";
01744
01745 if(_multiPolygonBuffer.empty() == false)
01746 {
01747 pol = *_multiPolygonBuffer.begin();
01748 _multiPolygonBuffer.erase(_multiPolygonBuffer.begin());
01749 return true;
01750 }
01751
01752 int geomId = tepg_recordset_->getInt(initIndex);
01753 std::string objectId = tepg_recordset_->getData(initIndex+1);
01754
01755 TePolygonSet ps;
01756 tepg_recordset_->getPGISMultiPolygon(initIndex+2, ps);
01757
01758
01759 for(unsigned int i = 0; i < ps.size(); ++i)
01760 {
01761 ps[i].geomId(geomId);
01762 ps[i].objectId(objectId);
01763 if(i == 0)
01764 {
01765 pol = ps[i];
01766 }
01767 else
01768 {
01769 _multiPolygonBuffer.add(ps[i]);
01770 }
01771 }
01772
01773 if(_multiPolygonBuffer.empty())
01774 {
01775 return fetchRow();
01776 }
01777
01778 return true;
01779 }
01780
01781 bool TePostGISPortal::fetchGeometry(TeLine2D& line)
01782 {
01783 errorMessage_ = "";
01784
01785 if(_multiLineBuffer.empty() == false)
01786 {
01787 line = *_multiLineBuffer.begin();
01788 _multiLineBuffer.erase(_multiLineBuffer.begin());
01789 return true;
01790 }
01791
01792 int geomId = tepg_recordset_->getInt("geom_id");
01793 std::string objectId = tepg_recordset_->getData("object_id");
01794
01795 TeLineSet ls;
01796 tepg_recordset_->getPGISMultiLine("spatial_data", ls);
01797
01798
01799 for(unsigned int i = 0; i < ls.size(); ++i)
01800 {
01801 ls[i].geomId(geomId);
01802 ls[i].objectId(objectId);
01803 if(i == 0)
01804 {
01805 line = ls[i];
01806 }
01807 else
01808 {
01809 _multiLineBuffer.add(ls[i]);
01810 }
01811 }
01812
01813 if(_multiLineBuffer.empty())
01814 {
01815 return fetchRow();
01816 }
01817
01818 return true;
01819 }
01820
01821 bool TePostGISPortal::fetchGeometry(TeLine2D& line, const unsigned int& initIndex)
01822 {
01823 errorMessage_ = "";
01824
01825 if(_multiLineBuffer.empty() == false)
01826 {
01827 line = *_multiLineBuffer.begin();
01828 _multiLineBuffer.erase(_multiLineBuffer.begin());
01829 return true;
01830 }
01831
01832 int geomId = tepg_recordset_->getInt(initIndex);
01833 std::string objectId = tepg_recordset_->getData(initIndex+1);
01834
01835 TeLineSet ls;
01836 tepg_recordset_->getPGISMultiLine(initIndex+2, ls);
01837
01838
01839 for(unsigned int i = 0; i < ls.size(); ++i)
01840 {
01841 ls[i].geomId(geomId);
01842 ls[i].objectId(objectId);
01843 if(i == 0)
01844 {
01845 line = ls[i];
01846 }
01847 else
01848 {
01849 _multiLineBuffer.add(ls[i]);
01850 }
01851 }
01852
01853 if(_multiLineBuffer.empty())
01854 {
01855 return fetchRow();
01856 }
01857
01858 return true;
01859 }
01860
01861 bool TePostGISPortal::fetchGeometry(TeNode& n)
01862 {
01863 errorMessage_ = "";
01864
01865 TePoint p;
01866 tepg_recordset_->getPGISPoint("spatial_data", p);
01867 n.add(p.location());
01868 n.geomId(tepg_recordset_->getInt("geom_id"));
01869 n.objectId(tepg_recordset_->getData("object_id"));
01870
01871 return fetchRow();
01872 }
01873
01874 bool TePostGISPortal::fetchGeometry(TeNode& n, const unsigned int& initIndex)
01875 {
01876 errorMessage_ = "";
01877
01878 TePoint p;
01879 tepg_recordset_->getPGISPoint(initIndex+2, p);
01880 n.add(p.location());
01881 n.geomId(tepg_recordset_->getInt(initIndex));
01882 n.objectId(tepg_recordset_->getData(initIndex+1));
01883
01884 return fetchRow();
01885 }
01886
01887 bool TePostGISPortal::fetchGeometry(TePoint& p)
01888 {
01889 errorMessage_ = "";
01890
01891 if(_multiPointBuffer.empty() == false)
01892 {
01893 p = *_multiPointBuffer.begin();
01894 _multiPointBuffer.erase(_multiPointBuffer.begin());
01895 return true;
01896 }
01897
01898 int geomId = tepg_recordset_->getInt("geom_id");
01899 std::string objectId = tepg_recordset_->getData("object_id");
01900
01901 TePointSet ps;
01902 tepg_recordset_->getPGISMultiPoint("spatial_data", ps);
01903
01904 for(unsigned int i = 0; i < ps.size(); ++i)
01905 {
01906 ps[i].geomId(geomId);
01907 ps[i].objectId(objectId);
01908 if(i == 0)
01909 {
01910 p = ps[i];
01911 }
01912 else
01913 {
01914 _multiPointBuffer.add(ps[i]);
01915 }
01916 }
01917
01918 if(_multiPointBuffer.empty())
01919 {
01920 return fetchRow();
01921 }
01922
01923 return true;
01924 }
01925
01926 bool TePostGISPortal::fetchGeometry(TePoint& p, const unsigned int& initIndex)
01927 {
01928 errorMessage_ = "";
01929
01930 if(_multiPointBuffer.empty() == false)
01931 {
01932 p = *_multiPointBuffer.begin();
01933 _multiPointBuffer.erase(_multiPointBuffer.begin());
01934 return true;
01935 }
01936
01937 int geomId = tepg_recordset_->getInt(initIndex);
01938 std::string objectId = tepg_recordset_->getData(initIndex+1);
01939
01940 TePointSet ps;
01941 tepg_recordset_->getPGISMultiPoint(initIndex+2, ps);
01942
01943 for(unsigned int i = 0; i < ps.size(); ++i)
01944 {
01945 ps[i].geomId(geomId);
01946 ps[i].objectId(objectId);
01947 if(i == 0)
01948 {
01949 p = ps[i];
01950 }
01951 else
01952 {
01953 _multiPointBuffer.add(ps[i]);
01954 }
01955 }
01956
01957 if(_multiPointBuffer.empty())
01958 {
01959 return fetchRow();
01960 }
01961
01962 return true;
01963 }
01964
01965 bool TePostGISPortal::fetchGeometry(TeCell& cell)
01966 {
01967 errorMessage_ = "";
01968
01969 TePolygon pol;
01970 tepg_recordset_->getPGISPolygon("spatial_data", pol);
01971
01972 cell.geomId(tepg_recordset_->getInt("geom_id"));
01973 cell.objectId(tepg_recordset_->getData("object_id"));
01974 cell.setBox (pol.box());
01975 cell.column(tepg_recordset_->getInt("col_number"));
01976 cell.line(tepg_recordset_->getInt("row_number"));
01977
01978 return fetchRow();
01979 }
01980
01981 bool TePostGISPortal::fetchGeometry(TeCell& cell, const unsigned int& initIndex)
01982 {
01983 errorMessage_ = "";
01984
01985 TePolygon pol;
01986 tepg_recordset_->getPGISPolygon(initIndex+2, pol);
01987
01988 cell.geomId(tepg_recordset_->getInt(initIndex));
01989 cell.objectId(tepg_recordset_->getData(initIndex+1));
01990 cell.setBox (pol.box());
01991 cell.column(tepg_recordset_->getInt(initIndex+3));
01992 cell.line(tepg_recordset_->getInt(initIndex+4));
01993
01994 return fetchRow();
01995 }
01996