MySQL  8.0.27
Source Code Documentation
spatial.h
Go to the documentation of this file.
1 /* Copyright (c) 2002, 2021, Oracle and/or its affiliates.
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 SPATIAL_INCLUDED
24 #define SPATIAL_INCLUDED
25 
26 #include <assert.h>
27 #include <float.h>
28 #include <string.h>
29 #include <sys/types.h>
30 #include <algorithm>
31 #include <cstddef>
32 #include <iterator>
33 
34 #include "lex_string.h"
35 #include "my_byteorder.h"
36 #include "my_compiler.h"
37 
38 #include "my_inttypes.h"
41 #include "sql/gis/srid.h"
42 #include "sql/inplace_vector.h"
43 #include "sql_string.h" // String
44 #include "unsafe_string_append.h"
45 
46 class Gis_read_stream;
47 class THD;
48 
49 const uint GEOM_DIM = 2;
50 const uint SRID_SIZE = 4;
53 const uint WKB_HEADER_SIZE = (1 + 4);
55 
56 const uint32 GET_SIZE_ERROR = 0xFFFFFFFFU;
57 
58 /**
59  Point with coordinates X and Y.
60 */
61 class point_xy {
62  public:
63  double x;
64  double y;
65  point_xy() = default;
66  point_xy(double x_arg, double y_arg) : x(x_arg), y(y_arg) {}
67  double distance(const point_xy &p) const;
68  /**
69  Compare to another point.
70  Return true if equal, false if not equal.
71  */
72  bool eq(point_xy p) const { return (x == p.x) && (y == p.y); }
73 };
74 
75 typedef struct wkb_header_st {
79 
80 /***************************** MBR *******************************/
81 
82 struct MBR {
83  double xmin, ymin, xmax, ymax;
84 
85  MBR() {
86  xmin = ymin = DBL_MAX;
87  xmax = ymax = -DBL_MAX;
88  }
89 
90  MBR(const double xmin_arg, const double ymin_arg, const double xmax_arg,
91  const double ymax_arg)
92  : xmin(xmin_arg), ymin(ymin_arg), xmax(xmax_arg), ymax(ymax_arg) {}
93 
94  MBR(const point_xy &min, const point_xy &max)
95  : xmin(min.x), ymin(min.y), xmax(max.x), ymax(max.y) {}
96 
97  void add_xy(double x, double y) {
98  /* Not using "else" for proper one point MBR calculation */
99  if (x < xmin) xmin = x;
100  if (x > xmax) xmax = x;
101  if (y < ymin) ymin = y;
102  if (y > ymax) ymax = y;
103  }
104  void add_xy(point_xy p) { add_xy(p.x, p.y); }
105  void add_xy(const char *px, const char *py) {
106  double x = float8get(px);
107  double y = float8get(py);
108  add_xy(x, y);
109  }
110  void add_mbr(const MBR *mbr) {
111  if (mbr->xmin < xmin) xmin = mbr->xmin;
112  if (mbr->xmax > xmax) xmax = mbr->xmax;
113  if (mbr->ymin < ymin) ymin = mbr->ymin;
114  if (mbr->ymax > ymax) ymax = mbr->ymax;
115  }
116 
117  int equals(const MBR *mbr) const {
118  /* The following should be safe, even if we compare doubles */
119  return ((mbr->xmin == xmin) && (mbr->ymin == ymin) && (mbr->xmax == xmax) &&
120  (mbr->ymax == ymax));
121  }
122 
123  int disjoint(const MBR *mbr) const {
124  /* The following should be safe, even if we compare doubles */
125  return ((mbr->xmin > xmax) || (mbr->ymin > ymax) || (mbr->xmax < xmin) ||
126  (mbr->ymax < ymin));
127  }
128 
129  int intersects(const MBR *mbr) const { return !disjoint(mbr); }
130 
131  int touches(const MBR *mbr) const;
132 
133  int within(const MBR *mbr) const;
134 
135  int contains(const MBR *mbr) const { return mbr->within(this); }
136 
137  int covered_by(const MBR *mbr) const {
138  /* The following should be safe, even if we compare doubles */
139  return ((mbr->xmin <= xmin) && (mbr->ymin <= ymin) && (mbr->xmax >= xmax) &&
140  (mbr->ymax >= ymax));
141  }
142 
143  int covers(const MBR *mbr) const { return mbr->covered_by(this); }
144 
145  bool inner_point(double x, double y) const {
146  /* The following should be safe, even if we compare doubles */
147  return (xmin < x) && (xmax > x) && (ymin < y) && (ymax > y);
148  }
149 
150  /**
151  The dimension maps to an integer as:
152  - Polygon -> 2
153  - Horizontal or vertical line -> 1
154  - Point -> 0
155  - Invalid MBR -> -1
156  */
157  int dimension() const {
158  int d = 0;
159 
160  if (xmin > xmax)
161  return -1;
162  else if (xmin < xmax)
163  d++;
164 
165  if (ymin > ymax)
166  return -1;
167  else if (ymin < ymax)
168  d++;
169 
170  return d;
171  }
172 
173  int overlaps(const MBR *mbr) const {
174  /*
175  overlaps() requires that some point inside *this is also inside
176  *mbr, and that both geometries and their intersection are of the
177  same dimension.
178  */
179  int d = dimension();
180  assert(d >= 0 && d <= 2);
181 
182  if (d != mbr->dimension() || d == 0 || contains(mbr) || within(mbr))
183  return 0;
184 
185  MBR intersection(std::max(xmin, mbr->xmin), std::max(ymin, mbr->ymin),
186  std::min(xmax, mbr->xmax), std::min(ymax, mbr->ymax));
187 
188  return (d == intersection.dimension());
189  }
190 };
191 
192 /***************************** Geometry *******************************/
193 
194 struct Geometry_buffer;
195 
196 /*
197  Memory management functions for BG adapter code. Allocate extra space for
198  GEOMETRY header so that we can later prefix the header if needed.
199  */
200 void *gis_wkb_alloc(size_t sz);
201 
202 inline void *gis_wkb_fixed_alloc(size_t sz) { return gis_wkb_alloc(sz); }
203 
204 void *gis_wkb_realloc(void *p, size_t sz);
205 
206 inline void gis_wkb_free(void *p) {
207  if (p == nullptr) return;
208  char *cp = static_cast<char *>(p);
210 }
211 
212 inline void gis_wkb_raw_free(void *p) { my_free(p); }
213 
214 class Geometry {
215  friend void parse_wkb_data(Geometry *geom, const char *p, size_t num_geoms);
216 
217  protected:
218  // Flag bits for m_flags.props.
219 
220  /*
221  Whether the linestring is a polygon's outer ring, or inner ring.
222  */
223  const static int POLYGON_OUTER_RING = 0x1;
224  const static int POLYGON_INNER_RING = 0x2;
225 
226  /*
227  Whether the Geometry object is created to be used by Boost Geometry or
228  only by MySQL. There are some operations that only work for one type and
229  can or must be skipped otherwise. This state is transient and mutable, we
230  set it even to a const geometry object.
231  */
232  const static int IS_BOOST_GEOMETRY_ADAPTER = 0x4;
233 
234  /*
235  Whether the geometry length is verified, so that we can return the stored
236  length without having to parse the WKB again.
237  */
238  const static int GEOM_LENGTH_VERIFIED = 0x8;
239 
240  /*
241  Whether the geometry has components stored out of line, see
242  Gis_wkb_vector<>::resize for details.
243  */
244  const static int HAS_OUT_OF_LINE_COMPONENTS = 0x10;
245 
246  /*
247  Whether the polygon's data is in WKB form, as is so in MySQL, or it's in
248  BG form, where the m_ptr points to an outer ring object, and m_inn_rings
249  points to the inner rings. See Gis_polygon for more information.
250  */
251  const static int POLYGON_IN_WKB_FORM = 0x20;
252 
253  /*
254  whether the geometry's data buffer has space for a GEOMETRY header.
255  BG adapter code use gis_wkb_alloc to allocate WKB buffer for Geometry
256  objects, they always has such space. Gis_geometry_collection created
257  from a single geometry and then appended with more geometries also have
258  such space. Those with such space we can simply prefix the GEOMETRY header
259  into its buffer without copying its WKB data.
260  */
261  const static int HAS_GEOM_HEADER_SPACE = 0x40;
262 
263  /*
264  Whether the multi geometry has overlapped components, if false(the bit set)
265  this geometry will be skipped from merge-component operation.
266  Effective only for multipolygons, multilinestrings and geometry collections.
267  Such geometries returned by BG always has this bit set, i.e. their
268  components don't overlap.
269  */
270  const static int MULTIPOLYGON_NO_OVERLAPPED_COMPS = 0x80;
271 
272  public:
273  // Check user's transmitted data against these limits.
274  const static uint32 MAX_GEOM_WKB_LENGTH = 0x3fffffff;
275 
276  const static gis::srid_t default_srid = 0;
277 
278  virtual ~Geometry();
279 
280  /*
281  We have to define a wkb_first and wkb_invalid_type and set them to 0
282  because Geometry objects stored in m_geo_vect vector can be constructed
283  using the default constructur Geometry() which sets geotype to 0, and
284  there are asserts in BG adapter code which asserts geotype is in valid
285  range [wkb_first, wkb_last]. Neither items will be treated as valid
286  geometry types.
287 
288  wkb_first and wkb_last are only intended to be used to express a valid
289  range of wkbType values, other items are to be used as real type values.
290  */
291  enum wkbType {
301  /*
302  OGC defines 10 more basic geometry types for values 8 to 17, we don't
303  support them now so don't define them. And there may be more of
304  them defined in the future. Since we will need 5 bits anyway, we grow
305  from 31 down to 18 for our extra private types instead of from 18 to 31,
306  to avoid potential data file format binary compatibility issues, which
307  would occur if OGC defined more basic types and we would support them.
308  */
310  wkb_last = 31
311  };
313  wkb_xdr = 0, /* Big Endian */
314  wkb_ndr = 1, /* Little Endian */
316  };
320  coord_last = 1
321  };
322 
324 
325  /**
326  Constant storage for WKB.
327  Encapsulation and the available methods make it impossible
328  to update the members of wkb_container once it is initialized.
329  The only allowed modification method is set(),
330  which fully replaces the previous buffer.
331  */
333  protected:
334  const char *m_data;
335  const char *m_data_end;
336 
337  public:
338  wkb_container() = default;
339  wkb_container(const char *data, const char *data_end) {
340  set(data, data_end);
341  }
342  void set(const char *data, const char *data_end) {
343  m_data = data;
345  }
346  const char *data() const { return m_data; }
347  const char *data_end() const { return m_data_end; }
348  uint32 length() const { return (uint32)(m_data_end - m_data); }
349  /**
350  Check if there's enough data remaining as requested.
351 
352  @arg data_amount data requested
353 
354  @return true if not enough data
355  */
356  bool no_data(size_t data_amount) const {
357  return (m_data + data_amount > m_data_end);
358  }
359 
360  /**
361  Check if there're enough points remaining as requested.
362 
363  Need to perform the calculation in logical units, since multiplication
364  can overflow the size data type.
365 
366  @arg expected_points number of points expected
367  @arg extra_point_space extra space for each point element in the array
368 
369  @return true if there are not enough points
370  */
371  bool not_enough_points(uint32 expected_points,
372  uint32 extra_point_space = 0) const {
373  return (m_data_end < m_data ||
374  expected_points > ((m_data_end - m_data) /
375  (POINT_DATA_SIZE + extra_point_space)));
376  }
377  };
378 
379  /**
380  WKB parser, designed to traverse through WKB data from
381  beginning of the buffer towards the end using a set
382  of scan_xxx(), get_xxx() and skip_xxx() routines,
383  with safety tests to avoid going beyond the buffer end.
384  */
385  class wkb_parser : public wkb_container {
386  /* Low level routines to get data of various types */
387  void get_uint4(uint32 *number) {
388  *number = uint4korr(m_data); // GIS-TODO: byte order
389  }
390  void get_float8(double *x) {
391  *x = float8get(m_data); // GIS-TODO: byte order
392  }
393 
394  public:
395  wkb_parser(const char *data, const char *data_end)
397 
398  /* Routines to skip non-interesting data */
399  void skip_unsafe(size_t nbytes) {
400  assert(!no_data(nbytes));
401  m_data += nbytes;
402  }
403  bool skip(size_t nbytes) {
404  if (no_data(nbytes)) return true;
405  m_data += nbytes;
406  return false;
407  }
410 
411  /* Routines to scan wkb header information */
412  bool scan_wkb_header(wkb_header *header) {
413  if (no_data(WKB_HEADER_SIZE)) return true;
414  header->byte_order = (uchar)(*m_data);
415  m_data++;
416  get_uint4(&header->wkb_type);
417  m_data += 4;
418  return false;
419  }
420 
421  /* Routines to scan uint4 information */
422  bool scan_uint4(uint32 *number) {
423  if (no_data(4)) return true;
424  get_uint4(number);
425  m_data += 4;
426  return false;
427  }
428  bool scan_non_zero_uint4(uint32 *number) {
429  return (scan_uint4(number) || 0 == *number);
430  }
432  uint32 extra_point_space = 0) {
433  return scan_non_zero_uint4(n_points) ||
434  not_enough_points(*n_points, extra_point_space);
435  }
436 
437  /* Routines to scan coordinate information */
439  assert(!no_data(POINT_DATA_SIZE));
440  get_float8(&p->x);
442  get_float8(&p->y);
444  }
445  bool scan_xy(point_xy *p) {
446  if (no_data(SIZEOF_STORED_DOUBLE * 2)) return true;
447  scan_xy_unsafe(p);
448  return false;
449  }
450  bool scan_coord(double *x) {
451  if (no_data(SIZEOF_STORED_DOUBLE)) return true;
452  get_float8(x);
454  return false;
455  }
456  };
457 
458  /** Callback which creates Geometry objects on top of a given placement. */
459  typedef Geometry *(*create_geom_t)(char *);
460 
461  class Class_info {
462  public:
466  Class_info(const char *name, int type_id, create_geom_t create_func);
467  };
468 
469  virtual const Class_info *get_class_info() const { return nullptr; }
470 
471  virtual uint32 get_data_size() const { return -1; }
472 
473  /* read from trs the wkt string and write into wkb as wkb encoded data. */
474  virtual bool init_from_wkt(Gis_read_stream *trs [[maybe_unused]],
475  String *wkb [[maybe_unused]]) {
476  return true;
477  }
478 
479  /* read from wkb the wkb data and write into res as wkb encoded data. */
480  /* returns the length of the wkb that was read */
481  virtual uint init_from_wkb(THD *thd [[maybe_unused]],
482  const char *wkb [[maybe_unused]],
483  uint len [[maybe_unused]],
484  wkbByteOrder bo [[maybe_unused]],
485  String *res [[maybe_unused]]) {
486  return 0;
487  }
488 
489  virtual bool get_data_as_wkt(String *txt [[maybe_unused]],
490  wkb_parser *wkb [[maybe_unused]]) const {
491  return true;
492  }
493  virtual bool get_mbr(MBR *mbr [[maybe_unused]],
494  wkb_parser *wkb [[maybe_unused]]) const {
495  return true;
496  }
497  bool get_mbr(MBR *mbr) {
498  wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
499  return get_mbr(mbr, &wkb);
500  }
501  virtual bool dimension(uint32 *dim, wkb_parser *wkb) const {
502  *dim = feature_dimension();
503  uint32 length;
504  if ((length = get_data_size()) == GET_SIZE_ERROR) return true;
505  wkb->skip(length);
506  return false;
507  }
508  bool dimension(uint32 *dim) const {
509  wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
510  return dimension(dim, &wkb);
511  }
512  wkbType get_type() const {
513  return static_cast<Geometry::wkbType>(get_class_info()->m_type_id);
514  }
516  virtual uint32 feature_dimension() const {
517  assert(false);
518  return 0;
519  }
520 
521  virtual int get_x(double *x [[maybe_unused]]) const { return -1; }
522  virtual int get_y(double *y [[maybe_unused]]) const { return -1; }
523  virtual int geom_length(double *len [[maybe_unused]]) const { return -1; }
524  virtual int is_closed(int *closed [[maybe_unused]]) const { return -1; }
525  virtual int num_interior_ring(uint32 *n_int_rings [[maybe_unused]]) const {
526  return -1;
527  }
528  virtual int num_points(uint32 *n_points [[maybe_unused]]) const { return -1; }
529  virtual int num_geometries(uint32 *num [[maybe_unused]]) const { return -1; }
530  virtual int copy_points(String *result [[maybe_unused]]) const { return -1; }
531  /* The following 7 functions return geometries in wkb format. */
532  virtual int start_point(String *point [[maybe_unused]]) const { return -1; }
533  virtual int end_point(String *point [[maybe_unused]]) const { return -1; }
534  virtual int exterior_ring(String *ring [[maybe_unused]]) const { return -1; }
535  virtual int point_n(uint32 num [[maybe_unused]],
536  String *result [[maybe_unused]]) const {
537  return -1;
538  }
539  virtual int interior_ring_n(uint32 num [[maybe_unused]],
540  String *result [[maybe_unused]]) const {
541  return -1;
542  }
543  virtual int geometry_n(uint32 num [[maybe_unused]],
544  String *result [[maybe_unused]]) const {
545  return -1;
546  }
547 
548  /**
549  Reverses the coordinates of a geometry.
550 
551  Switches the coordinates of the wkb string pointed to by the Geometry.
552  Ex: Used on a POINT(5,2), the result would be POINT(2, 5).
553 
554  @retval false coordinate reversal was successful
555  @retval true coordinate reversal was unsuccessful
556  */
557  virtual bool reverse_coordinates() = 0;
558 
559  /**
560  Check that the coordinates of a geometry is within the valid range.
561 
562  Checks if the coordinates in a geometry are within allowed range of a
563  geographic spatial reference system. Valid range for longitude and latitude
564  coordinates in geographic spatial reference systems are (-180, 180) and
565  [-90, 90] degrees, respectively.
566 
567  @param[in] srs_angular_unit Unit to radians conversion factor.
568  @param[out] long_out_of_range Longitude is out of range.
569  @param[out] lat_out_of_range Latitude is out of range.
570  @param[out] out_of_range_value The value that is out of range.
571 
572  @retval false Coordinates are within allowed range.
573  @retval true Coordinates are not within allowed range, or an error occurred
574  during range checking.
575  */
576  virtual bool validate_coordinate_range(double srs_angular_unit,
577  bool *long_out_of_range,
578  bool *lat_out_of_range,
579  double *out_of_range_value) = 0;
580 
581  public:
582  static Geometry *create_by_typeid(Geometry_buffer *buffer, int type_id);
583 
584  static Geometry *construct(Geometry_buffer *buffer, const char *data,
585  uint32 data_len, bool has_srid = true);
587  bool has_srid = true) {
588  return construct(buffer, str->ptr(), static_cast<uint32>(str->length()),
589  has_srid);
590  }
592  Gis_read_stream *trs, String *wkt,
593  bool init_stream = true,
594  bool check_trailing = true);
596  const char *wkb, uint32 len, String *res,
597  bool init);
598  bool as_wkt(String *wkt, wkb_parser *wkb) const {
600  if (wkt->reserve(len + 2, 512)) return true;
602  wkt->append("GEOMETRYCOLLECTION");
603  else
604  qs_append(get_class_info()->m_name.str, len, wkt);
605  if (get_data_as_wkt(wkt, wkb)) return true;
606  return false;
607  }
608  bool as_wkt(String *wkt) const {
609  wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
610  return as_wkt(wkt, &wkb);
611  }
612 
613  bool as_wkb(String *wkb, bool shallow_copy) const;
614  bool as_geometry(String *wkb, bool shallow_copy) const;
615 
616  void set_data_ptr(const void *data, size_t data_len) {
617  m_ptr = const_cast<void *>(data);
618  set_nbytes(data_len);
619  }
620 
621  void set_data_ptr(const wkb_container *c) {
622  m_ptr = const_cast<void *>(static_cast<const void *>(c->data()));
623  set_nbytes(c->length());
624  }
625  void *get_data_ptr() const { return m_ptr; }
626 
627  bool envelope(String *result) const;
628  bool envelope(MBR *mbr) const;
629 
631 
632  bool is_polygon_ring() const {
634  }
635 
636  bool is_polygon_outer_ring() const {
638  }
639 
640  bool is_polygon_inner_ring() const {
642  }
643 
644  bool has_geom_header_space() const {
645  return (m_flags.props & HAS_GEOM_HEADER_SPACE) ||
647  }
648 
649  void has_geom_header_space(bool b) {
650  if (b)
652  else
654  }
655 
658  }
659 
661  assert(get_type() == wkb_multilinestring ||
662  get_type() == wkb_multipolygon ||
664  if (b)
666  else
668  }
669 
671  assert(0xfff >= flag);
672  m_flags.props |= flag;
673  }
674 
675  uint16 get_props() const { return (uint16)m_flags.props; }
676 
677  void set_srid(gis::srid_t id) { m_srid = id; }
678 
679  gis::srid_t get_srid() const { return m_srid; }
680 
681  const void *normalize_ring_order();
682 
683  protected:
684  static Class_info *find_class(int type_id) {
685  return ((type_id < wkb_first) || (type_id > wkb_last))
686  ? nullptr
687  : ci_collection[type_id];
688  }
689  static Class_info *find_class(const char *name, size_t len);
690  void append_points(String *txt, uint32 n_points, wkb_parser *wkb,
691  uint32 offset, bool bracket_pt = false) const;
692  bool create_point(String *result, wkb_parser *wkb) const;
693  bool create_point(String *result, point_xy p) const;
694  bool get_mbr_for_points(MBR *mbr, wkb_parser *wkb, uint offset) const;
695  bool is_length_verified() const {
697  }
698 
699  // Have to make this const because it's called in a const member function.
700  void set_length_verified(bool b) const {
701  if (b)
703  else
705  }
706 
707  /***************************** Boost Geometry Adapter Interface ************/
708  public:
709  /**
710  Highest byte is stores byte order, dimension, nomem and geotype as follows:
711  bo: byte order, 1 for little endian(ndr), 0 for big endian(xdr); Currently
712  it must be always wkb_ndr since it is MySQL's portable geometry format.
713  dimension: 0~3 for 1~4 dimensions;
714  nomem: indicating whether this object has its own memory.
715  If so, the memory is released when the object is destroyed. Some
716  objects may refer to an existing WKB buffer and access it read only.
717  geotype: stores the wkbType enum numbers, at most 32 values, valid range
718  so far: [0, 7] and 31.
719 
720  nybytes: takes the following 30 bits, stores number of effective and valid
721  data bytes of current object's wkb data.
722 
723  props: bits OR'ed for various other runtime properties of the geometry
724  object. Bits are defined above. No properties are stored
725  permanently, all properties here are specified/used at runtime
726  while the Geometry object is alive.
727  zm: not used now, always be 0, i.e. always 2D geometries. In future,
728  they represent Z and/or M settings, 1: Z, 2: M, 3: ZM.
729  unused: reserved for future use, it's unused now.
730  */
731  class Flags_t {
732  public:
734  memset(this, 0, sizeof(*this));
735  bo = wkb_ndr;
736  dim = GEOM_DIM - 1;
737  nomem = 1;
738  }
739 
740  Flags_t(wkbType type, size_t len) {
741  memset(this, 0, sizeof(*this));
742  geotype = type;
743  nbytes = len;
744  bo = wkb_ndr;
745  dim = GEOM_DIM - 1;
746  nomem = 1;
747  }
748 
749  uint64 bo : 1;
750  uint64 dim : 2;
754  uint64 props : 12;
755  uint64 zm : 2;
757  };
758  static_assert(sizeof(Flags_t) == sizeof(uint64),
759  "Flags are expected to line up exactly with an uint64.");
760 
762  m_ptr = nullptr;
763  m_owner = nullptr;
764  set_ownmem(false);
767  }
768 
769  /**
770  Constructor used as BG adapter or by default constructors of children
771  classes.
772  @param ptr WKB buffer address, or NULL for an empty object.
773  @param len WKB buffer length in bytes.
774  @param flags the flags to set, no field is used for now except geotype.
775  @param srid srid of the geometry.
776  */
777  Geometry(const void *ptr, size_t len, const Flags_t &flags,
778  gis::srid_t srid) {
779  m_ptr = const_cast<void *>(ptr);
780  m_flags.nbytes = len;
781  set_srid(srid);
782  m_flags.geotype = flags.geotype;
783  m_owner = nullptr;
784  set_ownmem(false);
785  }
786 
787  Geometry(const Geometry &geo);
788 
789  Geometry &operator=(const Geometry &rhs);
790 
791  /* Getters and setters. */
792  void *get_ptr() const { return m_ptr; }
793 
794  char *get_cptr() const { return static_cast<char *>(m_ptr); }
795 
796  uchar *get_ucptr() const { return static_cast<uchar *>(m_ptr); }
797 
798  Geometry *get_owner() const { return m_owner; }
799 
800  void set_owner(Geometry *o) { m_owner = o; }
801 
803  assert(bo == Geometry::wkb_ndr);
804  m_flags.bo = static_cast<char>(bo);
805  }
806 
807  void set_dimension(char dim) {
808  // Valid dim is one of [1, 2, 3, 4].
809  assert(dim > 0 && dim < 5);
810  m_flags.dim = dim - 1;
811  }
812 
813  /**
814  Check if a given geometry type is a valid geometry type according
815  to OpenGIS.
816 
817  Internal geometry types of MySQL are regarded as invalid.
818 
819  @param gtype geometry type to check
820 
821  @retval true valid geometry type
822  @retval false invalid geometry type
823  */
824  static bool is_valid_opengis_geotype(uint32 gtype) {
825  return gtype >= wkb_first && gtype <= wkb_geometrycollection;
826  }
827 
828  /**
829  Check if a given geometry type is a valid internal geometry type.
830 
831  Both OpenGIS standard geometry types and internal geometry types
832  of MySQL are regarded as valid.
833 
834  @param gtype geometry type to check
835 
836  @retval true valid geometry type
837  @retval false invalid geometry type
838  */
839  static bool is_valid_geotype(uint32 gtype) {
840  /*
841  Stricter check, outside only checks for [wkb_first, wkb_last],
842  they don't have to know about the details.
843  */
844  return ((gtype >= wkb_first && gtype <= wkb_geometrycollection) ||
845  gtype == wkb_polygon_inner_rings);
846  }
847 
848  /**
849  Check if a given geometry type is a valid internal geometry type.
850 
851  Both OpenGIS standard geometry types and internal geometry types
852  of MySQL are regarded as valid.
853 
854  @param gt geometry type to check
855 
856  @retval true valid geometry type
857  @retval false invalid geometry type
858  */
860  /*
861  Stricter check, outside only checks for [wkb_first, wkb_last],
862  they don't have to know about the details.
863  */
864  return ((gt >= wkb_first && gt <= wkb_geometrycollection) ||
866  }
867 
868  /**
869  Verify that a string is a well-formed GEOMETRY string.
870 
871  This does not check if the geometry is geometrically valid.
872 
873  @see Geometry_well_formed_checker
874 
875  @param from String to check
876  @param length Length of string
877  @param type Expected type of geometry, or
878  Geoemtry::wkb_invalid_type if any type is allowed
879 
880  @param bo byte order
881  @return True if the string is a well-formed GEOMETRY string,
882  false otherwise
883  */
884  static bool is_well_formed(const char *from, size_t length, wkbType type,
885  wkbByteOrder bo);
886 
888  is_valid_geotype(gt);
889  m_flags.geotype = static_cast<char>(gt);
890  }
891 
892  // Have to make this const because it's called in a const member function.
893  void set_nbytes(size_t n) const {
894  if (get_nbytes() != n) {
895  set_length_verified(false);
896  m_flags.nbytes = n;
897  }
898  }
899 
900  /**
901  Set whether this object has its own memory. If so, the memory is released
902  when this object is destroyed.
903  @param b true if this object has its own memory, false otherwise.
904 
905  */
906  void set_ownmem(bool b) { m_flags.nomem = (b ? 0 : 1); }
907 
908  /**
909  Returns whether this object has its own memory. If so, the memory is
910  released when this object is destroyed.
911  */
912  bool get_ownmem() const { return !m_flags.nomem; }
913 
915  assert(m_flags.bo == 1);
916  return Geometry::wkb_ndr;
917  }
918 
919  char get_dimension() const { return static_cast<char>(m_flags.dim) + 1; }
920 
922  char gt = static_cast<char>(m_flags.geotype);
923  return static_cast<Geometry::wkbType>(gt);
924  }
925 
926  /**
927  Build an OGC standard type value from m_flags.zm and m_flags.geotype. For
928  now m_flags.zm is always 0 so simply call get_geotype(). We don't
929  directly store the OGC defined values in order to save more bits
930  of m_flags for other purposes; and also separating zm settings from basic
931  geometry types is easier for coding and geometry type identification.
932 
933  When we start to support Z/M settings we need to modify all code which call
934  write_wkb_header and write_geometry_header to pass to them an OGC standard
935  type value returned by this function or built similarly. And by doing so
936  our internal runtime geometry type encoding will work consistently with
937  OGC defined standard geometry type values in byte strings of WKB format.
938 
939  @return OGC standard geometry type value.
940  */
941  uint32 get_ogc_geotype() const { return static_cast<uint32>(get_geotype()); }
942 
943  size_t get_nbytes() const { return static_cast<size_t>(m_flags.nbytes); }
944 
945  /*
946  Only sets m_ptr, different from the overloaded one in Gis_wkb_vector<>
947  which also does WKB parsing.
948  */
949  void set_ptr(const void *ptr) { m_ptr = const_cast<void *>(ptr); }
950 
951  /**
952  Whether the Geometry object is created to be used by Boost Geometry or
953  only by MySQL. There are some operations that only work for one type and
954  can or must be skipped otherwise.
955  @return true if it's a BG adapter, false otherwise.
956  */
957  bool is_bg_adapter() const {
959  }
960 
961  /**
962  Set whether this object is a BG adapter.
963  @param b true if it's a BG adapter, false otherwise.
964  Have to declare this as const because even when a Geometry object's const
965  adapter member function is called, it's regarded as a BG adapter object.
966  */
967  void set_bg_adapter(bool b) const {
968  if (b)
970  else
972  }
973 
974  /*
975  Give up ownership of m_ptr, so as not to release them when
976  this object is destroyed, to be called when the two member is shallow
977  assigned to another geometry object.
978  */
979  virtual void donate_data() {
980  set_ownmem(false);
981  set_nbytes(0);
982  m_ptr = nullptr;
983  }
984 
985  protected:
986  /**
987  In a polygon usable by boost geometry, the m_ptr points to the outer ring
988  object, and m_inn_rings points to the inner rings, thus the polygon's data
989  isn't stored in a single WKB. Users should call
990  @c Gis_polygon::to_wkb_unparsed() before getting the polygon's wkb data,
991  @c Gis_polygon::to_wkb_unparsed() will form a single WKB for the polygon
992  and refer to it with m_ptr, and release the outer ring object
993  and the inner rings objects, and such an polygon isn't usable by BG any
994  more, it's exactly what we got with
995  @c Geometry::create_from_wkt / @c Geometry::create_from_wkt.
996  */
997  bool polygon_is_wkb_form() const {
999  }
1000 
1001  void polygon_is_wkb_form(bool b) {
1002  if (b)
1004  else
1006  }
1007 
1008  /**
1009  If call Gis_wkb_vector<T>::resize() to add a component to X, the
1010  geometry may have a geometry not stored inside the WKB buffer of X, hence
1011  X has out of line component. For such an X, user should call
1012  Gis_wkb_vector<T>::reassemble() before fetching its WKB data.
1013  */
1016  }
1017 
1019  if (b)
1021  else
1023  }
1024 
1026  virtual void shallow_push(const Geometry *) { assert(false); }
1027 
1028  protected:
1029  /**
1030  The topmost (root) geometry object, whose m_ptr is the 1st byte of a
1031  wkb memory buffer. other geometry objects hold m_ptr which points
1032  inside somewhere in the memory buffer. when updating a geometry object,
1033  need to ask m_owner to reallocate memory if needed for new data.
1034  */
1036 
1037  /**
1038  Pointer to the geometry's wkb data's 1st byte, right after its
1039  wkb header if any.
1040  If the geometry is wkb_polygon, this field is a
1041  Gis_polygon_ring* pointer, pointing to the outer ring. Outer ring's wkb data
1042  is in the same wkb buffer as the inner rings, so we can get the wkb header
1043  from the outer ring like ((Geometry*)m_ptr)->get_ptr().
1044  */
1045  void *m_ptr;
1046 
1047  private:
1048  /// Flags and meta information about this object.
1049  /// Make it mutable to modify some flags in const member functions.
1050  mutable Flags_t m_flags;
1051 
1052  /// Srid of this object.
1054 
1055  public:
1056  Flags_t get_flags() const { return m_flags; }
1057 
1058  void set_flags(const Flags_t &flags) { m_flags = flags; }
1059 };
1060 
1061 inline Geometry::wkbByteOrder get_byte_order(const void *p0) {
1062  const char *p = static_cast<const char *>(p0);
1063 
1064  if (!(*p == 0 || *p == 1)) return Geometry::wkb_invalid;
1065  return *p == 0 ? Geometry::wkb_xdr : Geometry::wkb_ndr;
1066 }
1067 
1068 inline void set_byte_order(void *p0, Geometry::wkbByteOrder bo) {
1069  char *p = static_cast<char *>(p0);
1070  *p = (bo == Geometry::wkb_ndr ? 1 : 0);
1071 }
1072 
1073 /**
1074  Get wkbType value from WKB, the WKB is always little endian, so need
1075  platform specific conversion.
1076  @param p0 WKB geometry type field address.
1077  @return geometry type.
1078  */
1079 inline Geometry::wkbType get_wkb_geotype(const void *p0) {
1080  const char *p = static_cast<const char *>(p0);
1081  uint32 gt = uint4korr(p);
1082  assert(Geometry::is_valid_geotype(gt));
1083  return static_cast<Geometry::wkbType>(gt);
1084 }
1085 
1086 /*
1087  Functions to write a GEOMETRY or WKB header into a piece of allocated and
1088  big enough raw memory or into a String object with enough reserved memory,
1089  and optionally append the object count right after the header.
1090  */
1091 inline char *write_wkb_header(void *p0, Geometry::wkbType geotype) {
1092  char *p = static_cast<char *>(p0);
1093  *p = static_cast<char>(Geometry::wkb_ndr);
1094  p++;
1095  int4store(p, static_cast<uint32>(geotype));
1096  return p + 4;
1097 }
1098 
1099 inline char *write_wkb_header(void *p0, Geometry::wkbType geotype,
1100  uint32 obj_count) {
1101  char *p = static_cast<char *>(p0);
1102  p = write_wkb_header(p, geotype);
1103  int4store(p, obj_count);
1104  return p + 4;
1105 }
1106 
1107 inline char *write_geometry_header(void *p0, gis::srid_t srid,
1108  Geometry::wkbType geotype) {
1109  char *p = static_cast<char *>(p0);
1110  int4store(p, srid);
1111  return write_wkb_header(p + 4, geotype);
1112 }
1113 
1114 inline char *write_geometry_header(void *p0, gis::srid_t srid,
1115  Geometry::wkbType geotype,
1116  uint32 obj_count) {
1117  char *p = static_cast<char *>(p0);
1118  int4store(p, srid);
1119  return write_wkb_header(p + 4, geotype, obj_count);
1120 }
1121 
1123  q_append(static_cast<char>(Geometry::wkb_ndr), str);
1124  q_append(static_cast<uint32>(geotype), str);
1125 }
1126 
1128  uint32 obj_count) {
1129  write_wkb_header(str, geotype);
1130  q_append(obj_count, str);
1131 }
1132 
1134  Geometry::wkbType geotype) {
1135  q_append(srid, str);
1136  write_wkb_header(str, geotype);
1137 }
1138 
1140  Geometry::wkbType geotype, uint32 obj_count) {
1141  write_geometry_header(str, srid, geotype);
1142  q_append(obj_count, str);
1143 }
1144 
1145 /***************************** Point *******************************/
1146 
1147 class Gis_point : public Geometry {
1148  public:
1149  uint32 get_data_size() const override;
1150  /**
1151  Initialize from a partial WKT string (everything following "POINT").
1152 
1153  @param trs Input stream
1154  @param wkb Output string
1155  @param parens Whether parentheses are expected around the
1156  coordinates.
1157  @retval true Error
1158  @retval false Success
1159  */
1160  bool init_from_wkt(Gis_read_stream *trs, String *wkb, const bool parens);
1161  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override {
1162  return init_from_wkt(trs, wkb, true);
1163  }
1164  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
1165  String *res) override;
1166  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
1167  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
1168 
1169  int get_xy(point_xy *p) const {
1170  wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
1171  return wkb.scan_xy(p);
1172  }
1173  int get_x(double *x) const override {
1174  wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
1175  return wkb.scan_coord(x);
1176  }
1177  int get_y(double *y) const override {
1178  wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
1179  return wkb.skip_coord() || wkb.scan_coord(y);
1180  }
1181  uint32 feature_dimension() const override { return 0; }
1182  const Class_info *get_class_info() const override;
1183  bool reverse_coordinates() override;
1184  bool validate_coordinate_range(double srs_angular_unit,
1185  bool *long_out_of_range,
1186  bool *lat_out_of_range,
1187  double *out_of_range_value) override;
1188 
1189  /************* Boost Geometry Adapter Interface *************/
1190 
1191  typedef Gis_point self;
1192  typedef Geometry base;
1193 
1194  explicit Gis_point(bool is_bg_adapter = true)
1196  set_ownmem(false);
1198  }
1199 
1200  /// @brief Default constructor, no initialization.
1201  Gis_point(const void *ptr, size_t nbytes, const Flags_t &flags,
1202  gis::srid_t srid)
1203  : Geometry(ptr, nbytes, flags, srid) {
1205  assert(
1206  (ptr != nullptr && get_nbytes() == SIZEOF_STORED_DOUBLE * GEOM_DIM) ||
1207  (ptr == nullptr && get_nbytes() == 0));
1208  set_ownmem(false);
1209  set_bg_adapter(true);
1210  }
1211 
1212  Gis_point(const self &pt);
1213 
1214  ~Gis_point() override = default;
1215 
1216  Gis_point &operator=(const Gis_point &rhs);
1217 
1218  void set_ptr(void *ptr, size_t len);
1219 
1220  /// @brief Get a coordinate
1221  /// @tparam K coordinate to get
1222  /// @return the coordinate
1223  template <std::size_t K>
1224  double get() const {
1225  assert(K < static_cast<size_t>(get_dimension()) &&
1226  ((m_ptr != nullptr &&
1228  (m_ptr == nullptr && get_nbytes() == 0)));
1229 
1230  set_bg_adapter(true);
1231  const char *p = static_cast<char *>(m_ptr) + K * SIZEOF_STORED_DOUBLE;
1232 
1233  /*
1234  Boost Geometry may use a point that is only default constructed that
1235  has not specified with any meaningful value, and in such a case the
1236  default value are expected to be all zeros.
1237  */
1238  if (m_ptr == nullptr) return 0;
1239 
1240  return float8get(p);
1241  }
1242 
1243  /// @brief Set a coordinate
1244  /// @tparam K coordinate to set
1245  /// @param value value to set
1246  // Deep assignment, not only allow assigning to a point owning its memory,
1247  // but also a point not own memory, since points are of same size.
1248  template <std::size_t K>
1249  void set(double const &value) {
1250  /* Allow assigning to others' memory. */
1251  assert((m_ptr != nullptr && K < static_cast<size_t>(get_dimension()) &&
1253  (!get_ownmem() && get_nbytes() == 0 && m_ptr == nullptr));
1254  set_bg_adapter(true);
1255  if (m_ptr == nullptr) {
1257  if (m_ptr == nullptr) {
1258  set_ownmem(false);
1259  set_nbytes(0);
1260  return;
1261  }
1262  set_ownmem(true);
1264  }
1265 
1266  char *p = get_cptr() + K * SIZEOF_STORED_DOUBLE;
1267  float8store(p, value);
1268  }
1269 
1270  bool operator<(const Gis_point &pt) const {
1271  bool x = get<0>(), px = pt.get<0>();
1272  return x == px ? get<1>() < pt.get<1>() : x < px;
1273  }
1274 
1275  bool operator==(const Gis_point &pt) const {
1276  return (get<0>() == pt.get<0>() && get<1>() == pt.get<1>());
1277  }
1278 
1279  bool operator!=(const Gis_point &pt) const { return !(operator==(pt)); }
1280 };
1281 
1282 /******************************** Gis_wkb_vector **************************/
1283 
1284 template <typename T>
1285 class Gis_wkb_vector;
1286 
1287 /// @ingroup iterators
1288 /// @{
1289 /// @defgroup Gis_wkb_vector_iterators Iterator classes for Gis_wkb_vector.
1290 /// Gis_wkb_vector has two iterator classes --- Gis_wkb_vector_const_iterator
1291 /// and Gis_wkb_vector_iterator. The differences
1292 /// between the two classes are that the Gis_wkb_vector_const_iterator
1293 /// can only be used to read its referenced value, so it is intended as
1294 /// Gis_wkb_vector's const iterator; While the other class allows both read and
1295 /// write access. If your access pattern is readonly, it is strongly
1296 /// recommended that you use the const iterator because it is faster
1297 /// and more efficient.
1298 /// The two classes have identical behaviors to std::vector::const_iterator and
1299 /// std::vector::iterator respectively.
1300 //@{
1301 ///////////////////////////////////////////////////////////////////////
1302 ///////////////////////////////////////////////////////////////////////
1303 //
1304 // Gis_wkb_vector_const_iterator class template definition
1305 //
1306 /// Gis_wkb_vector_const_iterator is const_iterator class for Gis_wkb_vector,
1307 /// and base class of Gis_wkb_vector_iterator -- iterator class for
1308 /// Gis_wkb_vector.
1309 /// @tparam T Vector element type
1310 template <typename T>
1312  protected:
1315  typedef ptrdiff_t index_type;
1316 
1317  public:
1318  ////////////////////////////////////////////////////////////////////
1319  //
1320  // Begin public type definitions.
1321  //
1322  typedef T value_type;
1323  typedef ptrdiff_t difference_type;
1325  typedef typename owner_t::size_type size_type;
1326 
1327  /// This is the return type for operator[].
1330  // Use the STL tag, to ensure compatability with interal STL functions.
1331  //
1332  typedef std::random_access_iterator_tag iterator_category;
1333  ////////////////////////////////////////////////////////////////////
1334 
1335  ////////////////////////////////////////////////////////////////////
1336  // Begin public constructors and destructor.
1337  /// @name Constructors and destroctor
1338  /// Do not construct iterators explictily using these constructors,
1339  /// but call Gis_wkb_vector::begin() const to get an valid iterator.
1340  /// @sa Gis_wkb_vector::begin() const
1341  //@{
1343  m_curidx = vi.m_curidx;
1344  m_owner = vi.m_owner;
1345  }
1346 
1348  m_curidx = -1;
1349  m_owner = nullptr;
1350  }
1351 
1353  m_curidx = idx;
1354  m_owner = const_cast<owner_t *>(owner);
1355  }
1356 
1358  //@}
1359 
1360  ////////////////////////////////////////////////////////////////////
1361 
1362  ////////////////////////////////////////////////////////////////////
1363  //
1364  // Begin functions that compare iterator positions.
1365  //
1366  /// @name Iterator comparison operators
1367  /// The way to compare two iterators is to compare the index values
1368  /// of the two elements they point to. The iterator sitting on an
1369  /// element with less index is regarded to be smaller. And the invalid
1370  /// iterator sitting after last element is greater than any other
1371  /// iterators, because it is assumed to have an index equal to last
1372  /// element's index plus one; The invalid iterator sitting before first
1373  /// element is less than any other iterators because it is assumed to
1374  /// have an index -1.
1375  //@{
1376  /// @brief Equality comparison operator.
1377  ///
1378  /// Invalid iterators are equal; Valid iterators
1379  /// sitting on the same key/data pair equal; Otherwise not equal.
1380  /// @param itr The iterator to compare against.
1381  /// @return True if this iterator equals to itr; False otherwise.
1382  bool operator==(const self &itr) const {
1383  assert(m_owner == itr.m_owner);
1384  return m_curidx == itr.m_curidx;
1385  }
1386 
1387  /// @brief Unequal compare, identical to !operator(==itr)
1388  /// @param itr The iterator to compare against.
1389  /// @return False if this iterator equals to itr; True otherwise.
1390  bool operator!=(const self &itr) const { return !(*this == itr); }
1391 
1392  // The end() iterator is largest. If both are end() iterator return false.
1393  /// @brief Less than comparison operator.
1394  /// @param itr The iterator to compare against.
1395  /// @return True if this iterator is less than itr.
1396  bool operator<(const self &itr) const {
1397  assert(m_owner == itr.m_owner);
1398  return m_curidx < itr.m_curidx;
1399  }
1400 
1401  /// @brief Less equal comparison operator.
1402  /// @param itr The iterator to compare against.
1403  /// @return True if this iterator is less than or equal to itr.
1404  bool operator<=(const self &itr) const { return !(this->operator>(itr)); }
1405 
1406  /// @brief Greater equal comparison operator.
1407  /// @param itr The iterator to compare against.
1408  /// @return True if this iterator is greater than or equal to itr.
1409  bool operator>=(const self &itr) const { return !(this->operator<(itr)); }
1410 
1411  // The end() iterator is largest. If both are end() iterator return false.
1412  /// @brief Greater comparison operator.
1413  /// @param itr The iterator to compare against.
1414  /// @return True if this iterator is greater than itr.
1415  bool operator>(const self &itr) const {
1416  assert(m_owner == itr.m_owner);
1417  return m_curidx > itr.m_curidx;
1418  }
1419  //@} // vctitr_cmp
1420  ////////////////////////////////////////////////////////////////////
1421 
1422  ////////////////////////////////////////////////////////////////////
1423  //
1424  // Begin functions that shift the iterator position.
1425  //
1426  /// @name Iterator movement operators.
1427  /// When we talk about iterator movement, we think the
1428  /// container is a uni-directional range, represented by [begin, end),
1429  /// and this is true no matter we are using iterators or reverse
1430  /// iterators. When an iterator is moved closer to "begin", we say it
1431  /// is moved backward, otherwise we say it is moved forward.
1432  //@{
1433  /// @brief Pre-increment.
1434  ///
1435  /// Move the iterator one element forward, so that
1436  /// the element it sits on has a bigger index.
1437  /// Use ++iter rather than iter++ where possible to avoid two useless
1438  /// iterator copy constructions.
1439  /// @return This iterator after incremented.
1440  self &operator++() {
1441  move_by(*this, 1, false);
1442  return *this;
1443  }
1444 
1445  /// @brief Post-increment.
1446  /// Move the iterator one element forward, so that
1447  /// the element it sits on has a bigger index.
1448  /// Use ++iter rather than iter++ where possible to avoid two useless
1449  /// iterator copy constructions.
1450  /// @return A new iterator not incremented.
1451  self operator++(int) {
1452  self itr(*this);
1453  move_by(*this, 1, false);
1454 
1455  return itr;
1456  }
1457 
1458  /// @brief Pre-decrement.
1459  /// Move the iterator one element backward, so
1460  /// that the element it sits on has a smaller index.
1461  /// Use --iter rather than iter-- where possible to avoid two useless
1462  /// iterator copy constructions.
1463  /// @return This iterator after decremented.
1464  self &operator--() {
1465  move_by(*this, 1, true);
1466  return *this;
1467  }
1468 
1469  /// @brief Post-decrement.
1470  ///
1471  /// Move the iterator one element backward, so
1472  /// that the element it sits on has a smaller index.
1473  /// Use --iter rather than iter-- where possible to avoid two useless
1474  /// iterator copy constructions.
1475  /// @return A new iterator not decremented.
1476  self operator--(int) {
1477  self itr = *this;
1478  move_by(*this, 1, true);
1479  return itr;
1480  }
1481 
1482  /// @brief Assignment operator.
1483  ///
1484  /// This iterator will point to the same key/data
1485  /// pair as itr, and have the same configurations as itr.
1486  /// @param itr The right value of the assignment.
1487  /// @return This iterator's reference.
1488  const self &operator=(const self &itr) {
1489  m_curidx = itr.m_curidx;
1490  m_owner = itr.m_owner;
1491  return itr;
1492  }
1493 
1494  /// Iterator movement operator.
1495  /// Return another iterator by moving this iterator forward by n
1496  /// elements.
1497  /// @param n The amount and direction of movement. If negative, will
1498  /// move backward by |n| element.
1499  /// @return The new iterator at new position.
1501  self itr(*this);
1502  move_by(itr, n, false);
1503  return itr;
1504  }
1505 
1506  /// @brief Move this iterator forward by n elements.
1507  /// @param n The amount and direction of movement. If negative, will
1508  /// move backward by |n| element.
1509  /// @return Reference to this iterator at new position.
1511  move_by(*this, n, false);
1512  return *this;
1513  }
1514 
1515  /// @brief Iterator movement operator.
1516  ///
1517  /// Return another iterator by moving this iterator backward by n
1518  /// elements.
1519  /// @param n The amount and direction of movement. If negative, will
1520  /// move forward by |n| element.
1521  /// @return The new iterator at new position.
1523  self itr(*this);
1524  move_by(itr, n, true);
1525 
1526  return itr;
1527  }
1528 
1529  /// @brief Move this iterator backward by n elements.
1530  /// @param n The amount and direction of movement. If negative, will
1531  /// move forward by |n| element.
1532  /// @return Reference to this iterator at new position.
1534  move_by(*this, n, true);
1535  return *this;
1536  }
1537  //@} //itr_movement
1538 
1539  /// @brief Iterator distance operator.
1540  ///
1541  /// Return the index difference of this iterator and itr, so if this
1542  /// iterator sits on an element with a smaller index, this call will
1543  /// return a negative number.
1544  /// @param itr The other iterator to substract. itr can be the invalid
1545  /// iterator after last element or before first element, their index
1546  /// will be regarded as last element's index + 1 and -1 respectively.
1547  /// @return The index difference.
1548  difference_type operator-(const self &itr) const {
1549  assert(m_owner == itr.m_owner);
1550  return (m_curidx - itr.m_curidx);
1551  }
1552 
1553  ////////////////////////////////////////////////////////////////////
1554  //
1555  // Begin functions that retrieve values from the iterator.
1556  //
1557  /// @name Functions that retrieve values from the iterator.
1558  //@{
1559  /// @brief Dereference operator.
1560  ///
1561  /// Return the reference to the cached data element.
1562  /// The returned value can only be used to read its referenced
1563  /// element.
1564  /// @return The reference to the element this iterator points to.
1566  assert(this->m_owner != nullptr && this->m_curidx >= 0 &&
1567  this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1568  return (*m_owner)[m_curidx];
1569  }
1570 
1571  /// @brief Arrow operator.
1572  ///
1573  /// Return the pointer to the cached data element.
1574  /// The returned value can only be used to read its referenced
1575  /// element.
1576  /// @return The address of the referenced object.
1577  pointer operator->() const {
1578  assert(this->m_owner != NULL && this->m_curidx >= 0 &&
1579  this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1580  return &(*m_owner)[m_curidx];
1581  }
1582 
1583  /// @brief Iterator index operator.
1584  ///
1585  /// @param offset The offset of target element relative to this iterator.
1586  /// @return Return the reference of the element which is at
1587  /// position *this + offset.
1588  /// The returned value can only be used to read its referenced
1589  /// element.
1590  reference operator[](difference_type offset) const {
1591  self itr = *this;
1592  move_by(itr, offset, false);
1593 
1594  assert(itr.m_owner != NULL && itr.m_curidx >= 0 &&
1595  itr.m_curidx < static_cast<index_type>(itr.m_owner->size()));
1596  return (*m_owner)[itr.m_curidx];
1597  }
1598  //@}
1599  ////////////////////////////////////////////////////////////////////
1600 
1601  protected:
1602  // The 'back' parameter indicates whether to decrease or
1603  // increase the index when moving. The default is to decrease.
1604  //
1605  void move_by(self &itr, difference_type n, bool back) const {
1606  if (back) n = -n;
1607 
1608  index_type newidx = itr.m_curidx + n;
1609  size_t sz = 0;
1610 
1611  if (newidx < 0)
1612  newidx = -1;
1613  else if (newidx >= static_cast<index_type>((sz = m_owner->size())))
1614  newidx = sz;
1615 
1616  itr.m_curidx = newidx;
1617  }
1618 
1619  protected:
1620  /// Current element's index, starting from 0.
1622  /// The owner container of this iteraotr.
1624 }; // Gis_wkb_vector_const_iterator<>
1625 
1626 ///////////////////////////////////////////////////////////////////////
1627 ///////////////////////////////////////////////////////////////////////
1628 //
1629 // Gis_wkb_vector_iterator class template definition
1630 /// This class is the iterator class for Gis_wkb_vector, its instances can
1631 /// be used to mutate their referenced data element.
1632 /// @tparam T Vector element type
1633 //
1634 template <class T>
1636  protected:
1640 
1641  public:
1642  typedef ptrdiff_t index_type;
1643  typedef T value_type;
1644  typedef ptrdiff_t difference_type;
1648  // Use the STL tag, to ensure compatability with interal STL functions.
1649  typedef std::random_access_iterator_tag iterator_category;
1650 
1651  ////////////////////////////////////////////////////////////////////
1652  /// Begin public constructors and destructor.
1653  //
1654  /// @name Constructors and destructor
1655  /// Do not construct iterators explictily using these constructors,
1656  /// but call Gis_wkb_vector::begin to get an valid iterator.
1657  /// @sa Gis_wkb_vector::begin
1658  //@{
1659  Gis_wkb_vector_iterator(const self &vi) : base(vi) {}
1660 
1662 
1663  Gis_wkb_vector_iterator(const base &obj) : base(obj) {}
1664 
1666  : base(idx, owner) {}
1667 
1669  //@}
1670 
1671  ////////////////////////////////////////////////////////////////////
1672 
1673  ////////////////////////////////////////////////////////////////////
1674  //
1675  /// Begin functions that shift the iterator position.
1676  //
1677  /// These functions are identical to those defined in
1678  /// Gis_wkb_vector_const_iterator, but we have to redefine them here because
1679  /// the "self" have different definitions.
1680  //
1681  /// @name Iterator movement operators.
1682  /// These functions have identical behaviors and semantics as those of
1683  /// Gis_wkb_vector_const_iterator, so please refer to equivalent in that
1684  /// class.
1685  //@{
1686  /// @brief Pre-increment.
1687  /// @return This iterator after incremented.
1688  /// @sa Gis_wkb_vector_const_iterator::operator++()
1689  self &operator++() {
1690  this->move_by(*this, 1, false);
1691  return *this;
1692  }
1693 
1694  /// @brief Post-increment.
1695  /// @return A new iterator not incremented.
1696  /// @sa Gis_wkb_vector_const_iterator::operator++(int)
1697  self operator++(int) {
1698  self itr(*this);
1699  this->move_by(*this, 1, false);
1700 
1701  return itr;
1702  }
1703 
1704  /// @brief Pre-decrement.
1705  /// @return This iterator after decremented.
1706  /// @sa Gis_wkb_vector_const_iterator::operator--()
1707  self &operator--() {
1708  this->move_by(*this, 1, true);
1709  return *this;
1710  }
1711 
1712  /// @brief Post-decrement.
1713  /// @return A new iterator not decremented.
1714  /// @sa Gis_wkb_vector_const_iterator::operator--(int)
1715  self operator--(int) {
1716  self itr = *this;
1717  this->move_by(*this, 1, true);
1718  return itr;
1719  }
1720 
1721  /// @brief Assignment operator.
1722  ///
1723  /// This iterator will point to the same key/data
1724  /// pair as itr, and have the same configurations as itr.
1725  /// @param itr The right value of the assignment.
1726  /// @return This iterator's reference.
1727  const self &operator=(const self &itr) {
1728  base::operator=(itr);
1729 
1730  return itr;
1731  }
1732 
1733  /// @brief Iterator movement operator.
1734  ///
1735  /// Return another iterator by moving this iterator backward by n
1736  /// elements.
1737  /// @param n The amount and direction of movement. If negative, will
1738  /// move forward by |n| element.
1739  /// @return The new iterator at new position.
1740  /// @sa Gis_wkb_vector_const_iterator::operator+(difference_type n) const
1742  self itr(*this);
1743  this->move_by(itr, n, false);
1744  return itr;
1745  }
1746 
1747  /// @brief Move this iterator backward by n elements.
1748  /// @param n The amount and direction of movement. If negative, will
1749  /// move forward by |n| element.
1750  /// @return Reference to this iterator at new position.
1751  /// @sa Gis_wkb_vector_const_iterator::operator+=(difference_type n)
1753  this->move_by(*this, n, false);
1754  return *this;
1755  }
1756 
1757  /// @brief Iterator movement operator.
1758  ///
1759  /// Return another iterator by moving this iterator forward by n
1760  /// elements.
1761  /// @param n The amount and direction of movement. If negative, will
1762  /// move backward by |n| element.
1763  /// @return The new iterator at new position.
1764  /// @sa Gis_wkb_vector_const_iterator::operator-(difference_type n) const
1766  self itr(*this);
1767  this->move_by(itr, n, true);
1768 
1769  return itr;
1770  }
1771 
1772  /// @brief Move this iterator forward by n elements.
1773  /// @param n The amount and direction of movement. If negative, will
1774  /// move backward by |n| element.
1775  /// @return Reference to this iterator at new position.
1776  /// @sa Gis_wkb_vector_const_iterator::operator-=(difference_type n)
1778  this->move_by(*this, n, true);
1779  return *this;
1780  }
1781  //@} // itr_movement
1782 
1783  /// @brief Iterator distance operator.
1784  ///
1785  /// Return the index difference of this iterator and itr, so if this
1786  /// iterator sits on an element with a smaller index, this call will
1787  /// return a negative number.
1788  /// @param itr The other iterator to substract. itr can be the invalid
1789  /// iterator after last element or before first element, their index
1790  /// will be regarded as last element's index + 1 and -1 respectively.
1791  /// @return The index difference.
1792  /// @sa Gis_wkb_vector_const_iterator::operator-(const self &itr) const
1793  difference_type operator-(const self &itr) const {
1794  return base::operator-(itr);
1795  }
1796  ////////////////////////////////////////////////////////////////////
1797 
1798  ////////////////////////////////////////////////////////////////////
1799  //
1800  // Begin functions that retrieve values from the iterator.
1801  //
1802  /// @name Functions that retrieve values from the iterator.
1803  //@{
1804  /// @brief Dereference operator.
1805  ///
1806  /// Return the reference to the cached data element
1807  /// The returned value can be used to read or update its referenced
1808  /// element.
1809  /// @return The reference to the element this iterator points to.
1811  assert(this->m_owner != nullptr && this->m_curidx >= 0 &&
1812  this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1813  return (*this->m_owner)[this->m_curidx];
1814  }
1815 
1816  /// @brief Arrow operator.
1817  ///
1818  /// Return the pointer to the cached data element
1819  /// The returned value can be used to read or update its referenced
1820  /// element.
1821  /// @return The address of the referenced object.
1822  pointer operator->() const {
1823  assert(this->m_owner != nullptr && this->m_curidx >= 0 &&
1824  this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1825  return &(*this->m_owner)[this->m_curidx];
1826  }
1827 
1828  /// @brief Iterator index operator.
1829  ///
1830  /// @param offset The offset of target element relative to this iterator.
1831  /// @return Return the element which is at position *this + offset.
1832  /// The returned value can be used to read or update its referenced
1833  /// element.
1834  reference operator[](difference_type offset) const {
1835  self itr = *this;
1836  this->move_by(itr, offset, false);
1837  assert(itr.m_owner != NULL && itr.m_curidx >= 0 &&
1838  itr.m_curidx < static_cast<index_type>(this->m_owner->size()));
1839  return (*this->m_owner)[itr.m_curidx];
1840  }
1841  //@} // funcs_val
1842  ////////////////////////////////////////////////////////////////////
1843 
1844 }; // Gis_wkb_vector_iterator
1845 //@} // Gis_wkb_vector_iterators
1846 ///@} // iterators
1847 
1848 // These operators make "n + itr" expressions valid. Without it, you can only
1849 // use "itr + n"
1850 template <typename T>
1853  const Gis_wkb_vector_const_iterator<T> &itr) {
1855 
1856  itr2 += n;
1857  return itr2;
1858 }
1859 
1860 template <typename T>
1863  const Gis_wkb_vector_iterator<T> &itr) {
1864  Gis_wkb_vector_iterator<T> itr2 = itr;
1865 
1866  itr2 += n;
1867  return itr2;
1868 }
1869 
1870 void *get_packed_ptr(const Geometry *geo, size_t *pnbytes);
1871 const char *get_packed_ptr(Geometry *geo);
1872 bool polygon_is_packed(Geometry *plgn, Geometry *mplgn);
1873 void own_rings(Geometry *geo);
1874 void parse_wkb_data(Geometry *geom, const char *p, size_t num_geoms = 0);
1875 
1876 /**
1877  Geometry vector class.
1878  @tparam T Vector element type.
1879  */
1880 template <typename T>
1881 class Geometry_vector : public Inplace_vector<T> {
1883 
1884  public:
1886 };
1887 
1888 /// @ingroup containers
1889 //@{
1890 ////////////////////////////////////////////////////////////////////////
1891 ////////////////////////////////////////////////////////////////////////
1892 //
1893 /// Gis_wkb_vector class template definition
1894 /// @tparam T Vector element type
1895 //
1896 template <typename T>
1897 class Gis_wkb_vector : public Geometry {
1898  private:
1899  typedef Gis_wkb_vector<T> self;
1900  typedef ptrdiff_t index_type;
1901  typedef Geometry base;
1902 
1903  public:
1904  typedef T value_type;
1907  typedef size_t size_type;
1908  typedef const T *const_pointer;
1909  typedef const T &const_reference;
1910  typedef T *pointer;
1911  typedef T &reference;
1912  typedef ptrdiff_t difference_type;
1913 
1915 
1916  private:
1917  /**
1918  The geometry vector of this geometry object's components, each of which
1919  is an object of Geometry or its children classes where appropriate.
1920  */
1922 
1923  public:
1924  /////////////////////////////////////////////////////////////////////
1925  // Begin functions that create iterators.
1926  /// @name Iterator functions.
1927  //@{
1929  set_bg_adapter(true);
1930  iterator itr(m_geo_vect ? 0 : -1, this);
1931  return itr;
1932  }
1933 
1934  /// @brief Create a const iterator.
1935  ///
1936  /// The created iterator can only be used to read its referenced
1937  /// data element. Can only be called when using a const reference to
1938  /// the contaienr object.
1940  set_bg_adapter(true);
1941  const_iterator itr(m_geo_vect ? 0 : -1, this);
1942  return itr;
1943  }
1944 
1945  /// @brief Create an open boundary iterator.
1946  /// @return Returns an invalid iterator denoting the position after
1947  /// the last valid element of the container.
1949  iterator itr(m_geo_vect ? m_geo_vect->size() : -1, this);
1950  return itr;
1951  }
1952 
1953  /// @brief Create an open boundary iterator.
1954  /// @return Returns an invalid const iterator denoting the position
1955  /// after the last valid element of the container.
1957  const_iterator itr(m_geo_vect ? m_geo_vect->size() : -1, this);
1958  return itr;
1959  }
1960 
1961  //@} // iterator_funcs
1962  /////////////////////////////////////////////////////////////////////
1963 
1964  /// @brief Get container size.
1965  /// @return Return the number of elements in this container.
1966  size_type size() const {
1967  set_bg_adapter(true);
1968  return m_geo_vect ? m_geo_vect->size() : 0;
1969  }
1970 
1971  bool empty() const { return size() == 0; }
1972 
1974  set_bg_adapter(true);
1975  /*
1976  Carefully crafted to avoid invoking any copy constructor using pointer
1977  cast. Also true for the two operator[] member functions below.
1978  */
1979  const Geometry *p = &(get_geo_vect()->back());
1980  return *((const T *)p);
1981  }
1982 
1984  set_bg_adapter(true);
1985  /*
1986  Carefully crafted to avoid invoking any copy constructor using pointer
1987  cast. Also true for the two operator[] member functions below.
1988  */
1989  Geometry *p = &(get_geo_vect()->back());
1990  return *((T *)p);
1991  }
1992 
1994  assert(!(i < 0 || i >= (index_type)size()));
1995  set_bg_adapter(true);
1996 
1997  const Geometry *p = &((*m_geo_vect)[i]);
1998  return *((const T *)p);
1999  }
2000 
2002  assert(!(i < 0 || i >= (index_type)size()));
2003  set_bg_adapter(true);
2004 
2005  Geometry *p = &((*m_geo_vect)[i]);
2006  return *((T *)p);
2007  }
2008 
2009  Gis_wkb_vector(const void *ptr, size_t nbytes, const Geometry::Flags_t &flags,
2010  gis::srid_t srid, bool is_bg_adapter = true);
2011  Gis_wkb_vector(const self &v);
2012 
2013  Gis_wkb_vector() : Geometry() { m_geo_vect = nullptr; }
2014 
2015  ~Gis_wkb_vector() override {
2016  /*
2017  See ~Geometry() for why we do try-catch like this.
2018 
2019  Note that although ~Inplace_vector() calls std::vector member functions,
2020  all of them have no-throw guarantees, so this function won't throw any
2021  exception now. We do so nonetheless for potential mis-use of exceptions
2022  in futher code.
2023  */
2024 #if !defined(NDEBUG)
2025  try {
2026 #endif
2027  if (!is_bg_adapter()) return;
2028  if (m_geo_vect != nullptr) clear_wkb_data();
2029 #if !defined(NDEBUG)
2030  } catch (...) {
2031  // Should never throw exceptions in destructor.
2032  assert(false);
2033  }
2034 #endif
2035  }
2036 
2038  delete m_geo_vect;
2039  m_geo_vect = nullptr;
2040  }
2041 
2042  self &operator=(const self &rhs);
2043 
2044  // SUPPRESS_UBSAN Wrong downcast. FIXME
2045  void shallow_push(const Geometry *g) override SUPPRESS_UBSAN;
2046 
2047  Geo_vector *get_geo_vect(bool create_if_null = false) {
2048  if (m_geo_vect == nullptr && create_if_null) m_geo_vect = new Geo_vector;
2049  return m_geo_vect;
2050  }
2051 
2052  Geo_vector *get_geo_vect() const { return m_geo_vect; }
2053 
2054  void set_geo_vect(Geo_vector *ptr) { m_geo_vect = ptr; }
2055 
2056  /*
2057  Give up ownership of m_ptr and m_geo_vect, so as not to release them when
2058  this object is destroyed, to be called when the two member is shallow
2059  assigned to another geometry object.
2060  */
2061  void donate_data() override {
2062  set_ownmem(false);
2063  set_nbytes(0);
2064  m_ptr = nullptr;
2065  m_geo_vect = nullptr;
2066  }
2067 
2068  void set_ptr(void *ptr, size_t len);
2069  void clear();
2070  size_t get_nbytes_free() const;
2071  size_t current_size() const;
2072  void push_back(const T &val);
2073  void resize(size_t sz);
2074  void reassemble();
2075  bool reverse_coordinates() override {
2076  assert(false);
2077  return true;
2078  }
2079  bool validate_coordinate_range(double, bool *, bool *, double *) override {
2080  assert(false); /* purecov: inspected */
2081  return true; /* purecov: inspected */
2082  }
2083 
2084  private:
2087 
2088 }; // Gis_wkb_vector
2089 
2090 //@} //
2091 
2092 /***************************** LineString *******************************/
2093 
2094 class Gis_line_string : public Gis_wkb_vector<Gis_point> {
2095  // Maximum number of points in LineString that can fit into String
2096  static const uint32 max_n_points =
2097  (uint32)(UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
2099 
2100  public:
2101  uint32 get_data_size() const override;
2102  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2103  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2104  String *res) override;
2105  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2106  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2107  int geom_length(double *len) const override;
2108  int is_closed(int *closed) const override;
2109  int num_points(uint32 *n_points) const override;
2110  int start_point(String *point) const override;
2111  int end_point(String *point) const override;
2112  int point_n(uint32 n, String *result) const override;
2113  uint32 feature_dimension() const override { return 1; }
2114  const Class_info *get_class_info() const override;
2115  bool reverse_coordinates() override;
2116  bool validate_coordinate_range(double srs_angular_unit,
2117  bool *long_out_of_range,
2118  bool *lat_out_of_range,
2119  double *out_of_range_value) override;
2120 
2121  /**** Boost Geometry Adapter Interface ******/
2122 
2124  typedef Gis_line_string self;
2125 
2126  explicit Gis_line_string(bool is_bg_adapter = true)
2128  is_bg_adapter) {}
2129 
2130  Gis_line_string(const void *wkb, size_t len, const Flags_t &flags,
2131  gis::srid_t srid)
2132  : base_type(wkb, len, flags, srid, true) {
2134  }
2135 
2136  Gis_line_string(const self &ls) = default;
2137 
2139 };
2140 
2141 /*
2142  We have to use such an independent class in order to meet Ring Concept of
2143  Boost Geometry --- there must be a specialization of traits::tag defining
2144  ring_tag as type.
2145  If directly use Gis_line_string, we would have defined that tag twice.
2146 */
2147 class Gis_polygon_ring : public Gis_wkb_vector<Gis_point> {
2148  public:
2150  typedef Gis_polygon_ring self;
2151 
2152  ~Gis_polygon_ring() override = default;
2153  Gis_polygon_ring(const void *wkb, size_t nbytes, const Flags_t &flags,
2154  gis::srid_t srid)
2155  : base(wkb, nbytes, flags, srid, true) {
2157  }
2158 
2159  // Coordinate data type, closed-ness and direction will never change, thus no
2160  // need for the template version of copy constructor.
2161  Gis_polygon_ring(const self &r) = default;
2162 
2164 
2167  true) {}
2168 
2169  bool set_ring_order(bool want_ccw);
2170 };
2171 
2172 /***************************** Polygon *******************************/
2173 
2174 // For internal use only, only convert types, don't create rings.
2176  assert(g->get_geotype() == Geometry::wkb_polygon);
2177  Gis_polygon_ring *out = static_cast<Gis_polygon_ring *>(g->get_ptr());
2178 
2179  return out;
2180 }
2181 
2182 class Gis_polygon : public Geometry {
2183  public:
2184  uint32 get_data_size() const override;
2185  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2186  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2187  String *res) override;
2188  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2189  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2190  int exterior_ring(String *result) const override;
2191  int num_interior_ring(uint32 *n_int_rings) const override;
2192  int interior_ring_n(uint32 num, String *result) const override;
2193  uint32 feature_dimension() const override { return 2; }
2194  const Class_info *get_class_info() const override;
2195  bool reverse_coordinates() override;
2196  bool validate_coordinate_range(double srs_angular_unit,
2197  bool *long_out_of_range,
2198  bool *lat_out_of_range,
2199  double *out_of_range_value) override;
2200 
2201  /**** Boost Geometry Adapter Interface ******/
2202  typedef Gis_polygon self;
2205 
2206  ring_type &outer() const {
2207  assert(!polygon_is_wkb_form());
2208  set_bg_adapter(true);
2209  // Create outer ring if none, although read only, calller may just want
2210  // to traverse the outer ring if any.
2211  if (this->m_ptr == nullptr) const_cast<self *>(this)->make_rings();
2212 
2213  return *(outer_ring(this));
2214  }
2215 
2217  assert(!polygon_is_wkb_form());
2218  set_bg_adapter(true);
2219  // Create inner rings if none, although read only, calller may just want
2220  // to traverse the inner rings if any.
2221  if (m_inn_rings == nullptr) const_cast<self *>(this)->make_rings();
2222 
2223  return *m_inn_rings;
2224  }
2225 
2226  /// Clears outer and inner rings.
2227  void clear() {
2228  set_bg_adapter(true);
2229  outer_ring(this)->clear();
2230  if (m_inn_rings) m_inn_rings->clear();
2231  }
2232 
2233  Gis_polygon(const void *wkb, size_t nbytes, const Flags_t &flags,
2234  gis::srid_t srid);
2235 
2236  /*
2237  We can't require boost geometry use the 'polygon' in any particular way,
2238  so we have to default to true.
2239  */
2240  explicit Gis_polygon(bool isbgadapter = true)
2242  m_inn_rings = nullptr;
2243  set_bg_adapter(isbgadapter);
2244  }
2245 
2246  Gis_polygon(const self &r);
2247  Gis_polygon &operator=(const Gis_polygon &rhs);
2248  ~Gis_polygon() override;
2249 
2250  void to_wkb_unparsed();
2251  void set_ptr(void *ptr, size_t len);
2252 
2253  /*
2254  Give up ownership of m_ptr and m_inn_rings, so as not to release them when
2255  this object is destroyed, to be called when the two member is shallow
2256  assigned to another geometry object.
2257  */
2258  void donate_data() override {
2259  set_ownmem(false);
2260  set_nbytes(0);
2261  m_ptr = nullptr;
2262  m_inn_rings = nullptr;
2263  }
2264 
2265  bool set_polygon_ring_order();
2266 
2267  // SUPPRESS_UBSAN Wrong downcast. FIXME
2269  return m_inn_rings;
2270  }
2271 
2272  // SUPPRESS_UBSAN Wrong downcast. FIXME
2274  m_inn_rings = inns;
2275  }
2276 
2277  private:
2279 
2280  void make_rings();
2281 };
2282 
2283 /***************************** MultiPoint *******************************/
2284 
2285 class Gis_multi_point : public Gis_wkb_vector<Gis_point> {
2286  // Maximum number of points in MultiPoint that can fit into String
2287  static const uint32 max_n_points =
2288  (uint32)(UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
2290 
2291  public:
2292  uint32 get_data_size() const override;
2293  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2294  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2295  String *res) override;
2296  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2297  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2298  int num_geometries(uint32 *num) const override;
2299  int geometry_n(uint32 num, String *result) const override;
2300  uint32 feature_dimension() const override { return 0; }
2301  const Class_info *get_class_info() const override;
2302  bool reverse_coordinates() override;
2303  bool validate_coordinate_range(double srs_angular_unit,
2304  bool *long_out_of_range,
2305  bool *lat_out_of_range,
2306  double *out_of_range_value) override;
2307 
2308  /**** Boost Geometry Adapter Interface ******/
2309 
2311  typedef Gis_multi_point self;
2312 
2313  explicit Gis_multi_point(bool is_bg_adapter = true)
2315  is_bg_adapter) {}
2316 
2317  Gis_multi_point(const void *ptr, size_t nbytes, const Flags_t &flags,
2318  gis::srid_t srid)
2319  : base_type(ptr, nbytes, flags, srid, true) {
2321  }
2322 
2323  Gis_multi_point(const self &mpts) = default;
2324 };
2325 
2326 /***************************** MultiLineString *******************************/
2327 
2328 class Gis_multi_line_string : public Gis_wkb_vector<Gis_line_string> {
2329  public:
2330  uint32 get_data_size() const override;
2331  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2332  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2333  String *res) override;
2334  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2335  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2336  int num_geometries(uint32 *num) const override;
2337  int geometry_n(uint32 num, String *result) const override;
2338  int geom_length(double *len) const override;
2339  int is_closed(int *closed) const override;
2340  uint32 feature_dimension() const override { return 1; }
2341  const Class_info *get_class_info() const override;
2342  bool reverse_coordinates() override;
2343  bool validate_coordinate_range(double srs_angular_unit,
2344  bool *long_out_of_range,
2345  bool *lat_out_of_range,
2346  double *out_of_range_value) override;
2347 
2348  /**** Boost Geometry Adapter Interface ******/
2349 
2352 
2353  explicit Gis_multi_line_string(bool is_bg_adapter = true)
2355  is_bg_adapter) {}
2356 
2357  Gis_multi_line_string(const void *ptr, size_t nbytes, const Flags_t &,
2358  gis::srid_t srid)
2359  : base(ptr, nbytes, Flags_t(wkb_multilinestring, nbytes), srid, true) {
2361  }
2362 
2363  Gis_multi_line_string(const self &mls) = default;
2364 };
2365 
2366 /***************************** MultiPolygon *******************************/
2367 
2368 class Gis_multi_polygon : public Gis_wkb_vector<Gis_polygon> {
2369  public:
2370  uint32 get_data_size() const override;
2371  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2372  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2373  String *res) override;
2374  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2375  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2376  int num_geometries(uint32 *num) const override;
2377  int geometry_n(uint32 num, String *result) const override;
2378  uint32 feature_dimension() const override { return 2; }
2379  const Class_info *get_class_info() const override;
2380  bool reverse_coordinates() override;
2381  bool validate_coordinate_range(double srs_angular_unit,
2382  bool *long_out_of_range,
2383  bool *lat_out_of_range,
2384  double *out_of_range_value) override;
2385 
2386  /**** Boost Geometry Adapter Interface ******/
2387  typedef Gis_multi_polygon self;
2389 
2390  explicit Gis_multi_polygon(bool is_bg_adapter = true)
2392  is_bg_adapter) {}
2393 
2394  Gis_multi_polygon(const void *ptr, size_t nbytes, const Flags_t &flags,
2395  gis::srid_t srid)
2396  : base(ptr, nbytes, flags, srid, true) {
2398  }
2399 
2400  Gis_multi_polygon(const self &mpl) = default;
2401 };
2402 
2403 /*********************** GeometryCollection *******************************/
2405  private:
2408 
2409  public:
2412  set_bg_adapter(false);
2413  }
2414  Gis_geometry_collection(Geometry *geo, String *gcbuf);
2415  Gis_geometry_collection(gis::srid_t srid, wkbType gtype, const String *gbuf,
2416  String *gcbuf);
2417  bool append_geometry(const Geometry *geo, String *gcbuf);
2418  bool append_geometry(gis::srid_t srid, wkbType gtype, const String *gbuf,
2419  String *gcbuf);
2420  uint32 get_data_size() const override;
2421  bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2422  uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2423  String *res) override;
2424  bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2425  bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2426  int num_geometries(uint32 *num) const override;
2427  int geometry_n(uint32 num, String *result) const override;
2428  bool dimension(uint32 *dim, wkb_parser *wkb) const override;
2429  uint32 feature_dimension() const override {
2430  assert(0);
2431  return 0;
2432  }
2433  bool reverse_coordinates() override;
2434  bool validate_coordinate_range(double srs_angular_unit,
2435  bool *long_out_of_range,
2436  bool *lat_out_of_range,
2437  double *out_of_range_value) override;
2438  const Class_info *get_class_info() const override;
2439 };
2440 
2441 /**
2442  Gis_polygon objects and Gis_wkb_vector<> objects are of same size, and
2443  Gis_point and Geometry objects are smaller. They are always allocated
2444  inside a Geometry_buffer object, unless used as boost geometry adapter,
2445  in which case the object may simply placed on stack or new'ed on heap.
2446  */
2448  alignas(Gis_polygon) char data[sizeof(Gis_polygon)];
2449 };
2450 
2452  public:
2453  virtual ~WKB_scanner_event_handler() = default;
2454 
2455  /**
2456  Notified when scanner sees the start of a geometry WKB.
2457  @param bo byte order of the WKB.
2458  @param geotype geometry type of the WKB;
2459  @param wkb WKB byte string, the first byte after the WKB header if any.
2460  @param len NO. of bytes of the WKB byte string starting from wkb.
2461  There can be many geometries in the [wkb, wkb+len) buffer.
2462  @param has_hdr whether there is a WKB header right before 'wkb' in the
2463  byte string.
2464  */
2466  Geometry::wkbType geotype, const void *wkb,
2467  uint32 len, bool has_hdr) = 0;
2468 
2469  /**
2470  Notified when scanner sees the end of a geometry WKB.
2471  @param wkb the position of the first byte after the WKB byte string which
2472  the scanner just scanned.
2473  */
2474  virtual void on_wkb_end(const void *wkb) = 0;
2475 
2476  /*
2477  Called after each on_wkb_start/end call, if returns false, wkb_scanner
2478  will stop scanning.
2479  */
2480  virtual bool continue_scan() const { return true; }
2481 };
2482 
2483 const char *wkb_scanner(THD *thd, const char *wkb, uint32 *len, uint32 geotype,
2484  bool has_hdr, WKB_scanner_event_handler *handler);
2485 #endif
static mysql_service_status_t init()
Component initialization.
Definition: audit_api_message_emit.cc:570
Definition: spatial.h:461
Class_info(const char *name, int type_id, create_geom_t create_func)
Definition: spatial.cc:237
const LEX_CSTRING m_name
Definition: spatial.h:463
int m_type_id
Definition: spatial.h:464
create_geom_t m_create_func
Definition: spatial.h:465
Highest byte is stores byte order, dimension, nomem and geotype as follows: bo: byte order,...
Definition: spatial.h:731
uint64 nomem
Definition: spatial.h:751
uint64 zm
Definition: spatial.h:755
uint64 dim
Definition: spatial.h:750
uint64 bo
Definition: spatial.h:749
uint64 nbytes
Definition: spatial.h:753
uint64 props
Definition: spatial.h:754
uint64 unused
Definition: spatial.h:756
Flags_t(wkbType type, size_t len)
Definition: spatial.h:740
Flags_t()
Definition: spatial.h:733
uint64 geotype
Definition: spatial.h:752
Constant storage for WKB.
Definition: spatial.h:332
const char * m_data_end
Definition: spatial.h:335
uint32 length() const
Definition: spatial.h:348
wkb_container(const char *data, const char *data_end)
Definition: spatial.h:339
bool no_data(size_t data_amount) const
Check if there's enough data remaining as requested.
Definition: spatial.h:356
void set(const char *data, const char *data_end)
Definition: spatial.h:342
const char * data() const
Definition: spatial.h:346
const char * m_data
Definition: spatial.h:334
const char * data_end() const
Definition: spatial.h:347
bool not_enough_points(uint32 expected_points, uint32 extra_point_space=0) const
Check if there're enough points remaining as requested.
Definition: spatial.h:371
WKB parser, designed to traverse through WKB data from beginning of the buffer towards the end using ...
Definition: spatial.h:385
bool scan_wkb_header(wkb_header *header)
Definition: spatial.h:412
bool scan_non_zero_uint4(uint32 *number)
Definition: spatial.h:428
bool skip(size_t nbytes)
Definition: spatial.h:403
bool scan_n_points_and_check_data(uint32 *n_points, uint32 extra_point_space=0)
Definition: spatial.h:431
bool skip_coord()
Definition: spatial.h:409
wkb_parser(const char *data, const char *data_end)
Definition: spatial.h:395
void get_float8(double *x)
Definition: spatial.h:390
void scan_xy_unsafe(point_xy *p)
Definition: spatial.h:438
bool skip_wkb_header()
Definition: spatial.h:408
bool scan_xy(point_xy *p)
Definition: spatial.h:445
void skip_unsafe(size_t nbytes)
Definition: spatial.h:399
bool scan_coord(double *x)
Definition: spatial.h:450
bool scan_uint4(uint32 *number)
Definition: spatial.h:422
void get_uint4(uint32 *number)
Definition: spatial.h:387
Geometry vector class.
Definition: spatial.h:1881
Inplace_vector< T > base
Definition: spatial.h:1882
Geometry_vector()
Definition: spatial.h:1885
Definition: spatial.h:214
virtual int point_n(uint32 num[[maybe_unused]], String *result[[maybe_unused]]) const
Definition: spatial.h:535
static Geometry * create_from_wkb(THD *thd, Geometry_buffer *buffer, const char *wkb, uint32 len, String *res, bool init)
Read from 'wkb' (which contains WKB encoded in either endianess) the geometry data,...
Definition: spatial.cc:943
enum_coordinate_reference_system get_coordsys() const
Definition: spatial.h:515
void set_byte_order(Geometry::wkbByteOrder bo)
Definition: spatial.h:802
static String bad_geometry_data
Definition: spatial.h:323
bool polygon_is_wkb_form() const
In a polygon usable by boost geometry, the m_ptr points to the outer ring object, and m_inn_rings poi...
Definition: spatial.h:997
void set_ownmem(bool b)
Set whether this object has its own memory.
Definition: spatial.h:906
virtual uint32 get_data_size() const
Definition: spatial.h:471
Geometry(const void *ptr, size_t len, const Flags_t &flags, gis::srid_t srid)
Constructor used as BG adapter or by default constructors of children classes.
Definition: spatial.h:777
Geometry & operator=(const Geometry &rhs)
Assignment operator for Geometry class, assignment operators of children classes calls this to do gen...
Definition: spatial.cc:1229
enum_coordinate_reference_system
Definition: spatial.h:317
@ coord_first
Definition: spatial.h:318
@ coord_last
Definition: spatial.h:320
@ cartesian
Definition: spatial.h:319
bool as_wkt(String *wkt, wkb_parser *wkb) const
Definition: spatial.h:598
uchar * get_ucptr() const
Definition: spatial.h:796
void * m_ptr
Pointer to the geometry's wkb data's 1st byte, right after its wkb header if any.
Definition: spatial.h:1045
static Class_info * ci_collection[wkb_last+1]
Definition: spatial.h:630
virtual int end_point(String *point[[maybe_unused]]) const
Definition: spatial.h:533
virtual void shallow_push(const Geometry *)
Definition: spatial.h:1026
bool is_components_no_overlapped() const
Definition: spatial.h:656
static bool is_valid_geotype(uint32 gtype)
Check if a given geometry type is a valid internal geometry type.
Definition: spatial.h:839
virtual int interior_ring_n(uint32 num[[maybe_unused]], String *result[[maybe_unused]]) const
Definition: spatial.h:539
static Geometry * create_by_typeid(Geometry_buffer *buffer, int type_id)
Definition: spatial.cc:334
bool get_mbr_for_points(MBR *mbr, wkb_parser *wkb, uint offset) const
Get most bounding rectangle (mbr) for X points.
Definition: spatial.cc:1147
void * get_data_ptr() const
Definition: spatial.h:625
wkbByteOrder
Definition: spatial.h:312
@ wkb_invalid
Definition: spatial.h:315
@ wkb_ndr
Definition: spatial.h:314
@ wkb_xdr
Definition: spatial.h:313
bool as_geometry(String *wkb, bool shallow_copy) const
Write this geometry's GEOMETRY byte string into specified buffer, the SRID will be written before the...
Definition: spatial.cc:523
virtual int num_interior_ring(uint32 *n_int_rings[[maybe_unused]]) const
Definition: spatial.h:525
bool has_out_of_line_components() const
If call Gis_wkb_vector<T>::resize() to add a component to X, the geometry may have a geometry not sto...
Definition: spatial.h:1014
void clear_wkb_data()
Geometry()
Definition: spatial.h:761
virtual uint32 feature_dimension() const
Definition: spatial.h:516
void has_out_of_line_components(bool b)
Definition: spatial.h:1018
virtual const Class_info * get_class_info() const
Definition: spatial.h:469
virtual int geom_length(double *len[[maybe_unused]]) const
Definition: spatial.h:523
bool create_point(String *result, wkb_parser *wkb) const
Create a point from data.
Definition: spatial.cc:1076
char get_dimension() const
Definition: spatial.h:919
virtual int exterior_ring(String *ring[[maybe_unused]]) const
Definition: spatial.h:534
static const uint32 MAX_GEOM_WKB_LENGTH
Definition: spatial.h:274
Geometry *(* create_geom_t)(char *)
Callback which creates Geometry objects on top of a given placement.
Definition: spatial.h:459
static const int MULTIPOLYGON_NO_OVERLAPPED_COMPS
Definition: spatial.h:270
static bool is_valid_geotype(Geometry::wkbType gt)
Check if a given geometry type is a valid internal geometry type.
Definition: spatial.h:859
friend void parse_wkb_data(Geometry *geom, const char *p, size_t num_geoms)
Parse the wkb buffer to build the component vector m_geo_vect for geom.
Definition: spatial.cc:3861
gis::srid_t m_srid
Srid of this object.
Definition: spatial.h:1053
static bool is_valid_opengis_geotype(uint32 gtype)
Check if a given geometry type is a valid geometry type according to OpenGIS.
Definition: spatial.h:824
static Geometry * create_from_wkt(Geometry_buffer *buffer, Gis_read_stream *trs, String *wkt, bool init_stream=true, bool check_trailing=true)
Read wkt text from trs, and write little endian wkb encoding into 'wkt', and create a Geometry instan...
Definition: spatial.cc:436
uint16 get_props() const
Definition: spatial.h:675
void set_flags(const Flags_t &flags)
Definition: spatial.h:1058
virtual int geometry_n(uint32 num[[maybe_unused]], String *result[[maybe_unused]]) const
Definition: spatial.h:543
bool as_wkt(String *wkt) const
Definition: spatial.h:608
static const int GEOM_LENGTH_VERIFIED
Definition: spatial.h:238
virtual bool get_mbr(MBR *mbr[[maybe_unused]], wkb_parser *wkb[[maybe_unused]]) const
Definition: spatial.h:493
Geometry * get_owner() const
Definition: spatial.h:798
static const int POLYGON_INNER_RING
Definition: spatial.h:224
void set_length_verified(bool b) const
Definition: spatial.h:700
virtual uint init_from_wkb(THD *thd[[maybe_unused]], const char *wkb[[maybe_unused]], uint len[[maybe_unused]], wkbByteOrder bo[[maybe_unused]], String *res[[maybe_unused]])
Definition: spatial.h:481
virtual bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value)=0
Check that the coordinates of a geometry is within the valid range.
static Class_info * find_class(int type_id)
Definition: spatial.h:684
void set_owner(Geometry *o)
Definition: spatial.h:800
Geometry * m_owner
The topmost (root) geometry object, whose m_ptr is the 1st byte of a wkb memory buffer.
Definition: spatial.h:1035
wkbType
Definition: spatial.h:291
@ wkb_multipolygon
Definition: spatial.h:299
@ wkb_multilinestring
Definition: spatial.h:298
@ wkb_point
Definition: spatial.h:294
@ wkb_polygon
Definition: spatial.h:296
@ wkb_invalid_type
Definition: spatial.h:292
@ wkb_geometrycollection
Definition: spatial.h:300
@ wkb_last
Definition: spatial.h:310
@ wkb_linestring
Definition: spatial.h:295
@ wkb_multipoint
Definition: spatial.h:297
@ wkb_polygon_inner_rings
Definition: spatial.h:309
@ wkb_first
Definition: spatial.h:293
bool envelope(String *result) const
Definition: spatial.cc:998
bool has_geom_header_space() const
Definition: spatial.h:644
virtual int copy_points(String *result[[maybe_unused]]) const
Definition: spatial.h:530
bool dimension(uint32 *dim) const
Definition: spatial.h:508
static const int HAS_GEOM_HEADER_SPACE
Definition: spatial.h:261
bool is_polygon_ring() const
Definition: spatial.h:632
bool is_polygon_inner_ring() const
Definition: spatial.h:640
void set_srid(gis::srid_t id)
Definition: spatial.h:677
virtual int num_geometries(uint32 *num[[maybe_unused]]) const
Definition: spatial.h:529
void set_ptr(const void *ptr)
Definition: spatial.h:949
Flags_t get_flags() const
Definition: spatial.h:1056
bool get_mbr(MBR *mbr)
Definition: spatial.h:497
void set_props(uint16 flag)
Definition: spatial.h:670
static Geometry * construct(Geometry_buffer *buffer, const String *str, bool has_srid=true)
Definition: spatial.h:586
void set_dimension(char dim)
Definition: spatial.h:807
virtual bool reverse_coordinates()=0
Reverses the coordinates of a geometry.
uint32 get_ogc_geotype() const
Build an OGC standard type value from m_flags.zm and m_flags.geotype.
Definition: spatial.h:941
wkbType get_type() const
Definition: spatial.h:512
void polygon_is_wkb_form(bool b)
Definition: spatial.h:1001
virtual int get_x(double *x[[maybe_unused]]) const
Definition: spatial.h:521
static const int POLYGON_OUTER_RING
Definition: spatial.h:223
gis::srid_t get_srid() const
Definition: spatial.h:679
virtual int is_closed(int *closed[[maybe_unused]]) const
Definition: spatial.h:524
bool get_ownmem() const
Returns whether this object has its own memory.
Definition: spatial.h:912
void set_bg_adapter(bool b) const
Set whether this object is a BG adapter.
Definition: spatial.h:967
virtual int start_point(String *point[[maybe_unused]]) const
Definition: spatial.h:532
Geometry::wkbByteOrder get_byte_order() const
Definition: spatial.h:914
Flags_t m_flags
Flags and meta information about this object.
Definition: spatial.h:1050
void * get_ptr() const
Definition: spatial.h:792
char * get_cptr() const
Definition: spatial.h:794
void has_geom_header_space(bool b)
Definition: spatial.h:649
bool is_polygon_outer_ring() const
Definition: spatial.h:636
static const int HAS_OUT_OF_LINE_COMPONENTS
Definition: spatial.h:244
virtual ~Geometry()
Definition: spatial.cc:1180
void append_points(String *txt, uint32 n_points, wkb_parser *wkb, uint32 offset, bool bracket_pt=false) const
Append N points from packed format to text Before calling this function, caller must have already che...
Definition: spatial.cc:1119
void set_geotype(Geometry::wkbType gt)
Definition: spatial.h:887
bool is_bg_adapter() const
Whether the Geometry object is created to be used by Boost Geometry or only by MySQL.
Definition: spatial.h:957
const void * normalize_ring_order()
In place normalize polygons' rings, making outer ring CCW and inner rings CW by reversing the ring's ...
Definition: spatial.cc:4135
void set_data_ptr(const wkb_container *c)
Definition: spatial.h:621
Geometry::wkbType get_geotype() const
Definition: spatial.h:921
void set_components_no_overlapped(bool b)
Definition: spatial.h:660
virtual void donate_data()
Definition: spatial.h:979
static bool is_well_formed(const char *from, size_t length, wkbType type, wkbByteOrder bo)
Verify that a string is a well-formed GEOMETRY string.
Definition: spatial.cc:755
virtual int get_y(double *y[[maybe_unused]]) const
Definition: spatial.h:522
virtual int num_points(uint32 *n_points[[maybe_unused]]) const
Definition: spatial.h:528
virtual bool dimension(uint32 *dim, wkb_parser *wkb) const
Definition: spatial.h:501
void set_nbytes(size_t n) const
Definition: spatial.h:893
bool as_wkb(String *wkb, bool shallow_copy) const
Write this geometry's WKB byte string into specified buffer, the SRID is not written into the buffer.
Definition: spatial.cc:475
void set_data_ptr(const void *data, size_t data_len)
Definition: spatial.h:616
virtual bool get_data_as_wkt(String *txt[[maybe_unused]], wkb_parser *wkb[[maybe_unused]]) const
Definition: spatial.h:489
static const int POLYGON_IN_WKB_FORM
Definition: spatial.h:251
virtual bool init_from_wkt(Gis_read_stream *trs[[maybe_unused]], String *wkb[[maybe_unused]])
Definition: spatial.h:474
static Geometry * construct(Geometry_buffer *buffer, const char *data, uint32 data_len, bool has_srid=true)
Construct a Geometry object using GEOMETRY byte string.
Definition: spatial.cc:361
bool is_length_verified() const
Definition: spatial.h:695
size_t get_nbytes() const
Definition: spatial.h:943
static const int IS_BOOST_GEOMETRY_ADAPTER
Definition: spatial.h:232
static const gis::srid_t default_srid
Definition: spatial.h:276
Definition: spatial.h:2404
const Class_info * get_class_info() const override
Definition: spatial.cc:3637
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:3565
static Geometry * scan_header_and_create(wkb_parser *wkb, Geometry_buffer *buffer)
Create a Geometry object from WKB.
Definition: spatial.cc:3101
int num_geometries(uint32 *num) const override
Definition: spatial.cc:3491
bool dimension(uint32 *dim, wkb_parser *wkb) const override
Definition: spatial.cc:3546
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:3436
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:3461
Gis_geometry_collection()
Definition: spatial.h:2410
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:3604
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.cc:3350
bool append_geometry(const Geometry *geo, String *gcbuf)
Append geometry into geometry collection which can be empty.
Definition: spatial.cc:3136
int geometry_n(uint32 num, String *result) const override
Definition: spatial.cc:3498
uint32 get_data_size() const override
Definition: spatial.cc:3303
uint32 feature_dimension() const override
Definition: spatial.h:2429
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:3393
Definition: spatial.h:2094
Gis_line_string(const void *wkb, size_t len, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2130
int point_n(uint32 n, String *result) const override
Definition: spatial.cc:1633
Gis_wkb_vector< Gis_point > base_type
Definition: spatial.h:2123
int is_closed(int *closed) const override
Definition: spatial.cc:1589
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:1566
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:1514
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.cc:1472
Gis_line_string(const self &ls)=default
static const uint32 max_n_points
Definition: spatial.h:2096
uint32 feature_dimension() const override
Definition: spatial.h:2113
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:1545
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:1662
int num_points(uint32 *n_points) const override
Definition: spatial.cc:1613
Gis_line_string(bool is_bg_adapter=true)
Definition: spatial.h:2126
uint32 get_data_size() const override
Definition: spatial.cc:1450
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:1642
int end_point(String *point) const override
Definition: spatial.cc:1625
Gis_line_string & operator=(const Gis_line_string &)=default
int geom_length(double *len) const override
Definition: spatial.cc:1570
const Class_info * get_class_info() const override
Definition: spatial.cc:1689
int start_point(String *point) const override
Definition: spatial.cc:1618
Definition: spatial.h:2328
int geom_length(double *len) const override
Definition: spatial.cc:2718
int geometry_n(uint32 num, String *result) const override
Definition: spatial.cc:2699
uint32 feature_dimension() const override
Definition: spatial.h:2340
const Class_info * get_class_info() const override
Definition: spatial.cc:2828
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:2683
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.cc:2594
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:2621
Gis_multi_line_string(const self &mls)=default
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:2795
Gis_multi_line_string(const void *ptr, size_t nbytes, const Flags_t &, gis::srid_t srid)
Definition: spatial.h:2357
uint32 get_data_size() const override
Definition: spatial.cc:2568
int is_closed(int *closed) const override
Definition: spatial.cc:2741
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:2659
Gis_multi_line_string(bool is_bg_adapter=true)
Definition: spatial.h:2353
int num_geometries(uint32 *num) const override
Definition: spatial.cc:2694
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:2758
Gis_wkb_vector< Gis_line_string > base
Definition: spatial.h:2350
Definition: spatial.h:2285
int num_geometries(uint32 *num) const override
Definition: spatial.cc:2486
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:2482
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:2464
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.cc:2394
Gis_multi_point(bool is_bg_adapter=true)
Definition: spatial.h:2313
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:2504
static const uint32 max_n_points
Definition: spatial.h:2287
uint32 get_data_size() const override
Definition: spatial.cc:2376
Gis_wkb_vector< Gis_point > base_type
Definition: spatial.h:2310
uint32 feature_dimension() const override
Definition: spatial.h:2300
const Class_info * get_class_info() const override
Definition: spatial.cc:2563
Gis_multi_point(const self &mpts)=default
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:2530
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:2437
int geometry_n(uint32 num, String *result) const override
Definition: spatial.cc:2491
Gis_multi_point(const void *ptr, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2317
Definition: spatial.h:2368
Gis_multi_polygon(const void *ptr, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2394
int num_geometries(uint32 *num) const override
Definition: spatial.cc:2976
uint32 get_data_size() const override
Definition: spatial.cc:2833
Gis_wkb_vector< Gis_polygon > base
Definition: spatial.h:2388
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:2927
uint32 feature_dimension() const override
Definition: spatial.h:2378
Gis_multi_polygon(const self &mpl)=default
int geometry_n(uint32 num, String *result) const override
Definition: spatial.cc:2981
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:2959
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:3010
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.cc:2864
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:3048
const Class_info * get_class_info() const override
Definition: spatial.cc:3082
Gis_multi_polygon(bool is_bg_adapter=true)
Definition: spatial.h:2390
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:2890
Definition: spatial.h:1147
int get_y(double *y) const override
Definition: spatial.h:1177
Gis_point(bool is_bg_adapter=true)
Definition: spatial.h:1194
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:1392
Gis_point & operator=(const Gis_point &rhs)
Deep assignment from point 'p' to this object.
Definition: spatial.cc:1281
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:1380
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:1427
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:1405
Gis_point(const void *ptr, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Default constructor, no initialization.
Definition: spatial.h:1201
bool operator<(const Gis_point &pt) const
Definition: spatial.h:1270
bool init_from_wkt(Gis_read_stream *trs, String *wkb, const bool parens)
Initialize from a partial WKT string (everything following "POINT").
Definition: spatial.cc:1356
const Class_info * get_class_info() const override
Definition: spatial.cc:1445
~Gis_point() override=default
int get_x(double *x) const override
Definition: spatial.h:1173
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:1413
int get_xy(point_xy *p) const
Definition: spatial.h:1169
bool operator!=(const Gis_point &pt) const
Definition: spatial.h:1279
double get() const
Get a coordinate.
Definition: spatial.h:1224
uint32 feature_dimension() const override
Definition: spatial.h:1181
Geometry base
Definition: spatial.h:1192
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.h:1161
void set_ptr(void *ptr, size_t len)
Shallow assignment, let this point object refer to the specified memory address as its WKB data,...
Definition: spatial.cc:1334
uint32 get_data_size() const override
Definition: spatial.cc:1348
bool operator==(const Gis_point &pt) const
Definition: spatial.h:1275
void set(double const &value)
Set a coordinate.
Definition: spatial.h:1249
Definition: spatial.h:2147
Gis_polygon_ring(const self &r)=default
Gis_polygon_ring & operator=(const Gis_polygon_ring &)=default
bool set_ring_order(bool want_ccw)
Set the specified ring to counter-clockwise(CCW) or clockwise(CW) if it's not.
Definition: spatial.cc:1868
Gis_wkb_vector< Gis_point > base
Definition: spatial.h:2149
~Gis_polygon_ring() override=default
Gis_polygon_ring()
Definition: spatial.h:2165
Gis_polygon_ring(const void *wkb, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2153
Definition: spatial.h:2182
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:2085
bool validate_coordinate_range(double srs_angular_unit, bool *long_out_of_range, bool *lat_out_of_range, double *out_of_range_value) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.cc:2229
const Class_info * get_class_info() const override
Definition: spatial.cc:2265
int interior_ring_n(uint32 num, String *result) const override
Definition: spatial.cc:2174
uint32 feature_dimension() const override
Definition: spatial.h:2193
inner_container_type * m_inn_rings
Definition: spatial.h:2278
int num_interior_ring(uint32 *n_int_rings) const override
Definition: spatial.cc:2167
bool get_mbr(MBR *mbr, wkb_parser *wkb) const override
Definition: spatial.cc:2139
inner_container_type * inner_rings() const SUPPRESS_UBSAN
Definition: spatial.h:2268
void set_inner_rings(inner_container_type *inns) SUPPRESS_UBSAN
Definition: spatial.h:2273
void clear()
Clears outer and inner rings.
Definition: spatial.h:2227
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:2118
inner_container_type & inners() const
Definition: spatial.h:2216
void set_ptr(void *ptr, size_t len)
Set WKB data to this object, the WKB data will be used read only.
Definition: spatial.cc:1816
Gis_polygon_ring ring_type
Definition: spatial.h:2203
void to_wkb_unparsed()
Make the polygon's data in a single buffer as WKB format.
Definition: spatial.cc:1843
void donate_data() override
Definition: spatial.h:2258
Gis_polygon(bool isbgadapter=true)
Definition: spatial.h:2240
Gis_polygon & operator=(const Gis_polygon &rhs)
Deep assignment from polygon 'o' to this object.
Definition: spatial.cc:1782
int exterior_ring(String *result) const override
Definition: spatial.cc:2150
uint32 get_data_size() const override
Definition: spatial.cc:2029
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.cc:2058
ring_type & outer() const
Definition: spatial.h:2206
void make_rings()
Make outer ring and inner rings objects for this polygon if it doesn't have one yet.
Definition: spatial.cc:2012
~Gis_polygon() override
Definition: spatial.cc:1747
Gis_wkb_vector< ring_type > inner_container_type
Definition: spatial.h:2204
Gis_polygon(const void *wkb, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.cc:1731
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:2199
bool set_polygon_ring_order()
Set this polygon's outer ring to be CCW and inner rings to be CW.
Definition: spatial.cc:1988
Definition: gstream.h:35
Gis_wkb_vector_const_iterator is const_iterator class for Gis_wkb_vector, and base class of Gis_wkb_v...
Definition: spatial.h:1311
bool operator>=(const self &itr) const
Greater equal comparison operator.
Definition: spatial.h:1409
bool operator==(const self &itr) const
Equality comparison operator.
Definition: spatial.h:1382
void move_by(self &itr, difference_type n, bool back) const
Definition: spatial.h:1605
const self & operator+=(difference_type n)
Move this iterator forward by n elements.
Definition: spatial.h:1510
Gis_wkb_vector< T > owner_t
Definition: spatial.h:1314
value_type & reference
This is the return type for operator[].
Definition: spatial.h:1328
owner_t::size_type size_type
Definition: spatial.h:1325
self operator+(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1500
self & operator--()
Pre-decrement.
Definition: spatial.h:1464
Gis_wkb_vector_const_iterator(index_type idx, const owner_t *owner)
Definition: spatial.h:1352
std::random_access_iterator_tag iterator_category
Definition: spatial.h:1332
ptrdiff_t index_type
Definition: spatial.h:1315
bool operator>(const self &itr) const
Greater comparison operator.
Definition: spatial.h:1415
index_type m_curidx
Current element's index, starting from 0.
Definition: spatial.h:1621
self operator++(int)
Post-increment.
Definition: spatial.h:1451
owner_t * m_owner
The owner container of this iteraotr.
Definition: spatial.h:1623
difference_type operator-(const self &itr) const
Iterator distance operator.
Definition: spatial.h:1548
self operator--(int)
Post-decrement.
Definition: spatial.h:1476
Gis_wkb_vector_const_iterator()
Definition: spatial.h:1347
const self & operator=(const self &itr)
Assignment operator.
Definition: spatial.h:1488
const self & operator-=(difference_type n)
Move this iterator backward by n elements.
Definition: spatial.h:1533
self & operator++()
Pre-increment.
Definition: spatial.h:1440
difference_type distance_type
Definition: spatial.h:1324
T value_type
Definition: spatial.h:1322
bool operator<=(const self &itr) const
Less equal comparison operator.
Definition: spatial.h:1404
pointer operator->() const
Arrow operator.
Definition: spatial.h:1577
ptrdiff_t difference_type
Definition: spatial.h:1323
reference operator*() const
Dereference operator.
Definition: spatial.h:1565
bool operator<(const self &itr) const
Less than comparison operator.
Definition: spatial.h:1396
reference operator[](difference_type offset) const
Iterator index operator.
Definition: spatial.h:1590
self operator-(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1522
value_type * pointer
Definition: spatial.h:1329
bool operator!=(const self &itr) const
Unequal compare, identical to !operator(==itr)
Definition: spatial.h:1390
Gis_wkb_vector_const_iterator(const self &vi)
Definition: spatial.h:1342
This class is the iterator class for Gis_wkb_vector, its instances can be used to mutate their refere...
Definition: spatial.h:1635
difference_type distance_type
Definition: spatial.h:1645
Gis_wkb_vector_iterator(const base &obj)
Definition: spatial.h:1663
Gis_wkb_vector_iterator(index_type idx, const owner_t *owner)
Definition: spatial.h:1665
ptrdiff_t index_type
Definition: spatial.h:1642
self operator-(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1765
value_type & reference
Definition: spatial.h:1646
Gis_wkb_vector_iterator(const self &vi)
Definition: spatial.h:1659
value_type * pointer
Definition: spatial.h:1647
std::random_access_iterator_tag iterator_category
Definition: spatial.h:1649
const self & operator=(const self &itr)
Assignment operator.
Definition: spatial.h:1727
reference operator*() const
Dereference operator.
Definition: spatial.h:1810
const self & operator+=(difference_type n)
Move this iterator backward by n elements.
Definition: spatial.h:1752
pointer operator->() const
Arrow operator.
Definition: spatial.h:1822
self operator++(int)
Post-increment.
Definition: spatial.h:1697
self & operator--()
Pre-decrement.
Definition: spatial.h:1707
Gis_wkb_vector_const_iterator< T > base
Definition: spatial.h:1638
Gis_wkb_vector< T > owner_t
Definition: spatial.h:1639
Gis_wkb_vector_iterator()
Definition: spatial.h:1661
self operator+(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1741
ptrdiff_t difference_type
Definition: spatial.h:1644
reference operator[](difference_type offset) const
Iterator index operator.
Definition: spatial.h:1834
self operator--(int)
Post-decrement.
Definition: spatial.h:1715
difference_type operator-(const self &itr) const
Iterator distance operator.
Definition: spatial.h:1793
const self & operator-=(difference_type n)
Move this iterator forward by n elements.
Definition: spatial.h:1777
~Gis_wkb_vector_iterator()=default
self & operator++()
Pre-increment.
Definition: spatial.h:1689
T value_type
Definition: spatial.h:1643
Gis_wkb_vector class template definition.
Definition: spatial.h:1897
const_iterator end() const
Create an open boundary iterator.
Definition: spatial.h:1956
size_t size_type
Definition: spatial.h:1907
iterator end()
Create an open boundary iterator.
Definition: spatial.h:1948
const_reference back() const
Definition: spatial.h:1973
void set_geo_vect(Geo_vector *ptr)
Definition: spatial.h:2054
iterator begin()
Definition: spatial.h:1928
T value_type
Definition: spatial.h:1904
const_iterator begin() const
Create a const iterator.
Definition: spatial.h:1939
Geo_vector * get_geo_vect() const
Definition: spatial.h:2052
ptrdiff_t index_type
Definition: spatial.h:1900
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.h:2075
const_reference operator[](index_type i) const
Definition: spatial.h:1993
void reassemble()
Because of resize, a geometry's components may reside not in one chunk, some may in the m_ptr's chunk...
Definition: spatial.cc:4206
const T * const_pointer
Definition: spatial.h:1908
void shallow_push(const Geometry *g) override SUPPRESS_UBSAN
The copy constructors of Geometry classes always do deep copy, but when pushing a Geometry object int...
Definition: spatial.cc:4569
ptrdiff_t difference_type
Definition: spatial.h:1912
size_t get_nbytes_free() const
Get number of free bytes in the buffer held by m_ptr.
Definition: spatial.cc:4676
Gis_wkb_vector< Gis_point > Linestring
Definition: spatial.h:2085
size_t current_size() const
Returns payload number of bytes of the topmost geometry holding this geometry, i.e.
Definition: spatial.cc:4663
void donate_data() override
Definition: spatial.h:2061
void clear()
Update support We suppose updating a geometry can happen in the following ways:
Definition: spatial.cc:4638
reference back()
Definition: spatial.h:1983
Geo_vector * get_geo_vect(bool create_if_null=false)
Definition: spatial.h:2047
bool validate_coordinate_range(double, bool *, bool *, double *) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.h:2079
void clear_wkb_data()
Definition: spatial.h:2037
Gis_wkb_vector_iterator< T > iterator
Definition: spatial.h:1906
const T & const_reference
Definition: spatial.h:1909
self & operator=(const self &rhs)
Deep assignment from vector 'rhs' to this object.
Definition: spatial.cc:4492
Gis_wkb_vector_const_iterator< T > const_iterator
Definition: spatial.h:1905
Geo_vector * m_geo_vect
The geometry vector of this geometry object's components, each of which is an object of Geometry or i...
Definition: spatial.h:1921
size_type size() const
Get container size.
Definition: spatial.h:1966
T * pointer
Definition: spatial.h:1910
~Gis_wkb_vector() override
Definition: spatial.h:2015
void resize(size_t sz)
Definition: spatial.cc:4838
Geometry base
Definition: spatial.h:1901
bool empty() const
Definition: spatial.h:1971
reference operator[](index_type i)
Definition: spatial.h:2001
void set_ptr(void *ptr, size_t len)
Definition: spatial.cc:4593
Gis_wkb_vector< Linestring > Multi_linestrings
Definition: spatial.h:2086
T & reference
Definition: spatial.h:1911
Geometry_vector< T > Geo_vector
Definition: spatial.h:1914
void push_back(const T &val)
Definition: spatial.cc:4699
Gis_wkb_vector()
Definition: spatial.h:2013
Utility container class to store elements stably and scalably.
Definition: inplace_vector.h:59
size_t size() const
STL std::vector::size interface.
Definition: inplace_vector.h:198
const objtype & back() const
STL std::vector::back interface.
Definition: inplace_vector.h:224
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:165
bool append(const String &s)
Definition: sql_string.cc:445
bool reserve(size_t space_needed)
Definition: sql_string.h:554
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:821
Definition: spatial.h:2451
virtual void on_wkb_end(const void *wkb)=0
Notified when scanner sees the end of a geometry WKB.
virtual void on_wkb_start(Geometry::wkbByteOrder bo, Geometry::wkbType geotype, const void *wkb, uint32 len, bool has_hdr)=0
Notified when scanner sees the start of a geometry WKB.
virtual bool continue_scan() const
Definition: spatial.h:2480
virtual ~WKB_scanner_event_handler()=default
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4131
Point with coordinates X and Y.
Definition: spatial.h:61
point_xy(double x_arg, double y_arg)
Definition: spatial.h:66
bool eq(point_xy p) const
Compare to another point.
Definition: spatial.h:72
double x
Definition: spatial.h:63
point_xy()=default
double distance(const point_xy &p) const
Distance to another point.
Definition: spatial.cc:218
double y
Definition: spatial.h:64
const char * p
Definition: ctype-mb.cc:1236
Dialog Client Authentication nullptr
Definition: dialog.cc:352
static constexpr unsigned PSI_INSTRUMENT_ME
Definition: psi_bits.h:42
static int flags[50]
Definition: hp_test1.cc:39
static int flag
Definition: hp_test1.cc:39
Functions for reading and storing in machine-independent format.
void float8store(char *V, double M)
Definition: my_byteorder.h:202
double float8get(const char *M)
Definition: my_byteorder.h:198
void int4store(char *pT, uint32 A)
Definition: my_byteorder.h:172
uint32 uint4korr(const char *pT)
Definition: my_byteorder.h:144
Header for compiler-dependent features.
#define SUPPRESS_UBSAN
Definition: my_compiler.h:133
Some integer typedefs for easier portability.
unsigned char uchar
Definition: my_inttypes.h:51
uint64_t uint64
Definition: my_inttypes.h:68
uint16_t uint16
Definition: my_inttypes.h:64
uint32_t uint32
Definition: my_inttypes.h:66
#define UINT_MAX32
Definition: my_inttypes.h:78
void my_free(void *ptr)
Frees the memory pointed by the ptr.
Definition: my_memory.cc:80
std::string str(const mysqlrouter::ConfigGenerator::Options::Endpoint &ep)
Definition: config_generator.cc:1056
bool length(const dd::Spatial_reference_system *srs, const Geometry *g1, double *length, bool *null) noexcept
Computes the length of linestrings and multilinestrings.
Definition: length.cc:75
bool intersection(const dd::Spatial_reference_system *srs, const Geometry *g1, const Geometry *g2, const char *func_name, std::unique_ptr< Geometry > *result) noexcept
Finds the intersection between two geometries.
Definition: intersection.cc:35
std::uint32_t srid_t
A spatial reference system ID (SRID).
Definition: srid.h:32
mutable_buffer buffer(void *p, size_t n) noexcept
Definition: buffer.h:391
const string value("\"Value\"")
const mysql_service_registry_t * r
Definition: pfs_example_plugin_employee.cc:85
Performance schema instrumentation interface.
required string type
Definition: replication_group_member_actions.proto:33
wkbByteOrder
Definition: sp_defs.h:44
wkbType
Definition: sp_defs.h:34
const uint SRID_SIZE
Definition: spatial.h:50
const uint SIZEOF_STORED_DOUBLE
Definition: spatial.h:51
const uint WKB_HEADER_SIZE
Definition: spatial.h:53
void gis_wkb_free(void *p)
Definition: spatial.h:206
Geometry::wkbType get_wkb_geotype(const void *p0)
Get wkbType value from WKB, the WKB is always little endian, so need platform specific conversion.
Definition: spatial.h:1079
void * get_packed_ptr(const Geometry *geo, size_t *pnbytes)
Packup a polygon's outer ring and inner rings into a single chunk of memory as result.
Definition: spatial.cc:2279
const uint GEOM_HEADER_SIZE
Definition: spatial.h:54
void * gis_wkb_realloc(void *p, size_t sz)
Definition: spatial.cc:63
const char * wkb_scanner(THD *thd, const char *wkb, uint32 *len, uint32 geotype, bool has_hdr, WKB_scanner_event_handler *handler)
Scan WKB byte string and notify WKB events by calling registered callbacks.
Definition: spatial.cc:839
const uint GEOM_DIM
Definition: spatial.h:49
void set_byte_order(void *p0, Geometry::wkbByteOrder bo)
Definition: spatial.h:1068
const uint32 GET_SIZE_ERROR
Definition: spatial.h:56
void parse_wkb_data(Geometry *geom, const char *p, size_t num_geoms=0)
Parse the wkb buffer to build the component vector m_geo_vect for geom.
Definition: spatial.cc:3861
Geometry::wkbByteOrder get_byte_order(const void *p0)
Definition: spatial.h:1061
Gis_wkb_vector_const_iterator< T > operator+(typename Gis_wkb_vector_const_iterator< T >::difference_type n, const Gis_wkb_vector_const_iterator< T > &itr)
Definition: spatial.h:1851
bool polygon_is_packed(Geometry *plgn, Geometry *mplgn)
Check whether plgn is packed into its owner mplgn's WKB buffer.
Definition: spatial.cc:2346
void * gis_wkb_fixed_alloc(size_t sz)
Definition: spatial.h:202
void gis_wkb_raw_free(void *p)
Definition: spatial.h:212
char * write_wkb_header(void *p0, Geometry::wkbType geotype)
Definition: spatial.h:1091
void own_rings(Geometry *geo)
Definition: spatial.cc:2367
const uint POINT_DATA_SIZE
Definition: spatial.h:52
struct wkb_header_st wkb_header
void * gis_wkb_alloc(size_t sz)
Definition: spatial.cc:55
Gis_polygon_ring * outer_ring(const Geometry *g)
Definition: spatial.h:2175
char * write_geometry_header(void *p0, gis::srid_t srid, Geometry::wkbType geotype)
Definition: spatial.h:1107
Our own string classes, used pervasively throughout the executor.
case opt name
Definition: sslopt-case.h:32
Gis_polygon objects and Gis_wkb_vector<> objects are of same size, and Gis_point and Geometry objects...
Definition: spatial.h:2447
char data[sizeof(Gis_polygon)]
Definition: spatial.h:2448
Definition: spatial.h:82
double xmin
Definition: spatial.h:83
int covered_by(const MBR *mbr) const
Definition: spatial.h:137
MBR()
Definition: spatial.h:85
int equals(const MBR *mbr) const
Definition: spatial.h:117
int dimension() const
The dimension maps to an integer as:
Definition: spatial.h:157
MBR(const double xmin_arg, const double ymin_arg, const double xmax_arg, const double ymax_arg)
Definition: spatial.h:90
MBR(const point_xy &min, const point_xy &max)
Definition: spatial.h:94
int touches(const MBR *mbr) const
Definition: spatial.cc:80
int contains(const MBR *mbr) const
Definition: spatial.h:135
int overlaps(const MBR *mbr) const
Definition: spatial.h:173
void add_xy(point_xy p)
Definition: spatial.h:104
void add_xy(double x, double y)
Definition: spatial.h:97
void add_xy(const char *px, const char *py)
Definition: spatial.h:105
double ymax
Definition: spatial.h:83
int within(const MBR *mbr) const
Definition: spatial.cc:114
int covers(const MBR *mbr) const
Definition: spatial.h:143
bool inner_point(double x, double y) const
Definition: spatial.h:145
double xmax
Definition: spatial.h:83
double ymin
Definition: spatial.h:83
int intersects(const MBR *mbr) const
Definition: spatial.h:129
void add_mbr(const MBR *mbr)
Definition: spatial.h:110
int disjoint(const MBR *mbr) const
Definition: spatial.h:123
Definition: mysql_lex_string.h:39
size_t length
Definition: mysql_lex_string.h:41
Definition: result.h:29
Definition: spatial.h:75
uint32 wkb_type
Definition: spatial.h:77
uchar byte_order
Definition: spatial.h:76
#define NULL
Definition: types.h:54
unsigned int uint
Definition: uca-dump.cc:29
void q_append(const char c, String *str)
Definition: unsafe_string_append.h:34
void qs_append(const char *str_in, size_t len, String *str)
Definition: sql_string.cc:681
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:506
int n
Definition: xcom_base.cc:505