postgis: pass floating-point numbers to queries in hexfloat format
This commit is contained in:
parent
f365a9d2e4
commit
6c2faf346b
4 changed files with 59 additions and 21 deletions
|
@ -34,6 +34,48 @@
|
|||
namespace mapnik { namespace pgcommon {
|
||||
|
||||
|
||||
// sql_float4
|
||||
|
||||
struct sql_float4
|
||||
{
|
||||
float value;
|
||||
};
|
||||
|
||||
inline sql_float4 sql_float(float value)
|
||||
{
|
||||
return {value};
|
||||
}
|
||||
|
||||
inline std::ostream & operator << (std::ostream & os, sql_float4 sf)
|
||||
{
|
||||
char const fmt[] = "float4 '%a'";
|
||||
char buf[sizeof(fmt) + 25];
|
||||
int len = std::snprintf(buf, sizeof(buf), fmt, sf.value);
|
||||
return os.write(buf, std::min(len, int(sizeof(buf)) - 1));
|
||||
}
|
||||
|
||||
|
||||
// sql_float8
|
||||
|
||||
struct sql_float8
|
||||
{
|
||||
double value;
|
||||
};
|
||||
|
||||
inline sql_float8 sql_float(double value)
|
||||
{
|
||||
return {value};
|
||||
}
|
||||
|
||||
inline std::ostream & operator << (std::ostream & os, sql_float8 sf)
|
||||
{
|
||||
char const fmt[] = "float8 '%a'";
|
||||
char buf[sizeof(fmt) + 25];
|
||||
int len = std::snprintf(buf, sizeof(buf), fmt, sf.value);
|
||||
return os.write(buf, std::min(len, int(sizeof(buf)) - 1));
|
||||
}
|
||||
|
||||
|
||||
// sql_bbox
|
||||
|
||||
struct sql_bbox : box2d<double>
|
||||
|
|
|
@ -60,6 +60,7 @@ const std::string pgraster_datasource::SPATIAL_REF_SYS = "spatial_ref_system";
|
|||
using std::shared_ptr;
|
||||
using mapnik::attribute_descriptor;
|
||||
using mapnik::pgcommon::sql_bbox;
|
||||
using mapnik::pgcommon::sql_float;
|
||||
using mapnik::sql_utils::identifier;
|
||||
using mapnik::sql_utils::literal;
|
||||
using mapnik::value_integer;
|
||||
|
@ -611,9 +612,6 @@ std::string pgraster_datasource::populate_tokens(std::string const& sql,
|
|||
char const* start = sql.data();
|
||||
char const* end = start + sql.size();
|
||||
|
||||
populated_sql.precision(16);
|
||||
populated_sql << std::showpoint;
|
||||
|
||||
while (std::regex_search(start, end, m, re_tokens_))
|
||||
{
|
||||
populated_sql.write(start, m[0].first - start);
|
||||
|
@ -641,15 +639,15 @@ std::string pgraster_datasource::populate_tokens(std::string const& sql,
|
|||
}
|
||||
else if (boost::algorithm::equals(m1, "pixel_height"))
|
||||
{
|
||||
populated_sql << pixel_height;
|
||||
populated_sql << sql_float(pixel_height);
|
||||
}
|
||||
else if (boost::algorithm::equals(m1, "pixel_width"))
|
||||
{
|
||||
populated_sql << pixel_width;
|
||||
populated_sql << sql_float(pixel_width);
|
||||
}
|
||||
else if (boost::algorithm::equals(m1, "scale_denominator"))
|
||||
{
|
||||
populated_sql << scale_denom;
|
||||
populated_sql << sql_float(scale_denom);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -889,9 +887,9 @@ featureset_ptr pgraster_datasource::features_with_context(query const& q,process
|
|||
if (prescale_rasters_) {
|
||||
const double scale = std::min(px_gw, px_gh);
|
||||
s << ", least(1.0, abs(ST_ScaleX(" << identifier(col)
|
||||
<< "))::float8/" << scale
|
||||
<< "))::float8/" << sql_float(scale)
|
||||
<< "), least(1.0, abs(ST_ScaleY(" << identifier(col)
|
||||
<< "))::float8/" << scale << "))";
|
||||
<< "))::float8/" << sql_float(scale) << "))";
|
||||
// TODO: if band_ is given, we'll interpret as indexed so
|
||||
// the rescaling must NOT ruin it (use algorithm mode!)
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ const std::string postgis_datasource::SPATIAL_REF_SYS = "spatial_ref_system";
|
|||
using std::shared_ptr;
|
||||
using mapnik::attribute_descriptor;
|
||||
using mapnik::pgcommon::sql_bbox;
|
||||
using mapnik::pgcommon::sql_float;
|
||||
using mapnik::sql_utils::identifier;
|
||||
using mapnik::sql_utils::literal;
|
||||
|
||||
|
@ -521,9 +522,6 @@ std::string postgis_datasource::populate_tokens(
|
|||
char const* start = sql.data();
|
||||
char const* end = start + sql.size();
|
||||
|
||||
populated_sql.precision(16);
|
||||
populated_sql << std::showpoint;
|
||||
|
||||
while (std::regex_search(start, end, m, re_tokens_))
|
||||
{
|
||||
populated_sql.write(start, m[0].first - start);
|
||||
|
@ -551,15 +549,15 @@ std::string postgis_datasource::populate_tokens(
|
|||
}
|
||||
else if (boost::algorithm::equals(m1, "pixel_height"))
|
||||
{
|
||||
populated_sql << pixel_height;
|
||||
populated_sql << sql_float(pixel_height);
|
||||
}
|
||||
else if (boost::algorithm::equals(m1, "pixel_width"))
|
||||
{
|
||||
populated_sql << pixel_width;
|
||||
populated_sql << sql_float(pixel_width);
|
||||
}
|
||||
else if (boost::algorithm::equals(m1, "scale_denominator"))
|
||||
{
|
||||
populated_sql << scale_denom;
|
||||
populated_sql << sql_float(scale_denom);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -779,9 +777,9 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
|
|||
}
|
||||
|
||||
// ! ST_RemoveRepeatedPoints()
|
||||
s << "," << twkb_tolerance << ")";
|
||||
s << "," << sql_float(twkb_tolerance) << ")";
|
||||
// ! ST_Simplify(), with parameter to keep collapsed geometries
|
||||
s << "," << twkb_tolerance << ",true)";
|
||||
s << "," << sql_float(twkb_tolerance) << ",true)";
|
||||
// ! ST_TWKB()
|
||||
s << "," << twkb_rounding << ") AS geom";
|
||||
}
|
||||
|
@ -808,7 +806,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
|
|||
if (simplify_geometries_ && simplify_snap_ratio_ > 0.0)
|
||||
{
|
||||
const double tolerance = px_sz * simplify_snap_ratio_;
|
||||
s << "," << tolerance << ")";
|
||||
s << "," << sql_float(tolerance) << ")";
|
||||
}
|
||||
|
||||
// ! ST_ClipByBox2D()
|
||||
|
@ -821,7 +819,7 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
|
|||
if (simplify_geometries_)
|
||||
{
|
||||
const double tolerance = px_sz * simplify_dp_ratio_;
|
||||
s << ", " << tolerance;
|
||||
s << ", " << sql_float(tolerance);
|
||||
// Add parameter to ST_Simplify to keep collapsed geometries
|
||||
if (simplify_dp_preserve_)
|
||||
{
|
||||
|
|
|
@ -316,9 +316,9 @@ TEST_CASE("postgis") {
|
|||
auto feature = featureset->next();
|
||||
CHECKED_IF(feature != nullptr)
|
||||
{
|
||||
CHECK(feature->get("t_pixel_width").to_string() == "numeric");
|
||||
CHECK(feature->get("t_pixel_height").to_string() == "numeric");
|
||||
CHECK(feature->get("t_scale_denom").to_string() == "numeric");
|
||||
CHECK(feature->get("t_pixel_width").to_string() == "double precision");
|
||||
CHECK(feature->get("t_pixel_height").to_string() == "double precision");
|
||||
CHECK(feature->get("t_scale_denom").to_string() == "double precision");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue