1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
|
#ifndef SQL_GIS_RTREE_SUPPORT_H_INCLUDED
#define SQL_GIS_RTREE_SUPPORT_H_INCLUDED
// Copyright (c) 2017, 2025, Oracle and/or its affiliates.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, version 2.0,
// as published by the Free Software Foundation.
//
// This program is designed to work with certain software (including
// but not limited to OpenSSL) that is licensed under separate terms,
// as designated in a particular file or component or in included license
// documentation. The authors of MySQL hereby grant you an additional
// permission to link the program and your derivative works with the
// separately licensed software that they have either included with
// the program or referenced in the documentation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License, version 2.0, for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
/// @file
///
/// This file declares a set of functions that storage engines can call to do
/// geometrical operations.
#include "my_inttypes.h" // uchar, uint
#include "sql/gis/srid.h"
namespace dd {
class Spatial_reference_system;
}
/// In memory representation of a minimum bounding rectangle
typedef struct rtr_mbr {
/// minimum on x
double xmin;
/// maximum on x
double xmax;
/// minimum on y
double ymin;
/// maximum on y
double ymax;
} rtr_mbr_t;
/// Fetches a copy of the dictionary entry for a spatial reference system.
///
/// Spatial reference dictionary cache objects have a limited lifetime,
/// typically until the end of a transaction. This function returns a clone of
/// the dictionary object so that it is valid also after the transaction has
/// ended. This is necessary since InnoDB may do index operations after the
/// transaction has ended.
///
/// @param[in] srid The spatial reference system ID to look up.
///
/// @return The spatial reference system dictionary entry, or nullptr.
dd::Spatial_reference_system *fetch_srs(gis::srid_t srid);
/// Checks if one MBR covers another MBR.
///
/// @warning Despite the name, this function computes the covers relation, not
/// contains.
///
/// For both MBRs, the coordinates of the MBR's minimum corners must be smaller
/// than or equal to the corresponding coordinates of the maximum corner.
///
/// @param[in] srs Spatial reference system.
/// @param[in] a The first MBR.
/// @param[in] b The second MBR.
///
/// @retval true MBR a contains MBR b.
/// @retval false MBR a doesn't contain MBR b.
bool mbr_contain_cmp(const dd::Spatial_reference_system *srs, rtr_mbr_t *a,
rtr_mbr_t *b);
/// Checks if two MBRs are equal physically
///
/// There is another function mbr_equal_logically(), which checks for
/// equality in logical sense.
///
/// If the spatial index was created in version before 8.0, there is possibility
/// that MBR can have format of {x,y}min = DBL_MAX, {x,y}max= -DBL_MAX
///
/// @param[in] a The first MBR.
/// @param[in] b The second MBR.
///
/// @retval true The two MBRs are equal physically.
/// @retval false The two MBRs aren't equal physically.
bool mbr_equal_physically(rtr_mbr_t *a, rtr_mbr_t *b);
/// Checks if two MBRs are equal logically
///
/// Comparison is epsilon based using boost geometry.
///
/// There is another function mbr_equal_physically(), which checks for
/// equality in physical sense.
///
/// For both MBRs, the coordinates of the MBR's minimum corners must be smaller
/// than or equal to the corresponding coordinates of the maximum corner.
///
/// @param[in] srs Spatial reference system.
/// @param[in] a The first MBR.
/// @param[in] b The second MBR.
///
/// @retval true The two MBRs are equal logically.
/// @retval false The two MBRs aren't equal logically.
bool mbr_equal_logically(const dd::Spatial_reference_system *srs, rtr_mbr_t *a,
rtr_mbr_t *b);
/// Checks if two MBRs intersect each other
///
/// @param[in] srs Spatial reference system.
/// @param[in] a The first MBR.
/// @param[in] b The second MBR.
///
/// For both MBRs, the coordinates of the MBR's minimum corners must be smaller
/// than or equal to the corresponding coordinates of the maximum corner.
///
/// @retval true The MBRs intersect each other.
/// @retval false The MBRs are disjoint.
bool mbr_intersect_cmp(const dd::Spatial_reference_system *srs, rtr_mbr_t *a,
rtr_mbr_t *b);
/// Checks if two MBRs are disjoint
///
/// For both MBRs, the coordinates of the MBR's minimum corners must be smaller
/// than or equal to the corresponding coordinates of the maximum corner.
///
/// @retval true The MBRs are disjoint.
/// @retval false The MBRs intersect each other.
bool mbr_disjoint_cmp(const dd::Spatial_reference_system *srs, rtr_mbr_t *a,
rtr_mbr_t *b);
/// Checks if one MBR is covered by another MBR.
///
/// @warning Despite the name, this function computes the covered_by relation,
/// not within.
///
/// @note If for `a` the minimum corner coordinates are larger than the
/// corresponding coordinates of the maximum corner, we return true.
///
/// @param[in] srs Spatial reference system.
/// @param[in] a The first MBR.
/// @param[in] b The second MBR.
///
/// @retval true MBR a is within MBR b.
/// @retval false MBR a isn't within MBR b.
bool mbr_within_cmp(const dd::Spatial_reference_system *srs, rtr_mbr_t *a,
rtr_mbr_t *b);
/// Expands an MBR to also cover another MBR.
///
/// @note The function takes a dimension parameter, but currently only supports
/// 2d MBRs.
///
/// MBR format: a[0] = xmin, a[1] = xmax, a[2] = ymin, a[3] = ymax. Same for b.
///
/// @param[in] srs Spatial reference system.
/// @param[in,out] a The first MBR, where the joined result will be.
/// @param[in] b The second MBR.
/// @param[in] n_dim Number of dimensions. Must be 2.
void mbr_join(const dd::Spatial_reference_system *srs, double *a,
const double *b, int n_dim);
/// Computes the combined area of two MBRs.
///
/// The MBRs may overlap.
///
/// @note The function takes a dimension parameter, but currently only supports
/// 2d MBRs.
///
/// @param[in] srs Spatial reference system.
/// @param[in] a The first MBR.
/// @param[in] b The second MBR.
/// @param[in] n_dim Number of dimensions. Must be 2.
///
/// @return The area of MBR a expanded by MBR b.
double mbr_join_area(const dd::Spatial_reference_system *srs, const double *a,
const double *b, int n_dim);
/// Computes the area of an MBR.
///
/// @note The function takes a dimension parameter, but currently only supports
/// 2d MBRs.
///
/// @param[in] srs Spatial reference system.
/// @param[in] a The MBR.
/// @param[in] n_dim Number of dimensions. Must be 2.
///
/// @return Are of the MBR.
double compute_area(const dd::Spatial_reference_system *srs, const double *a,
int n_dim);
/// Computes the MBR of a geometry.
///
/// If the geometry is empty, a box that covers the entire domain is returned.
///
/// The geometry is expected to be on the storage format (SRID + WKB). The
/// caller is expected to provide an output buffer that is large enough.
///
/// @note The function takes a dimension parameter, but currently only supports
/// 2d MBRs.
///
/// The SRID of the SRS parameter must match the SRID stored in the first four
/// bytes of the geometry string.
///
/// @param[in] srs Spatial reference system.
/// @param[in] store The geometry.
/// @param[in] size Number of bytes in the geometry string.
/// @param[in] n_dims Number of dimensions. Must be 2.
/// @param[out] mbr The computed MBR.
/// @param[out] srid SRID of the geometry
///
/// @retval 0 The geometry is valid.
/// @retval -1 The geometry is invalid.
int get_mbr_from_store(const dd::Spatial_reference_system *srs,
const uchar *store, uint size, uint n_dims, double *mbr,
gis::srid_t *srid);
/// Computes the extra area covered if an MBR is expanded to cover another MBR.
///
/// The formula is area(a + b) - area(a). This is generally different from
/// area(b). If MBR b overlaps MBR a, area(a+b) - area(a) < area(b). If they are
/// far apart, area(a+b) - area(a) > area(b).
///
/// @note If MBRs a and b are far apart, the function may return Inf.
///
/// @param[in] srs Spatial reference system.
/// @param[in] mbr_a First MBR.
/// @param[in] mbr_b Second MBR.
/// @param[in] mbr_len MBR length in bytes. Must be 4 * sizeof(double).
/// @param[out] ab_area The total area of MBRs a and b combined into one MBR.
///
/// @return The increase in area when expanding from MBR a to also cover MBR b.
double rtree_area_increase(const dd::Spatial_reference_system *srs,
const uchar *mbr_a, const uchar *mbr_b, int mbr_len,
double *ab_area);
/// Calculates the overlapping area between two MBRs.
///
/// @param[in] srs Spatial reference system.
/// @param[in] mbr_a First MBR.
/// @param[in] mbr_b Second MBR.
/// @param[in] mbr_len MBR length in bytes. Must be 4 * sizeof(double).
///
/// @return The area of the overlapping region.
double rtree_area_overlapping(const dd::Spatial_reference_system *srs,
const uchar *mbr_a, const uchar *mbr_b,
int mbr_len);
#endif // SQL_GIS_RTREE_SUPPORT_H_INCLUDED
|