|
13 | 13 | #include <algorithm> |
14 | 14 | #include <cmath> |
15 | 15 | #include <iterator> |
| 16 | +#include <numeric> |
16 | 17 | #include <tuple> |
17 | 18 | #include <utility> |
18 | 19 |
|
@@ -334,52 +335,19 @@ geometry_t segmentize(geometry_t const &input, double max_segment_length) |
334 | 335 | return output; |
335 | 336 | } |
336 | 337 |
|
337 | | -static double get_ring_area(ring_t const &ring) noexcept |
338 | | -{ |
339 | | - assert(ring.size() > 3); |
340 | | - |
341 | | - double total = 0.0; |
342 | | - auto it = ring.begin(); |
343 | | - auto prev = *it++; |
344 | | - |
345 | | - while (it != ring.end()) { |
346 | | - auto const cur = *it; |
347 | | - total += prev.x() * cur.y() - cur.x() * prev.y(); |
348 | | - prev = cur; |
349 | | - ++it; |
350 | | - } |
351 | | - |
352 | | - return total; |
353 | | -} |
354 | | - |
355 | | -static double get_polygon_area(polygon_t const &polygon) |
356 | | -{ |
357 | | - double total = get_ring_area(polygon.outer()); |
358 | | - |
359 | | - for (auto const &ring : polygon.inners()) { |
360 | | - total += get_ring_area(ring); |
361 | | - } |
362 | | - |
363 | | - return total * 0.5; |
364 | | -} |
365 | | - |
366 | 338 | double area(geometry_t const &geom) |
367 | 339 | { |
368 | | - double total = 0.0; |
369 | | - |
370 | | - if (geom.is_polygon()) { |
371 | | - total = get_polygon_area(geom.get<polygon_t>()); |
372 | | - } else if (geom.is_multipolygon()) { |
373 | | - for (auto const &polygon : geom.get<multipolygon_t>()) { |
374 | | - total += get_polygon_area(polygon); |
375 | | - } |
376 | | - } else if (geom.is_collection()) { |
377 | | - for (auto const &sgeom : geom.get<collection_t>()) { |
378 | | - total += area(sgeom); |
379 | | - } |
380 | | - } |
381 | | - |
382 | | - return std::abs(total); |
| 340 | + return std::abs(geom.visit( |
| 341 | + overloaded{[&](geom::nullgeom_t const & /*input*/) { return 0.0; }, |
| 342 | + [&](geom::collection_t const &input) { |
| 343 | + return std::accumulate(input.cbegin(), input.cend(), 0.0, |
| 344 | + [](double sum, auto const &geom) { |
| 345 | + return sum + area(geom); |
| 346 | + }); |
| 347 | + }, |
| 348 | + [&](auto const &input) { |
| 349 | + return static_cast<double>(boost::geometry::area(input)); |
| 350 | + }})); |
383 | 351 | } |
384 | 352 |
|
385 | 353 | double length(geometry_t const &geom) |
|
0 commit comments