MySQL  8.0.28
Source Code Documentation
functor.h
Go to the documentation of this file.
1 #ifndef SQL_GIS_FUNCTOR_H_INCLUDED
2 #define SQL_GIS_FUNCTOR_H_INCLUDED
3 // Copyright (c) 2017, 2021, Oracle and/or its affiliates.
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License, version 2.0,
7 // as published by the Free Software Foundation.
8 //
9 // This program is also distributed with certain software (including
10 // but not limited to OpenSSL) that is licensed under separate terms,
11 // as designated in a particular file or component or in included license
12 // documentation. The authors of MySQL hereby grant you an additional
13 // permission to link the program and your derivative works with the
14 // separately licensed software that they have included with MySQL.
15 //
16 // This program is distributed in the hope that it will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU General Public License, version 2.0, for more details.
20 //
21 // You should have received a copy of the GNU General Public License
22 // along with this program; if not, write to the Free Software
23 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
24 
25 /// @file
26 ///
27 /// This file contains the superclasses for GIS functors.
28 ///
29 /// Each GIS function is split in two: a functor class (for internal use) and a
30 /// function (for external use) that uses the functor. The functor provides the
31 /// internal interface to GIS functions, and it may throw exceptions. Some
32 /// functions may need a combination of different functors to implement the
33 /// desired functionality.
34 ///
35 /// The function, not the functor, is the interface to the rest of MySQL.
36 ///
37 /// @see distance_functor.h
38 
39 #include <assert.h>
40 #include <exception> // std::exception
41 #include <sstream> // std::stringstream
42 #include <string> // std::string
43 
44 // assert
45 #include "sql/gis/geometries.h" // gis::{Geometry{,_type}, Coordinate_system}
46 #include "sql/gis/geometries_cs.h" // gis::{Cartesian_*, Geographic_*}
47 #include "template_utils.h" // down_cast
48 
49 namespace gis {
50 
51 /// Longitude out of range exception
52 ///
53 /// Thrown by GIS functors when longtitude is out of range when reinterpreting
54 /// geometry coordinates.
55 struct longitude_out_of_range_exception : public std::exception {
56  double value;
57  double range_min;
58  double range_max;
59 
61  double range_max)
63 };
64 
65 /// Latitude out of range exception
66 ///
67 /// Thrown by GIS functors when latitude is out of range when reinterpreting
68 /// geometry coordinates.
69 struct latitude_out_of_range_exception : public std::exception {
70  double value;
71  double range_min;
72  double range_max;
73 
75  double range_max)
77 };
78 
79 /// Function/parameter combination not implemented exception.
80 ///
81 /// Geometry is tagged as geographic or Cartesian/projected. In the latter case,
82 /// whether it is Cartesian or projected is determined by the accompanying SRS.
83 ///
84 /// To obtain an instance of this exception, use
85 /// not_implemented_exception::for_projected if geometry is projected, and
86 /// not_implemented_exception::for_non_projected otherwise.
87 class not_implemented_exception : public std::exception {
88  public:
90 
91  private:
93 
94  std::string m_typenames;
95 
98  m_typenames = std::string(type_to_name(g.type()));
99  }
100 
102  const Geometry &g2) {
103  assert(g1.coordinate_system() == g2.coordinate_system());
105  std::stringstream ss;
106  ss << type_to_name(g1.type()) << ", " << type_to_name(g2.type());
107  m_typenames = ss.str();
108  }
109 
110  public:
111  Srs_type srs_type() const { return m_srs_type; }
112  const char *typenames() const { return m_typenames.c_str(); }
113 
116  }
117 
119  const Geometry &g2) {
120  return not_implemented_exception(kProjected, g1, g2);
121  }
122 
124  switch (g.coordinate_system()) {
125  default:
126  assert(false); // C++11 woes. /* purecov: inspected */
131  }
132  }
133 
135  const Geometry &g2) {
136  switch (g1.coordinate_system()) {
137  default:
138  assert(false); // C++11 woes. /* purecov: inspected */
140  return not_implemented_exception(kCartesian, g1, g2);
142  return not_implemented_exception(kGeographic, g1, g2);
143  }
144  }
145 };
146 
147 /// NULL value exception.
148 ///
149 /// Thrown when the functor discovers that the result is NULL. Normally, NULL
150 /// returns can be detected before calling the functor, but not always.
151 class null_value_exception : public std::exception {};
152 
153 /// The base class of all functors that takes two geometry arguments.
154 ///
155 /// Subclasses of this functor base class will implement operator() and call
156 /// apply() to do type combination dispatching. The actual body of the functor
157 /// is in the eval() member function, which must be implemented for each
158 /// different parameter type combination.
159 ///
160 /// The functor may throw exceptions.
161 ///
162 /// @tparam T The return type of the functor.
163 template <typename T>
164 class Functor {
165  public:
166  virtual T operator()(const Geometry *g1, const Geometry *g2) const = 0;
167  virtual ~Functor() = default;
168 
169  protected:
170  template <typename F>
171  static inline T apply(F &f, const Geometry *g1, const Geometry *g2) {
172  assert(g1->coordinate_system() == g2->coordinate_system());
173  switch (g1->coordinate_system()) {
175  switch (g1->type()) {
177  switch (g2->type()) {
179  return f.eval(down_cast<const Cartesian_point *>(g1),
180  down_cast<const Cartesian_point *>(g2));
182  return f.eval(down_cast<const Cartesian_point *>(g1),
183  down_cast<const Cartesian_linestring *>(g2));
185  return f.eval(down_cast<const Cartesian_point *>(g1),
186  down_cast<const Cartesian_polygon *>(g2));
188  return f.eval(
189  down_cast<const Cartesian_point *>(g1),
190  down_cast<const Cartesian_geometrycollection *>(g2));
192  return f.eval(down_cast<const Cartesian_point *>(g1),
193  down_cast<const Cartesian_multipoint *>(g2));
195  return f.eval(down_cast<const Cartesian_point *>(g1),
196  down_cast<const Cartesian_multilinestring *>(g2));
198  return f.eval(down_cast<const Cartesian_point *>(g1),
199  down_cast<const Cartesian_multipolygon *>(g2));
200  default:
201  assert(false); /* purecov: inspected */
203  }
205  switch (g2->type()) {
207  return f.eval(down_cast<const Cartesian_linestring *>(g1),
208  down_cast<const Cartesian_point *>(g2));
210  return f.eval(down_cast<const Cartesian_linestring *>(g1),
211  down_cast<const Cartesian_linestring *>(g2));
213  return f.eval(down_cast<const Cartesian_linestring *>(g1),
214  down_cast<const Cartesian_polygon *>(g2));
216  return f.eval(
217  down_cast<const Cartesian_linestring *>(g1),
218  down_cast<const Cartesian_geometrycollection *>(g2));
220  return f.eval(down_cast<const Cartesian_linestring *>(g1),
221  down_cast<const Cartesian_multipoint *>(g2));
223  return f.eval(down_cast<const Cartesian_linestring *>(g1),
224  down_cast<const Cartesian_multilinestring *>(g2));
226  return f.eval(down_cast<const Cartesian_linestring *>(g1),
227  down_cast<const Cartesian_multipolygon *>(g2));
228  default:
229  assert(false); /* purecov: inspected */
231  }
233  switch (g2->type()) {
235  return f.eval(down_cast<const Cartesian_polygon *>(g1),
236  down_cast<const Cartesian_point *>(g2));
238  return f.eval(down_cast<const Cartesian_polygon *>(g1),
239  down_cast<const Cartesian_linestring *>(g2));
241  return f.eval(down_cast<const Cartesian_polygon *>(g1),
242  down_cast<const Cartesian_polygon *>(g2));
244  return f.eval(
245  down_cast<const Cartesian_polygon *>(g1),
246  down_cast<const Cartesian_geometrycollection *>(g2));
248  return f.eval(down_cast<const Cartesian_polygon *>(g1),
249  down_cast<const Cartesian_multipoint *>(g2));
251  return f.eval(down_cast<const Cartesian_polygon *>(g1),
252  down_cast<const Cartesian_multilinestring *>(g2));
254  return f.eval(down_cast<const Cartesian_polygon *>(g1),
255  down_cast<const Cartesian_multipolygon *>(g2));
256  default:
257  assert(false); /* purecov: inspected */
259  }
261  switch (g2->type()) {
263  return f.eval(
264  down_cast<const Cartesian_geometrycollection *>(g1),
265  down_cast<const Cartesian_point *>(g2));
267  return f.eval(
268  down_cast<const Cartesian_geometrycollection *>(g1),
269  down_cast<const Cartesian_linestring *>(g2));
271  return f.eval(
272  down_cast<const Cartesian_geometrycollection *>(g1),
273  down_cast<const Cartesian_polygon *>(g2));
275  return f.eval(
276  down_cast<const Cartesian_geometrycollection *>(g1),
277  down_cast<const Cartesian_geometrycollection *>(g2));
279  return f.eval(
280  down_cast<const Cartesian_geometrycollection *>(g1),
281  down_cast<const Cartesian_multipoint *>(g2));
283  return f.eval(
284  down_cast<const Cartesian_geometrycollection *>(g1),
285  down_cast<const Cartesian_multilinestring *>(g2));
287  return f.eval(
288  down_cast<const Cartesian_geometrycollection *>(g1),
289  down_cast<const Cartesian_multipolygon *>(g2));
290  default:
291  assert(false); /* purecov: inspected */
293  }
295  switch (g2->type()) {
297  return f.eval(down_cast<const Cartesian_multipoint *>(g1),
298  down_cast<const Cartesian_point *>(g2));
300  return f.eval(down_cast<const Cartesian_multipoint *>(g1),
301  down_cast<const Cartesian_linestring *>(g2));
303  return f.eval(down_cast<const Cartesian_multipoint *>(g1),
304  down_cast<const Cartesian_polygon *>(g2));
306  return f.eval(
307  down_cast<const Cartesian_multipoint *>(g1),
308  down_cast<const Cartesian_geometrycollection *>(g2));
310  return f.eval(down_cast<const Cartesian_multipoint *>(g1),
311  down_cast<const Cartesian_multipoint *>(g2));
313  return f.eval(down_cast<const Cartesian_multipoint *>(g1),
314  down_cast<const Cartesian_multilinestring *>(g2));
316  return f.eval(down_cast<const Cartesian_multipoint *>(g1),
317  down_cast<const Cartesian_multipolygon *>(g2));
318  default:
319  assert(false); /* purecov: inspected */
321  }
323  switch (g2->type()) {
325  return f.eval(down_cast<const Cartesian_multilinestring *>(g1),
326  down_cast<const Cartesian_point *>(g2));
328  return f.eval(down_cast<const Cartesian_multilinestring *>(g1),
329  down_cast<const Cartesian_linestring *>(g2));
331  return f.eval(down_cast<const Cartesian_multilinestring *>(g1),
332  down_cast<const Cartesian_polygon *>(g2));
334  return f.eval(
335  down_cast<const Cartesian_multilinestring *>(g1),
336  down_cast<const Cartesian_geometrycollection *>(g2));
338  return f.eval(down_cast<const Cartesian_multilinestring *>(g1),
339  down_cast<const Cartesian_multipoint *>(g2));
341  return f.eval(down_cast<const Cartesian_multilinestring *>(g1),
342  down_cast<const Cartesian_multilinestring *>(g2));
344  return f.eval(down_cast<const Cartesian_multilinestring *>(g1),
345  down_cast<const Cartesian_multipolygon *>(g2));
346  default:
347  assert(false); /* purecov: inspected */
349  }
351  switch (g2->type()) {
353  return f.eval(down_cast<const Cartesian_multipolygon *>(g1),
354  down_cast<const Cartesian_point *>(g2));
356  return f.eval(down_cast<const Cartesian_multipolygon *>(g1),
357  down_cast<const Cartesian_linestring *>(g2));
359  return f.eval(down_cast<const Cartesian_multipolygon *>(g1),
360  down_cast<const Cartesian_polygon *>(g2));
362  return f.eval(
363  down_cast<const Cartesian_multipolygon *>(g1),
364  down_cast<const Cartesian_geometrycollection *>(g2));
366  return f.eval(down_cast<const Cartesian_multipolygon *>(g1),
367  down_cast<const Cartesian_multipoint *>(g2));
369  return f.eval(down_cast<const Cartesian_multipolygon *>(g1),
370  down_cast<const Cartesian_multilinestring *>(g2));
372  return f.eval(down_cast<const Cartesian_multipolygon *>(g1),
373  down_cast<const Cartesian_multipolygon *>(g2));
374  default:
375  assert(false); /* purecov: inspected */
377  }
378  default:
379  assert(false); /* purecov: inspected */
381  } // switch (g1->type())
383  switch (g1->type()) {
385  switch (g2->type()) {
387  return f.eval(down_cast<const Geographic_point *>(g1),
388  down_cast<const Geographic_point *>(g2));
390  return f.eval(down_cast<const Geographic_point *>(g1),
391  down_cast<const Geographic_linestring *>(g2));
393  return f.eval(down_cast<const Geographic_point *>(g1),
394  down_cast<const Geographic_polygon *>(g2));
396  return f.eval(
397  down_cast<const Geographic_point *>(g1),
398  down_cast<const Geographic_geometrycollection *>(g2));
400  return f.eval(down_cast<const Geographic_point *>(g1),
401  down_cast<const Geographic_multipoint *>(g2));
403  return f.eval(
404  down_cast<const Geographic_point *>(g1),
405  down_cast<const Geographic_multilinestring *>(g2));
407  return f.eval(down_cast<const Geographic_point *>(g1),
408  down_cast<const Geographic_multipolygon *>(g2));
409  default:
410  assert(false); /* purecov: inspected */
412  }
414  switch (g2->type()) {
416  return f.eval(down_cast<const Geographic_linestring *>(g1),
417  down_cast<const Geographic_point *>(g2));
419  return f.eval(down_cast<const Geographic_linestring *>(g1),
420  down_cast<const Geographic_linestring *>(g2));
422  return f.eval(down_cast<const Geographic_linestring *>(g1),
423  down_cast<const Geographic_polygon *>(g2));
425  return f.eval(
426  down_cast<const Geographic_linestring *>(g1),
427  down_cast<const Geographic_geometrycollection *>(g2));
429  return f.eval(down_cast<const Geographic_linestring *>(g1),
430  down_cast<const Geographic_multipoint *>(g2));
432  return f.eval(
433  down_cast<const Geographic_linestring *>(g1),
434  down_cast<const Geographic_multilinestring *>(g2));
436  return f.eval(down_cast<const Geographic_linestring *>(g1),
437  down_cast<const Geographic_multipolygon *>(g2));
438  default:
439  assert(false); /* purecov: inspected */
441  }
443  switch (g2->type()) {
445  return f.eval(down_cast<const Geographic_polygon *>(g1),
446  down_cast<const Geographic_point *>(g2));
448  return f.eval(down_cast<const Geographic_polygon *>(g1),
449  down_cast<const Geographic_linestring *>(g2));
451  return f.eval(down_cast<const Geographic_polygon *>(g1),
452  down_cast<const Geographic_polygon *>(g2));
454  return f.eval(
455  down_cast<const Geographic_polygon *>(g1),
456  down_cast<const Geographic_geometrycollection *>(g2));
458  return f.eval(down_cast<const Geographic_polygon *>(g1),
459  down_cast<const Geographic_multipoint *>(g2));
461  return f.eval(
462  down_cast<const Geographic_polygon *>(g1),
463  down_cast<const Geographic_multilinestring *>(g2));
465  return f.eval(down_cast<const Geographic_polygon *>(g1),
466  down_cast<const Geographic_multipolygon *>(g2));
467  default:
468  assert(false); /* purecov: inspected */
470  }
472  switch (g2->type()) {
474  return f.eval(
475  down_cast<const Geographic_geometrycollection *>(g1),
476  down_cast<const Geographic_point *>(g2));
478  return f.eval(
479  down_cast<const Geographic_geometrycollection *>(g1),
480  down_cast<const Geographic_linestring *>(g2));
482  return f.eval(
483  down_cast<const Geographic_geometrycollection *>(g1),
484  down_cast<const Geographic_polygon *>(g2));
486  return f.eval(
487  down_cast<const Geographic_geometrycollection *>(g1),
488  down_cast<const Geographic_geometrycollection *>(g2));
490  return f.eval(
491  down_cast<const Geographic_geometrycollection *>(g1),
492  down_cast<const Geographic_multipoint *>(g2));
494  return f.eval(
495  down_cast<const Geographic_geometrycollection *>(g1),
496  down_cast<const Geographic_multilinestring *>(g2));
498  return f.eval(
499  down_cast<const Geographic_geometrycollection *>(g1),
500  down_cast<const Geographic_multipolygon *>(g2));
501  default:
502  assert(false); /* purecov: inspected */
504  }
506  switch (g2->type()) {
508  return f.eval(down_cast<const Geographic_multipoint *>(g1),
509  down_cast<const Geographic_point *>(g2));
511  return f.eval(down_cast<const Geographic_multipoint *>(g1),
512  down_cast<const Geographic_linestring *>(g2));
514  return f.eval(down_cast<const Geographic_multipoint *>(g1),
515  down_cast<const Geographic_polygon *>(g2));
517  return f.eval(
518  down_cast<const Geographic_multipoint *>(g1),
519  down_cast<const Geographic_geometrycollection *>(g2));
521  return f.eval(down_cast<const Geographic_multipoint *>(g1),
522  down_cast<const Geographic_multipoint *>(g2));
524  return f.eval(
525  down_cast<const Geographic_multipoint *>(g1),
526  down_cast<const Geographic_multilinestring *>(g2));
528  return f.eval(down_cast<const Geographic_multipoint *>(g1),
529  down_cast<const Geographic_multipolygon *>(g2));
530  default:
531  assert(false); /* purecov: inspected */
533  }
535  switch (g2->type()) {
537  return f.eval(down_cast<const Geographic_multilinestring *>(g1),
538  down_cast<const Geographic_point *>(g2));
540  return f.eval(down_cast<const Geographic_multilinestring *>(g1),
541  down_cast<const Geographic_linestring *>(g2));
543  return f.eval(down_cast<const Geographic_multilinestring *>(g1),
544  down_cast<const Geographic_polygon *>(g2));
546  return f.eval(
547  down_cast<const Geographic_multilinestring *>(g1),
548  down_cast<const Geographic_geometrycollection *>(g2));
550  return f.eval(down_cast<const Geographic_multilinestring *>(g1),
551  down_cast<const Geographic_multipoint *>(g2));
553  return f.eval(
554  down_cast<const Geographic_multilinestring *>(g1),
555  down_cast<const Geographic_multilinestring *>(g2));
557  return f.eval(down_cast<const Geographic_multilinestring *>(g1),
558  down_cast<const Geographic_multipolygon *>(g2));
559  default:
560  assert(false); /* purecov: inspected */
562  }
564  switch (g2->type()) {
566  return f.eval(down_cast<const Geographic_multipolygon *>(g1),
567  down_cast<const Geographic_point *>(g2));
569  return f.eval(down_cast<const Geographic_multipolygon *>(g1),
570  down_cast<const Geographic_linestring *>(g2));
572  return f.eval(down_cast<const Geographic_multipolygon *>(g1),
573  down_cast<const Geographic_polygon *>(g2));
575  return f.eval(
576  down_cast<const Geographic_multipolygon *>(g1),
577  down_cast<const Geographic_geometrycollection *>(g2));
579  return f.eval(down_cast<const Geographic_multipolygon *>(g1),
580  down_cast<const Geographic_multipoint *>(g2));
582  return f.eval(
583  down_cast<const Geographic_multipolygon *>(g1),
584  down_cast<const Geographic_multilinestring *>(g2));
586  return f.eval(down_cast<const Geographic_multipolygon *>(g1),
587  down_cast<const Geographic_multipolygon *>(g2));
588  default:
589  assert(false); /* purecov: inspected */
591  }
592  default:
593  assert(false); /* purecov: inspected */
595  } // switch (g1->type())
596  } // switch (g1->coordinate_system())
597 
598  assert(false); /* purecov: inspected */
600  }
601 };
602 
603 /// The base class of all functors that take one geometry argument.
604 ///
605 /// Subclasses of this functor base class will implement operator() and call
606 /// apply() to do type combination dispatching. The actual body of the functor
607 /// is in the eval() member function, which must be implemented for each
608 /// different parameter type combination.
609 ///
610 /// The functor may throw exceptions.
611 ///
612 /// @tparam T The return type of the functor.
613 template <typename T>
615  public:
616  virtual T operator()(const Geometry &) const = 0;
617  virtual ~Unary_functor() = default;
618 
619  protected:
620  template <class F>
621  static inline T apply(F &f, const Geometry &g) {
622  switch (g.coordinate_system()) {
624  switch (g.type()) {
626  return f.eval(down_cast<const Cartesian_point &>(g));
628  return f.eval(down_cast<const Cartesian_linestring &>(g));
630  return f.eval(down_cast<const Cartesian_polygon &>(g));
632  return f.eval(down_cast<const Cartesian_geometrycollection &>(g));
634  return f.eval(down_cast<const Cartesian_multipoint &>(g));
636  return f.eval(down_cast<const Cartesian_multilinestring &>(g));
638  return f.eval(down_cast<const Cartesian_multipolygon &>(g));
639  default:
640  assert(false); /* purecov: inspected */
641  // We don't know here whether the geometry is Cartesan or projected.
642  // Assume Cartesian. This is dead code anyway.
644  }
645  }
647  switch (g.type()) {
649  return f.eval(down_cast<const Geographic_point &>(g));
651  return f.eval(down_cast<const Geographic_linestring &>(g));
653  return f.eval(down_cast<const Geographic_polygon &>(g));
655  return f.eval(down_cast<const Geographic_geometrycollection &>(g));
657  return f.eval(down_cast<const Geographic_multipoint &>(g));
659  return f.eval(down_cast<const Geographic_multilinestring &>(g));
661  return f.eval(down_cast<const Geographic_multipolygon &>(g));
662  default:
663  assert(false); /* purecov: inspected */
664  // We don't know here whether the geometry is Cartesan or projected.
665  // Assume Cartesian. This is dead code anyway.
667  }
668  }
669  }
670  assert(false); /* purecov: inspected */
671  // We don't know here whether the geometry is Cartesan or projected.
672  // Assume Cartesian. This is dead code anyway.
674  }
675 };
676 
677 } // namespace gis
678 
679 #endif // SQL_GIS_FUNCTOR_H_INCLUDED
The base class of all functors that takes two geometry arguments.
Definition: functor.h:164
virtual T operator()(const Geometry *g1, const Geometry *g2) const =0
virtual ~Functor()=default
static T apply(F &f, const Geometry *g1, const Geometry *g2)
Definition: functor.h:171
Abstract superclass for all geometric objects.
Definition: geometries.h:99
virtual Coordinate_system coordinate_system() const =0
Gets the coordinate system.
virtual Geometry_type type() const =0
Gets the geometry type of the object.
The base class of all functors that take one geometry argument.
Definition: functor.h:614
virtual T operator()(const Geometry &) const =0
virtual ~Unary_functor()=default
static T apply(F &f, const Geometry &g)
Definition: functor.h:621
Function/parameter combination not implemented exception.
Definition: functor.h:87
Srs_type
Definition: functor.h:89
@ kCartesian
Definition: functor.h:89
@ kProjected
Definition: functor.h:89
@ kGeographic
Definition: functor.h:89
Srs_type m_srs_type
Definition: functor.h:92
std::string m_typenames
Definition: functor.h:94
static not_implemented_exception for_projected(const Geometry &g1, const Geometry &g2)
Definition: functor.h:118
Srs_type srs_type() const
Definition: functor.h:111
static not_implemented_exception for_non_projected(const Geometry &g)
Definition: functor.h:123
not_implemented_exception(Srs_type srs_type, const Geometry &g1, const Geometry &g2)
Definition: functor.h:101
static not_implemented_exception for_non_projected(const Geometry &g1, const Geometry &g2)
Definition: functor.h:134
static not_implemented_exception for_projected(const Geometry &g)
Definition: functor.h:114
const char * typenames() const
Definition: functor.h:112
not_implemented_exception(Srs_type srs_type, const Geometry &g)
Definition: functor.h:96
NULL value exception.
Definition: functor.h:151
This file declares the geometry class hierarchy used by the server as the internal representation of ...
This file declares the coordinate system specific subclasses of the geometry class hierarchy.
Definition: area.cc:46
@ kCartesian
A Cartesian plane with the same unit in both directions.
@ kGeographic
An ellipsoidal system with longitude and latitude coordinates, both in the same unit.
const char * type_to_name(Geometry_type type)
Get the type name string corresponding to a geometry type.
Definition: geometries.cc:687
Latitude out of range exception.
Definition: functor.h:69
double range_min
Definition: functor.h:71
double range_max
Definition: functor.h:72
latitude_out_of_range_exception(double value, double range_min, double range_max)
Definition: functor.h:74
double value
Definition: functor.h:70
Longitude out of range exception.
Definition: functor.h:55
longitude_out_of_range_exception(double value, double range_min, double range_max)
Definition: functor.h:60
double value
Definition: functor.h:56
double range_min
Definition: functor.h:57
double range_max
Definition: functor.h:58