Skip to content

Commit 4caafe6

Browse files
authored
Merge pull request #2492 from joto/fix-expire
Fix a bug in diff expire handling
2 parents 560190a + 3b95ca4 commit 4caafe6

2 files changed

Lines changed: 142 additions & 51 deletions

File tree

‎src/flex-table-column.cpp‎

Lines changed: 56 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -214,24 +214,6 @@ void flex_table_column_t::add_expire(expire_config_t const &config)
214214
}
215215

216216
namespace {
217-
218-
/**
219-
* This expires all geometries in "geoms" by themselves. Used when we don't
220-
* need diff expire.
221-
*/
222-
void separate_expire(std::vector<geom::geometry_t> const &geoms,
223-
expire_config_t const &expire_config,
224-
expire_tiles_t &expire_tiles,
225-
std::vector<expire_output_t> *expire_outputs)
226-
{
227-
assert(expire_outputs);
228-
229-
for (auto const &geom : geoms) {
230-
expire_tiles.from_geometry(geom, expire_config);
231-
}
232-
expire_tiles.commit_tiles(&expire_outputs->at(expire_config.expire_output));
233-
}
234-
235217
/**
236218
* When doing diff expire, we need to calculate the symmetric difference
237219
* between old and new geometries. The difference is done by type, so points
@@ -282,28 +264,14 @@ void classify_geometries(T input_geoms, geom::multipoint_t *points,
282264
}
283265
// NOLINTEND(cppcoreguidelines-rvalue-reference-param-not-moved)
284266

285-
template <typename T>
286-
void diff_and_expire(geom::multigeometry_t<T> const &old_geoms,
287-
geom::multigeometry_t<T> const &new_geoms,
288-
expire_config_t const &expire_config,
289-
expire_tiles_t &expire_tiles)
290-
{
291-
std::vector<T> diffs;
292-
boost::geometry::sym_difference(old_geoms, new_geoms, diffs);
293-
for (auto const &geom : diffs) {
294-
expire_tiles.from_geometry(geom, expire_config);
295-
}
296-
}
297-
298-
void diff_expire(std::vector<geom::geometry_t> *geoms_old,
299-
std::vector<geom::geometry_t> *geoms_new,
300-
expire_config_t const &expire_config,
301-
expire_tiles_t &expire_tiles,
302-
std::vector<expire_output_t> *expire_outputs)
267+
void find_difference(std::vector<geom::geometry_t> *geoms_old,
268+
std::vector<geom::geometry_t> *geoms_new,
269+
std::vector<geom::point_t> *diff_points,
270+
std::vector<geom::linestring_t> *diff_linestrings,
271+
std::vector<geom::polygon_t> *diff_polygons)
303272
{
304273
assert(geoms_old);
305274
assert(geoms_new);
306-
assert(expire_outputs);
307275

308276
geom::multipoint_t old_points;
309277
geom::multilinestring_t old_linestrings;
@@ -319,12 +287,10 @@ void diff_expire(std::vector<geom::geometry_t> *geoms_old,
319287
classify_geometries(geoms_new, &new_points, &new_linestrings,
320288
&new_polygons);
321289

322-
diff_and_expire(old_points, new_points, expire_config, expire_tiles);
323-
diff_and_expire(old_linestrings, new_linestrings, expire_config,
324-
expire_tiles);
325-
diff_and_expire(old_polygons, new_polygons, expire_config, expire_tiles);
326-
327-
expire_tiles.commit_tiles(&expire_outputs->at(expire_config.expire_output));
290+
boost::geometry::sym_difference(old_points, new_points, *diff_points);
291+
boost::geometry::sym_difference(old_linestrings, new_linestrings,
292+
*diff_linestrings);
293+
boost::geometry::sym_difference(old_polygons, new_polygons, *diff_polygons);
328294
}
329295

330296
} // anonymous namespace
@@ -340,19 +306,58 @@ void flex_table_column_t::do_expire(
340306
assert(expire);
341307
assert(expire_outputs);
342308

309+
// Sometimes it doesn't depend on the expire config whether we want to
310+
// do diff expire.
311+
bool const always_separate =
312+
!enable_diff_expire || geoms_old->empty() || geoms_new->empty();
313+
314+
bool need_diff_expire = false;
315+
343316
for (auto const &expire_config : m_expires) {
344317
assert(expire_config.expire_output < expire->size());
345318
auto &expire_tiles = expire->at(expire_config.expire_output);
346319

347-
if (!expire_config.diff_expire || !enable_diff_expire ||
348-
geoms_old->empty() || geoms_new->empty()) {
349-
separate_expire(*geoms_old, expire_config, expire_tiles,
350-
expire_outputs);
351-
separate_expire(*geoms_new, expire_config, expire_tiles,
352-
expire_outputs);
320+
if (!expire_config.diff_expire || always_separate) {
321+
for (auto const &geom : *geoms_old) {
322+
expire_tiles.from_geometry(geom, expire_config);
323+
}
324+
for (auto const &geom : *geoms_new) {
325+
expire_tiles.from_geometry(geom, expire_config);
326+
}
327+
expire_tiles.commit_tiles(
328+
&expire_outputs->at(expire_config.expire_output));
353329
} else {
354-
diff_expire(geoms_old, geoms_new, expire_config, expire_tiles,
355-
expire_outputs);
330+
need_diff_expire = true;
331+
}
332+
}
333+
334+
if (always_separate || !need_diff_expire) {
335+
return;
336+
}
337+
338+
std::vector<geom::point_t> diff_points;
339+
std::vector<geom::linestring_t> diff_linestrings;
340+
std::vector<geom::polygon_t> diff_polygons;
341+
342+
find_difference(geoms_old, geoms_new, &diff_points, &diff_linestrings,
343+
&diff_polygons);
344+
345+
for (auto const &expire_config : m_expires) {
346+
assert(expire_config.expire_output < expire->size());
347+
auto &expire_tiles = expire->at(expire_config.expire_output);
348+
349+
if (expire_config.diff_expire) {
350+
for (auto const &geom : diff_points) {
351+
expire_tiles.from_geometry(geom, expire_config);
352+
}
353+
for (auto const &geom : diff_linestrings) {
354+
expire_tiles.from_geometry(geom, expire_config);
355+
}
356+
for (auto const &geom : diff_polygons) {
357+
expire_tiles.from_geometry(geom, expire_config);
358+
}
359+
expire_tiles.commit_tiles(
360+
&expire_outputs->at(expire_config.expire_output));
356361
}
357362
}
358363
}

‎tests/bdd/flex/expire-diff.feature‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -359,3 +359,89 @@ Feature: Diff expire
359359
| 8 | 129 | 126 |
360360
| 8 | 130 | 126 |
361361

362+
Scenario: multiple expire configs, with and without diff expire
363+
Given the OSM data
364+
"""
365+
n1 v1 x0 y0
366+
n2 v1 x2 y0
367+
n3 v1 x2 y1
368+
n4 v1 x4 y1
369+
w1 v1 Thighway=primary Nn1,n2,n3,n4
370+
"""
371+
And the lua style
372+
"""
373+
local eo1 = osm2pgsql.define_expire_output({
374+
table = 'osm2pgsql_test_expire1',
375+
maxzoom = 8,
376+
})
377+
378+
local eo2 = osm2pgsql.define_expire_output({
379+
table = 'osm2pgsql_test_expire2',
380+
maxzoom = 8,
381+
})
382+
383+
local eo3 = osm2pgsql.define_expire_output({
384+
table = 'osm2pgsql_test_expire3',
385+
maxzoom = 7,
386+
})
387+
388+
local the_table = osm2pgsql.define_way_table('osm2pgsql_test', {
389+
{ column = 'geom', type = 'linestring', expire = {
390+
{ output = eo1, diff_expire = true },
391+
{ output = eo2, diff_expire = false },
392+
{ output = eo3, diff_expire = true }
393+
}
394+
},
395+
})
396+
397+
function osm2pgsql.process_way(object)
398+
the_table:insert{
399+
geom = object:as_linestring()
400+
}
401+
end
402+
"""
403+
When running osm2pgsql flex with parameters
404+
| --slim | -c |
405+
Then table osm2pgsql_test has 1 rows
406+
Then table osm2pgsql_test contains exactly
407+
| way_id | geom!geo |
408+
| 1 | 0 0,222638.98158654713 0,222638.98158654713 111325.14285463623,445277.96317309426 111325.14285463623 |
409+
Then table osm2pgsql_test_expire1 has 0 rows
410+
Then table osm2pgsql_test_expire2 has 0 rows
411+
Then table osm2pgsql_test_expire3 has 0 rows
412+
413+
Given the OSM data
414+
"""
415+
n2 v2 x0 y1
416+
"""
417+
When running osm2pgsql flex with parameters
418+
| --slim | -a |
419+
Then table osm2pgsql_test contains exactly
420+
| way_id | geom!geo |
421+
| 1 | 0 0,0 111325.14285463623,222638.98158654713 111325.14285463623,445277.96317309426 111325.14285463623 |
422+
Then table osm2pgsql_test_expire1 contains exactly
423+
| zoom | x | y |
424+
| 8 | 127 | 127 |
425+
| 8 | 128 | 127 |
426+
| 8 | 129 | 127 |
427+
| 8 | 127 | 128 |
428+
| 8 | 128 | 128 |
429+
| 8 | 129 | 128 |
430+
431+
Then table osm2pgsql_test_expire2 contains exactly
432+
| zoom | x | y |
433+
| 8 | 127 | 127 |
434+
| 8 | 128 | 127 |
435+
| 8 | 129 | 127 |
436+
| 8 | 130 | 127 |
437+
| 8 | 127 | 128 |
438+
| 8 | 128 | 128 |
439+
| 8 | 129 | 128 |
440+
441+
Then table osm2pgsql_test_expire3 contains exactly
442+
| zoom | x | y |
443+
| 7 | 63 | 63 |
444+
| 7 | 63 | 64 |
445+
| 7 | 64 | 63 |
446+
| 7 | 64 | 64 |
447+

0 commit comments

Comments
 (0)