/* This file is part of Mapnik (c++ mapping toolkit) * Copyright (C) 2005 Artem Pavlenko * * Mapnik is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ //$Id: postgis.cc 44 2005-04-22 18:53:54Z pavlenko $ #include "postgis.hpp" #include #include #include #include #include "connection_manager.hpp" DATASOURCE_PLUGIN(postgis_datasource) const std::string postgis_datasource::GEOMETRY_COLUMNS="geometry_columns"; const std::string postgis_datasource::SPATIAL_REF_SYS="spatial_ref_system"; using std::cerr; using std::cout; using std::endl; using boost::lexical_cast; using boost::bad_lexical_cast; using boost::shared_ptr; postgis_datasource::postgis_datasource(const parameters& params) : table_(params.get("table")), type_(datasource::Vector), desc_(params.get("name")), creator_(params.get("host"), params.get("dbname"), params.get("user"), params.get("password")) { ConnectionManager *mgr=ConnectionManager::instance(); mgr->registerPool(creator_,10,20); shared_ptr > pool=mgr->getPool(creator_.id()); if (pool) { const shared_ptr& conn = pool->borrowObject(); if (conn && conn->isOK()) { PoolGuard,shared_ptr > > guard(conn,pool); std::string table_name=table_from_sql(table_); std::ostringstream s; s << "select f_geometry_column,srid,type from "; s << GEOMETRY_COLUMNS <<" where f_table_name='"< rs=conn->executeQuery(s.str()); if (rs->next()) { try { srid_ = lexical_cast(rs->getValue("srid")); desc_.set_srid(srid_); } catch (bad_lexical_cast &ex) { cerr << ex.what() << endl; } geometryColumn_=rs->getValue("f_geometry_column"); std::string postgisType=rs->getValue("type"); } rs->close(); s.str(""); s << "select xmin(ext),ymin(ext),xmax(ext),ymax(ext)"; s << " from (select estimated_extent('"<executeQuery(s.str()); if (rs->next()) { try { double lox=lexical_cast(rs->getValue(0)); double loy=lexical_cast(rs->getValue(1)); double hix=lexical_cast(rs->getValue(2)); double hiy=lexical_cast(rs->getValue(3)); extent_.init(lox,loy,hix,hiy); } catch (bad_lexical_cast &ex) { cerr << ex.what() << endl; } } rs->close(); // collect attribute desc s.str(""); s << "select * from "<executeQuery(s.str()); if (rs->next()) { int count = rs->getNumFields(); for (int i=0;igetFieldName(i); int length = rs->getFieldLength(i); int type_oid = rs->getTypeOID(i); switch (type_oid) { case 17285: // geometry desc_.add_descriptor(attribute_descriptor(fld_name,Geometry)); break; case 21: // int2 case 23: // int4 desc_.add_descriptor(attribute_descriptor(fld_name,Integer,false,length)); break; case 701: // float8 desc_.add_descriptor(attribute_descriptor(fld_name,Double,false,length)); case 1042: // bpchar case 1043: // varchar desc_.add_descriptor(attribute_descriptor(fld_name,String)); break; default: // shouldn't get here cout << "unknown type_oid="< const& box=q.get_bbox(); ConnectionManager *mgr=ConnectionManager::instance(); shared_ptr > pool=mgr->getPool(creator_.id()); if (pool) { const shared_ptr& conn = pool->borrowObject(); if (conn && conn->isOK()) { PoolGuard,shared_ptr > > guard(conn,pool); std::ostringstream s; // can we rely on 'gid' name??? s << "select gid,asbinary("< const& props=q.property_names(); std::set::const_iterator pos=props.begin(); while (pos!=props.end()) { s <<",\""<<*pos<<"\""; ++pos; } s << " from " << table_<<" where "< rs=conn->executeQuery(s.str(),1); fs=new postgis_featureset(rs,props.size()); } } return featureset_ptr(fs); } const Envelope& postgis_datasource::envelope() const { return extent_; } postgis_datasource::~postgis_datasource() {}