File Coverage

src/panda/Geos/tesselate.cpp
Criterion Covered Total %
statement 49 49 100.0
branch 45 82 54.8
condition n/a
subroutine n/a
pod n/a
total 94 131 71.7


line stmt bran cond sub pod time code
1             #include "tesselate.h"
2             #include "mapbox/earcut.hpp"
3             #include
4             #include
5              
6             using coord_t = geos::geom::Coordinate;
7              
8             namespace mapbox {
9             namespace util {
10              
11             template <>
12             struct nth<0, coord_t> {
13 24           inline static auto get(const coord_t &t) {
14 24           return t.x;
15             };
16             };
17             template <>
18             struct nth<1, coord_t> {
19 24           inline static auto get(const coord_t &t) {
20 24           return t.y;
21             };
22             };
23              
24             } // namespace util
25             } // namespace mapbox
26              
27             namespace panda { namespace Geos {
28              
29 1           geos::geom::GeometryCollection* tesselate(geos::geom::Polygon& input) {
30             using seq_holder_t = std::unique_ptr;
31             using result_t = std::vector;
32             using poly_sequence_t = std::vector;
33              
34 1 50         auto shell = input.getExteriorRing();
35 2 50         auto shell_coords = seq_holder_t{shell->getCoordinates()};
36 2           std::vector polygon;
37 2           poly_sequence_t linearized;
38              
39             /* outer ring/shell */
40 1 50         assert(shell_coords->size() > 1);
    50          
41 2           poly_sequence_t shell_seq;
42 5 50         for (size_t i = 0; i < shell_coords->size() - 1; ++i) {
    100          
43 4 50         auto& coord = shell_coords->getAt(i);
44 4 50         shell_seq.push_back(coord);
45 4 50         linearized.push_back(coord);
46             }
47 1 50         polygon.push_back(shell_seq);
48              
49             /* inner rings/holes */
50 1 50         auto holes_num = input.getNumInteriorRing();
51 2 100         for (size_t i = 0; i < holes_num; ++i) {
52 1 50         auto* hole = input.getInteriorRingN(i);
53 2 50         auto hole_coords = seq_holder_t{hole->getCoordinates()};
54 1 50         assert(hole_coords->size() > 1);
    50          
55 2           poly_sequence_t seq;
56 5 50         for (size_t j = 0; j < hole_coords->size() - 1; ++j) {
    100          
57 4 50         auto& coord = hole_coords->getAt(j);
58 4 50         seq.push_back(coord);
59 4 50         linearized.push_back(coord);
60             }
61 1 50         polygon.push_back(seq);
62             }
63              
64             /* run tesselation */
65             using N = uint32_t;
66 2 50         std::vector indices = mapbox::earcut(polygon);
67 1           auto vertices = indices.size();
68 1 50         if (!vertices) throw "no tesselation (invalid polygon?)";
69 1 50         assert(vertices % 3 == 0);
70              
71             /* construct triangles as polygones */
72 1           auto factory = input.getFactory();
73 1 50         auto seq_factory = factory->getCoordinateSequenceFactory();
74 1 50         auto triangles = new result_t();
75 9 100         for(size_t i = 0; i < indices.size(); i += 3) {
76 8           auto& c_A = linearized[indices[i + 0]];
77 8           auto& c_B = linearized[indices[i + 1]];
78 8           auto& c_C = linearized[indices[i + 2]];
79 16 50         auto seq = seq_holder_t{seq_factory->create(4, 2)};
80 8 50         seq->setAt(c_A, 0);
81 8 50         seq->setAt(c_B, 1);
82 8 50         seq->setAt(c_C, 2);
83 8 50         seq->setAt(c_A, 3); /* close the poly */
84              
85 8 50         auto shell = factory->createLinearRing(seq.release());
86 8 50         auto holes = new std::vector();
87 8 50         auto poly = factory->createPolygon(shell, holes);
88 8 50         triangles->push_back(poly);
    50          
89             }
90              
91 2 50         return factory->createGeometryCollection(triangles);
92             }
93              
94              
95 184 50         }}
    50