1 /* Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef ITEM_GEOFUNC_BGWRAP_INCLUDED 24 #define ITEM_GEOFUNC_BGWRAP_INCLUDED 25 26 /** 27 Wraps and dispatches type specific BG function calls according to operation 28 type and both operands' types. 29 30 We want to isolate boost header file inclusion only inside this file, so we 31 put this class declaration in an internal header file. And we want to make the 32 methods static since no state is needed here. 33 34 @tparam Geom_types Geometry types definitions. 35 */ 36 37 #include <stddef.h> 38 #include <string.h> // Boost expects ::memset to be already present. 39 #include <set> 40 #include <string> // Boost expects std::string to be already present. 41 #include <vector> 42 43 #include <boost/geometry/algorithms/crosses.hpp> 44 #include <boost/geometry/algorithms/intersects.hpp> 45 #include <boost/geometry/algorithms/touches.hpp> 46 #include <boost/geometry/algorithms/within.hpp> 47 48 #include "my_inttypes.h" 49 #include "my_sys.h" 50 #include "mysqld_error.h" 51 #include "sql/item_geofunc.h" 52 53 class Geometry; 54 struct bgpt_lt; 55 56 template <typename Geom_types> 57 class BG_wrap { 58 public: 59 typedef typename Geom_types::Point Point; 60 typedef typename Geom_types::Linestring Linestring; 61 typedef typename Geom_types::Polygon Polygon; 62 typedef typename Geom_types::Multipoint Multipoint; 63 typedef typename Geom_types::Multilinestring Multilinestring; 64 typedef typename Geom_types::Multipolygon Multipolygon; 65 typedef typename Geom_types::Coordinate_type Coord_type; 66 typedef typename Geom_types::Coordinate_system Coordsys; 67 68 // For abbrievation. 69 typedef Item_func_spatial_rel Ifsr; 70 typedef std::set<Point, bgpt_lt> Point_set; 71 typedef std::vector<Point> Point_vector; 72 73 static int point_within_geometry(Geometry *g1, Geometry *g2, 74 bool *pnull_value); 75 76 static int multipoint_within_geometry(Geometry *g1, Geometry *g2, 77 bool *pnull_value); 78 79 static int linestring_within_geometry(Geometry *g1, Geometry *g2, 80 bool *pnull_value); 81 static int multilinestring_within_geometry(Geometry *g1, Geometry *g2, 82 bool *pnull_value); 83 static int polygon_within_geometry(Geometry *g1, Geometry *g2, 84 bool *pnull_value); 85 static int multipolygon_within_geometry(Geometry *g1, Geometry *g2, 86 bool *pnull_value); 87 88 static int multipoint_equals_geometry(Geometry *g1, Geometry *g2, 89 bool *pnull_value); 90 91 static int point_disjoint_geometry(Geometry *g1, Geometry *g2, 92 bool *pnull_value); 93 static int multipoint_disjoint_geometry(Geometry *g1, Geometry *g2, 94 bool *pnull_value); 95 96 static int linestring_disjoint_geometry(Geometry *g1, Geometry *g2, 97 bool *pnull_value); 98 static int multilinestring_disjoint_geometry(Geometry *g1, Geometry *g2, 99 bool *pnull_value); 100 static int polygon_disjoint_geometry(Geometry *g1, Geometry *g2, 101 bool *pnull_value); 102 static int multipolygon_disjoint_geometry(Geometry *g1, Geometry *g2, 103 bool *pnull_value); 104 static int point_intersects_geometry(Geometry *g1, Geometry *g2, 105 bool *pnull_value); 106 static int multipoint_intersects_geometry(Geometry *g1, Geometry *g2, 107 bool *pnull_value); 108 static int linestring_intersects_geometry(Geometry *g1, Geometry *g2, 109 bool *pnull_value); 110 static int multilinestring_intersects_geometry(Geometry *g1, Geometry *g2, 111 bool *pnull_value); 112 static int polygon_intersects_geometry(Geometry *g1, Geometry *g2, 113 bool *pnull_value); 114 static int multipolygon_intersects_geometry(Geometry *g1, Geometry *g2, 115 bool *pnull_value); 116 static int linestring_crosses_geometry(Geometry *g1, Geometry *g2, 117 bool *pnull_value); 118 static int multipoint_crosses_geometry(Geometry *g1, Geometry *g2, 119 bool *pnull_value); 120 static int multilinestring_crosses_geometry(Geometry *g1, Geometry *g2, 121 bool *pnull_value); 122 static int multipoint_overlaps_multipoint(Geometry *g1, Geometry *g2); 123 static int point_touches_geometry(Geometry *g1, Geometry *g2, 124 bool *pnull_value); 125 static int multipoint_touches_geometry(Geometry *g1, Geometry *g2, 126 bool *pnull_value); 127 static int linestring_touches_geometry(Geometry *g1, Geometry *g2, 128 bool *pnull_value); 129 static int multilinestring_touches_polygon(Geometry *g1, Geometry *g2, 130 bool *pnull_value); 131 static int multilinestring_touches_geometry(Geometry *g1, Geometry *g2, 132 bool *pnull_value); 133 static int polygon_touches_geometry(Geometry *g1, Geometry *g2, 134 bool *pnull_value); 135 static int multipolygon_touches_geometry(Geometry *g1, Geometry *g2, 136 bool *pnull_value); 137 138 private: 139 template <typename Geom_type> 140 static int multipoint_disjoint_geometry_internal(const Multipoint &mpts1, 141 const Geom_type &geom); 142 template <typename Geom_type> 143 static int multipoint_disjoint_multi_geometry(const Multipoint &mpts, 144 const Geom_type &geom); 145 template <typename GeomType> 146 static int multipoint_within_geometry_internal(const Multipoint &mpts, 147 const GeomType &geom); 148 static int multipoint_within_multipolygon(const Multipoint &mpts, 149 const Multipolygon &mplgn); 150 }; // BG_wrap 151 152 /* 153 Call a BG function with specified types of operands. We have to create 154 geo1 and geo2 because operands g1 and g2 are created without their WKB data 155 parsed, so not suitable for BG to use. geo1 will share the same copy of WKB 156 data with g1, also true for geo2. 157 */ 158 #define BGCALL(res, bgfunc, GeoType1, g1, GeoType2, g2, pnullval) \ 159 do { \ 160 const void *pg1 = g1->normalize_ring_order(); \ 161 const void *pg2 = g2->normalize_ring_order(); \ 162 if (pg1 != NULL && pg2 != NULL) { \ 163 GeoType1 geo1(pg1, g1->get_data_size(), g1->get_flags(), \ 164 g1->get_srid()); \ 165 GeoType2 geo2(pg2, g2->get_data_size(), g2->get_flags(), \ 166 g2->get_srid()); \ 167 res = boost::geometry::bgfunc(geo1, geo2); \ 168 } else { \ 169 my_error(ER_GIS_INVALID_DATA, MYF(0), "st_" #bgfunc); \ 170 (*(pnullval)) = 1; \ 171 } \ 172 } while (0) 173 174 #endif // ITEM_GEOFUNC_BGWRAP_INCLUDED 175