Skip to content

Commit d6013c4

Browse files
authored
Merge pull request #1809 from joto/refactor-expire-by-geom
Refactor expire by geometry code
2 parents c7438e3 + 4bfa132 commit d6013c4

7 files changed

Lines changed: 527 additions & 51 deletions

File tree

src/expire-tiles.cpp

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -78,41 +78,57 @@ void expire_tiles::from_point_list(geom::point_list_t const &list)
7878
});
7979
}
8080

81-
void expire_tiles::from_geometry(geom::geometry_t const &geom)
81+
void expire_tiles::from_geometry(geom::point_t const &geom)
82+
{
83+
geom::box_t const box = geom::envelope(geom);
84+
from_bbox(box);
85+
}
86+
87+
void expire_tiles::from_geometry(geom::linestring_t const &geom)
8288
{
83-
if (geom.srid() != 3857) {
84-
return;
89+
from_point_list(geom);
90+
}
91+
92+
void expire_tiles::from_polygon_boundary(geom::polygon_t const &geom)
93+
{
94+
from_point_list(geom.outer());
95+
for (auto const &inner : geom.inners()) {
96+
from_point_list(inner);
8597
}
98+
}
8699

87-
if (geom.is_point()) {
88-
auto const box = geom::envelope(geom);
89-
from_bbox(box);
90-
} else if (geom.is_linestring()) {
91-
from_point_list(geom.get<geom::linestring_t>());
92-
} else if (geom.is_multilinestring()) {
93-
for (auto const &list : geom.get<geom::multilinestring_t>()) {
94-
from_point_list(list);
95-
}
96-
} else if (geom.is_polygon() || geom.is_multipolygon()) {
97-
auto const box = geom::envelope(geom);
98-
if (from_bbox(box)) {
99-
if (geom.is_polygon()) {
100-
from_point_list(geom.get<geom::polygon_t>().outer());
101-
for (auto const &inner : geom.get<geom::polygon_t>().inners()) {
102-
from_point_list(inner);
103-
}
104-
} else if (geom.is_multipolygon()) {
105-
for (auto const &polygon : geom.get<geom::multipolygon_t>()) {
106-
from_point_list(polygon.outer());
107-
for (auto const &inner : polygon.inners()) {
108-
from_point_list(inner);
109-
}
110-
}
111-
}
100+
void expire_tiles::from_geometry(geom::polygon_t const &geom)
101+
{
102+
geom::box_t const box = geom::envelope(geom);
103+
if (from_bbox(box)) {
104+
/* Bounding box too big - just expire tiles on the boundary */
105+
from_polygon_boundary(geom);
106+
}
107+
}
108+
109+
void expire_tiles::from_geometry(geom::multipolygon_t const &geom)
110+
{
111+
geom::box_t const box = geom::envelope(geom);
112+
if (from_bbox(box)) {
113+
/* Bounding box too big - just expire tiles on the boundary */
114+
for (auto const &sgeom : geom) {
115+
from_polygon_boundary(sgeom);
112116
}
113117
}
114118
}
115119

120+
void expire_tiles::from_geometry(geom::geometry_t const &geom)
121+
{
122+
geom.visit([&](auto const &g) { from_geometry(g); });
123+
}
124+
125+
void expire_tiles::from_geometry_if_3857(geom::geometry_t const &geom)
126+
{
127+
if (geom.srid() == 3857) {
128+
from_geometry(geom);
129+
}
130+
}
131+
116132
/*
117133
* Expire tiles that a line crosses
118134
*/
@@ -281,11 +297,8 @@ std::size_t output_tiles_to_file(quadkey_list_t const &tiles_maxzoom,
281297

282298
int expire_from_result(expire_tiles *expire, pg_result_t const &result)
283299
{
284-
if (!expire->enabled()) {
285-
return -1;
286-
}
287-
288300
auto const num_tuples = result.num_tuples();
301+
289302
for (int i = 0; i < num_tuples; ++i) {
290303
char const *const wkb = result.get_value(i, 0);
291304
expire->from_geometry(ewkb_to_geom(decode_hex(wkb)));

src/expire-tiles.hpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,26 @@ class expire_tiles
3232

3333
bool enabled() const noexcept { return m_maxzoom != 0; }
3434

35+
void from_polygon_boundary(geom::polygon_t const &geom);
36+
37+
void from_geometry(geom::nullgeom_t const & /*geom*/) {}
38+
void from_geometry(geom::point_t const &geom);
39+
void from_geometry(geom::linestring_t const &geom);
40+
void from_geometry(geom::polygon_t const &geom);
41+
void from_geometry(geom::multipolygon_t const &geom);
42+
43+
template <typename T>
44+
void from_geometry(geom::multigeometry_t<T> const &geom)
45+
{
46+
for (auto const &sgeom : geom) {
47+
from_geometry(sgeom);
48+
}
49+
}
50+
3551
void from_geometry(geom::geometry_t const &geom);
3652

53+
void from_geometry_if_3857(geom::geometry_t const &geom);
54+
3755
int from_bbox(geom::box_t const &box);
3856

3957
/**

src/options.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -710,6 +710,12 @@ void options_t::check_options()
710710
"large and has been set to 31.");
711711
}
712712

713+
if (expire_tiles_zoom != 0 && projection->target_srs() != 3857) {
714+
log_warn("Expire has been enabled (with -e or --expire-tiles) but "
715+
"target SRS is not Mercator (EPSG:3857). Expire disabled!");
716+
expire_tiles_zoom = 0;
717+
}
718+
713719
if (output_backend == "flex" || output_backend == "gazetteer") {
714720
if (style == DEFAULT_STYLE) {
715721
throw std::runtime_error{

src/output-flex.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -711,13 +711,13 @@ void output_flex_t::write_column(
711711
type == table_column_type::multilinestring ||
712712
type == table_column_type::multipolygon);
713713
if (geom->srid() == column.srid()) {
714-
m_expire.from_geometry(*geom);
714+
m_expire.from_geometry_if_3857(*geom);
715715
copy_mgr->add_hex_geom(geom_to_ewkb(*geom, wrap_multi));
716716
} else {
717717
auto const proj =
718718
reprojection::create_projection(column.srid());
719719
auto const tgeom = geom::transform(*geom, *proj);
720-
m_expire.from_geometry(tgeom);
720+
m_expire.from_geometry_if_3857(tgeom);
721721
copy_mgr->add_hex_geom(geom_to_ewkb(tgeom, wrap_multi));
722722
}
723723
} else {
@@ -1681,7 +1681,7 @@ void output_flex_t::add_row(table_connection_t *table_connection,
16811681

16821682
auto const geoms = geom::split_multi(std::move(geom), split_multi);
16831683
for (auto const &sgeom : geoms) {
1684-
m_expire.from_geometry(sgeom);
1684+
m_expire.from_geometry_if_3857(sgeom);
16851685
write_row(table_connection, object.type(), id, sgeom,
16861686
table.geom_column().srid());
16871687
}
@@ -1906,15 +1906,12 @@ void output_flex_t::delete_from_table(table_connection_t *table_connection,
19061906
osmium::item_type type, osmid_t osm_id)
19071907
{
19081908
assert(table_connection);
1909-
auto const id = table_connection->table().map_id(type, osm_id);
1909+
auto const &table = table_connection->table();
1910+
auto const id = table.map_id(type, osm_id);
19101911

1911-
if (m_expire.enabled() && table_connection->table().has_geom_column()) {
1912+
if (m_expire.enabled() && table.has_geom_column() &&
1913+
table.geom_column().srid() == 3857) {
19121914
auto const result = table_connection->get_geom_by_id(type, id);
1913-
1914-
if (result.num_tuples() == 0) {
1915-
return;
1916-
}
1917-
19181915
expire_from_result(&m_expire, result);
19191916
}
19201917

src/output-pgsql.cpp

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void output_pgsql_t::pgsql_out_way(osmium::Way const &way, taglist_t *tags,
6767

6868
auto const wkb = geom_to_ewkb(projected_geom);
6969
if (!wkb.empty()) {
70-
m_expire.from_geometry(projected_geom);
70+
m_expire.from_geometry_if_3857(projected_geom);
7171
if (m_enable_way_area) {
7272
double const area = calculate_area(
7373
get_options()->reproject_area, geom, projected_geom);
@@ -82,7 +82,7 @@ void output_pgsql_t::pgsql_out_way(osmium::Way const &way, taglist_t *tags,
8282
auto const geoms = geom::split_multi(geom::segmentize(
8383
geom::transform(geom::create_linestring(way), *m_proj), split_at));
8484
for (auto const &sgeom : geoms) {
85-
m_expire.from_geometry(sgeom);
85+
m_expire.from_geometry_if_3857(sgeom);
8686
auto const wkb = geom_to_ewkb(sgeom);
8787
m_tables[t_line]->write_row(way.id(), *tags, wkb);
8888
if (roads) {
@@ -169,7 +169,7 @@ void output_pgsql_t::node_add(osmium::Node const &node)
169169
}
170170

171171
auto const geom = geom::transform(geom::create_point(node), *m_proj);
172-
m_expire.from_geometry(geom);
172+
m_expire.from_geometry_if_3857(geom);
173173
auto const wkb = geom_to_ewkb(geom);
174174
m_tables[t_point]->write_row(node.id(), outtags, wkb);
175175
}
@@ -272,7 +272,7 @@ void output_pgsql_t::pgsql_process_relation(osmium::Relation const &rel)
272272
}
273273
auto const geoms = geom::split_multi(std::move(projected_geom));
274274
for (auto const &sgeom : geoms) {
275-
m_expire.from_geometry(sgeom);
275+
m_expire.from_geometry_if_3857(sgeom);
276276
auto const wkb = geom_to_ewkb(sgeom);
277277
m_tables[t_line]->write_row(-rel.id(), outtags, wkb);
278278
if (roads) {
@@ -288,7 +288,7 @@ void output_pgsql_t::pgsql_process_relation(osmium::Relation const &rel)
288288
!get_options()->enable_multi);
289289
for (auto const &sgeom : geoms) {
290290
auto const projected_geom = geom::transform(sgeom, *m_proj);
291-
m_expire.from_geometry(projected_geom);
291+
m_expire.from_geometry_if_3857(projected_geom);
292292
auto const wkb = geom_to_ewkb(projected_geom);
293293
if (m_enable_way_area) {
294294
double const area = calculate_area(
@@ -325,8 +325,12 @@ void output_pgsql_t::relation_add(osmium::Relation const &rel)
325325
* contain the change for that also. */
326326
void output_pgsql_t::node_delete(osmid_t osm_id)
327327
{
328-
auto const results = m_tables[t_point]->get_wkb(osm_id);
329-
if (expire_from_result(&m_expire, results) != 0) {
328+
if (m_expire.enabled()) {
329+
auto const results = m_tables[t_point]->get_wkb(osm_id);
330+
if (expire_from_result(&m_expire, results) != 0) {
331+
m_tables[t_point]->delete_row(osm_id);
332+
}
333+
} else {
330334
m_tables[t_point]->delete_row(osm_id);
331335
}
332336
}
@@ -336,8 +340,12 @@ void output_pgsql_t::delete_from_output_and_expire(osmid_t id)
336340
m_tables[t_roads]->delete_row(id);
337341

338342
for (auto table : {t_line, t_poly}) {
339-
auto const results = m_tables[table]->get_wkb(id);
340-
if (expire_from_result(&m_expire, results) != 0) {
343+
if (m_expire.enabled()) {
344+
auto const results = m_tables[table]->get_wkb(id);
345+
if (expire_from_result(&m_expire, results) != 0) {
346+
m_tables[table]->delete_row(id);
347+
}
348+
} else {
341349
m_tables[table]->delete_row(id);
342350
}
343351
}

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ set_test(test-check-input LABELS NoDB)
4141
set_test(test-db-copy-thread)
4242
set_test(test-db-copy-mgr)
4343
set_test(test-domain-matcher LABELS NoDB)
44+
set_test(test-expire-from-geometry LABELS NoDB)
4445
set_test(test-expire-tiles LABELS NoDB)
4546
set_test(test-geom-box LABELS NoDB)
4647
set_test(test-geom-collections LABELS NoDB)

0 commit comments

Comments
 (0)