TePostGIS.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 
00011 You should have received a copy of the GNU Lesser General Public
00012 License along with this library.
00013 
00014 The authors reassure the license terms regarding the warranties.
00015 They specifically disclaim any warranties, including, but not limited to,
00016 the implied warranties of merchantability and fitness for a particular purpose.
00017 The library provided hereunder is on an "as is" basis, and the authors have no
00018 obligation to provide maintenance, support, updates, enhancements, or modifications.
00019 In no event shall INPE and Tecgraf / PUC-Rio be held liable to any party for direct,
00020 indirect, special, incidental, or consequential damages arising out of the use
00021 of this library and its documentation.
00022 *************************************************************************************/
00023 
00024 #include "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                 //create conceptual model
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 // see if PostGIS is present
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 // see if RTree GiST is present for box: it must be present
00111         int version = PQserverVersion(tepg_connection_->c_ptr());
00112         if(version >= 80100)
00113         {
00114                 gistBoxOps_ = "box_ops";
00115                 if(version >= 90000)
00116                 {
00117                         //modification because of the new default bytea type
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:            //type = "OID";
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                 // check if column is part of primary key
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 //sometimes, not only the name of the table but a complete join is given in the 'table' argument. Tries to break the string if there is an space
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         //tipos dos parametros
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)";//::geometry
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         //tipos dos parametros
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         //tipos dos parametros
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         //tipos dos parametros
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         // Get all lines
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         //tipos dos parametros
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         //tipos dos parametros
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         //tipos dos parametros
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         //tipos dos parametros
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         //tipos dos parametros
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         //tipos dos parametros
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 /*type*/, short /*level*/, short /*tile*/)
01456 {
01457 // we need to find te type we are indexing: a box from PostgreSQL or a geometry from PostGIS.
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 //changed for compatibility with postGIS EWKB data. This modification allows query for data which has a projection different from -1 associated. Compatibility with -1 projection data is kept.
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         //string select  = tableName +".* , ";
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 // we need to find the type we are computing bounding box: a box from PostgreSQL or a geometry from PostGIS.
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)     // use the TePostgreSQL method
01605         {
01606                 rec.close();
01607 
01608                 return TePostgreSQL::getMBRGeom(tableGeom, object_id, box, colGeom);
01609         }
01610 
01611         rec.close();
01612 
01613 // if we are here, so it is a PostGIS geometry: in this case we can use the function extent
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 

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