MySQL 8.0.29
Source Code Documentation
spatial.h
Go to the documentation of this file.
1/* Copyright (c) 2002, 2022, 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
45
46class Gis_read_stream;
47class THD;
48
49const uint GEOM_DIM = 2;
50const uint SRID_SIZE = 4;
53const uint WKB_HEADER_SIZE = (1 + 4);
55
56const uint32 GET_SIZE_ERROR = 0xFFFFFFFFU;
57
58/**
59 Point with coordinates X and Y.
60*/
61class 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
75typedef struct wkb_header_st {
79
80/***************************** MBR *******************************/
81
82struct 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
194struct 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 */
200void *gis_wkb_alloc(size_t sz);
201
202inline void *gis_wkb_fixed_alloc(size_t sz) { return gis_wkb_alloc(sz); }
203
204void *gis_wkb_realloc(void *p, size_t sz);
205
206inline void gis_wkb_free(void *p) {
207 if (p == nullptr) return;
208 char *cp = static_cast<char *>(p);
210}
211
212inline void gis_wkb_raw_free(void *p) { my_free(p); }
213
214class 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 */
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 }
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 }
446 if (no_data(SIZEOF_STORED_DOUBLE * 2)) return true;
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
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 ~0U; }
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) {
499 return get_mbr(mbr, &wkb);
500 }
501 virtual bool dimension(uint32 *dim, wkb_parser *wkb) const {
502 *dim = feature_dimension();
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 {
510 return dimension(dim, &wkb);
511 }
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 {
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
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
638 }
639
642 }
643
647 }
648
650 if (b)
652 else
653 m_flags.props &= ~HAS_GEOM_HEADER_SPACE;
654 }
655
658 }
659
661 assert(get_type() == wkb_multilinestring ||
664 if (b)
666 else
667 m_flags.props &= ~MULTIPOLYGON_NO_OVERLAPPED_COMPS;
668 }
669
671 assert(0xfff >= flag);
672 m_flags.props |= flag;
673 }
674
675 uint16 get_props() const { return (uint16)m_flags.props; }
676
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
704 m_flags.props &= ~GEOM_LENGTH_VERIFIED;
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
735 Flags_t(wkbType type, size_t len)
736 : bo(wkb_ndr),
737 dim(GEOM_DIM - 1),
738 nomem(1),
739 geotype(type),
740 nbytes(len),
741 props(0),
742 zm(0) {}
743
752 };
753 static_assert(sizeof(Flags_t) == sizeof(uint64),
754 "Flags are expected to line up exactly with an uint64.");
755
757 m_ptr = nullptr;
758 m_owner = nullptr;
759 set_ownmem(false);
762 }
763
764 /**
765 Constructor used as BG adapter or by default constructors of children
766 classes.
767 @param ptr WKB buffer address, or NULL for an empty object.
768 @param len WKB buffer length in bytes.
769 @param flags the flags to set, no field is used for now except geotype.
770 @param srid srid of the geometry.
771 */
772 Geometry(const void *ptr, size_t len, const Flags_t &flags,
773 gis::srid_t srid) {
774 m_ptr = const_cast<void *>(ptr);
775 m_flags.nbytes = len;
776 set_srid(srid);
777 m_flags.geotype = flags.geotype;
778 m_owner = nullptr;
779 set_ownmem(false);
780 }
781
782 Geometry(const Geometry &geo);
783
784 Geometry &operator=(const Geometry &rhs);
785
786 /* Getters and setters. */
787 void *get_ptr() const { return m_ptr; }
788
789 char *get_cptr() const { return static_cast<char *>(m_ptr); }
790
791 uchar *get_ucptr() const { return static_cast<uchar *>(m_ptr); }
792
793 Geometry *get_owner() const { return m_owner; }
794
795 void set_owner(Geometry *o) { m_owner = o; }
796
798 assert(bo == Geometry::wkb_ndr);
799 m_flags.bo = static_cast<char>(bo);
800 }
801
802 void set_dimension(char dim) {
803 // Valid dim is one of [1, 2, 3, 4].
804 assert(dim > 0 && dim < 5);
805 m_flags.dim = dim - 1;
806 }
807
808 /**
809 Check if a given geometry type is a valid geometry type according
810 to OpenGIS.
811
812 Internal geometry types of MySQL are regarded as invalid.
813
814 @param gtype geometry type to check
815
816 @retval true valid geometry type
817 @retval false invalid geometry type
818 */
819 static bool is_valid_opengis_geotype(uint32 gtype) {
820 return gtype >= wkb_first && gtype <= wkb_geometrycollection;
821 }
822
823 /**
824 Check if a given geometry type is a valid internal geometry type.
825
826 Both OpenGIS standard geometry types and internal geometry types
827 of MySQL are regarded as valid.
828
829 @param gtype geometry type to check
830
831 @retval true valid geometry type
832 @retval false invalid geometry type
833 */
834 static bool is_valid_geotype(uint32 gtype) {
835 /*
836 Stricter check, outside only checks for [wkb_first, wkb_last],
837 they don't have to know about the details.
838 */
839 return ((gtype >= wkb_first && gtype <= wkb_geometrycollection) ||
840 gtype == wkb_polygon_inner_rings);
841 }
842
843 /**
844 Check if a given geometry type is a valid internal geometry type.
845
846 Both OpenGIS standard geometry types and internal geometry types
847 of MySQL are regarded as valid.
848
849 @param gt geometry type to check
850
851 @retval true valid geometry type
852 @retval false invalid geometry type
853 */
855 /*
856 Stricter check, outside only checks for [wkb_first, wkb_last],
857 they don't have to know about the details.
858 */
859 return ((gt >= wkb_first && gt <= wkb_geometrycollection) ||
861 }
862
863 /**
864 Verify that a string is a well-formed GEOMETRY string.
865
866 This does not check if the geometry is geometrically valid.
867
868 @see Geometry_well_formed_checker
869
870 @param from String to check
871 @param length Length of string
872 @param type Expected type of geometry, or
873 Geoemtry::wkb_invalid_type if any type is allowed
874
875 @param bo byte order
876 @return True if the string is a well-formed GEOMETRY string,
877 false otherwise
878 */
879 static bool is_well_formed(const char *from, size_t length, wkbType type,
880 wkbByteOrder bo);
881
884 m_flags.geotype = static_cast<char>(gt);
885 }
886
887 // Have to make this const because it's called in a const member function.
888 void set_nbytes(size_t n) const {
889 if (get_nbytes() != n) {
890 set_length_verified(false);
891 m_flags.nbytes = n;
892 }
893 }
894
895 /**
896 Set whether this object has its own memory. If so, the memory is released
897 when this object is destroyed.
898 @param b true if this object has its own memory, false otherwise.
899
900 */
901 void set_ownmem(bool b) { m_flags.nomem = (b ? 0 : 1); }
902
903 /**
904 Returns whether this object has its own memory. If so, the memory is
905 released when this object is destroyed.
906 */
907 bool get_ownmem() const { return !m_flags.nomem; }
908
910 assert(m_flags.bo == 1);
911 return Geometry::wkb_ndr;
912 }
913
914 char get_dimension() const { return static_cast<char>(m_flags.dim) + 1; }
915
917 char gt = static_cast<char>(m_flags.geotype);
918 return static_cast<Geometry::wkbType>(gt);
919 }
920
921 /**
922 Build an OGC standard type value from m_flags.zm and m_flags.geotype. For
923 now m_flags.zm is always 0 so simply call get_geotype(). We don't
924 directly store the OGC defined values in order to save more bits
925 of m_flags for other purposes; and also separating zm settings from basic
926 geometry types is easier for coding and geometry type identification.
927
928 When we start to support Z/M settings we need to modify all code which call
929 write_wkb_header and write_geometry_header to pass to them an OGC standard
930 type value returned by this function or built similarly. And by doing so
931 our internal runtime geometry type encoding will work consistently with
932 OGC defined standard geometry type values in byte strings of WKB format.
933
934 @return OGC standard geometry type value.
935 */
936 uint32 get_ogc_geotype() const { return static_cast<uint32>(get_geotype()); }
937
938 size_t get_nbytes() const { return static_cast<size_t>(m_flags.nbytes); }
939
940 /*
941 Only sets m_ptr, different from the overloaded one in Gis_wkb_vector<>
942 which also does WKB parsing.
943 */
944 void set_ptr(const void *ptr) { m_ptr = const_cast<void *>(ptr); }
945
946 /**
947 Whether the Geometry object is created to be used by Boost Geometry or
948 only by MySQL. There are some operations that only work for one type and
949 can or must be skipped otherwise.
950 @return true if it's a BG adapter, false otherwise.
951 */
952 bool is_bg_adapter() const {
954 }
955
956 /**
957 Set whether this object is a BG adapter.
958 @param b true if it's a BG adapter, false otherwise.
959 Have to declare this as const because even when a Geometry object's const
960 adapter member function is called, it's regarded as a BG adapter object.
961 */
962 void set_bg_adapter(bool b) const {
963 if (b)
965 else
966 m_flags.props &= ~IS_BOOST_GEOMETRY_ADAPTER;
967 }
968
969 /*
970 Give up ownership of m_ptr, so as not to release them when
971 this object is destroyed, to be called when the two member is shallow
972 assigned to another geometry object.
973 */
974 virtual void donate_data() {
975 set_ownmem(false);
976 set_nbytes(0);
977 m_ptr = nullptr;
978 }
979
980 protected:
981 /**
982 In a polygon usable by boost geometry, the m_ptr points to the outer ring
983 object, and m_inn_rings points to the inner rings, thus the polygon's data
984 isn't stored in a single WKB. Users should call
985 @c Gis_polygon::to_wkb_unparsed() before getting the polygon's wkb data,
986 @c Gis_polygon::to_wkb_unparsed() will form a single WKB for the polygon
987 and refer to it with m_ptr, and release the outer ring object
988 and the inner rings objects, and such an polygon isn't usable by BG any
989 more, it's exactly what we got with
990 @c Geometry::create_from_wkt / @c Geometry::create_from_wkt.
991 */
992 bool polygon_is_wkb_form() const {
994 }
995
996 void polygon_is_wkb_form(bool b) {
997 if (b)
999 else
1000 m_flags.props &= ~POLYGON_IN_WKB_FORM;
1001 }
1002
1003 /**
1004 If call Gis_wkb_vector<T>::resize() to add a component to X, the
1005 geometry may have a geometry not stored inside the WKB buffer of X, hence
1006 X has out of line component. For such an X, user should call
1007 Gis_wkb_vector<T>::reassemble() before fetching its WKB data.
1008 */
1011 }
1012
1014 if (b)
1016 else
1017 m_flags.props &= ~HAS_OUT_OF_LINE_COMPONENTS;
1018 }
1019
1021 virtual void shallow_push(const Geometry *) { assert(false); }
1022
1023 protected:
1024 /**
1025 The topmost (root) geometry object, whose m_ptr is the 1st byte of a
1026 wkb memory buffer. other geometry objects hold m_ptr which points
1027 inside somewhere in the memory buffer. when updating a geometry object,
1028 need to ask m_owner to reallocate memory if needed for new data.
1029 */
1031
1032 /**
1033 Pointer to the geometry's wkb data's 1st byte, right after its
1034 wkb header if any.
1035 If the geometry is wkb_polygon, this field is a
1036 Gis_polygon_ring* pointer, pointing to the outer ring. Outer ring's wkb data
1037 is in the same wkb buffer as the inner rings, so we can get the wkb header
1038 from the outer ring like ((Geometry*)m_ptr)->get_ptr().
1039 */
1040 void *m_ptr;
1041
1042 private:
1043 /// Flags and meta information about this object.
1044 /// Make it mutable to modify some flags in const member functions.
1046
1047 /// Srid of this object.
1049
1050 public:
1051 Flags_t get_flags() const { return m_flags; }
1052
1054};
1055
1057 const char *p = static_cast<const char *>(p0);
1058
1059 if (!(*p == 0 || *p == 1)) return Geometry::wkb_invalid;
1060 return *p == 0 ? Geometry::wkb_xdr : Geometry::wkb_ndr;
1061}
1062
1063inline void set_byte_order(void *p0, Geometry::wkbByteOrder bo) {
1064 char *p = static_cast<char *>(p0);
1065 *p = (bo == Geometry::wkb_ndr ? 1 : 0);
1066}
1067
1068/**
1069 Get wkbType value from WKB, the WKB is always little endian, so need
1070 platform specific conversion.
1071 @param p0 WKB geometry type field address.
1072 @return geometry type.
1073 */
1074inline Geometry::wkbType get_wkb_geotype(const void *p0) {
1075 const char *p = static_cast<const char *>(p0);
1076 uint32 gt = uint4korr(p);
1077 assert(Geometry::is_valid_geotype(gt));
1078 return static_cast<Geometry::wkbType>(gt);
1079}
1080
1081/*
1082 Functions to write a GEOMETRY or WKB header into a piece of allocated and
1083 big enough raw memory or into a String object with enough reserved memory,
1084 and optionally append the object count right after the header.
1085 */
1086inline char *write_wkb_header(void *p0, Geometry::wkbType geotype) {
1087 char *p = static_cast<char *>(p0);
1088 *p = static_cast<char>(Geometry::wkb_ndr);
1089 p++;
1090 int4store(p, static_cast<uint32>(geotype));
1091 return p + 4;
1092}
1093
1094inline char *write_wkb_header(void *p0, Geometry::wkbType geotype,
1095 uint32 obj_count) {
1096 char *p = static_cast<char *>(p0);
1097 p = write_wkb_header(p, geotype);
1098 int4store(p, obj_count);
1099 return p + 4;
1100}
1101
1102inline char *write_geometry_header(void *p0, gis::srid_t srid,
1103 Geometry::wkbType geotype) {
1104 char *p = static_cast<char *>(p0);
1105 int4store(p, srid);
1106 return write_wkb_header(p + 4, geotype);
1107}
1108
1109inline char *write_geometry_header(void *p0, gis::srid_t srid,
1110 Geometry::wkbType geotype,
1111 uint32 obj_count) {
1112 char *p = static_cast<char *>(p0);
1113 int4store(p, srid);
1114 return write_wkb_header(p + 4, geotype, obj_count);
1115}
1116
1118 q_append(static_cast<char>(Geometry::wkb_ndr), str);
1119 q_append(static_cast<uint32>(geotype), str);
1120}
1121
1123 uint32 obj_count) {
1124 write_wkb_header(str, geotype);
1125 q_append(obj_count, str);
1126}
1127
1129 Geometry::wkbType geotype) {
1130 q_append(srid, str);
1131 write_wkb_header(str, geotype);
1132}
1133
1135 Geometry::wkbType geotype, uint32 obj_count) {
1136 write_geometry_header(str, srid, geotype);
1137 q_append(obj_count, str);
1138}
1139
1140/***************************** Point *******************************/
1141
1142class Gis_point : public Geometry {
1143 public:
1144 uint32 get_data_size() const override;
1145 /**
1146 Initialize from a partial WKT string (everything following "POINT").
1147
1148 @param trs Input stream
1149 @param wkb Output string
1150 @param parens Whether parentheses are expected around the
1151 coordinates.
1152 @retval true Error
1153 @retval false Success
1154 */
1155 bool init_from_wkt(Gis_read_stream *trs, String *wkb, const bool parens);
1156 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override {
1157 return init_from_wkt(trs, wkb, true);
1158 }
1159 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
1160 String *res) override;
1161 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
1162 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
1163
1164 int get_xy(point_xy *p) const {
1165 wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
1166 return wkb.scan_xy(p);
1167 }
1168 int get_x(double *x) const override {
1169 wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
1170 return wkb.scan_coord(x);
1171 }
1172 int get_y(double *y) const override {
1173 wkb_parser wkb(get_cptr(), get_cptr() + get_nbytes());
1174 return wkb.skip_coord() || wkb.scan_coord(y);
1175 }
1176 uint32 feature_dimension() const override { return 0; }
1177 const Class_info *get_class_info() const override;
1178 bool reverse_coordinates() override;
1179 bool validate_coordinate_range(double srs_angular_unit,
1180 bool *long_out_of_range,
1181 bool *lat_out_of_range,
1182 double *out_of_range_value) override;
1183
1184 /************* Boost Geometry Adapter Interface *************/
1185
1186 typedef Gis_point self;
1188
1189 explicit Gis_point(bool is_bg_adapter = true)
1191 set_ownmem(false);
1193 }
1194
1195 /// @brief Default constructor, no initialization.
1196 Gis_point(const void *ptr, size_t nbytes, const Flags_t &flags,
1197 gis::srid_t srid)
1198 : Geometry(ptr, nbytes, flags, srid) {
1200 assert(
1201 (ptr != nullptr && get_nbytes() == SIZEOF_STORED_DOUBLE * GEOM_DIM) ||
1202 (ptr == nullptr && get_nbytes() == 0));
1203 set_ownmem(false);
1204 set_bg_adapter(true);
1205 }
1206
1207 Gis_point(const self &pt);
1208
1209 ~Gis_point() override = default;
1210
1211 Gis_point &operator=(const Gis_point &rhs);
1212
1213 void set_ptr(void *ptr, size_t len);
1214
1215 /// @brief Get a coordinate
1216 /// @tparam K coordinate to get
1217 /// @return the coordinate
1218 template <std::size_t K>
1219 double get() const {
1220 assert(K < static_cast<size_t>(get_dimension()) &&
1221 ((m_ptr != nullptr &&
1223 (m_ptr == nullptr && get_nbytes() == 0)));
1224
1225 set_bg_adapter(true);
1226 const char *p = static_cast<char *>(m_ptr) + K * SIZEOF_STORED_DOUBLE;
1227
1228 /*
1229 Boost Geometry may use a point that is only default constructed that
1230 has not specified with any meaningful value, and in such a case the
1231 default value are expected to be all zeros.
1232 */
1233 if (m_ptr == nullptr) return 0;
1234
1235 return float8get(p);
1236 }
1237
1238 /// @brief Set a coordinate
1239 /// @tparam K coordinate to set
1240 /// @param value value to set
1241 // Deep assignment, not only allow assigning to a point owning its memory,
1242 // but also a point not own memory, since points are of same size.
1243 template <std::size_t K>
1244 void set(double const &value) {
1245 /* Allow assigning to others' memory. */
1246 assert((m_ptr != nullptr && K < static_cast<size_t>(get_dimension()) &&
1248 (!get_ownmem() && get_nbytes() == 0 && m_ptr == nullptr));
1249 set_bg_adapter(true);
1250 if (m_ptr == nullptr) {
1252 if (m_ptr == nullptr) {
1253 set_ownmem(false);
1254 set_nbytes(0);
1255 return;
1256 }
1257 set_ownmem(true);
1259 }
1260
1261 char *p = get_cptr() + K * SIZEOF_STORED_DOUBLE;
1262 float8store(p, value);
1263 }
1264
1265 bool operator<(const Gis_point &pt) const {
1266 bool x = get<0>(), px = pt.get<0>();
1267 return x == px ? get<1>() < pt.get<1>() : x < px;
1268 }
1269
1270 bool operator==(const Gis_point &pt) const {
1271 return (get<0>() == pt.get<0>() && get<1>() == pt.get<1>());
1272 }
1273
1274 bool operator!=(const Gis_point &pt) const { return !(operator==(pt)); }
1275};
1276
1277/******************************** Gis_wkb_vector **************************/
1278
1279template <typename T>
1280class Gis_wkb_vector;
1281
1282/// @ingroup iterators
1283/// @{
1284/// @defgroup Gis_wkb_vector_iterators Iterator classes for Gis_wkb_vector.
1285/// Gis_wkb_vector has two iterator classes --- Gis_wkb_vector_const_iterator
1286/// and Gis_wkb_vector_iterator. The differences
1287/// between the two classes are that the Gis_wkb_vector_const_iterator
1288/// can only be used to read its referenced value, so it is intended as
1289/// Gis_wkb_vector's const iterator; While the other class allows both read and
1290/// write access. If your access pattern is readonly, it is strongly
1291/// recommended that you use the const iterator because it is faster
1292/// and more efficient.
1293/// The two classes have identical behaviors to std::vector::const_iterator and
1294/// std::vector::iterator respectively.
1295//@{
1296///////////////////////////////////////////////////////////////////////
1297///////////////////////////////////////////////////////////////////////
1298//
1299// Gis_wkb_vector_const_iterator class template definition
1300//
1301/// Gis_wkb_vector_const_iterator is const_iterator class for Gis_wkb_vector,
1302/// and base class of Gis_wkb_vector_iterator -- iterator class for
1303/// Gis_wkb_vector.
1304/// @tparam T Vector element type
1305template <typename T>
1307 protected:
1310 typedef ptrdiff_t index_type;
1311
1312 public:
1313 ////////////////////////////////////////////////////////////////////
1314 //
1315 // Begin public type definitions.
1316 //
1317 typedef T value_type;
1318 typedef ptrdiff_t difference_type;
1321
1322 /// This is the return type for operator[].
1325 // Use the STL tag, to ensure compatability with interal STL functions.
1326 //
1327 typedef std::random_access_iterator_tag iterator_category;
1328 ////////////////////////////////////////////////////////////////////
1329
1330 ////////////////////////////////////////////////////////////////////
1331 // Begin public constructors and destructor.
1332 /// @name Constructors and destroctor
1333 /// Do not construct iterators explictily using these constructors,
1334 /// but call Gis_wkb_vector::begin() const to get an valid iterator.
1335 /// @sa Gis_wkb_vector::begin() const
1336 //@{
1338 m_curidx = vi.m_curidx;
1339 m_owner = vi.m_owner;
1340 }
1341
1343 m_curidx = -1;
1344 m_owner = nullptr;
1345 }
1346
1348 m_curidx = idx;
1349 m_owner = const_cast<owner_t *>(owner);
1350 }
1351
1353 //@}
1354
1355 ////////////////////////////////////////////////////////////////////
1356
1357 ////////////////////////////////////////////////////////////////////
1358 //
1359 // Begin functions that compare iterator positions.
1360 //
1361 /// @name Iterator comparison operators
1362 /// The way to compare two iterators is to compare the index values
1363 /// of the two elements they point to. The iterator sitting on an
1364 /// element with less index is regarded to be smaller. And the invalid
1365 /// iterator sitting after last element is greater than any other
1366 /// iterators, because it is assumed to have an index equal to last
1367 /// element's index plus one; The invalid iterator sitting before first
1368 /// element is less than any other iterators because it is assumed to
1369 /// have an index -1.
1370 //@{
1371 /// @brief Equality comparison operator.
1372 ///
1373 /// Invalid iterators are equal; Valid iterators
1374 /// sitting on the same key/data pair equal; Otherwise not equal.
1375 /// @param itr The iterator to compare against.
1376 /// @return True if this iterator equals to itr; False otherwise.
1377 bool operator==(const self &itr) const {
1378 assert(m_owner == itr.m_owner);
1379 return m_curidx == itr.m_curidx;
1380 }
1381
1382 /// @brief Unequal compare, identical to !operator(==itr)
1383 /// @param itr The iterator to compare against.
1384 /// @return False if this iterator equals to itr; True otherwise.
1385 bool operator!=(const self &itr) const { return !(*this == itr); }
1386
1387 // The end() iterator is largest. If both are end() iterator return false.
1388 /// @brief Less than comparison operator.
1389 /// @param itr The iterator to compare against.
1390 /// @return True if this iterator is less than itr.
1391 bool operator<(const self &itr) const {
1392 assert(m_owner == itr.m_owner);
1393 return m_curidx < itr.m_curidx;
1394 }
1395
1396 /// @brief Less equal comparison operator.
1397 /// @param itr The iterator to compare against.
1398 /// @return True if this iterator is less than or equal to itr.
1399 bool operator<=(const self &itr) const { return !(this->operator>(itr)); }
1400
1401 /// @brief Greater equal comparison operator.
1402 /// @param itr The iterator to compare against.
1403 /// @return True if this iterator is greater than or equal to itr.
1404 bool operator>=(const self &itr) const { return !(this->operator<(itr)); }
1405
1406 // The end() iterator is largest. If both are end() iterator return false.
1407 /// @brief Greater comparison operator.
1408 /// @param itr The iterator to compare against.
1409 /// @return True if this iterator is greater than itr.
1410 bool operator>(const self &itr) const {
1411 assert(m_owner == itr.m_owner);
1412 return m_curidx > itr.m_curidx;
1413 }
1414 //@} // vctitr_cmp
1415 ////////////////////////////////////////////////////////////////////
1416
1417 ////////////////////////////////////////////////////////////////////
1418 //
1419 // Begin functions that shift the iterator position.
1420 //
1421 /// @name Iterator movement operators.
1422 /// When we talk about iterator movement, we think the
1423 /// container is a uni-directional range, represented by [begin, end),
1424 /// and this is true no matter we are using iterators or reverse
1425 /// iterators. When an iterator is moved closer to "begin", we say it
1426 /// is moved backward, otherwise we say it is moved forward.
1427 //@{
1428 /// @brief Pre-increment.
1429 ///
1430 /// Move the iterator one element forward, so that
1431 /// the element it sits on has a bigger index.
1432 /// Use ++iter rather than iter++ where possible to avoid two useless
1433 /// iterator copy constructions.
1434 /// @return This iterator after incremented.
1435 self &operator++() {
1436 move_by(*this, 1, false);
1437 return *this;
1438 }
1439
1440 /// @brief Post-increment.
1441 /// Move the iterator one element forward, so that
1442 /// the element it sits on has a bigger index.
1443 /// Use ++iter rather than iter++ where possible to avoid two useless
1444 /// iterator copy constructions.
1445 /// @return A new iterator not incremented.
1446 self operator++(int) {
1447 self itr(*this);
1448 move_by(*this, 1, false);
1449
1450 return itr;
1451 }
1452
1453 /// @brief Pre-decrement.
1454 /// Move the iterator one element backward, so
1455 /// that the element it sits on has a smaller index.
1456 /// Use --iter rather than iter-- where possible to avoid two useless
1457 /// iterator copy constructions.
1458 /// @return This iterator after decremented.
1459 self &operator--() {
1460 move_by(*this, 1, true);
1461 return *this;
1462 }
1463
1464 /// @brief Post-decrement.
1465 ///
1466 /// Move the iterator one element backward, so
1467 /// that the element it sits on has a smaller index.
1468 /// Use --iter rather than iter-- where possible to avoid two useless
1469 /// iterator copy constructions.
1470 /// @return A new iterator not decremented.
1471 self operator--(int) {
1472 self itr = *this;
1473 move_by(*this, 1, true);
1474 return itr;
1475 }
1476
1477 /// @brief Assignment operator.
1478 ///
1479 /// This iterator will point to the same key/data
1480 /// pair as itr, and have the same configurations as itr.
1481 /// @param itr The right value of the assignment.
1482 /// @return This iterator's reference.
1483 const self &operator=(const self &itr) {
1484 m_curidx = itr.m_curidx;
1485 m_owner = itr.m_owner;
1486 return itr;
1487 }
1488
1489 /// Iterator movement operator.
1490 /// Return another iterator by moving this iterator forward by n
1491 /// elements.
1492 /// @param n The amount and direction of movement. If negative, will
1493 /// move backward by |n| element.
1494 /// @return The new iterator at new position.
1496 self itr(*this);
1497 move_by(itr, n, false);
1498 return itr;
1499 }
1500
1501 /// @brief Move this iterator forward by n elements.
1502 /// @param n The amount and direction of movement. If negative, will
1503 /// move backward by |n| element.
1504 /// @return Reference to this iterator at new position.
1506 move_by(*this, n, false);
1507 return *this;
1508 }
1509
1510 /// @brief Iterator movement operator.
1511 ///
1512 /// Return another iterator by moving this iterator backward by n
1513 /// elements.
1514 /// @param n The amount and direction of movement. If negative, will
1515 /// move forward by |n| element.
1516 /// @return The new iterator at new position.
1518 self itr(*this);
1519 move_by(itr, n, true);
1520
1521 return itr;
1522 }
1523
1524 /// @brief Move this iterator backward by n elements.
1525 /// @param n The amount and direction of movement. If negative, will
1526 /// move forward by |n| element.
1527 /// @return Reference to this iterator at new position.
1529 move_by(*this, n, true);
1530 return *this;
1531 }
1532 //@} //itr_movement
1533
1534 /// @brief Iterator distance operator.
1535 ///
1536 /// Return the index difference of this iterator and itr, so if this
1537 /// iterator sits on an element with a smaller index, this call will
1538 /// return a negative number.
1539 /// @param itr The other iterator to substract. itr can be the invalid
1540 /// iterator after last element or before first element, their index
1541 /// will be regarded as last element's index + 1 and -1 respectively.
1542 /// @return The index difference.
1543 difference_type operator-(const self &itr) const {
1544 assert(m_owner == itr.m_owner);
1545 return (m_curidx - itr.m_curidx);
1546 }
1547
1548 ////////////////////////////////////////////////////////////////////
1549 //
1550 // Begin functions that retrieve values from the iterator.
1551 //
1552 /// @name Functions that retrieve values from the iterator.
1553 //@{
1554 /// @brief Dereference operator.
1555 ///
1556 /// Return the reference to the cached data element.
1557 /// The returned value can only be used to read its referenced
1558 /// element.
1559 /// @return The reference to the element this iterator points to.
1561 assert(this->m_owner != nullptr && this->m_curidx >= 0 &&
1562 this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1563 return (*m_owner)[m_curidx];
1564 }
1565
1566 /// @brief Arrow operator.
1567 ///
1568 /// Return the pointer to the cached data element.
1569 /// The returned value can only be used to read its referenced
1570 /// element.
1571 /// @return The address of the referenced object.
1572 pointer operator->() const {
1573 assert(this->m_owner != NULL && this->m_curidx >= 0 &&
1574 this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1575 return &(*m_owner)[m_curidx];
1576 }
1577
1578 /// @brief Iterator index operator.
1579 ///
1580 /// @param offset The offset of target element relative to this iterator.
1581 /// @return Return the reference of the element which is at
1582 /// position *this + offset.
1583 /// The returned value can only be used to read its referenced
1584 /// element.
1585 reference operator[](difference_type offset) const {
1586 self itr = *this;
1587 move_by(itr, offset, false);
1588
1589 assert(itr.m_owner != NULL && itr.m_curidx >= 0 &&
1590 itr.m_curidx < static_cast<index_type>(itr.m_owner->size()));
1591 return (*m_owner)[itr.m_curidx];
1592 }
1593 //@}
1594 ////////////////////////////////////////////////////////////////////
1595
1596 protected:
1597 // The 'back' parameter indicates whether to decrease or
1598 // increase the index when moving. The default is to decrease.
1599 //
1600 void move_by(self &itr, difference_type n, bool back) const {
1601 if (back) n = -n;
1602
1603 index_type newidx = itr.m_curidx + n;
1604 size_t sz = 0;
1605
1606 if (newidx < 0)
1607 newidx = -1;
1608 else if (newidx >= static_cast<index_type>((sz = m_owner->size())))
1609 newidx = sz;
1610
1611 itr.m_curidx = newidx;
1612 }
1613
1614 protected:
1615 /// Current element's index, starting from 0.
1617 /// The owner container of this iteraotr.
1619}; // Gis_wkb_vector_const_iterator<>
1620
1621///////////////////////////////////////////////////////////////////////
1622///////////////////////////////////////////////////////////////////////
1623//
1624// Gis_wkb_vector_iterator class template definition
1625/// This class is the iterator class for Gis_wkb_vector, its instances can
1626/// be used to mutate their referenced data element.
1627/// @tparam T Vector element type
1628//
1629template <class T>
1631 protected:
1635
1636 public:
1637 typedef ptrdiff_t index_type;
1638 typedef T value_type;
1639 typedef ptrdiff_t difference_type;
1643 // Use the STL tag, to ensure compatability with interal STL functions.
1644 typedef std::random_access_iterator_tag iterator_category;
1645
1646 ////////////////////////////////////////////////////////////////////
1647 /// Begin public constructors and destructor.
1648 //
1649 /// @name Constructors and destructor
1650 /// Do not construct iterators explictily using these constructors,
1651 /// but call Gis_wkb_vector::begin to get an valid iterator.
1652 /// @sa Gis_wkb_vector::begin
1653 //@{
1654 Gis_wkb_vector_iterator(const self &vi) : base(vi) {}
1655
1657
1658 Gis_wkb_vector_iterator(const base &obj) : base(obj) {}
1659
1661 : base(idx, owner) {}
1662
1664 //@}
1665
1666 ////////////////////////////////////////////////////////////////////
1667
1668 ////////////////////////////////////////////////////////////////////
1669 //
1670 /// Begin functions that shift the iterator position.
1671 //
1672 /// These functions are identical to those defined in
1673 /// Gis_wkb_vector_const_iterator, but we have to redefine them here because
1674 /// the "self" have different definitions.
1675 //
1676 /// @name Iterator movement operators.
1677 /// These functions have identical behaviors and semantics as those of
1678 /// Gis_wkb_vector_const_iterator, so please refer to equivalent in that
1679 /// class.
1680 //@{
1681 /// @brief Pre-increment.
1682 /// @return This iterator after incremented.
1683 /// @sa Gis_wkb_vector_const_iterator::operator++()
1684 self &operator++() {
1685 this->move_by(*this, 1, false);
1686 return *this;
1687 }
1688
1689 /// @brief Post-increment.
1690 /// @return A new iterator not incremented.
1691 /// @sa Gis_wkb_vector_const_iterator::operator++(int)
1692 self operator++(int) {
1693 self itr(*this);
1694 this->move_by(*this, 1, false);
1695
1696 return itr;
1697 }
1698
1699 /// @brief Pre-decrement.
1700 /// @return This iterator after decremented.
1701 /// @sa Gis_wkb_vector_const_iterator::operator--()
1702 self &operator--() {
1703 this->move_by(*this, 1, true);
1704 return *this;
1705 }
1706
1707 /// @brief Post-decrement.
1708 /// @return A new iterator not decremented.
1709 /// @sa Gis_wkb_vector_const_iterator::operator--(int)
1710 self operator--(int) {
1711 self itr = *this;
1712 this->move_by(*this, 1, true);
1713 return itr;
1714 }
1715
1716 /// @brief Assignment operator.
1717 ///
1718 /// This iterator will point to the same key/data
1719 /// pair as itr, and have the same configurations as itr.
1720 /// @param itr The right value of the assignment.
1721 /// @return This iterator's reference.
1722 const self &operator=(const self &itr) {
1723 base::operator=(itr);
1724
1725 return itr;
1726 }
1727
1728 /// @brief Iterator movement operator.
1729 ///
1730 /// Return another iterator by moving this iterator backward by n
1731 /// elements.
1732 /// @param n The amount and direction of movement. If negative, will
1733 /// move forward by |n| element.
1734 /// @return The new iterator at new position.
1735 /// @sa Gis_wkb_vector_const_iterator::operator+(difference_type n) const
1737 self itr(*this);
1738 this->move_by(itr, n, false);
1739 return itr;
1740 }
1741
1742 /// @brief Move this iterator backward by n elements.
1743 /// @param n The amount and direction of movement. If negative, will
1744 /// move forward by |n| element.
1745 /// @return Reference to this iterator at new position.
1746 /// @sa Gis_wkb_vector_const_iterator::operator+=(difference_type n)
1748 this->move_by(*this, n, false);
1749 return *this;
1750 }
1751
1752 /// @brief Iterator movement operator.
1753 ///
1754 /// Return another iterator by moving this iterator forward by n
1755 /// elements.
1756 /// @param n The amount and direction of movement. If negative, will
1757 /// move backward by |n| element.
1758 /// @return The new iterator at new position.
1759 /// @sa Gis_wkb_vector_const_iterator::operator-(difference_type n) const
1761 self itr(*this);
1762 this->move_by(itr, n, true);
1763
1764 return itr;
1765 }
1766
1767 /// @brief Move this iterator forward by n elements.
1768 /// @param n The amount and direction of movement. If negative, will
1769 /// move backward by |n| element.
1770 /// @return Reference to this iterator at new position.
1771 /// @sa Gis_wkb_vector_const_iterator::operator-=(difference_type n)
1773 this->move_by(*this, n, true);
1774 return *this;
1775 }
1776 //@} // itr_movement
1777
1778 /// @brief Iterator distance operator.
1779 ///
1780 /// Return the index difference of this iterator and itr, so if this
1781 /// iterator sits on an element with a smaller index, this call will
1782 /// return a negative number.
1783 /// @param itr The other iterator to substract. itr can be the invalid
1784 /// iterator after last element or before first element, their index
1785 /// will be regarded as last element's index + 1 and -1 respectively.
1786 /// @return The index difference.
1787 /// @sa Gis_wkb_vector_const_iterator::operator-(const self &itr) const
1788 difference_type operator-(const self &itr) const {
1789 return base::operator-(itr);
1790 }
1791 ////////////////////////////////////////////////////////////////////
1792
1793 ////////////////////////////////////////////////////////////////////
1794 //
1795 // Begin functions that retrieve values from the iterator.
1796 //
1797 /// @name Functions that retrieve values from the iterator.
1798 //@{
1799 /// @brief Dereference operator.
1800 ///
1801 /// Return the reference to the cached data element
1802 /// The returned value can be used to read or update its referenced
1803 /// element.
1804 /// @return The reference to the element this iterator points to.
1806 assert(this->m_owner != nullptr && this->m_curidx >= 0 &&
1807 this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1808 return (*this->m_owner)[this->m_curidx];
1809 }
1810
1811 /// @brief Arrow operator.
1812 ///
1813 /// Return the pointer to the cached data element
1814 /// The returned value can be used to read or update its referenced
1815 /// element.
1816 /// @return The address of the referenced object.
1817 pointer operator->() const {
1818 assert(this->m_owner != nullptr && this->m_curidx >= 0 &&
1819 this->m_curidx < static_cast<index_type>(this->m_owner->size()));
1820 return &(*this->m_owner)[this->m_curidx];
1821 }
1822
1823 /// @brief Iterator index operator.
1824 ///
1825 /// @param offset The offset of target element relative to this iterator.
1826 /// @return Return the element which is at position *this + offset.
1827 /// The returned value can be used to read or update its referenced
1828 /// element.
1829 reference operator[](difference_type offset) const {
1830 self itr = *this;
1831 this->move_by(itr, offset, false);
1832 assert(itr.m_owner != NULL && itr.m_curidx >= 0 &&
1833 itr.m_curidx < static_cast<index_type>(this->m_owner->size()));
1834 return (*this->m_owner)[itr.m_curidx];
1835 }
1836 //@} // funcs_val
1837 ////////////////////////////////////////////////////////////////////
1838
1839}; // Gis_wkb_vector_iterator
1840//@} // Gis_wkb_vector_iterators
1841///@} // iterators
1842
1843// These operators make "n + itr" expressions valid. Without it, you can only
1844// use "itr + n"
1845template <typename T>
1850
1851 itr2 += n;
1852 return itr2;
1853}
1854
1855template <typename T>
1858 const Gis_wkb_vector_iterator<T> &itr) {
1859 Gis_wkb_vector_iterator<T> itr2 = itr;
1860
1861 itr2 += n;
1862 return itr2;
1863}
1864
1865void *get_packed_ptr(const Geometry *geo, size_t *pnbytes);
1866const char *get_packed_ptr(Geometry *geo);
1867bool polygon_is_packed(Geometry *plgn, Geometry *mplgn);
1868void own_rings(Geometry *geo);
1869void parse_wkb_data(Geometry *geom, const char *p, size_t num_geoms = 0);
1870
1871/**
1872 Geometry vector class.
1873 @tparam T Vector element type.
1874 */
1875template <typename T>
1878
1879 public:
1881};
1882
1883/// @ingroup containers
1884//@{
1885////////////////////////////////////////////////////////////////////////
1886////////////////////////////////////////////////////////////////////////
1887//
1888/// Gis_wkb_vector class template definition
1889/// @tparam T Vector element type
1890//
1891template <typename T>
1892class Gis_wkb_vector : public Geometry {
1893 private:
1894 typedef Gis_wkb_vector<T> self;
1895 typedef ptrdiff_t index_type;
1897
1898 public:
1899 typedef T value_type;
1902 typedef size_t size_type;
1903 typedef const T *const_pointer;
1904 typedef const T &const_reference;
1905 typedef T *pointer;
1906 typedef T &reference;
1907 typedef ptrdiff_t difference_type;
1908
1910
1911 private:
1912 /**
1913 The geometry vector of this geometry object's components, each of which
1914 is an object of Geometry or its children classes where appropriate.
1915 */
1917
1918 public:
1919 /////////////////////////////////////////////////////////////////////
1920 // Begin functions that create iterators.
1921 /// @name Iterator functions.
1922 //@{
1924 set_bg_adapter(true);
1925 iterator itr(m_geo_vect ? 0 : -1, this);
1926 return itr;
1927 }
1928
1929 /// @brief Create a const iterator.
1930 ///
1931 /// The created iterator can only be used to read its referenced
1932 /// data element. Can only be called when using a const reference to
1933 /// the contaienr object.
1935 set_bg_adapter(true);
1936 const_iterator itr(m_geo_vect ? 0 : -1, this);
1937 return itr;
1938 }
1939
1940 /// @brief Create an open boundary iterator.
1941 /// @return Returns an invalid iterator denoting the position after
1942 /// the last valid element of the container.
1944 iterator itr(m_geo_vect ? m_geo_vect->size() : -1, this);
1945 return itr;
1946 }
1947
1948 /// @brief Create an open boundary iterator.
1949 /// @return Returns an invalid const iterator denoting the position
1950 /// after the last valid element of the container.
1952 const_iterator itr(m_geo_vect ? m_geo_vect->size() : -1, this);
1953 return itr;
1954 }
1955
1956 //@} // iterator_funcs
1957 /////////////////////////////////////////////////////////////////////
1958
1959 /// @brief Get container size.
1960 /// @return Return the number of elements in this container.
1961 size_type size() const {
1962 set_bg_adapter(true);
1963 return m_geo_vect ? m_geo_vect->size() : 0;
1964 }
1965
1966 bool empty() const { return size() == 0; }
1967
1969 set_bg_adapter(true);
1970 /*
1971 Carefully crafted to avoid invoking any copy constructor using pointer
1972 cast. Also true for the two operator[] member functions below.
1973 */
1974 const Geometry *p = &(get_geo_vect()->back());
1975 return *((const T *)p);
1976 }
1977
1979 set_bg_adapter(true);
1980 /*
1981 Carefully crafted to avoid invoking any copy constructor using pointer
1982 cast. Also true for the two operator[] member functions below.
1983 */
1984 Geometry *p = &(get_geo_vect()->back());
1985 return *((T *)p);
1986 }
1987
1989 assert(!(i < 0 || i >= (index_type)size()));
1990 set_bg_adapter(true);
1991
1992 const Geometry *p = &((*m_geo_vect)[i]);
1993 return *((const T *)p);
1994 }
1995
1997 assert(!(i < 0 || i >= (index_type)size()));
1998 set_bg_adapter(true);
1999
2000 Geometry *p = &((*m_geo_vect)[i]);
2001 return *((T *)p);
2002 }
2003
2004 Gis_wkb_vector(const void *ptr, size_t nbytes, const Geometry::Flags_t &flags,
2005 gis::srid_t srid, bool is_bg_adapter = true);
2006 Gis_wkb_vector(const self &v);
2007
2009
2010 ~Gis_wkb_vector() override {
2011 /*
2012 See ~Geometry() for why we do try-catch like this.
2013
2014 Note that although ~Inplace_vector() calls std::vector member functions,
2015 all of them have no-throw guarantees, so this function won't throw any
2016 exception now. We do so nonetheless for potential mis-use of exceptions
2017 in futher code.
2018 */
2019#if !defined(NDEBUG)
2020 try {
2021#endif
2022 if (!is_bg_adapter()) return;
2023 if (m_geo_vect != nullptr) clear_wkb_data();
2024#if !defined(NDEBUG)
2025 } catch (...) {
2026 // Should never throw exceptions in destructor.
2027 assert(false);
2028 }
2029#endif
2030 }
2031
2033 delete m_geo_vect;
2034 m_geo_vect = nullptr;
2035 }
2036
2037 self &operator=(const self &rhs);
2038
2039 // SUPPRESS_UBSAN Wrong downcast. FIXME
2040 void shallow_push(const Geometry *g) override SUPPRESS_UBSAN;
2041
2042 Geo_vector *get_geo_vect(bool create_if_null = false) {
2043 if (m_geo_vect == nullptr && create_if_null) m_geo_vect = new Geo_vector;
2044 return m_geo_vect;
2045 }
2046
2048
2049 void set_geo_vect(Geo_vector *ptr) { m_geo_vect = ptr; }
2050
2051 /*
2052 Give up ownership of m_ptr and m_geo_vect, so as not to release them when
2053 this object is destroyed, to be called when the two member is shallow
2054 assigned to another geometry object.
2055 */
2056 void donate_data() override {
2057 set_ownmem(false);
2058 set_nbytes(0);
2059 m_ptr = nullptr;
2060 m_geo_vect = nullptr;
2061 }
2062
2063 void set_ptr(void *ptr, size_t len);
2064 void clear();
2065 size_t get_nbytes_free() const;
2066 size_t current_size() const;
2067 void push_back(const T &val);
2068 void resize(size_t sz);
2069 void reassemble();
2070 bool reverse_coordinates() override {
2071 assert(false);
2072 return true;
2073 }
2074 bool validate_coordinate_range(double, bool *, bool *, double *) override {
2075 assert(false); /* purecov: inspected */
2076 return true; /* purecov: inspected */
2077 }
2078
2079 private:
2082
2083}; // Gis_wkb_vector
2084
2085//@} //
2086
2087/***************************** LineString *******************************/
2088
2089class Gis_line_string : public Gis_wkb_vector<Gis_point> {
2090 // Maximum number of points in LineString that can fit into String
2091 static const uint32 max_n_points =
2092 (uint32)(UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
2094
2095 public:
2096 uint32 get_data_size() const override;
2097 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2098 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2099 String *res) override;
2100 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2101 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2102 int geom_length(double *len) const override;
2103 int is_closed(int *closed) const override;
2104 int num_points(uint32 *n_points) const override;
2105 int start_point(String *point) const override;
2106 int end_point(String *point) const override;
2107 int point_n(uint32 n, String *result) const override;
2108 uint32 feature_dimension() const override { return 1; }
2109 const Class_info *get_class_info() const override;
2110 bool reverse_coordinates() override;
2111 bool validate_coordinate_range(double srs_angular_unit,
2112 bool *long_out_of_range,
2113 bool *lat_out_of_range,
2114 double *out_of_range_value) override;
2115
2116 /**** Boost Geometry Adapter Interface ******/
2117
2119 typedef Gis_line_string self;
2120
2121 explicit Gis_line_string(bool is_bg_adapter = true)
2123 is_bg_adapter) {}
2124
2125 Gis_line_string(const void *wkb, size_t len, const Flags_t &flags,
2126 gis::srid_t srid)
2127 : base_type(wkb, len, flags, srid, true) {
2129 }
2130
2131 Gis_line_string(const self &ls) = default;
2132
2134};
2135
2136/*
2137 We have to use such an independent class in order to meet Ring Concept of
2138 Boost Geometry --- there must be a specialization of traits::tag defining
2139 ring_tag as type.
2140 If directly use Gis_line_string, we would have defined that tag twice.
2141*/
2142class Gis_polygon_ring : public Gis_wkb_vector<Gis_point> {
2143 public:
2145 typedef Gis_polygon_ring self;
2146
2147 ~Gis_polygon_ring() override = default;
2148 Gis_polygon_ring(const void *wkb, size_t nbytes, const Flags_t &flags,
2149 gis::srid_t srid)
2150 : base(wkb, nbytes, flags, srid, true) {
2152 }
2153
2154 // Coordinate data type, closed-ness and direction will never change, thus no
2155 // need for the template version of copy constructor.
2156 Gis_polygon_ring(const self &r) = default;
2157
2159
2162 true) {}
2163
2164 bool set_ring_order(bool want_ccw);
2165};
2166
2167/***************************** Polygon *******************************/
2168
2169// For internal use only, only convert types, don't create rings.
2171 assert(g->get_geotype() == Geometry::wkb_polygon);
2172 Gis_polygon_ring *out = static_cast<Gis_polygon_ring *>(g->get_ptr());
2173
2174 return out;
2175}
2176
2177class Gis_polygon : public Geometry {
2178 public:
2179 uint32 get_data_size() const override;
2180 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2181 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2182 String *res) override;
2183 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2184 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2185 int exterior_ring(String *result) const override;
2186 int num_interior_ring(uint32 *n_int_rings) const override;
2187 int interior_ring_n(uint32 num, String *result) const override;
2188 uint32 feature_dimension() const override { return 2; }
2189 const Class_info *get_class_info() const override;
2190 bool reverse_coordinates() override;
2191 bool validate_coordinate_range(double srs_angular_unit,
2192 bool *long_out_of_range,
2193 bool *lat_out_of_range,
2194 double *out_of_range_value) override;
2195
2196 /**** Boost Geometry Adapter Interface ******/
2197 typedef Gis_polygon self;
2200
2201 ring_type &outer() const {
2202 assert(!polygon_is_wkb_form());
2203 set_bg_adapter(true);
2204 // Create outer ring if none, although read only, calller may just want
2205 // to traverse the outer ring if any.
2206 if (this->m_ptr == nullptr) const_cast<self *>(this)->make_rings();
2207
2208 return *(outer_ring(this));
2209 }
2210
2212 assert(!polygon_is_wkb_form());
2213 set_bg_adapter(true);
2214 // Create inner rings if none, although read only, calller may just want
2215 // to traverse the inner rings if any.
2216 if (m_inn_rings == nullptr) const_cast<self *>(this)->make_rings();
2217
2218 return *m_inn_rings;
2219 }
2220
2221 /// Clears outer and inner rings.
2222 void clear() {
2223 set_bg_adapter(true);
2224 outer_ring(this)->clear();
2226 }
2227
2228 Gis_polygon(const void *wkb, size_t nbytes, const Flags_t &flags,
2229 gis::srid_t srid);
2230
2231 /*
2232 We can't require boost geometry use the 'polygon' in any particular way,
2233 so we have to default to true.
2234 */
2235 explicit Gis_polygon(bool isbgadapter = true)
2237 m_inn_rings = nullptr;
2238 set_bg_adapter(isbgadapter);
2239 }
2240
2241 Gis_polygon(const self &r);
2242 Gis_polygon &operator=(const Gis_polygon &rhs);
2243 ~Gis_polygon() override;
2244
2245 void to_wkb_unparsed();
2246 void set_ptr(void *ptr, size_t len);
2247
2248 /*
2249 Give up ownership of m_ptr and m_inn_rings, so as not to release them when
2250 this object is destroyed, to be called when the two member is shallow
2251 assigned to another geometry object.
2252 */
2253 void donate_data() override {
2254 set_ownmem(false);
2255 set_nbytes(0);
2256 m_ptr = nullptr;
2257 m_inn_rings = nullptr;
2258 }
2259
2261
2262 // SUPPRESS_UBSAN Wrong downcast. FIXME
2264 return m_inn_rings;
2265 }
2266
2267 // SUPPRESS_UBSAN Wrong downcast. FIXME
2269 m_inn_rings = inns;
2270 }
2271
2272 private:
2274
2275 void make_rings();
2276};
2277
2278/***************************** MultiPoint *******************************/
2279
2280class Gis_multi_point : public Gis_wkb_vector<Gis_point> {
2281 // Maximum number of points in MultiPoint that can fit into String
2282 static const uint32 max_n_points =
2283 (uint32)(UINT_MAX32 - WKB_HEADER_SIZE - 4 /* n_points */) /
2285
2286 public:
2287 uint32 get_data_size() const override;
2288 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2289 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2290 String *res) override;
2291 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2292 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2293 int num_geometries(uint32 *num) const override;
2294 int geometry_n(uint32 num, String *result) const override;
2295 uint32 feature_dimension() const override { return 0; }
2296 const Class_info *get_class_info() const override;
2297 bool reverse_coordinates() override;
2298 bool validate_coordinate_range(double srs_angular_unit,
2299 bool *long_out_of_range,
2300 bool *lat_out_of_range,
2301 double *out_of_range_value) override;
2302
2303 /**** Boost Geometry Adapter Interface ******/
2304
2306 typedef Gis_multi_point self;
2307
2308 explicit Gis_multi_point(bool is_bg_adapter = true)
2310 is_bg_adapter) {}
2311
2312 Gis_multi_point(const void *ptr, size_t nbytes, const Flags_t &flags,
2313 gis::srid_t srid)
2314 : base_type(ptr, nbytes, flags, srid, true) {
2316 }
2317
2318 Gis_multi_point(const self &mpts) = default;
2319};
2320
2321/***************************** MultiLineString *******************************/
2322
2323class Gis_multi_line_string : public Gis_wkb_vector<Gis_line_string> {
2324 public:
2325 uint32 get_data_size() const override;
2326 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2327 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2328 String *res) override;
2329 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2330 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2331 int num_geometries(uint32 *num) const override;
2332 int geometry_n(uint32 num, String *result) const override;
2333 int geom_length(double *len) const override;
2334 int is_closed(int *closed) const override;
2335 uint32 feature_dimension() const override { return 1; }
2336 const Class_info *get_class_info() const override;
2337 bool reverse_coordinates() override;
2338 bool validate_coordinate_range(double srs_angular_unit,
2339 bool *long_out_of_range,
2340 bool *lat_out_of_range,
2341 double *out_of_range_value) override;
2342
2343 /**** Boost Geometry Adapter Interface ******/
2344
2347
2350 is_bg_adapter) {}
2351
2352 Gis_multi_line_string(const void *ptr, size_t nbytes, const Flags_t &,
2353 gis::srid_t srid)
2354 : base(ptr, nbytes, Flags_t(wkb_multilinestring, nbytes), srid, true) {
2356 }
2357
2358 Gis_multi_line_string(const self &mls) = default;
2359};
2360
2361/***************************** MultiPolygon *******************************/
2362
2363class Gis_multi_polygon : public Gis_wkb_vector<Gis_polygon> {
2364 public:
2365 uint32 get_data_size() const override;
2366 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2367 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2368 String *res) override;
2369 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2370 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2371 int num_geometries(uint32 *num) const override;
2372 int geometry_n(uint32 num, String *result) const override;
2373 uint32 feature_dimension() const override { return 2; }
2374 const Class_info *get_class_info() const override;
2375 bool reverse_coordinates() override;
2376 bool validate_coordinate_range(double srs_angular_unit,
2377 bool *long_out_of_range,
2378 bool *lat_out_of_range,
2379 double *out_of_range_value) override;
2380
2381 /**** Boost Geometry Adapter Interface ******/
2382 typedef Gis_multi_polygon self;
2384
2385 explicit Gis_multi_polygon(bool is_bg_adapter = true)
2387 is_bg_adapter) {}
2388
2389 Gis_multi_polygon(const void *ptr, size_t nbytes, const Flags_t &flags,
2390 gis::srid_t srid)
2391 : base(ptr, nbytes, flags, srid, true) {
2393 }
2394
2395 Gis_multi_polygon(const self &mpl) = default;
2396};
2397
2398/*********************** GeometryCollection *******************************/
2400 private:
2403
2404 public:
2407 set_bg_adapter(false);
2408 }
2410 Gis_geometry_collection(gis::srid_t srid, wkbType gtype, const String *gbuf,
2411 String *gcbuf);
2412 bool append_geometry(const Geometry *geo, String *gcbuf);
2413 bool append_geometry(gis::srid_t srid, wkbType gtype, const String *gbuf,
2414 String *gcbuf);
2415 uint32 get_data_size() const override;
2416 bool init_from_wkt(Gis_read_stream *trs, String *wkb) override;
2417 uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo,
2418 String *res) override;
2419 bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override;
2420 bool get_mbr(MBR *mbr, wkb_parser *wkb) const override;
2421 int num_geometries(uint32 *num) const override;
2422 int geometry_n(uint32 num, String *result) const override;
2423 bool dimension(uint32 *dim, wkb_parser *wkb) const override;
2424 uint32 feature_dimension() const override {
2425 assert(0);
2426 return 0;
2427 }
2428 bool reverse_coordinates() override;
2429 bool validate_coordinate_range(double srs_angular_unit,
2430 bool *long_out_of_range,
2431 bool *lat_out_of_range,
2432 double *out_of_range_value) override;
2433 const Class_info *get_class_info() const override;
2434};
2435
2436/**
2437 Gis_polygon objects and Gis_wkb_vector<> objects are of same size, and
2438 Gis_point and Geometry objects are smaller. They are always allocated
2439 inside a Geometry_buffer object, unless used as boost geometry adapter,
2440 in which case the object may simply placed on stack or new'ed on heap.
2441 */
2443 alignas(Gis_polygon) char data[sizeof(Gis_polygon)];
2444};
2445
2447 public:
2448 virtual ~WKB_scanner_event_handler() = default;
2449
2450 /**
2451 Notified when scanner sees the start of a geometry WKB.
2452 @param bo byte order of the WKB.
2453 @param geotype geometry type of the WKB;
2454 @param wkb WKB byte string, the first byte after the WKB header if any.
2455 @param len NO. of bytes of the WKB byte string starting from wkb.
2456 There can be many geometries in the [wkb, wkb+len) buffer.
2457 @param has_hdr whether there is a WKB header right before 'wkb' in the
2458 byte string.
2459 */
2461 Geometry::wkbType geotype, const void *wkb,
2462 uint32 len, bool has_hdr) = 0;
2463
2464 /**
2465 Notified when scanner sees the end of a geometry WKB.
2466 @param wkb the position of the first byte after the WKB byte string which
2467 the scanner just scanned.
2468 */
2469 virtual void on_wkb_end(const void *wkb) = 0;
2470
2471 /*
2472 Called after each on_wkb_start/end call, if returns false, wkb_scanner
2473 will stop scanning.
2474 */
2475 virtual bool continue_scan() const { return true; }
2476};
2477
2478const char *wkb_scanner(THD *thd, const char *wkb, uint32 *len, uint32 geotype,
2479 bool has_hdr, WKB_scanner_event_handler *handler);
2480#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:746
uint64 zm
Definition: spatial.h:750
uint64 dim
Definition: spatial.h:745
uint64 bo
Definition: spatial.h:744
uint64 nbytes
Definition: spatial.h:748
uint64 props
Definition: spatial.h:749
uint64 unused
Definition: spatial.h:751
Flags_t(wkbType type, size_t len)
Definition: spatial.h:735
Flags_t()
Definition: spatial.h:733
uint64 geotype
Definition: spatial.h:747
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 * m_data
Definition: spatial.h:334
const char * data() const
Definition: spatial.h:346
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
const char * data_end() const
Definition: spatial.h:347
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:1876
Inplace_vector< T > base
Definition: spatial.h:1877
Geometry_vector()
Definition: spatial.h:1880
Definition: spatial.h:214
virtual bool get_data_as_wkt(String *txt, wkb_parser *wkb) const
Definition: spatial.h:489
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:797
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:992
void set_ownmem(bool b)
Set whether this object has its own memory.
Definition: spatial.h:901
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:772
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
void * m_ptr
Pointer to the geometry's wkb data's 1st byte, right after its wkb header if any.
Definition: spatial.h:1040
char * get_cptr() const
Definition: spatial.h:789
static Class_info * ci_collection[wkb_last+1]
Definition: spatial.h:630
virtual bool init_from_wkt(Gis_read_stream *trs, String *wkb)
Definition: spatial.h:474
virtual void shallow_push(const Geometry *)
Definition: spatial.h:1021
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:834
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
static Geometry * construct(Geometry_buffer *buffer, const String *str, bool has_srid=true)
Definition: spatial.h:586
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
Geometry * get_owner() const
Definition: spatial.h:793
Geometry *(* create_geom_t)(char *)
Callback which creates Geometry objects on top of a given placement.
Definition: spatial.h:459
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:1009
void clear_wkb_data()
Geometry()
Definition: spatial.h:756
virtual uint32 feature_dimension() const
Definition: spatial.h:516
void has_out_of_line_components(bool b)
Definition: spatial.h:1013
virtual int num_geometries(uint32 *num) const
Definition: spatial.h:529
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:914
static const uint32 MAX_GEOM_WKB_LENGTH
Definition: spatial.h:274
virtual bool get_mbr(MBR *mbr, wkb_parser *wkb) const
Definition: spatial.h:493
static const int MULTIPOLYGON_NO_OVERLAPPED_COMPS
Definition: spatial.h:270
virtual int geom_length(double *len) const
Definition: spatial.h:523
static bool is_valid_geotype(Geometry::wkbType gt)
Check if a given geometry type is a valid internal geometry type.
Definition: spatial.h:854
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:1048
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:819
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
virtual int get_x(double *x) const
Definition: spatial.h:521
void set_flags(const Flags_t &flags)
Definition: spatial.h:1053
virtual int is_closed(int *closed) const
Definition: spatial.h:524
bool as_wkt(String *wkt) const
Definition: spatial.h:608
static const int GEOM_LENGTH_VERIFIED
Definition: spatial.h:238
virtual int num_interior_ring(uint32 *n_int_rings) const
Definition: spatial.h:525
static Class_info * find_class(int type_id)
Definition: spatial.h:684
static const int POLYGON_INNER_RING
Definition: spatial.h:224
void set_length_verified(bool b) const
Definition: spatial.h:700
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.
virtual int point_n(uint32 num, String *result) const
Definition: spatial.h:535
virtual int num_points(uint32 *n_points) const
Definition: spatial.h:528
void set_owner(Geometry *o)
Definition: spatial.h:795
Geometry * m_owner
The topmost (root) geometry object, whose m_ptr is the 1st byte of a wkb memory buffer.
Definition: spatial.h:1030
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
bool dimension(uint32 *dim) const
Definition: spatial.h:508
static const int HAS_GEOM_HEADER_SPACE
Definition: spatial.h:261
virtual int interior_ring_n(uint32 num, String *result) const
Definition: spatial.h:539
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
void set_ptr(const void *ptr)
Definition: spatial.h:944
Flags_t get_flags() const
Definition: spatial.h:1051
bool get_mbr(MBR *mbr)
Definition: spatial.h:497
void set_props(uint16 flag)
Definition: spatial.h:670
virtual uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res)
Definition: spatial.h:481
void set_dimension(char dim)
Definition: spatial.h:802
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:936
wkbType get_type() const
Definition: spatial.h:512
virtual int get_y(double *y) const
Definition: spatial.h:522
void * get_ptr() const
Definition: spatial.h:787
void polygon_is_wkb_form(bool b)
Definition: spatial.h:996
static const int POLYGON_OUTER_RING
Definition: spatial.h:223
gis::srid_t get_srid() const
Definition: spatial.h:679
virtual int geometry_n(uint32 num, String *result) const
Definition: spatial.h:543
virtual int exterior_ring(String *ring) const
Definition: spatial.h:534
bool get_ownmem() const
Returns whether this object has its own memory.
Definition: spatial.h:907
void set_bg_adapter(bool b) const
Set whether this object is a BG adapter.
Definition: spatial.h:962
Geometry::wkbByteOrder get_byte_order() const
Definition: spatial.h:909
Flags_t m_flags
Flags and meta information about this object.
Definition: spatial.h:1045
uchar * get_ucptr() const
Definition: spatial.h:791
virtual const Class_info * get_class_info() const
Definition: spatial.h:469
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:882
bool is_bg_adapter() const
Whether the Geometry object is created to be used by Boost Geometry or only by MySQL.
Definition: spatial.h:952
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
virtual int start_point(String *point) const
Definition: spatial.h:532
void set_data_ptr(const wkb_container *c)
Definition: spatial.h:621
Geometry::wkbType get_geotype() const
Definition: spatial.h:916
void set_components_no_overlapped(bool b)
Definition: spatial.h:660
virtual void donate_data()
Definition: spatial.h:974
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 bool dimension(uint32 *dim, wkb_parser *wkb) const
Definition: spatial.h:501
void set_nbytes(size_t n) const
Definition: spatial.h:888
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
virtual int end_point(String *point) const
Definition: spatial.h:533
virtual int copy_points(String *result) const
Definition: spatial.h:530
void set_data_ptr(const void *data, size_t data_len)
Definition: spatial.h:616
void * get_data_ptr() const
Definition: spatial.h:625
static const int POLYGON_IN_WKB_FORM
Definition: spatial.h:251
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:938
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:2399
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:2405
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:2424
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:3393
Definition: spatial.h:2089
Gis_line_string(const void *wkb, size_t len, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2125
int point_n(uint32 n, String *result) const override
Definition: spatial.cc:1633
Gis_wkb_vector< Gis_point > base_type
Definition: spatial.h:2118
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:2091
uint32 feature_dimension() const override
Definition: spatial.h:2108
Gis_line_string & operator=(const Gis_line_string &)=default
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:2121
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
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:2323
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:2335
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:2352
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:2348
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:2345
Definition: spatial.h:2280
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:2308
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:2504
static const uint32 max_n_points
Definition: spatial.h:2282
uint32 get_data_size() const override
Definition: spatial.cc:2376
Gis_wkb_vector< Gis_point > base_type
Definition: spatial.h:2305
uint32 feature_dimension() const override
Definition: spatial.h:2295
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:2312
Definition: spatial.h:2363
Gis_multi_polygon(const void *ptr, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2389
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:2383
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:2927
uint32 feature_dimension() const override
Definition: spatial.h:2373
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:2385
uint init_from_wkb(THD *thd, const char *wkb, uint len, wkbByteOrder bo, String *res) override
Definition: spatial.cc:2890
Definition: spatial.h:1142
int get_y(double *y) const override
Definition: spatial.h:1172
Gis_point(bool is_bg_adapter=true)
Definition: spatial.h:1189
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:1196
bool operator<(const Gis_point &pt) const
Definition: spatial.h:1265
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:1168
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.cc:1413
int get_xy(point_xy *p) const
Definition: spatial.h:1164
bool operator!=(const Gis_point &pt) const
Definition: spatial.h:1274
double get() const
Get a coordinate.
Definition: spatial.h:1219
uint32 feature_dimension() const override
Definition: spatial.h:1176
Geometry base
Definition: spatial.h:1187
bool init_from_wkt(Gis_read_stream *trs, String *wkb) override
Definition: spatial.h:1156
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:1270
void set(double const &value)
Set a coordinate.
Definition: spatial.h:1244
Definition: spatial.h:2142
Gis_polygon_ring(const self &r)=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:2144
Gis_polygon_ring & operator=(const Gis_polygon_ring &)=default
~Gis_polygon_ring() override=default
Gis_polygon_ring()
Definition: spatial.h:2160
Gis_polygon_ring(const void *wkb, size_t nbytes, const Flags_t &flags, gis::srid_t srid)
Definition: spatial.h:2148
Definition: spatial.h:2177
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:2188
inner_container_type * m_inn_rings
Definition: spatial.h:2273
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
void set_inner_rings(inner_container_type *inns) SUPPRESS_UBSAN
Definition: spatial.h:2268
void clear()
Clears outer and inner rings.
Definition: spatial.h:2222
bool get_data_as_wkt(String *txt, wkb_parser *wkb) const override
Definition: spatial.cc:2118
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:2198
void to_wkb_unparsed()
Make the polygon's data in a single buffer as WKB format.
Definition: spatial.cc:1843
ring_type & outer() const
Definition: spatial.h:2201
void donate_data() override
Definition: spatial.h:2253
inner_container_type * inner_rings() const SUPPRESS_UBSAN
Definition: spatial.h:2263
Gis_polygon(bool isbgadapter=true)
Definition: spatial.h:2235
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
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:2199
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
inner_container_type & inners() const
Definition: spatial.h:2211
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:1306
bool operator>=(const self &itr) const
Greater equal comparison operator.
Definition: spatial.h:1404
bool operator==(const self &itr) const
Equality comparison operator.
Definition: spatial.h:1377
void move_by(self &itr, difference_type n, bool back) const
Definition: spatial.h:1600
Gis_wkb_vector< T > owner_t
Definition: spatial.h:1309
const self & operator=(const self &itr)
Assignment operator.
Definition: spatial.h:1483
value_type & reference
This is the return type for operator[].
Definition: spatial.h:1323
owner_t::size_type size_type
Definition: spatial.h:1320
const self & operator-=(difference_type n)
Move this iterator backward by n elements.
Definition: spatial.h:1528
self & operator++()
Pre-increment.
Definition: spatial.h:1435
self operator+(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1495
Gis_wkb_vector_const_iterator(index_type idx, const owner_t *owner)
Definition: spatial.h:1347
std::random_access_iterator_tag iterator_category
Definition: spatial.h:1327
ptrdiff_t index_type
Definition: spatial.h:1310
self & operator--()
Pre-decrement.
Definition: spatial.h:1459
bool operator>(const self &itr) const
Greater comparison operator.
Definition: spatial.h:1410
index_type m_curidx
Current element's index, starting from 0.
Definition: spatial.h:1616
self operator++(int)
Post-increment.
Definition: spatial.h:1446
owner_t * m_owner
The owner container of this iteraotr.
Definition: spatial.h:1618
difference_type operator-(const self &itr) const
Iterator distance operator.
Definition: spatial.h:1543
self operator--(int)
Post-decrement.
Definition: spatial.h:1471
Gis_wkb_vector_const_iterator()
Definition: spatial.h:1342
difference_type distance_type
Definition: spatial.h:1319
const self & operator+=(difference_type n)
Move this iterator forward by n elements.
Definition: spatial.h:1505
T value_type
Definition: spatial.h:1317
bool operator<=(const self &itr) const
Less equal comparison operator.
Definition: spatial.h:1399
pointer operator->() const
Arrow operator.
Definition: spatial.h:1572
ptrdiff_t difference_type
Definition: spatial.h:1318
reference operator*() const
Dereference operator.
Definition: spatial.h:1560
bool operator<(const self &itr) const
Less than comparison operator.
Definition: spatial.h:1391
reference operator[](difference_type offset) const
Iterator index operator.
Definition: spatial.h:1585
self operator-(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1517
value_type * pointer
Definition: spatial.h:1324
bool operator!=(const self &itr) const
Unequal compare, identical to !operator(==itr)
Definition: spatial.h:1385
Gis_wkb_vector_const_iterator(const self &vi)
Definition: spatial.h:1337
This class is the iterator class for Gis_wkb_vector, its instances can be used to mutate their refere...
Definition: spatial.h:1630
difference_type distance_type
Definition: spatial.h:1640
Gis_wkb_vector_iterator(const base &obj)
Definition: spatial.h:1658
Gis_wkb_vector_iterator(index_type idx, const owner_t *owner)
Definition: spatial.h:1660
ptrdiff_t index_type
Definition: spatial.h:1637
self operator-(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1760
value_type & reference
Definition: spatial.h:1641
Gis_wkb_vector_iterator(const self &vi)
Definition: spatial.h:1654
const self & operator-=(difference_type n)
Move this iterator forward by n elements.
Definition: spatial.h:1772
value_type * pointer
Definition: spatial.h:1642
std::random_access_iterator_tag iterator_category
Definition: spatial.h:1644
reference operator*() const
Dereference operator.
Definition: spatial.h:1805
pointer operator->() const
Arrow operator.
Definition: spatial.h:1817
self operator++(int)
Post-increment.
Definition: spatial.h:1692
Gis_wkb_vector_const_iterator< T > base
Definition: spatial.h:1633
const self & operator+=(difference_type n)
Move this iterator backward by n elements.
Definition: spatial.h:1747
Gis_wkb_vector< T > owner_t
Definition: spatial.h:1634
Gis_wkb_vector_iterator()
Definition: spatial.h:1656
self operator+(difference_type n) const
Iterator movement operator.
Definition: spatial.h:1736
ptrdiff_t difference_type
Definition: spatial.h:1639
self & operator--()
Pre-decrement.
Definition: spatial.h:1702
const self & operator=(const self &itr)
Assignment operator.
Definition: spatial.h:1722
reference operator[](difference_type offset) const
Iterator index operator.
Definition: spatial.h:1829
self & operator++()
Pre-increment.
Definition: spatial.h:1684
self operator--(int)
Post-decrement.
Definition: spatial.h:1710
difference_type operator-(const self &itr) const
Iterator distance operator.
Definition: spatial.h:1788
~Gis_wkb_vector_iterator()=default
T value_type
Definition: spatial.h:1638
Gis_wkb_vector class template definition.
Definition: spatial.h:1892
const_iterator end() const
Create an open boundary iterator.
Definition: spatial.h:1951
size_t size_type
Definition: spatial.h:1902
iterator end()
Create an open boundary iterator.
Definition: spatial.h:1943
const_reference back() const
Definition: spatial.h:1968
void set_geo_vect(Geo_vector *ptr)
Definition: spatial.h:2049
iterator begin()
Definition: spatial.h:1923
T value_type
Definition: spatial.h:1899
const_iterator begin() const
Create a const iterator.
Definition: spatial.h:1934
ptrdiff_t index_type
Definition: spatial.h:1895
bool reverse_coordinates() override
Reverses the coordinates of a geometry.
Definition: spatial.h:2070
const_reference operator[](index_type i) const
Definition: spatial.h:1988
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:1903
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:4572
ptrdiff_t difference_type
Definition: spatial.h:1907
size_t get_nbytes_free() const
Get number of free bytes in the buffer held by m_ptr.
Definition: spatial.cc:4679
Gis_wkb_vector< Gis_point > Linestring
Definition: spatial.h:2080
size_t current_size() const
Returns payload number of bytes of the topmost geometry holding this geometry, i.e.
Definition: spatial.cc:4666
void donate_data() override
Definition: spatial.h:2056
void clear()
Update support We suppose updating a geometry can happen in the following ways:
Definition: spatial.cc:4641
reference back()
Definition: spatial.h:1978
bool validate_coordinate_range(double, bool *, bool *, double *) override
Check that the coordinates of a geometry is within the valid range.
Definition: spatial.h:2074
void clear_wkb_data()
Definition: spatial.h:2032
Gis_wkb_vector_iterator< T > iterator
Definition: spatial.h:1901
const T & const_reference
Definition: spatial.h:1904
self & operator=(const self &rhs)
Deep assignment from vector 'rhs' to this object.
Definition: spatial.cc:4495
Gis_wkb_vector_const_iterator< T > const_iterator
Definition: spatial.h:1900
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:1916
size_type size() const
Get container size.
Definition: spatial.h:1961
T * pointer
Definition: spatial.h:1905
~Gis_wkb_vector() override
Definition: spatial.h:2010
void resize(size_t sz)
Definition: spatial.cc:4841
Geometry base
Definition: spatial.h:1896
bool empty() const
Definition: spatial.h:1966
Geo_vector * get_geo_vect(bool create_if_null=false)
Definition: spatial.h:2042
reference operator[](index_type i)
Definition: spatial.h:1996
void set_ptr(void *ptr, size_t len)
Definition: spatial.cc:4596
Geo_vector * get_geo_vect() const
Definition: spatial.h:2047
Gis_wkb_vector< Linestring > Multi_linestrings
Definition: spatial.h:2081
T & reference
Definition: spatial.h:1906
Geometry_vector< T > Geo_vector
Definition: spatial.h:1909
void push_back(const T &val)
Definition: spatial.cc:4702
Gis_wkb_vector()
Definition: spatial.h:2008
Utility container class to store elements stably and scalably.
Definition: inplace_vector.h:59
const objtype & back() const
STL std::vector::back interface.
Definition: inplace_vector.h:224
size_t size() const
STL std::vector::size interface.
Definition: inplace_vector.h:198
Using this class is fraught with peril, and you need to be very careful when doing so.
Definition: sql_string.h:166
bool append(const String &s)
Definition: sql_string.cc:445
bool reserve(size_t space_needed)
Definition: sql_string.h:555
For each client connection we create a separate thread with THD serving as a thread/connection descri...
Definition: sql_class.h:945
Definition: spatial.h:2446
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:2475
virtual ~WKB_scanner_event_handler()=default
The handler class is the interface for dynamically loadable storage engines.
Definition: handler.h:4157
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
#define U
Definition: ctype-tis620.cc:74
Fido Client Authentication nullptr
Definition: fido_client_plugin.cc:221
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:1055
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 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
Gis_polygon_ring * outer_ring(const Geometry *g)
Definition: spatial.h:2170
void * gis_wkb_realloc(void *p, size_t sz)
Definition: spatial.cc:63
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:1074
const uint GEOM_HEADER_SIZE
Definition: spatial.h:54
const uint GEOM_DIM
Definition: spatial.h:49
void set_byte_order(void *p0, Geometry::wkbByteOrder bo)
Definition: spatial.h:1063
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 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:1056
void * gis_wkb_alloc(size_t sz)
Definition: spatial.cc:55
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_raw_free(void *p)
Definition: spatial.h:212
void own_rings(Geometry *geo)
Definition: spatial.cc:2367
char * write_wkb_header(void *p0, Geometry::wkbType geotype)
Definition: spatial.h:1086
const uint POINT_DATA_SIZE
Definition: spatial.h:52
struct wkb_header_st wkb_header
char * write_geometry_header(void *p0, gis::srid_t srid, Geometry::wkbType geotype)
Definition: spatial.h:1102
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:1846
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
void * gis_wkb_fixed_alloc(size_t sz)
Definition: spatial.h:202
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:2442
char data[sizeof(Gis_polygon)]
Definition: spatial.h:2443
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:675
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:506
int n
Definition: xcom_base.cc:505