Skip to content

Commit 06cd450

Browse files
committed
implement tesselation on import
1 parent b168197 commit 06cd450

File tree

1 file changed

+44
-17
lines changed

1 file changed

+44
-17
lines changed

src/s2geography/constructor.h

+44-17
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
#include <sstream>
55

6+
#include <s2/s2edge_tessellator.h>
7+
68
#include "geoarrow-imports.h"
79
#include "geography.h"
810

@@ -14,28 +16,32 @@ class Constructor : public Handler {
1416
public:
1517
class Options {
1618
public:
17-
Options() : oriented_(false), check_(true) {}
18-
bool oriented() { return oriented_; }
19+
Options() : oriented_(false), check_(true), tessellate_tolerance_(S1Angle::Infinity()) {}
20+
bool oriented() const { return oriented_; }
1921
void set_oriented(bool oriented) { oriented_ = oriented; }
20-
bool check() { return check_; }
22+
bool check() const { return check_; }
2123
void set_check(bool check) { check_ = check; }
24+
S1Angle tessellate_tolerance() const { return tessellate_tolerance_; }
25+
void set_tessellate_tolerance(S1Angle tessellate_tolerance) {
26+
tessellate_tolerance_ = tessellate_tolerance;
27+
}
2228

2329
private:
2430
bool oriented_;
2531
bool check_;
32+
S1Angle tessellate_tolerance_;
2633
};
2734

28-
Constructor(const Options& options) : options_(options) {}
35+
Constructor(const Options& options) :
36+
options_(options),
37+
projection_lnglat_(180),
38+
tessellator_(new S2EdgeTessellator(&projection_lnglat_, options.tessellate_tolerance())) {}
2939

3040
virtual ~Constructor() {}
3141

32-
Options* mutable_options() { return &options_; }
33-
3442
virtual Result coords(const double* coord, int64_t n, int32_t coord_size) {
3543
for (int64_t i = 0; i < n; i++) {
36-
S2LatLng pt = S2LatLng::FromDegrees(coord[i * coord_size + 1],
37-
coord[i * coord_size]);
38-
points_.push_back(pt.Normalized().ToPoint());
44+
input_points_.push_back(R2Point(coord[i * coord_size], coord[i * coord_size + 1]));
3945
}
4046

4147
return Result::CONTINUE;
@@ -44,8 +50,28 @@ class Constructor : public Handler {
4450
virtual std::unique_ptr<Geography> finish() = 0;
4551

4652
protected:
53+
std::vector<R2Point> input_points_;
4754
std::vector<S2Point> points_;
4855
Options options_;
56+
S2::PlateCarreeProjection projection_lnglat_;
57+
std::unique_ptr<S2EdgeTessellator> tessellator_;
58+
59+
void finish_points() {
60+
points_.clear();
61+
points_.reserve(input_points_.size());
62+
63+
if (options_.tessellate_tolerance() != S1Angle::Infinity()) {
64+
for (size_t i = 1; i < input_points_.size(); i++) {
65+
tessellator_->AppendUnprojected(input_points_[i - 1], input_points_[i], &points_);
66+
}
67+
} else {
68+
for (const auto& input_point: input_points_) {
69+
points_.push_back(projection_lnglat_.Unproject(input_point));
70+
}
71+
}
72+
73+
input_points_.clear();
74+
}
4975
};
5076

5177
class PointConstructor : public Constructor {
@@ -74,9 +100,8 @@ class PointConstructor : public Constructor {
74100
continue;
75101
}
76102

77-
S2LatLng pt = S2LatLng::FromDegrees(coord[i * coord_size + 1],
78-
coord[i * coord_size]);
79-
points_.push_back(pt.ToPoint());
103+
R2Point pt = R2Point(coord[i * coord_size], coord[i * coord_size + 1]);
104+
points_.push_back(projection_lnglat_.Unproject(pt));
80105
}
81106

82107
return Result::CONTINUE;
@@ -114,13 +139,15 @@ class PolylineConstructor : public Constructor {
114139
}
115140

116141
if (size > 0 && geometry_type == util::GeometryType::LINESTRING) {
117-
points_.reserve(size);
142+
input_points_.reserve(size);
118143
}
119144

120145
return Result::CONTINUE;
121146
}
122147

123148
Result geom_end() {
149+
finish_points();
150+
124151
if (points_.size() > 0) {
125152
auto polyline = absl::make_unique<S2Polyline>();
126153
polyline->Init(std::move(points_));
@@ -131,7 +158,6 @@ class PolylineConstructor : public Constructor {
131158
}
132159

133160
polylines_.push_back(std::move(polyline));
134-
points_.clear();
135161
}
136162

137163
return Result::CONTINUE;
@@ -160,20 +186,21 @@ class PolygonConstructor : public Constructor {
160186
PolygonConstructor(const Options& options) : Constructor(options) {}
161187

162188
Result ring_start(int64_t size) {
163-
points_.clear();
189+
input_points_.clear();
164190
if (size > 0) {
165-
points_.reserve(size);
191+
input_points_.reserve(size);
166192
}
167193

168194
return Result::CONTINUE;
169195
}
170196

171197
Result ring_end() {
198+
finish_points();
199+
172200
if (points_.size() == 0) {
173201
return Result::CONTINUE;
174202
}
175203

176-
// S2Loop is open instead of closed
177204
points_.pop_back();
178205
auto loop = absl::make_unique<S2Loop>();
179206
loop->set_s2debug_override(S2Debug::DISABLE);

0 commit comments

Comments
 (0)