8 #ifndef FIELDS2COVER_TYPES_GEOMETRY_IMPL_HPP_
9 #define FIELDS2COVER_TYPES_GEOMETRY_IMPL_HPP_
11 #include <gdal/cpl_conv.h>
20 template <
class T, OGRwkbGeometryType R>
22 downCast<T*>(OGRGeometryFactory::createGeometry(R)),
23 [](T* f) {OGRGeometryFactory::destroyGeometry(f);}) {}
25 template <
class T, OGRwkbGeometryType R>
27 [](T* f) {OGRGeometryFactory::destroyGeometry(f);}) {}
29 template <
class T, OGRwkbGeometryType R>
32 template <
class T, OGRwkbGeometryType R>
35 template <
class T, OGRwkbGeometryType R>
37 [](T* f) {OGRGeometryFactory::destroyGeometry(f);}) {}
39 template <
class T, OGRwkbGeometryType R>
41 data_(downCast<T*>(g), [](T* f) {}) {}
43 template <
class T, OGRwkbGeometryType R>
45 [](T* f) {OGRGeometryFactory::destroyGeometry(f);}) {}
47 template <
class T, OGRwkbGeometryType R>
48 Geometry<T, R>::~Geometry() =
default;
50 template <
class T, OGRwkbGeometryType R>
51 Geometry<T, R>::Geometry(
const Geometry& g) =
default;
53 template <
class T, OGRwkbGeometryType R>
54 Geometry<T, R>::Geometry(Geometry&& g) =
default;
56 template <
class T, OGRwkbGeometryType R>
57 typename Geometry<T, R>::Geometry& Geometry<T, R>::operator=(
58 Geometry&& g) =
default;
60 template <
class T, OGRwkbGeometryType R>
61 typename Geometry<T, R>::Geometry& Geometry<T, R>::operator=(
62 const Geometry& g) =
default;
64 template <
class T, OGRwkbGeometryType R>
67 template <
class T, OGRwkbGeometryType R>
70 template <
class T, OGRwkbGeometryType R>
73 template <
class T, OGRwkbGeometryType R>
76 template <
class T, OGRwkbGeometryType R>
78 return !geom2->Equals(data_.get());
81 template <
class T, OGRwkbGeometryType R>
83 return geom2->Equals(data_.get());
87 template <
class T, OGRwkbGeometryType R>
90 data_->getEnvelope(&envelope);
94 template <
class T, OGRwkbGeometryType R>
97 data_->getEnvelope(&envelope);
101 template <
class T, OGRwkbGeometryType R>
103 OGREnvelope envelope;
104 data_->getEnvelope(&envelope);
105 return envelope.MinY;
108 template <
class T, OGRwkbGeometryType R>
110 OGREnvelope envelope;
111 data_->getEnvelope(&envelope);
112 return envelope.MaxY;
115 template <
class T, OGRwkbGeometryType R>
117 OGREnvelope envelope;
118 data_->getEnvelope(&envelope);
119 return envelope.MaxY - envelope.MinY;
122 template <
class T, OGRwkbGeometryType R>
124 OGREnvelope envelope;
125 data_->getEnvelope(&envelope);
126 return envelope.MaxX - envelope.MinX;
129 template <
class T, OGRwkbGeometryType R>
131 OGREnvelope envelope;
132 data_->getEnvelope(&envelope);
133 return (envelope.MaxX - envelope.MinX) +
134 (envelope.MaxY - envelope.MinY);
137 template <
class T, OGRwkbGeometryType R>
138 template <
class T2, OGRwkbGeometryType R2>
140 return data_->Distance(p.
get());
143 template <
class T, OGRwkbGeometryType R>
144 template <
class T2, OGRwkbGeometryType R2>
146 return data_->Disjoint(geom.
get());
149 template <
class T, OGRwkbGeometryType R>
150 template <
class T2, OGRwkbGeometryType R2>
152 return data_->Crosses(geom.
get());
155 template <
class T, OGRwkbGeometryType R>
156 template <
class T2, OGRwkbGeometryType R2>
158 return data_->Touches(geom.
get());
161 template <
class T, OGRwkbGeometryType R>
162 template <
class T2, OGRwkbGeometryType R2>
164 return data_->Within(geom.
get());
167 template <
class T, OGRwkbGeometryType R>
168 template <
class T2, OGRwkbGeometryType R2>
170 return data_->Intersects(geom.
get());
173 template <
class T, OGRwkbGeometryType R>
175 return mod(val, boost::math::constants::two_pi<double>());
178 template <
class T, OGRwkbGeometryType R>
180 const auto two_pi = boost::math::constants::two_pi<double>();
181 auto val_id = round(prev_val / two_pi);
183 [two_pi] (
int i,
double value) {
return i * two_pi + mod_2pi(value);};
184 for (
int i = -2; i <= 0; ++i) {
185 if (fabs(getNearVal(val_id + i + 1, val) - prev_val) >
186 fabs(getNearVal(val_id + i, val) - prev_val)) {
187 return getNearVal(val_id + i, val);
190 return getNearVal(val_id + 1, val);
193 template <
class T, OGRwkbGeometryType R>
195 const std::vector<double>& val) {
196 std::vector<double> res {val[0]};
197 for (
size_t i = 1; i < val.size(); ++i) {
198 res.emplace_back(getAngContinuity(res[i - 1], val[i]));
203 template <
class T, OGRwkbGeometryType R>
205 const auto pi = boost::math::constants::pi<double>();
206 return pi - fabs(mod_2pi(b - a) - pi);
209 template <
class T, OGRwkbGeometryType R>
211 const auto pi = boost::math::constants::pi<double>();
212 double ma = mod_2pi(a);
213 double mb = mod_2pi(b);
214 if (abs(mb - ma) < pi) {
215 return 0.5 * (ma + mb);
217 return 0.5 * (ma + mb) + pi;
221 template <
class T, OGRwkbGeometryType R>
223 return (!data_ || data_->IsEmpty());
226 template <
class T, OGRwkbGeometryType R>
228 char *pszWKT =
nullptr;
230 std::string result{pszWKT};
235 template <
class T, OGRwkbGeometryType R>
243 template <
class T, OGRwkbGeometryType R>
251 template <
class T, OGRwkbGeometryType R>
259 template <
class T, OGRwkbGeometryType R>
261 auto char_text = text.c_str();
268 template <
class T, OGRwkbGeometryType R>
269 template <
typename To,
typename From>
272 (std::is_base_of<From,
typename std::remove_pointer<To>::type>::value),
273 "target type not derived from source type");
274 CPLAssert(f ==
nullptr ||
dynamic_cast<To
>(f) !=
nullptr);
275 return static_cast<To
>(f);
279 template <
class T, OGRwkbGeometryType R>
280 template<
typename RetType>
283 OGRGeometryFactory::destroyGeometry(g);
290 template <
class T, OGRwkbGeometryType R>
292 OGRGeometry *poOGRProduct =
nullptr;
294 GEOSContextHandle_t hGEOSCtxt = OGRGeometry::createGEOSContext();
295 GEOSGeom hGeosGeom = this->data_->exportToGEOS(hGEOSCtxt);
296 if (hGeosGeom !=
nullptr) {
297 GEOSBufferParams* hBufParams = GEOSBufferParams_create_r(hGEOSCtxt);
298 GEOSBufferParams_setEndCapStyle_r(hGEOSCtxt, hBufParams,
299 GEOSBufCapStyles::GEOSBUF_CAP_FLAT);
300 GEOSBufferParams_setJoinStyle_r(hGEOSCtxt, hBufParams,
301 GEOSBufJoinStyles::GEOSBUF_JOIN_MITRE);
302 GEOSBufferParams_setSingleSided_r(hGEOSCtxt, hBufParams, side != 0);
304 GEOSGeom hGeosProduct = GEOSBufferWithParams_r(hGEOSCtxt, hGeosGeom,
305 hBufParams, side >= 0 ? dfDist : -dfDist);
306 GEOSGeom_destroy_r(hGEOSCtxt, hGeosGeom);
307 GEOSBufferParams_destroy_r(hGEOSCtxt, hBufParams);
309 poOGRProduct = buildGeometryFromGEOS(hGEOSCtxt, hGeosProduct,
310 this->data_.get(),
nullptr);
312 OGRGeometry::freeGEOSContext(hGEOSCtxt);
320 template <
class T, OGRwkbGeometryType R>
322 const OGRGeometry *poGeom,
const OGRGeometry *poOtherGeom,
323 OGRGeometry *poOGRProduct)
const {
324 if (poOGRProduct !=
nullptr &&
325 wkbFlatten(poOGRProduct->getGeometryType()) != wkbPoint &&
326 (poGeom->hasCurveGeometry(
true) ||
327 (poOtherGeom && poOtherGeom->hasCurveGeometry(
true)))) {
328 OGRGeometry *poCurveGeom = poOGRProduct->getCurveGeometry();
334 template <
class T, OGRwkbGeometryType R>
336 GEOSContextHandle_t hGEOSCtxt, GEOSGeom hGeosProduct,
337 const OGRGeometry *poSelf,
const OGRGeometry *poOtherGeom)
const {
338 OGRGeometry *poOGRProduct =
nullptr;
339 if (hGeosProduct !=
nullptr) {
340 poOGRProduct = OGRGeometryFactory::createFromGEOS(hGEOSCtxt, hGeosProduct);
341 if (poOGRProduct !=
nullptr &&
342 poSelf->getSpatialReference() !=
nullptr &&
343 (poOtherGeom ==
nullptr ||
344 (poOtherGeom->getSpatialReference() !=
nullptr &&
345 poOtherGeom->getSpatialReference()->IsSame(
346 poSelf->getSpatialReference())))) {
347 poOGRProduct->assignSpatialReference(poSelf->getSpatialReference());
349 poOGRProduct = OGRGeometryRebuildCurves(poSelf, poOtherGeom, poOGRProduct);
350 GEOSGeom_destroy_r(hGEOSCtxt, hGeosProduct);
357 template <
class T, OGRwkbGeometryType R>
359 return fmod(fmod(a, b) + b, b);
365 #endif // FIELDS2COVER_TYPES_GEOMETRY_IMPL_HPP_