Compare commits

...

9 commits

Author SHA1 Message Date
artemp
fe89e70505 Merge branch 'master' into twkb-direct 2016-03-30 14:53:51 +02:00
artemp
ce52c91156 Merge branch 'master' into twkb-direct 2016-03-29 10:47:05 +01:00
artemp
d0e3f39c3c Merge branch 'master' into twkb-direct 2016-03-24 14:25:51 +00:00
artemp
542ad1d9aa fix markdown doh 2016-03-22 12:59:15 +01:00
artemp
a7f2819d76 fix SQL 2016-03-22 12:57:46 +01:00
artemp
dbdb392c6e add size comparisons (OSM planet Iceland) 2016-03-22 12:54:44 +01:00
artemp
367df4a5d7 add XML parameters setup 2016-03-22 10:50:39 +01:00
artemp
e0526e4182 Update TWKB howto 2016-03-22 10:41:50 +01:00
artemp
186c80ca38 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>
```
2016-03-22 10:34:49 +01:00
3 changed files with 133 additions and 33 deletions

69
TWKB-HOWTO.md Normal file
View file

@ -0,0 +1,69 @@
### 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;
```
*NOTE: `update planet_osm_polygon_twkb set twkb = ST_AsTWKB(way, 2);` should be using `ST_AsTWKB(ST_Simplify(ST_RemoveRepeatedPoints(way, <tolerance>),<tolerance>, true),2)`*
#### 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+
```
##### XML style
Make sure style has following parameters are present on top of usual postgis.input setup.
```xml
<Parameter name="geometry_field">twkb</Parameter>
<Parameter name="twkb_encoding">True</Parameter>
<Parameter name="twkb_direct">True</Parameter>
```
##### Iceland (osm2pgsql)
```sql
....
update planet_osm_line_twkb set twkb = ST_AsTWKB(ST_Simplify(ST_RemoveRepeatedPoints(way,1), 1, true),0);
update planet_osm_polygon_twkb set twkb = ST_AsTWKB(ST_Simplify(ST_RemoveRepeatedPoints(way,1), 1, true),0);
```
```bash
osm=# \d+
List of relations
Schema | Name | Type | Owner | Size | Description
--------+-------------------------+-------+-------+----------+-------------
public | geography_columns | view | artem | 0 bytes |
public | geometry_columns | view | artem | 0 bytes |
public | planet_osm_line | table | artem | 30 MB |
public | planet_osm_line_twkb | table | artem | 10216 kB |
public | planet_osm_nodes | table | artem | 93 MB |
public | planet_osm_point | table | artem | 7136 kB |
public | planet_osm_polygon | table | artem | 28 MB |
public | planet_osm_polygon_twkb | table | artem | 10 MB |
public | planet_osm_rels | table | artem | 3136 kB |
public | planet_osm_roads | table | artem | 4784 kB |
public | planet_osm_ways | table | artem | 51 MB |
public | spatial_ref_sys | table | artem | 4016 kB |
(12 rows)
```

View file

@ -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_)
{

View file

@ -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_;