1 #ifndef GIS_BG_TRAITS_INCLUDED 2 #define GIS_BG_TRAITS_INCLUDED 3 4 /* Copyright (c) 2014, 2021, Oracle and/or its affiliates. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License, version 2.0, 8 as published by the Free Software Foundation. 9 10 This program is also distributed with certain software (including 11 but not limited to OpenSSL) that is licensed under separate terms, 12 as designated in a particular file or component or in included license 13 documentation. The authors of MySQL hereby grant you an additional 14 permission to link the program and your derivative works with the 15 separately licensed software that they have included with MySQL. 16 17 This program is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License, version 2.0, for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program; if not, write to the Free Software Foundation, 24 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 25 */ 26 27 28 /* This file defines all boost geometry traits. */ 29 30 #include <boost/static_assert.hpp> 31 32 #include <boost/geometry/core/access.hpp> 33 #include <boost/geometry/core/coordinate_type.hpp> 34 #include <boost/geometry/core/coordinate_system.hpp> 35 #include <boost/geometry/core/coordinate_dimension.hpp> 36 #include <boost/geometry/core/interior_type.hpp> 37 #include <boost/geometry/core/ring_type.hpp> 38 #include <boost/geometry/core/exterior_ring.hpp> 39 #include <boost/geometry/core/interior_rings.hpp> 40 #include <boost/geometry/core/point_order.hpp> 41 #include <boost/geometry/core/closure.hpp> 42 #include <boost/geometry/core/tags.hpp> 43 #include <boost/geometry/core/cs.hpp> 44 #include <boost/geometry/multi/core/tags.hpp> 45 #include <boost/geometry/util/math.hpp> 46 #include <boost/concept/requires.hpp> 47 48 #include <boost/geometry/geometries/concepts/point_concept.hpp> 49 #include <boost/geometry/geometries/concepts/linestring_concept.hpp> 50 #include <boost/geometry/geometries/concepts/polygon_concept.hpp> 51 52 #include "spatial.h" 53 54 /** 55 Helper class for spherical, spherical_equaltorial(i.e. geography) 56 coordinate systems. Every Geometry subclass will need one. 57 */ 58 class Gis_point_spherical: public Gis_point 59 { 60 public: 61 explicit Gis_point_spherical(bool is_bg_adapter= true) Gis_point(is_bg_adapter)62 :Gis_point(is_bg_adapter) 63 { 64 } 65 66 /// @brief Default constructor, no initialization. Gis_point_spherical(const void * ptr,size_t nbytes,const Flags_t & flags,srid_t srid)67 Gis_point_spherical(const void *ptr, size_t nbytes, 68 const Flags_t &flags, srid_t srid) 69 :Gis_point(ptr, nbytes, flags, srid) 70 { 71 } 72 }; 73 74 75 class Gis_multi_point_spherical: public Gis_wkb_vector<Gis_point_spherical> 76 { 77 typedef Gis_wkb_vector<Gis_point_spherical> base_type; 78 public: 79 /**** Boost Geometry Adapter Interface ******/ 80 explicit Gis_multi_point_spherical(bool is_bg_adapter= true) 81 :base_type(NULL, 0, Flags_t(wkb_multipoint, 0), 82 default_srid, is_bg_adapter) 83 {} 84 Gis_multi_point_spherical(const void * ptr,size_t nbytes,const Flags_t & flags,srid_t srid)85 Gis_multi_point_spherical(const void *ptr, size_t nbytes, 86 const Flags_t &flags, srid_t srid) 87 :base_type(ptr, nbytes, flags, srid, true) 88 { 89 set_geotype(wkb_multipoint); 90 } 91 }; 92 93 94 class Gis_line_string_spherical : public Gis_wkb_vector<Gis_point_spherical> 95 { 96 typedef Gis_wkb_vector<Gis_point_spherical> base_type; 97 public: 98 explicit Gis_line_string_spherical(bool is_bg_adapter= true) 99 :base_type(NULL, 0, Flags_t(wkb_linestring, 0), default_srid, is_bg_adapter) 100 {} 101 Gis_line_string_spherical(const void * wkb,size_t len,const Flags_t & flags,srid_t srid)102 Gis_line_string_spherical(const void *wkb, size_t len, 103 const Flags_t &flags, srid_t srid) 104 :base_type(wkb, len, flags, srid, true) 105 { 106 set_geotype(wkb_linestring); 107 } 108 }; 109 110 111 class Gis_polygon_ring_spherical : public Gis_wkb_vector<Gis_point_spherical> 112 { 113 typedef Gis_wkb_vector<Gis_point_spherical> base_type; 114 public: Gis_polygon_ring_spherical(const void * wkb,size_t nbytes,const Flags_t & flags,srid_t srid)115 Gis_polygon_ring_spherical(const void *wkb, size_t nbytes, 116 const Flags_t &flags, srid_t srid) 117 :base_type(wkb, nbytes, flags, srid, true) 118 { 119 set_geotype(wkb_linestring); 120 } 121 Gis_polygon_ring_spherical()122 Gis_polygon_ring_spherical() 123 :base_type(NULL, 0, Flags_t(Geometry::wkb_linestring, 0), 124 default_srid, true) 125 {} 126 }; 127 128 129 /* 130 It's OK to derive from Gis_polygon because Gis_polygon doesn't derive from 131 Gis_wkb_vector<T>, and when its rings are accessed, the right ring type will 132 be used and hence the right point type will be used via iterator types. 133 */ 134 class Gis_polygon_spherical : public Gis_polygon 135 { 136 typedef Gis_polygon base_type; 137 public: 138 typedef Gis_polygon_ring_spherical ring_type; 139 typedef Gis_wkb_vector<ring_type> inner_container_type; 140 Gis_polygon_spherical(const void * wkb,size_t nbytes,const Flags_t & flags,srid_t srid)141 Gis_polygon_spherical(const void *wkb, size_t nbytes, 142 const Flags_t &flags, srid_t srid) 143 :base_type(wkb, nbytes, flags, srid) 144 { 145 } 146 base_type(isbgadapter)147 explicit Gis_polygon_spherical(bool isbgadapter= true) :base_type(isbgadapter) 148 { 149 } 150 151 /* 152 We have to define them here because the ring_type isn't the same. 153 The Gis_polygon_ring_spherical has nothing extra than Gis_polygon_ring, 154 so we can do so. 155 */ outer()156 ring_type &outer() const 157 { 158 return *(reinterpret_cast<ring_type *>(&base_type::outer())); 159 } 160 inners()161 inner_container_type &inners() const 162 { 163 return *(reinterpret_cast<inner_container_type *>(&base_type::inners())); 164 } 165 }; 166 167 168 class Gis_multi_line_string_spherical : 169 public Gis_wkb_vector<Gis_line_string_spherical> 170 { 171 typedef Gis_wkb_vector<Gis_line_string_spherical> base_type; 172 public: 173 explicit Gis_multi_line_string_spherical(bool is_bg_adapter= true) 174 :base_type(NULL, 0, Flags_t(wkb_multilinestring, 0), 175 default_srid, is_bg_adapter) 176 {} 177 Gis_multi_line_string_spherical(const void * ptr,size_t nbytes,const Flags_t & flags,srid_t srid)178 Gis_multi_line_string_spherical(const void *ptr, size_t nbytes, 179 const Flags_t &flags, srid_t srid) 180 :base_type(ptr, nbytes, flags, srid, true) 181 { 182 set_geotype(wkb_multilinestring); 183 } 184 }; 185 186 187 class Gis_multi_polygon_spherical : public Gis_wkb_vector<Gis_polygon_spherical> 188 { 189 typedef Gis_wkb_vector<Gis_polygon_spherical> base_type; 190 public: 191 explicit Gis_multi_polygon_spherical(bool is_bg_adapter= true) 192 :base_type(NULL, 0, Flags_t(wkb_multipolygon, 0), default_srid, is_bg_adapter) 193 {} 194 Gis_multi_polygon_spherical(const void * ptr,size_t nbytes,const Flags_t & flags,srid_t srid)195 Gis_multi_polygon_spherical(const void *ptr, size_t nbytes, 196 const Flags_t &flags, srid_t srid) 197 :base_type(ptr, nbytes, flags, srid, true) 198 { 199 set_geotype(wkb_multipolygon); 200 } 201 }; 202 203 204 // Boost Geometry traits. 205 namespace boost { namespace geometry 206 { 207 namespace traits 208 { 209 template<> 210 struct tag<Gis_point> 211 { 212 typedef boost::geometry::point_tag type; 213 }; 214 215 template<> 216 struct coordinate_type<Gis_point> 217 { 218 typedef double type; 219 }; 220 221 template<> 222 struct coordinate_system<Gis_point> 223 { 224 typedef boost::geometry::cs::cartesian type; 225 }; 226 227 template<> 228 struct dimension<Gis_point> 229 : boost::mpl::int_<GEOM_DIM> 230 {}; 231 232 template<std::size_t Dimension> 233 struct access<Gis_point, Dimension> 234 { 235 static inline double get( 236 Gis_point const& p) 237 { 238 return p.get<Dimension>(); 239 } 240 241 static inline void set( 242 Gis_point &p, 243 double const& value) 244 { 245 p.set<Dimension>(value); 246 } 247 }; 248 249 250 template<> 251 struct tag<Gis_point_spherical> 252 { 253 typedef boost::geometry::point_tag type; 254 }; 255 256 template<> 257 struct coordinate_type<Gis_point_spherical> 258 { 259 typedef double type; 260 }; 261 262 template<> 263 struct coordinate_system<Gis_point_spherical> 264 { 265 typedef boost::geometry::cs::spherical_equatorial< 266 boost::geometry::degree> type; 267 }; 268 269 template<> 270 struct dimension<Gis_point_spherical> 271 : boost::mpl::int_<GEOM_DIM> 272 {}; 273 274 template<std::size_t Dimension> 275 struct access<Gis_point_spherical, Dimension> 276 { 277 static inline double get( 278 Gis_point_spherical const& p) 279 { 280 return p.get<Dimension>(); 281 } 282 283 static inline void set( 284 Gis_point_spherical &p, 285 double const& value) 286 { 287 p.set<Dimension>(value); 288 } 289 }; 290 ////////////////////////////////// LINESTRING //////////////////////////// 291 template<> 292 struct tag<Gis_line_string> 293 { 294 typedef boost::geometry::linestring_tag type; 295 }; 296 template<> 297 struct tag<Gis_line_string_spherical> 298 { 299 typedef boost::geometry::linestring_tag type; 300 }; 301 302 303 ////////////////////////////////// POLYGON ////////////////////////////////// 304 305 306 template<> 307 struct tag 308 < 309 Gis_polygon 310 > 311 { 312 typedef boost::geometry::polygon_tag type; 313 }; 314 315 316 template<> 317 struct ring_const_type 318 < 319 Gis_polygon 320 > 321 { 322 typedef Gis_polygon::ring_type const& type; 323 }; 324 325 326 template<> 327 struct ring_mutable_type 328 < 329 Gis_polygon 330 > 331 { 332 typedef Gis_polygon::ring_type& type; 333 }; 334 335 template<> 336 struct interior_const_type 337 < 338 Gis_polygon 339 > 340 { 341 typedef Gis_polygon::inner_container_type const& type; 342 }; 343 344 345 template<> 346 struct interior_mutable_type 347 < 348 Gis_polygon 349 > 350 { 351 typedef Gis_polygon::inner_container_type& type; 352 }; 353 354 template<> 355 struct exterior_ring 356 < 357 Gis_polygon 358 > 359 { 360 typedef Gis_polygon polygon_type; 361 362 static inline polygon_type::ring_type& get(polygon_type& p) 363 { 364 return p.outer(); 365 } 366 367 static inline polygon_type::ring_type const& get( 368 polygon_type const& p) 369 { 370 return p.outer(); 371 } 372 }; 373 374 template<> 375 struct interior_rings 376 < 377 Gis_polygon 378 > 379 { 380 typedef Gis_polygon polygon_type; 381 382 static inline polygon_type::inner_container_type& get( 383 polygon_type& p) 384 { 385 return p.inners(); 386 } 387 388 static inline polygon_type::inner_container_type const& get( 389 polygon_type const& p) 390 { 391 return p.inners(); 392 } 393 }; 394 395 template<> 396 struct tag 397 < 398 Gis_polygon_spherical 399 > 400 { 401 typedef boost::geometry::polygon_tag type; 402 }; 403 404 405 template<> 406 struct ring_const_type 407 < 408 Gis_polygon_spherical 409 > 410 { 411 typedef Gis_polygon_spherical::ring_type const& type; 412 }; 413 414 415 template<> 416 struct ring_mutable_type 417 < 418 Gis_polygon_spherical 419 > 420 { 421 typedef Gis_polygon_spherical::ring_type& type; 422 }; 423 424 template<> 425 struct interior_const_type 426 < 427 Gis_polygon_spherical 428 > 429 { 430 typedef Gis_polygon_spherical::inner_container_type const& type; 431 }; 432 433 434 template<> 435 struct interior_mutable_type 436 < 437 Gis_polygon_spherical 438 > 439 { 440 typedef Gis_polygon_spherical::inner_container_type& type; 441 }; 442 443 template<> 444 struct exterior_ring 445 < 446 Gis_polygon_spherical 447 > 448 { 449 typedef Gis_polygon_spherical polygon_type; 450 451 static inline polygon_type::ring_type& get(polygon_type& p) 452 { 453 return p.outer(); 454 } 455 456 static inline polygon_type::ring_type const& get( 457 polygon_type const& p) 458 { 459 return p.outer(); 460 } 461 }; 462 463 template<> 464 struct interior_rings 465 < 466 Gis_polygon_spherical 467 > 468 { 469 typedef Gis_polygon_spherical polygon_type; 470 471 static inline polygon_type::inner_container_type& get( 472 polygon_type& p) 473 { 474 return p.inners(); 475 } 476 477 static inline polygon_type::inner_container_type const& get( 478 polygon_type const& p) 479 { 480 return p.inners(); 481 } 482 }; 483 ////////////////////////////////// RING ////////////////////////////////// 484 template<> 485 struct point_order<Gis_polygon_ring> 486 { 487 static const order_selector value = counterclockwise; 488 }; 489 490 template<> 491 struct closure<Gis_polygon_ring> 492 { 493 static const closure_selector value = closed; 494 }; 495 496 template<> 497 struct tag<Gis_polygon_ring> 498 { 499 typedef boost::geometry::ring_tag type; 500 }; 501 502 503 template<> 504 struct point_order<Gis_polygon_ring_spherical> 505 { 506 static const order_selector value = counterclockwise; 507 }; 508 509 template<> 510 struct closure<Gis_polygon_ring_spherical> 511 { 512 static const closure_selector value = closed; 513 }; 514 515 template<> 516 struct tag<Gis_polygon_ring_spherical> 517 { 518 typedef boost::geometry::ring_tag type; 519 }; 520 521 522 ////////////////////////////////// MULTI GEOMETRIES ///////////////////////// 523 524 525 /////////////////////////////////// multi linestring types ///////////////////// 526 template<> 527 struct tag< Gis_multi_line_string> 528 { 529 typedef boost::geometry::multi_linestring_tag type; 530 }; 531 532 template<> 533 struct tag< Gis_multi_line_string_spherical> 534 { 535 typedef boost::geometry::multi_linestring_tag type; 536 }; 537 538 539 /////////////////////////////////// multi point types ///////////////////// 540 541 542 template<> 543 struct tag< Gis_multi_point> 544 { 545 typedef boost::geometry::multi_point_tag type; 546 }; 547 548 template<> 549 struct tag< Gis_multi_point_spherical> 550 { 551 typedef boost::geometry::multi_point_tag type; 552 }; 553 554 555 /////////////////////////////////// multi polygon types ///////////////////// 556 template<> 557 struct tag< Gis_multi_polygon> 558 { 559 typedef boost::geometry::multi_polygon_tag type; 560 }; 561 562 template<> 563 struct tag< Gis_multi_polygon_spherical> 564 { 565 typedef boost::geometry::multi_polygon_tag type; 566 }; 567 568 569 } // namespace traits 570 571 } // namespace geometry 572 } // namespace boost 573 574 575 #endif // !GIS_BG_TRAITS_INCLUDED 576