|
10 | 10 | #include "flex-table-column.hpp" |
11 | 11 |
|
12 | 12 | #include "format.hpp" |
| 13 | +#include "geom-boost-adaptor.hpp" |
| 14 | +#include "overloaded.hpp" |
13 | 15 | #include "pgsql-capabilities.hpp" |
14 | 16 | #include "projection.hpp" |
15 | 17 | #include "util.hpp" |
@@ -208,18 +210,146 @@ void flex_table_column_t::add_expire(expire_config_t const &config) |
208 | 210 | m_expires.push_back(config); |
209 | 211 | } |
210 | 212 |
|
| 213 | +namespace { |
| 214 | + |
| 215 | +/** |
| 216 | + * This expires all geometries in "geoms" by themselves. Used when we don't |
| 217 | + * need diff expire. |
| 218 | + */ |
| 219 | +void separate_expire(std::vector<geom::geometry_t> const &geoms, |
| 220 | + expire_config_t const &expire_config, |
| 221 | + expire_tiles_t &expire_tiles, |
| 222 | + std::vector<expire_output_t> *expire_outputs) |
| 223 | +{ |
| 224 | + assert(expire_outputs); |
| 225 | + |
| 226 | + for (auto const &geom : geoms) { |
| 227 | + expire_tiles.from_geometry(geom, expire_config); |
| 228 | + } |
| 229 | + expire_tiles.commit_tiles(&expire_outputs->at(expire_config.expire_output)); |
| 230 | +} |
| 231 | + |
| 232 | +/** |
| 233 | + * When doing diff expire, we need to calculate the symmetric difference |
| 234 | + * between old and new geometries. The difference is done by type, so points |
| 235 | + * are compared with points, linestrings with linestrings, etc. This function |
| 236 | + * separates out the input geometries by the three fundamental types. |
| 237 | + */ |
| 238 | +// NOLINTBEGIN(cppcoreguidelines-rvalue-reference-param-not-moved) |
| 239 | +template <typename T> |
| 240 | +void classify_geometries(T input_geoms, geom::multipoint_t *points, |
| 241 | + geom::multilinestring_t *linestrings, |
| 242 | + geom::multipolygon_t *polygons) |
| 243 | +{ |
| 244 | + assert(points); |
| 245 | + assert(linestrings); |
| 246 | + assert(polygons); |
| 247 | + |
| 248 | + for (auto &&geom : *input_geoms) { |
| 249 | + visit(overloaded{ |
| 250 | + [&](geom::nullgeom_t && /*input*/) {}, |
| 251 | + [&](geom::point_t &&input) { points->add_geometry(input); }, |
| 252 | + [&](geom::linestring_t &&input) { |
| 253 | + linestrings->add_geometry(std::move(input)); |
| 254 | + }, |
| 255 | + [&](geom::polygon_t &&input) { |
| 256 | + polygons->add_geometry(std::move(input)); |
| 257 | + }, |
| 258 | + [&](geom::multipoint_t &&input) { |
| 259 | + for (auto &&point : input) { |
| 260 | + points->add_geometry(point); |
| 261 | + } |
| 262 | + }, |
| 263 | + [&](geom::multilinestring_t &&input) { |
| 264 | + for (auto &&linestring : input) { |
| 265 | + linestrings->add_geometry(std::move(linestring)); |
| 266 | + } |
| 267 | + }, |
| 268 | + [&](geom::multipolygon_t &&input) { |
| 269 | + for (auto &&polygon : input) { |
| 270 | + polygons->add_geometry(std::move(polygon)); |
| 271 | + } |
| 272 | + }, |
| 273 | + [&](geom::collection_t &&input) { |
| 274 | + classify_geometries(&input, points, linestrings, |
| 275 | + polygons); |
| 276 | + }}, |
| 277 | + std::move(geom)); |
| 278 | + } |
| 279 | +} |
| 280 | +// NOLINTEND(cppcoreguidelines-rvalue-reference-param-not-moved) |
| 281 | + |
| 282 | +template <typename T> |
| 283 | +void diff_and_expire(geom::multigeometry_t<T> const &old_geoms, |
| 284 | + geom::multigeometry_t<T> const &new_geoms, |
| 285 | + expire_config_t const &expire_config, |
| 286 | + expire_tiles_t &expire_tiles) |
| 287 | +{ |
| 288 | + std::vector<T> diffs; |
| 289 | + boost::geometry::sym_difference(old_geoms, new_geoms, diffs); |
| 290 | + for (auto const &geom : diffs) { |
| 291 | + expire_tiles.from_geometry(geom, expire_config); |
| 292 | + } |
| 293 | +} |
| 294 | + |
| 295 | +void diff_expire(std::vector<geom::geometry_t> *geoms_old, |
| 296 | + std::vector<geom::geometry_t> *geoms_new, |
| 297 | + expire_config_t const &expire_config, |
| 298 | + expire_tiles_t &expire_tiles, |
| 299 | + std::vector<expire_output_t> *expire_outputs) |
| 300 | +{ |
| 301 | + assert(geoms_old); |
| 302 | + assert(geoms_new); |
| 303 | + assert(expire_outputs); |
| 304 | + |
| 305 | + geom::multipoint_t old_points; |
| 306 | + geom::multilinestring_t old_linestrings; |
| 307 | + geom::multipolygon_t old_polygons; |
| 308 | + |
| 309 | + classify_geometries(geoms_old, &old_points, &old_linestrings, |
| 310 | + &old_polygons); |
| 311 | + |
| 312 | + geom::multipoint_t new_points; |
| 313 | + geom::multilinestring_t new_linestrings; |
| 314 | + geom::multipolygon_t new_polygons; |
| 315 | + |
| 316 | + classify_geometries(geoms_new, &new_points, &new_linestrings, |
| 317 | + &new_polygons); |
| 318 | + |
| 319 | + diff_and_expire(old_points, new_points, expire_config, expire_tiles); |
| 320 | + diff_and_expire(old_linestrings, new_linestrings, expire_config, |
| 321 | + expire_tiles); |
| 322 | + diff_and_expire(old_polygons, new_polygons, expire_config, expire_tiles); |
| 323 | + |
| 324 | + expire_tiles.commit_tiles(&expire_outputs->at(expire_config.expire_output)); |
| 325 | +} |
| 326 | + |
| 327 | +} // anonymous namespace |
| 328 | + |
211 | 329 | void flex_table_column_t::do_expire( |
212 | | - geom::geometry_t const &geom, std::vector<expire_tiles_t> *expire, |
213 | | - std::vector<expire_output_t> *expire_outputs) const |
| 330 | + std::vector<geom::geometry_t> *geoms_old, |
| 331 | + std::vector<geom::geometry_t> *geoms_new, |
| 332 | + std::vector<expire_tiles_t> *expire, |
| 333 | + std::vector<expire_output_t> *expire_outputs, bool enable_diff_expire) const |
214 | 334 | { |
| 335 | + assert(geoms_old); |
| 336 | + assert(geoms_new); |
215 | 337 | assert(expire); |
216 | 338 | assert(expire_outputs); |
217 | 339 |
|
218 | 340 | for (auto const &expire_config : m_expires) { |
219 | 341 | assert(expire_config.expire_output < expire->size()); |
220 | 342 | auto &expire_tiles = expire->at(expire_config.expire_output); |
221 | | - expire_tiles.from_geometry(geom, expire_config); |
222 | | - expire_tiles.commit_tiles( |
223 | | - &expire_outputs->at(expire_config.expire_output)); |
| 343 | + |
| 344 | + if (!expire_config.diff_expire || !enable_diff_expire || |
| 345 | + geoms_old->empty() || geoms_new->empty()) { |
| 346 | + separate_expire(*geoms_old, expire_config, expire_tiles, |
| 347 | + expire_outputs); |
| 348 | + separate_expire(*geoms_new, expire_config, expire_tiles, |
| 349 | + expire_outputs); |
| 350 | + } else { |
| 351 | + diff_expire(geoms_old, geoms_new, expire_config, expire_tiles, |
| 352 | + expire_outputs); |
| 353 | + } |
224 | 354 | } |
225 | 355 | } |
0 commit comments