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