MySQL  8.0.28
Source Code Documentation
ring_flip_visitor.h
Go to the documentation of this file.
1 #ifndef SQL_GIS_RING_FLIP_VISITOR_H_INCLUDED
2 #define SQL_GIS_RING_FLIP_VISITOR_H_INCLUDED
3 
4 // Copyright (c) 2017, 2021, Oracle and/or its affiliates.
5 //
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License, version 2.0,
8 // as published by the Free Software Foundation.
9 //
10 // This program is also distributed with certain software (including
11 // but not limited to OpenSSL) that is licensed under separate terms,
12 // as designated in a particular file or component or in included license
13 // documentation. The authors of MySQL hereby grant you an additional
14 // permission to link the program and your derivative works with the
15 // separately licensed software that they have included with MySQL.
16 //
17 // This program is distributed in the hope that it will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU General Public License, version 2.0, for more details.
21 //
22 // You should have received a copy of the GNU General Public License
23 // along with this program; if not, write to the Free Software
24 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
25 
26 #include <boost/geometry.hpp>
27 #include <memory> // std::unique_ptr
28 
29 #include "sql/dd/types/spatial_reference_system.h" // dd::Spatial_reference_system
30 #include "sql/gis/geometries_cs.h"
33 
34 namespace gis {
35 
36 /// A visitor that flips polygon rings so that exterior rings are in a
37 /// counter-clockwise direction and interior rings in a clockwise direction.
38 ///
39 /// Invalid polygon rings are not guaranteed to be flipped to the correct
40 /// direction.
42  private:
43  /// Strategy used for geographic SRSs.
44  std::unique_ptr<boost::geometry::strategy::area::geographic<>>
46  /// Whether the geometry is invalid. That happens either if the ellipsoid of
47  /// a geographic SRS is invalid or if we encounter a ring with unknown
48  /// direction.
49  bool m_invalid;
50 
51  public:
52  /// Construct a new ring flip visitor.
53  ///
54  /// @param[in] semi_major The semi-major axis of the ellipsoid.
55  /// @param[in] semi_minor The semi-minor axis of the ellipsoid.
56  Ring_flip_visitor(double semi_major, double semi_minor) {
57  try {
59  new boost::geometry::strategy::area::geographic<>(
60  boost::geometry::srs::spheroid<double>(semi_major, semi_minor)));
61  m_invalid = false;
62  } catch (...) {
63  // Spheroid construction may fail if the axes are invalid.
64  m_invalid = true;
65  }
66  }
67 
68  /// Check if anything wrong has been detected, either an invalid ellipsoid or
69  /// a ring with an unknown direction.
70  ///
71  /// Polygon rings which direction can't be determined are invalid. This is the
72  /// only way this visitor detects invalid rings. Other invalid rings, e.g.,
73  /// rings crossing themselves, are not necessarily detected.
74  ///
75  /// @retval true Invalid SRS ellipsoid or invalid polygon ring.
76  /// @retval false No invalid rings detected, but the geometry may still be
77  /// invalid.
78  bool invalid() const { return m_invalid; }
79 
81  bool visit_enter(Polygon *py) override;
82  bool visit_enter(Multipolygon *py) override;
83 
84  bool visit_enter(Multipoint *) override {
85  return true; // Don't descend into each point.
86  }
87 
88  bool visit_enter(Multilinestring *) override {
89  return true; // Don't descend into each linestring.
90  }
91 };
92 
93 } // namespace gis
94 
95 #endif // SQL_GIS_RING_FLIP_VISITOR_H_INCLUDED
A colletion of linestrings.
Definition: geometries.h:522
A collection of points.
Definition: geometries.h:483
A collection of polygons.
Definition: geometries.h:563
A visitor that implements the entire interface and does nothing.
Definition: geometry_visitor.h:121
bool visit_enter(Geometry *) override
Enters a compound geometry.
Definition: geometry_visitor.h:123
A polygon consisting of an outer ring and zero or more interior rings defining holes in the polygon.
Definition: geometries.h:348
A visitor that flips polygon rings so that exterior rings are in a counter-clockwise direction and in...
Definition: ring_flip_visitor.h:41
bool visit_enter(Multilinestring *) override
Definition: ring_flip_visitor.h:88
bool visit_enter(Geometry *) override
Definition: geometry_visitor.h:123
std::unique_ptr< boost::geometry::strategy::area::geographic<> > m_geographic_strategy
Strategy used for geographic SRSs.
Definition: ring_flip_visitor.h:45
bool visit_enter(Multipoint *) override
Definition: ring_flip_visitor.h:84
bool m_invalid
Whether the geometry is invalid.
Definition: ring_flip_visitor.h:49
bool invalid() const
Check if anything wrong has been detected, either an invalid ellipsoid or a ring with an unknown dire...
Definition: ring_flip_visitor.h:78
Ring_flip_visitor(double semi_major, double semi_minor)
Construct a new ring flip visitor.
Definition: ring_flip_visitor.h:56
This file declares the coordinate system specific subclasses of the geometry class hierarchy.
This file contains Boost.Geometry type traits declarations for Cartesian and geographic geometries.
The geometries implement a hierarchical visitor pattern.
Definition: area.cc:46