From 9a0bb92acd2e8f28e8f183a49b7e479c9b0f512c Mon Sep 17 00:00:00 2001 From: Dane Springmeyer Date: Thu, 27 Aug 2009 03:54:52 +0000 Subject: [PATCH] Improve handling of BBOX query substitution - closes #415 --- CHANGELOG | 2 ++ plugins/input/postgis/postgis.cpp | 58 ++++++++++++++++++------------- plugins/input/postgis/postgis.hpp | 2 ++ 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 6a3157be6..2c0cf3a37 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -14,6 +14,8 @@ For a complete change history, see the SVN log. Mapnik 0.6.2 Release -------------------- +- PostGIS Plugin: Add bbox substitution ability in sql query string (r1292) (#415) + - PostGIS Plugin: Throw and report errors if SQL execution fails (r1291) (#363) - PostGIS Plugin: Added missing support for BigInt(int8) postgres datatypes (r1250) (#384) diff --git a/plugins/input/postgis/postgis.cpp b/plugins/input/postgis/postgis.cpp index 9c1374123..23aa3dc91 100644 --- a/plugins/input/postgis/postgis.cpp +++ b/plugins/input/postgis/postgis.cpp @@ -74,7 +74,8 @@ postgis_datasource::postgis_datasource(parameters const& params) params.get("port"), params.get("dbname"), params.get("user"), - params.get("password")) + params.get("password")), + bbox_token_("!bbox!") { boost::optional initial_size = params_.get("inital_size",1); @@ -171,7 +172,8 @@ postgis_datasource::postgis_datasource(parameters const& params) // collect attribute desc s.str(""); - s << "select * from " << table_ << " limit 0"; + std::string table_with_bbox = populate_sql_bbox(table_,extent_); + s << "select * from " << table_with_bbox << " limit 0"; rs=conn->executeQuery(s.str()); int count = rs->getNumFields(); for (int i=0;i const& box) const +{ + std::string sql_with_bbox = boost::algorithm::to_lower_copy(sql); + std::ostringstream b; + b << "SetSRID('BOX3D("; + b << std::setprecision(16); + b << box.minx() << " " << box.miny() << ","; + b << box.maxx() << " " << box.maxy() << ")'::box3d," << srid_ << ")"; + if ( boost::algorithm::icontains(sql,bbox_token_) ) + { + boost::algorithm::replace_all(sql_with_bbox,bbox_token_,b.str()); + return sql_with_bbox; + } + else + { + std::ostringstream s; + s << " WHERE \"" << geometryColumn_ << "\" && " << b.str(); + return sql_with_bbox + s.str(); + } +} + std::string postgis_datasource::table_from_sql(const std::string& sql) { std::string table_name = boost::algorithm::to_lower_copy(sql); @@ -293,24 +316,9 @@ featureset_ptr postgis_datasource::features(const query& q) const ++pos; } - std::ostringstream b; - b << "SetSRID('BOX3D("; - b << std::setprecision(16); - b << box.minx() << " " << box.miny() << ","; - b << box.maxx() << " " << box.maxy() << ")'::box3d,"< 0) { s << " LIMIT " << row_limit_; @@ -346,11 +354,11 @@ featureset_ptr postgis_datasource::features_at_point(coord2d const& pt) const ++itr; ++size; } - - s << " FROM " << table_ << " WHERE \""< box(pt.x,pt.y,pt.x,pt.y); + std::string table_with_bbox = populate_sql_bbox(table_,box); + + s << " from " << table_with_bbox; if (row_limit_ > 0) { s << " LIMIT " << row_limit_; diff --git a/plugins/input/postgis/postgis.hpp b/plugins/input/postgis/postgis.hpp index 8619fb206..79e68ab1b 100644 --- a/plugins/input/postgis/postgis.hpp +++ b/plugins/input/postgis/postgis.hpp @@ -69,6 +69,7 @@ class postgis_datasource : public datasource ConnectionCreator creator_; bool multiple_geometries_; static const std::string name_; + const std::string bbox_token_; public: static std::string name(); int type() const; @@ -79,6 +80,7 @@ class postgis_datasource : public datasource postgis_datasource(const parameters ¶ms); ~postgis_datasource(); private: + std::string populate_sql_bbox(const std::string& sql, Envelope const& box) const; static std::string table_from_sql(const std::string& sql); boost::shared_ptr get_resultset(boost::shared_ptr const &conn, const std::string &sql) const; postgis_datasource(const postgis_datasource&);