add ability to read geometries stored as TWKB directly (experimental)
See TWKB-HOWTO.md for how to prepare data. XML style parameters : ```xml <Parameter name="twkb_encoding">True</Parameter> <Parameter name="twkb_direct">True</Parameter> ```
This commit is contained in:
parent
0fb587875e
commit
186c80ca38
3 changed files with 90 additions and 33 deletions
26
TWKB-HOWTO.md
Normal file
26
TWKB-HOWTO.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
### Direct TWKB
|
||||
#### Prerequisites
|
||||
|
||||
* Standard set of planet OSM tables imported into PostgreSQL with `osm2pgsql` or similar.
|
||||
|
||||
#### Creating and populating TWKB table
|
||||
|
||||
```sql
|
||||
create table planet_osm_polygon_twkb as (select * from planet_osm_polygon);
|
||||
alter table planet_osm_polygon_twkb add column twkb bytea;
|
||||
update planet_osm_polygon_twkb set twkb = ST_AsTWKB(way, 2);
|
||||
alter table planet_osm_polygon_twkb drop column way;
|
||||
```
|
||||
#### Spatial index
|
||||
|
||||
```sql
|
||||
create index planet_osm_polygon_twkb_index on planet_osm_polygon_twkb using GIST(ST_GeomFromTWKB(twkb));
|
||||
```
|
||||
|
||||
##### Vacuum to update stats
|
||||
|
||||
```sql
|
||||
VACUUM FULL ANALYZE VERBOSE planet_osm_polygon_twkb ;
|
||||
\d+
|
||||
```
|
||||
|
|
@ -89,6 +89,7 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
|||
max_async_connections_(*params_.get<mapnik::value_integer>("max_async_connection", 1)),
|
||||
asynchronous_request_(false),
|
||||
twkb_encoding_(false),
|
||||
twkb_direct_(*params_.get<mapnik::boolean_type>("twkb_direct", false)),
|
||||
twkb_rounding_adjustment_(*params_.get<mapnik::value_double>("twkb_rounding_adjustment", 0.0)),
|
||||
simplify_snap_ratio_(*params_.get<mapnik::value_double>("simplify_snap_ratio", 1.0/40.0)),
|
||||
// 1/20 of pixel seems to be a good compromise to avoid
|
||||
|
@ -242,8 +243,14 @@ postgis_datasource::postgis_datasource(parameters const& params)
|
|||
if (!geometryColumn_.empty() && srid_ <= 0)
|
||||
{
|
||||
std::ostringstream s;
|
||||
|
||||
s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM ";
|
||||
if (twkb_direct_)
|
||||
{
|
||||
s << "SELECT ST_SRID(ST_GeomFromTWKB(\"" << geometryColumn_ << "\")) AS srid FROM ";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "SELECT ST_SRID(\"" << geometryColumn_ << "\") AS srid FROM ";
|
||||
}
|
||||
if (!geometry_table_.empty())
|
||||
{
|
||||
if (!schema_.empty())
|
||||
|
@ -640,7 +647,14 @@ std::string postgis_datasource::populate_tokens(
|
|||
}
|
||||
else
|
||||
{
|
||||
s << " WHERE \"" << geometryColumn_ << "\" && " << box;
|
||||
if (twkb_direct_)
|
||||
{
|
||||
s << " WHERE ST_GeomFromTWKB(\"" << geometryColumn_ << "\") && " << box;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << " WHERE \"" << geometryColumn_ << "\" && " << box;
|
||||
}
|
||||
}
|
||||
populated_sql += s.str();
|
||||
}
|
||||
|
@ -815,38 +829,47 @@ featureset_ptr postgis_datasource::features_with_context(query const& q,processo
|
|||
|
||||
if (twkb_encoding_)
|
||||
{
|
||||
// This will only work against PostGIS 2.2, or a back-patched version
|
||||
// that has (a) a ST_Simplify with a "preserve collapsed" flag and
|
||||
// (b) a ST_RemoveRepeatedPoints with a tolerance parameter and
|
||||
// (c) a ST_AsTWKB implementation
|
||||
|
||||
// What number of decimals of rounding does the pixel size imply?
|
||||
const int twkb_rounding = -1 * std::lround(log10(px_sz) + twkb_rounding_adjustment_) + 1;
|
||||
// And what's that in map units?
|
||||
const double twkb_tolerance = pow(10.0, -1.0 * twkb_rounding);
|
||||
|
||||
s << "SELECT ST_AsTWKB(";
|
||||
s << "ST_Simplify(";
|
||||
s << "ST_RemoveRepeatedPoints(";
|
||||
|
||||
if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
|
||||
if (twkb_direct_)
|
||||
{
|
||||
s << "ST_ClipByBox2D(";
|
||||
s << "SELECT ";
|
||||
s << "\"" << geometryColumn_ << "\"";
|
||||
s << "AS geom";
|
||||
}
|
||||
s << "\"" << geometryColumn_ << "\"";
|
||||
|
||||
// ! ST_ClipByBox2D()
|
||||
if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
|
||||
else
|
||||
{
|
||||
s << "," << sql_bbox(box) << ")";
|
||||
}
|
||||
// This will only work against PostGIS 2.2, or a back-patched version
|
||||
// that has (a) a ST_Simplify with a "preserve collapsed" flag and
|
||||
// (b) a ST_RemoveRepeatedPoints with a tolerance parameter and
|
||||
// (c) a ST_AsTWKB implementation
|
||||
|
||||
// ! ST_RemoveRepeatedPoints()
|
||||
s << "," << twkb_tolerance << ")";
|
||||
// ! ST_Simplify(), with parameter to keep collapsed geometries
|
||||
s << "," << twkb_tolerance << ",true)";
|
||||
// ! ST_TWKB()
|
||||
s << "," << twkb_rounding << ") AS geom";
|
||||
// What number of decimals of rounding does the pixel size imply?
|
||||
const int twkb_rounding = -1 * std::lround(log10(px_sz) + twkb_rounding_adjustment_) + 1;
|
||||
// And what's that in map units?
|
||||
const double twkb_tolerance = pow(10.0, -1.0 * twkb_rounding);
|
||||
|
||||
s << "SELECT ST_AsTWKB(";
|
||||
s << "ST_Simplify(";
|
||||
s << "ST_RemoveRepeatedPoints(";
|
||||
|
||||
if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
|
||||
{
|
||||
s << "ST_ClipByBox2D(";
|
||||
}
|
||||
s << "\"" << geometryColumn_ << "\"";
|
||||
|
||||
// ! ST_ClipByBox2D()
|
||||
if (simplify_clip_resolution_ > 0.0 && simplify_clip_resolution_ > px_sz)
|
||||
{
|
||||
s << "," << sql_bbox(box) << ")";
|
||||
}
|
||||
|
||||
// ! ST_RemoveRepeatedPoints()
|
||||
s << "," << twkb_tolerance << ")";
|
||||
// ! ST_Simplify(), with parameter to keep collapsed geometries
|
||||
s << "," << twkb_tolerance << ",true)";
|
||||
// ! ST_TWKB()
|
||||
s << "," << twkb_rounding << ") AS geom";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1081,8 +1104,15 @@ box2d<double> postgis_datasource::envelope() const
|
|||
}
|
||||
else
|
||||
{
|
||||
s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)"
|
||||
<< " FROM (SELECT ST_Extent(" <<geometryColumn_<< ") as ext from ";
|
||||
s << "SELECT ST_XMin(ext),ST_YMin(ext),ST_XMax(ext),ST_YMax(ext)";
|
||||
if (twkb_direct_)
|
||||
{
|
||||
s << " FROM (SELECT ST_Extent(ST_GeomFromTWKB(" << geometryColumn_<< ")) as ext from ";
|
||||
}
|
||||
else
|
||||
{
|
||||
s << " FROM (SELECT ST_Extent(" << geometryColumn_<< ") as ext from ";
|
||||
}
|
||||
|
||||
if (extent_from_subquery_)
|
||||
{
|
||||
|
|
|
@ -120,6 +120,7 @@ private:
|
|||
int max_async_connections_;
|
||||
bool asynchronous_request_;
|
||||
bool twkb_encoding_;
|
||||
bool twkb_direct_;
|
||||
mapnik::value_double twkb_rounding_adjustment_;
|
||||
mapnik::value_double simplify_snap_ratio_;
|
||||
mapnik::value_double simplify_dp_ratio_;
|
||||
|
|
Loading…
Reference in a new issue