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