NAVTOR SDK  v.3.0
Software Development Kit for fast and efficient development of ECDIS, ECS and generic marine applications
geometry_base_types_helpers.h
Go to the documentation of this file.
1 #ifndef SDK_GEOMETRY_TYPES_HELPERS_H_
11 #define SDK_GEOMETRY_TYPES_HELPERS_H_
12 
13 #include <iostream>
14 #include <vector>
15 #include <math.h>
16 #include <base/inc/platform.h>
17 #include <base/inc/base_types.h>
18 #include <base/inc/float_util.h>
20 
21 #include "geometry_base_types.h"
22 
23 namespace sdk {
24 
25 // Classes declared in this file
26 class PointF2D;
27 class PointD2D;
28 class PointI2D;
29 class GeoPoint;
30 class SizeF;
31 class SizeD;
32 class Size;
33 class RectF2D;
34 class RectD2D;
35 class RectI2D;
36 typedef RectI2D Rect2D;
37 class RoundRectF2D;
38 class QBezierSegment;
39 class CuBezierSegment;
40 
41 typedef std::vector< PointF2D > PointF2DVec;
42 typedef std::vector< PointD2D > PointD2DVec;
43 typedef std::vector< PointI2D > PointI2DVec;
44 typedef std::vector< SizeF > SizeFVec;
45 typedef std::vector< SizeD > SizeDVec;
46 typedef std::vector< Size > SizeVec;
47 typedef std::vector< RectF2D > RectF2DVec;
48 typedef std::vector< RectD2D > RectD2DVec;
49 typedef std::vector< RectI2D > RectI2DVec, Rect2DVec;
50 typedef std::vector< RoundRectF2D > RoundRectF2DVec;
51 typedef std::vector< QBezierSegment > QBezierSegmentVec;
52 typedef std::vector< CuBezierSegment > CuBezierSegmentVec;
53 typedef std::vector< SDKGeoPoint > SDKGeoPointVec;
54 typedef std::vector< SDKGeoIntPoint > SDKGeoIntPointVec;
55 
58 class PointF2D : public SDKPointF2D {
59 public:
60  // Constructors
61  // Uninitialized PointF2D
62  PointF2D() noexcept { x = y = 0.0; }
63  // Copy constructor
64  PointF2D(const SDKPointF2D& src_pt) noexcept : SDKPointF2D(src_pt) {}
65  PointF2D(const SDKPointD2D& src_pt) noexcept {
66  x = coordinate_type(src_pt.x);
67  y = coordinate_type(src_pt.y);
68  }
69 
70  // From x and y
71  PointF2D(float init_x, float init_y) noexcept { x = init_x, y = init_y; }
72  // Operations
73  PointF2D& operator=(const SDKPointF2D& src_pt) noexcept {
74  x = src_pt.x, y = src_pt.y;
75  return *this;
76  }
77 
78  PointF2D& operator=(const SDKPointD2D& src_pt) noexcept {
79  x = coordinate_type(src_pt.x);
80  y = coordinate_type(src_pt.y);
81  return *this;
82  }
83 
84  PointF2D& operator+=(const SDKPointF2D& src_pt) noexcept {
85  x += src_pt.x, y += src_pt.y;
86  return *this;
87  }
88 
89  PointF2D& operator-=(const SDKPointF2D& src_pt) noexcept {
90  x -= src_pt.x, y -= src_pt.y;
91  return *this;
92  }
93 
94  #if 0
95  bool operator!=(const PointF2D& pt) const noexcept {return !operator==(pt);}
96  bool operator==(const PointF2D& pt) const noexcept
97  {
98  if (fabs(x - pt.x) <= FLT_EPSILON && fabs(y - pt.y) <= FLT_EPSILON)
99  return true;
100 
101  return false;
102  }
103  #endif
104  typedef std::vector<PointF2D> container;
105 };
106 
109 class PointD2D : public SDKPointD2D {
110 public:
111  // Constructors
112  // Uninitialized PointD2D
113  PointD2D() noexcept { x = y = 0.0; }
114  // Copy constructor
115  PointD2D(const SDKPointD2D& src_pt) noexcept : SDKPointD2D(src_pt) {}
116  // Copy constructor
117  PointD2D(const SDKPointF2D& src_pt) noexcept { x = src_pt.x, y = src_pt.y; }
118  // Copy constructor
119  PointD2D(const SDKGeoPoint& src) noexcept { x = src.x, y = src.y; }
120  // From x and y
121  PointD2D(double init_x, double init_y) noexcept { x = init_x, y = init_y; }
122  // Operations
123  PointD2D& operator=(const SDKPointF2D& src_pt) noexcept {
124  x = src_pt.x, y = src_pt.y;
125  return *this;
126  }
127 
128  PointD2D& operator=(const SDKPointD2D& src_pt) noexcept {
129  *static_cast<SDKPointD2D*>(this) = src_pt;
130  return *this;
131  }
132 
133  PointD2D& operator+=(const SDKPointD2D& src_pt) noexcept
134  {
135  x += src_pt.x, y += src_pt.y;
136  return *this;
137  }
138 
139  PointD2D& operator-=(const SDKPointD2D& src_pt) noexcept
140  {
141  x -= src_pt.x, y -= src_pt.y;
142  return *this;
143  }
144  #if 0
145  bool operator!=(const PointD2D& pt) const noexcept {return !operator==(pt);}
146  bool operator==(const PointD2D& pt) const noexcept
147  {
148  if (fabs(x - pt.x) <= FLT_EPSILON && fabs(y - pt.y) <= FLT_EPSILON)
149  return true;
150 
151  return false;
152  }
153  double Length(const PointD2D& p) const noexcept {
154  double dx = x - p.x;
155  double dy = y - p.y;
156  return sqrt(dx*dx + dy*dy);
157  }
158  #endif
159 
160  typedef std::vector<PointD2D> container;
161 };
162 
165 class PointI2D : public SDKPointI2D {
166 public:
167  // Constructors
168  // Uninitialized Point2D
169  PointI2D() noexcept { x = y = 0; }
170  // Copy constructor
171  PointI2D(const SDKPointI2D& src_pt) noexcept : SDKPointI2D(src_pt) {}
172  // From x and y
173  PointI2D(SDKInt32 init_x, SDKInt32 init_y) noexcept { x = init_x, y = init_y; }
174  // Operations
175  PointI2D& operator=(const SDKPointI2D& src_pt) noexcept {
176  *static_cast<SDKPointI2D*>(this) = src_pt;
177  return *this;
178  }
179 
180  typedef std::vector<PointI2D> container;
181  #if 0
182  bool operator!=(const PointI2D& pt) const noexcept { return !operator==(pt); }
183  bool operator==(const PointI2D& pt) const noexcept
184  {
185  if ((x == pt.x) && (y == pt.y))
186  return true;
187  return false;
188  }
189  #endif
190 };
191 
192 class PointF3D : public SDKPointF3D {
193 public:
194  PointF3D() noexcept { x = 0.f; y = 0.f; z = 0.f; }
195 
196  PointF3D(float _x, float _y, float _z) noexcept { x = _x; y = _y; z = _z; }
197  PointF3D(const SDKPointF3D& src) noexcept : SDKPointF3D(src) {}
198  PointF3D(const SDKPointD3D& src) noexcept {
199  x = coordinate_type(src.x);
200  y = coordinate_type(src.y);
201  z = coordinate_type(src.z);
202  }
203 
204  PointF3D& operator=(const SDKPointF3D& src) noexcept {
205  *static_cast<SDKPointF3D*>(this) = src;
206  return *this;
207  }
208 
209  PointF3D& operator=(const SDKPointD3D& src) noexcept {
210  x = coordinate_type(src.x);
211  y = coordinate_type(src.y);
212  z = coordinate_type(src.z);
213  return *this;
214  }
215 };
216 
217 class PointD3D : public SDKPointD3D {
218 public:
219  PointD3D() noexcept { x = 0.f; y = 0.f; z = 0.f; }
220  PointD3D(double _x, double _y, double _z) noexcept { x = _x; y = _y; z = _z; }
221  PointD3D(const SDKPointD3D& src) noexcept : SDKPointD3D(src) {}
222  PointD3D(const SDKPointF3D& src) noexcept { x = src.x; y = src.y; z = src.z; }
223  PointD3D& operator=(const SDKPointD3D& src) noexcept {
224  *static_cast<SDKPointD3D*>(this) = src;
225  return *this;
226  }
227 
228  PointD3D& operator=(const SDKPointF3D& src) noexcept {
229  x = coordinate_type(src.x);
230  y = coordinate_type(src.y);
231  z = coordinate_type(src.z);
232  return *this;
233  }
234 };
235 
238 class SizeF : public SDKSizeF {
239 public:
240  // Constructors
241  // Uninitialized SizeF
242  SizeF() noexcept { width = height = 0.0f; }
243  // Copy constructor
244  SizeF(const SDKSizeF& src_size) noexcept : SDKSizeF(src_size) {}
245  SizeF(const SDKSizeD& src_size) noexcept {
246  width = static_cast<float>(src_size.width);
247  height = static_cast<float>(src_size.height);
248  }
249 
250  SizeF(const SDKSize& src_size) noexcept {
251  width = static_cast<float>(src_size.width);
252  height = static_cast<float>(src_size.height);
253  }
254 
255  // From width and height
256  SizeF(float init_width, float init_height) noexcept {
257  width = init_width, height = init_height;
258  }
259  #if 0
260  // returns true if size width and height are 0
261  bool IsNull() const noexcept {
262  return (width == 0.0f && height == 0.0f);
263  }
264 
265  // Returns true if size is equal to another size
266  bool IsEqual(const SDKSizeF& s) const noexcept {
267  return (fabs(width - s.width) <= FLT_EPSILON && fabs(height - s.height) <= FLT_EPSILON);
268  }
269 
270  // Operations
271  void operator=(const SDKSizeF& src_size) noexcept {
272  width = src_size.width, height = src_size.height;
273  }
274  bool operator==(const SDKSizeF& s) const noexcept { return IsEqual(s); }
275  bool operator!=(const SDKSizeF& s) const noexcept { return !IsEqual(s); }
276  #endif
277  // Operations
278  SizeF& operator=(const SDKSizeF& src_size) noexcept {
279  *static_cast<SDKSizeF*>(this) = src_size;
280  return *this;
281  }
282 
283  SizeF& operator=(const SDKSizeD& src_size) noexcept {
284  width = static_cast<coordinate_type>(src_size.width);
285  height = static_cast<coordinate_type>(src_size.height);
286  return *this;
287  }
288 
289  SizeF& operator=(const SDKSize& src_size) noexcept {
290  width = static_cast<coordinate_type>(src_size.width);
291  height = static_cast<coordinate_type>(src_size.height);
292  return *this;
293  }
294 
295  typedef std::vector<SizeF> container;
296 };
297 
300 class SizeD : public SDKSizeD {
301 public:
302  // Constructors
303  // Uninitialized SizeF
304  SizeD() noexcept { width = height = 0.0f; }
305  // Copy constructor
306  SizeD(const SDKSizeD& src_size) noexcept : SDKSizeD(src_size) {}
307  SizeD(const SDKSizeF& src_size) noexcept {
308  width = src_size.width, height = src_size.height;
309  }
310 
311  SizeD(const SDKSize& src_size) noexcept {
312  width = static_cast<double>(src_size.width);
313  height = static_cast<double>(src_size.height);
314  }
315 
316  // From width and height
317  SizeD(double init_width, double init_height) noexcept {
318  width = init_width, height = init_height;
319  }
320  #if 0
321  // returns true if size width and height are 0
322  bool IsNull() const noexcept {
323  return (width == 0.0f && height == 0.0f);
324  }
325 
326  // Returns true if size is equal to another size
327  bool IsEqual(const SDKSizeD& s) const noexcept {
328  return (fabs(width - s.width) <= DBL_EPSILON && fabs(height - s.height) <= DBL_EPSILON);
329  }
330 
331  // Operations
332  void operator=(const SDKSizeD& src_size) noexcept {
333  width = src_size.width, height = src_size.height;
334  }
335  bool operator==(const SDKSizeD& s) const noexcept { return IsEqual(s); }
336  bool operator!=(const SDKSizeD& s) const noexcept { return !IsEqual(s); }
337  #endif
338  // Operations
339  SizeD& operator=(const SDKSizeD& src_size) noexcept {
340  *static_cast<SDKSizeD*>(this) = src_size;
341  return *this;
342  }
343 
344  SizeD& operator=(const SDKSizeF& src_size) noexcept {
345  width = static_cast<coordinate_type>(src_size.width);
346  height = static_cast<coordinate_type>(src_size.height);
347  return *this;
348  }
349 
350  SizeD& operator=(const SDKSize& src_size) noexcept {
351  width = static_cast<coordinate_type>(src_size.width);
352  height = static_cast<coordinate_type>(src_size.height);
353  return *this;
354  }
355 
356  typedef std::vector<SizeD> container;
357 };
358 
361 class Size : public SDKSize {
362 public:
363  // Constructors
364  // Uninitialized Size
365  Size() { width = height = 0; }
366  // Copy constructor
367  Size(const SDKSize& src_size) noexcept : SDKSize(src_size) {}
368  Size(const SDKSizeF& src_size) noexcept {
369  width = static_cast<SDKUInt32>(src_size.width);
370  height = static_cast<SDKUInt32>(src_size.height);
371  }
372 
373  Size(const SDKSizeD& src_size) noexcept {
374  width = static_cast<SDKUInt32>(src_size.width);
375  height = static_cast<SDKUInt32>(src_size.height);
376  }
377 
378  // From width and height
379  Size(SDKUInt32 init_width, SDKUInt32 init_height) noexcept {
380  width = init_width, height = init_height;
381  }
382 
383  #if 0
384  // returns true if size width and height are 0
385  bool IsNull() const noexcept {
386  return (width == 0 && height == 0);
387  }
388  // Returns true if size is equal to another size
389  bool IsEqual(const SDKSize& s) const noexcept {
390  return (width == s.width && height == s.height);
391  }
392 
393  // Operations
394  void operator=(const SDKSize& src_size) noexcept {
395  width = src_size.width, height = src_size.height;
396  }
397  bool operator==(const SDKSize& s) const noexcept { return IsEqual(s); }
398  bool operator!=(const SDKSize& s) const noexcept { return !IsEqual(s); }
399  #endif
400  // Operations
401  Size& operator=(const SDKSize& src_size) noexcept {
402  *static_cast<SDKSize*>(this) = src_size;
403  return *this;
404  }
405 
406  Size& operator=(const SDKSizeF& src_size) noexcept {
407  width = static_cast<coordinate_type>(src_size.width);
408  height = static_cast<coordinate_type>(src_size.height);
409  return *this;
410  }
411 
412  Size& operator=(const SDKSizeD& src_size) noexcept {
413  width = static_cast<coordinate_type>(src_size.width);
414  height = static_cast<coordinate_type>(src_size.height);
415  return *this;
416  }
417 
418  typedef std::vector<Size> container;
419 };
420 
423 class RectF2D : public SDKRectF2D {
424 public:
425  // Constructors
426  // Uninitialized rectangle
427  RectF2D() noexcept { x = y = width = height = 0.0f; }
428  // Copy constructor
429  RectF2D(const SDKRectF2D& src_r) noexcept : SDKRectF2D(src_r) {}
430  // From x, y, width, height
431  RectF2D(float init_x, float init_y, float init_w, float init_h) noexcept {
432  x = init_x, y = init_y, width = init_w, height = init_h;
433  }
434 
435  // From point and size
436  RectF2D(const SDKPointF2D& pt, const SDKSizeF& size) noexcept {
437  x = pt.x, y = pt.y, width = size.width, height = size.height;
438  }
439 
440  // From size and offset to origin
441  RectF2D(const SDKSizeF& size, const SDKPointF2D& org) noexcept {
442  x = -org.x, y = -org.y, width = size.width, height = size.height;
443  }
444  #if 0
445  // returns true if rectangle has no area
446  bool IsEmpty() const noexcept { return (width == 0.0f && height == 0.0f); }
447  // returns true if rectangle is at (0,0) and has no area
448  bool IsNull() const noexcept {
449  return (x == 0.0f && y == 0.0f && width == 0.0f && height == 0.0f);
450  }
451 
452  // Returns true if rectangle is equal to another rectangle
453  bool IsEqual(const SDKRectF2D& r) const noexcept {
454  return (x == r.x && y == r.y && width == r.width && height == r.height);
455  }
456 
457  PointF2D Center() {
458  return PointF2D(x + width / 2.0f, y + height / 2.0f);
459  }
460  #endif
461 
462  RectF2D& Union(const SDKRectF2D& rc) {
463  if (IsNull()) {
464  *this = rc;
465  return *this;
466  }
467  SDKPointF2D pts[2];
468  pts[0].x = rc.x < x ? rc.x : x;
469  pts[0].y = rc.y < y ? rc.y : y;
470  pts[1].x = ((rc.x + rc.width) > (x + width)) ?
471  (rc.x + rc.width) : (x + width);
472  pts[1].y = ((rc.y + rc.height) > (y + height)) ?
473  (rc.y + rc.height) : (y + height);
474  x = pts[0].x;
475  y = pts[0].y;
476  width = pts[1].x - pts[0].x;
477  height = pts[1].y - pts[0].y;
478  return *this;
479  }
480 
481  RectF2D& Intersect(const SDKRectF2D& rc) {
482  RectF2D res; // Empty rectangle by default
483  if (!IsEmpty() && !rc.IsEmpty() && x < rc.x + rc.width &&
484  rc.x < x + width && y + height > rc.y && rc.y + rc.height > y) {
485  // Two rectangles intersects
486  res.x = (x > rc.x) ? x : rc.x;
487  res.y = (y > rc.y) ? y : rc.y;
488  res.width = (x + width < rc.x + rc.width) ?
489  x + width - res.x : rc.x + rc.width - res.x;
490  res.height = (y + height < rc.y + rc.height) ?
491  y + height - res.y : rc.y + rc.height - res.y;
492  }
493 
494  return *this = res;
495  }
496 
497  // Operations
498  RectF2D& operator=(const SDKRectF2D& src_r) noexcept {
499  *static_cast<SDKRectF2D*>(this) = src_r;
500  return *this;
501  }
502  #if 0
503  bool operator==(const SDKRectF2D& r) const noexcept { return IsEqual(r); }
504  bool operator!=(const SDKRectF2D& r) const noexcept { return !IsEqual(r); }
505  #endif
506  RectF2D& operator |= (const SDKRectF2D& rc) {
507  Union(rc);
508  return *this;
509  }
510 
511  // Old version
512  bool IsIntersected(const SDKRectF2D& src) const noexcept {
513  return !(IsEmpty() || (src.width == 0) || (src.height == 0) ||
514  (x >= (src.x + src.width)) || (src.x >= (x + width)) ||
515  (y >= (src.y + src.height)) || (src.y >= y + height));
516  }
517 
518  // Returns false for empty operands, does not include right and top border
519  bool IsIntersected_Geometrical(const SDKRectF2D& src) const noexcept {
520  return !((width == 0) || (height == 0) ||
521  (src.width == 0) || (src.height == 0) ||
522  (x >= (src.x + src.width)) || (src.x >= (x + width)) ||
523  (y >= (src.y + src.height)) || (src.y >= y + height));
524  }
525 
526  // Intersects zero width/height rectangles, includes right and top border
527  bool IsIntersected_Graphical(const SDKRectF2D& src) const noexcept {
528  return !((x > (src.x + src.width)) || (src.x > (x + width)) ||
529  (y > (src.y + src.height)) || (src.y > y + height));
530  }
531 
532  bool IsIncludes(const SDKRectF2D& src) const noexcept {
533  return (IsPointInRect(src.x, src.y) &&
534  IsPointInRect(src.x + src.width, src.y + src.height));
535  }
536 
537  bool IsPointInRect(float p_x, float p_y) const noexcept {
538  if (IsNull())
539  return false;
540  return (p_x >= x && p_x <= (x + width) &&
541  p_y >= y && p_y <= (y + height));
542  }
543 
544  bool IsPointInRect(const SDKPointF2D& p) const noexcept {
545  return IsPointInRect(p.x, p.y);
546  }
547 
548  RectF2D& Expand(float factor) {
549  float expand_x = width * factor;
550  float expand_y = height * factor;
551  x -= expand_x;
552  y -= expand_y;
553  width += 2 * expand_x;
554  height += 2 * expand_y;
555  return *this;
556  }
557 
558  typedef std::vector<RectF2D> container;
559 };
560 
563 class RectD2D : public SDKRectD2D {
564 public:
565  // Constructors
566  // Uninitialized rectangle
567  RectD2D() noexcept { x = y = width = height = 0.0f; }
568 
569  // Copy constructor
570  RectD2D(const SDKRectD2D& src_r) noexcept
571  : SDKRectD2D(src_r) {
572  }
573 
574  // Copy constructor
575  RectD2D(const SDKRectF2D& src_r) noexcept {
576  x = src_r.x, y = src_r.y, width = src_r.width, height = src_r.height;
577  }
578  // From x, y, width, height
579  RectD2D(double init_x, double init_y, double init_w, double init_h) noexcept {
580  x = init_x, y = init_y, width = init_w, height = init_h;
581  }
582 
583  // From point and size
584  RectD2D(const SDKPointD2D& pt, const SDKSizeD& size) noexcept
585  {
586  x = pt.x, y = pt.y, width = size.width, height = size.height;
587  }
588 
589  // From size and offset to origin
590  RectD2D(const SDKSizeD& size, const SDKPointD2D& org) noexcept
591  {
592  x = -org.x, y = -org.y, width = size.width, height = size.height;
593  }
594 
595  #if 0
596  // returns true if rectangle has no area
597  bool IsEmpty() const noexcept { return (width == 0.0f && height == 0.0f); }
598  // returns true if rectangle is at (0,0) and has no area
599  bool IsNull() const noexcept {
600  return (x == 0.0f && y == 0.0f && width == 0.0f && height == 0.0f);
601  }
602  // Returns true if rectangle is equal to another rectangle
603  bool IsEqual(const SDKRectD2D& r) const noexcept {
604  return (x == r.x && y == r.y && width == r.width && height == r.height);
605  }
606  PointD2D Center()
607  {
608  return PointD2D(x + width / 2.0, y + height / 2.0);
609  }
610  #endif
611  RectD2D& Union(const SDKRectD2D& rc)
612  {
613  if (IsNull()) {
614  *this = rc;
615  return *this;
616  }
617  point_type pts[2];
618  pts[0].x = rc.x < x ? rc.x : x;
619  pts[0].y = rc.y < y ? rc.y : y;
620  pts[1].x = ((rc.x + rc.width) > (x + width)) ? (rc.x + rc.width) : (x + width);
621  pts[1].y = ((rc.y + rc.height) > (y + height)) ? (rc.y + rc.height) : (y + height);
622  x = pts[0].x;
623  y = pts[0].y;
624  width = pts[1].x - pts[0].x;
625  height = pts[1].y - pts[0].y;
626  return *this;
627  }
628 
629  RectD2D& Intersect(const SDKRectD2D& rc)
630  {
631  RectD2D res; // Empty rectangle by default
632  if (!IsEmpty() && !rc.IsEmpty()
633  && x < rc.x + rc.width && rc.x < x + width
634  && y + height > rc.y && rc.y + rc.height > y)
635  {
636  // Two rectangles intersects
637  res.x = (x > rc.x) ? x : rc.x;
638  res.y = (y > rc.y) ? y : rc.y;
639  res.width = (x + width < rc.x + rc.width) ?
640  x + width - res.x : rc.x + rc.width - res.x;
641  res.height = (y + height < rc.y + rc.height) ?
642  y + height - res.y : rc.y + rc.height - res.y;
643  }
644 
645  return *this = res;
646  }
647 
648  // Operations
649  RectD2D& operator=(const SDKRectD2D& src_r) noexcept {
650  *static_cast<SDKRectD2D*>(this) = src_r;
651  return *this;
652  }
653 
654  RectD2D& operator=(const SDKRectF2D& src_r) noexcept {
655  x = src_r.x, y = src_r.y, width = src_r.width, height = src_r.height;
656  return *this;
657  }
658 
659  #if 0
660  bool operator==(const SDKRectD2D& r) const noexcept { return IsEqual(r); }
661  bool operator!=(const SDKRectD2D& r) const noexcept { return !IsEqual(r); }
662  #endif
663  RectD2D& operator |= (const SDKRectD2D& rc)
664  {
665  Union(rc);
666  return *this;
667  }
668 
669  // Old version
670  bool IsIntersected(const SDKRectD2D& src) const noexcept {
671  return !(IsEmpty() || (src.width == 0) || (src.height == 0) ||
672  (x >= (src.x + src.width)) || (src.x >= (x + width)) ||
673  (y >= (src.y + src.height)) || (src.y >= y + height));
674  }
675 
676  // Returns false for empty operands, does not include right and top border
677  bool IsIntersected_Geometrical(const SDKRectD2D& src) const noexcept {
678  return !((width == 0) || (height == 0) ||
679  (src.width == 0) || (src.height == 0) ||
680  (x >= (src.x + src.width)) || (src.x >= (x + width)) ||
681  (y >= (src.y + src.height)) || (src.y >= y + height));
682  }
683 
684  // Intersects zero width/height rectangles, includes right and top border
685  bool IsIntersected_Graphical(const SDKRectD2D& src) const noexcept {
686  return !((x > (src.x + src.width)) || (src.x > (x + width)) ||
687  (y > (src.y + src.height)) || (src.y > y + height));
688  }
689 
690  bool IsIncludes(const SDKRectD2D& src) const noexcept {
691  return (IsPointInRect(src.x, src.y) &&
692  IsPointInRect(src.x + src.width, src.y + src.height));
693  }
694 
695  bool IsPointInRect(double p_x, double p_y) const noexcept {
696  if (IsNull())
697  return false;
698  return (p_x >= x && p_x <= (x + width) &&
699  p_y >= y && p_y <= (y + height));
700  }
701 
702  bool IsPointInRect(const SDKPointD2D& p) const noexcept {
703  return IsPointInRect(p.x, p.y);
704  }
705 
706  RectD2D& Expand(double factor)
707  {
708  double expand_x = width * factor;
709  double expand_y = height * factor;
710  x -= expand_x;
711  y -= expand_y;
712  width += 2 * expand_x;
713  height += 2 * expand_y;
714  return *this;
715  }
716 
717  RectF2D GetRectF2D() const
718  {
719  RectF2D rect_f2d(
720  static_cast<float>(x),
721  static_cast<float>(y),
722  static_cast<float>(width),
723  static_cast<float>(height));
724  return rect_f2d;
725  }
726 
727  typedef std::vector<RectD2D> container;
728 };
729 
732 class RectI2D : public SDKRectI2D {
733  // Constructors
734 public:
735  // Uninitialized rectangle
736  RectI2D() noexcept { x = y = width = height = 0; }
737  // Copy constructor
738  RectI2D(const SDKRectI2D& src) noexcept
739  : SDKRectI2D(src) {
740  }
741  // From x, y, width, height
742  RectI2D(
743  SDKInt32 init_x, SDKInt32 init_y,
744  SDKUInt32 init_w, SDKUInt32 init_h) noexcept {
745  x = init_x, y = init_y, width = init_w, height = init_h;
746  }
747  #if 0
748  // returns true if rectangle has no area
749  bool IsEmpty() const noexcept { return (width == 0 && height == 0); }
750  // returns true if rectangle is at (0,0) and has no area
751  bool IsNull() const noexcept {
752  return (x == 0 && y == 0 && width == 0 && height == 0);
753  }
754 
755  // Returns true if rectangle is equal to another rectangle
756  bool IsEqual(const SDKRect2D& r) const noexcept {
757  return (x == r.x && y == r.y && width == r.width && height == r.height);
758  }
759 
760  // Operations
761  void operator=(const SDKRectI2D& src_r) noexcept {
762  x = src_r.x, y = src_r.y, width = src_r.width, height = src_r.height;
763  }
764 
765  bool operator==(const SDKRect2D& r) const noexcept { return IsEqual(r); }
766  bool operator!=(const SDKRect2D& r) const noexcept { return !IsEqual(r); }
767  #endif
768  // Operations
769  RectI2D& operator=(const SDKRectI2D& src_r) noexcept {
770  *static_cast<SDKRectI2D*>(this) = src_r;
771  return *this;
772  }
773  RectI2D& operator=(const SDKRectF2D& src_r) noexcept {
774  x = point_type::coordinate_type(src_r.x);
775  y = point_type::coordinate_type(src_r.y);
776  width = size_type::coordinate_type(src_r.width);
777  height = size_type::coordinate_type(src_r.height);
778  return *this;
779  }
780  RectI2D& operator=(const SDKRectD2D& src_r) noexcept {
781  x = point_type::coordinate_type(src_r.x);
782  y = point_type::coordinate_type(src_r.y);
783  width = size_type::coordinate_type(src_r.width);
784  height = size_type::coordinate_type(src_r.height);
785  return *this;
786  }
787 
788  typedef std::vector<RectI2D> container;
789 };
790 
794 public:
795  // Constructors
796  // Uninitialized rectangle
797  RoundRectF2D() noexcept {
798  rect.x = rect.y = rect.width = rect.height = rad_x = rad_y = 0.0f;
799  }
800  // Copy constructor
801  RoundRectF2D(const SDKRoundRectF2D& src_r) noexcept : SDKRoundRectF2D(src_r) {}
802  // From rect, rad_x, rad_y
803  RoundRectF2D(const SDKRectF2D& init_r, float init_rad_x, float init_rad_y) noexcept {
804  rect = init_r;
805  rad_x = init_rad_x, rad_y = init_rad_y;
806  }
807  // Operations
808  RoundRectF2D& operator=(const SDKRoundRectF2D& src_r) noexcept {
809  *static_cast<SDKRoundRectF2D*>(this) = src_r;
810  return *this;
811  }
812 
813  typedef std::vector<RoundRectF2D> container;
814 };
815 
818 class EllipseF2D : public SDKEllipseF2D {
819 public:
820  // Constructors
821  // Uninitialized ellipse
822  EllipseF2D() noexcept { center.x = center.y = rad_x = rad_y = 0.0f; }
823  // Copy constructor
824  EllipseF2D(const SDKEllipseF2D& src_e) noexcept : SDKEllipseF2D(src_e) {}
825  // From center, rad_x and rad_y
826  EllipseF2D(const SDKPointF2D& init_pt, float init_rad_x, float init_rad_y) noexcept {
827  center = init_pt;
828  rad_x = init_rad_x, rad_y = init_rad_y;
829  }
830  // Operations
831  EllipseF2D& operator=(const SDKEllipseF2D& src_e) noexcept {
832  *static_cast<SDKEllipseF2D*>(this) = src_e;
833  return *this;
834  }
835 
836  typedef std::vector<EllipseF2D> container;
837 };
838 
842 public:
843  // Constructors
844  // Uninitialized segment
845  QBezierSegment() noexcept { pt1.x = pt1.y = pt2.x = pt2.y = 0.0f; }
846  // Copy constructor
847  QBezierSegment(const SDKQBezierSegment& src) noexcept : SDKQBezierSegment(src) {}
848  // From two points
849  QBezierSegment(const SDKPointF2D& init_pt1, const SDKPointF2D& init_pt2) noexcept {
850  pt1 = init_pt1;
851  pt2 = init_pt2;
852  }
853  // From 4 coordinates
854  QBezierSegment(float x_c, float y_c, float x_end, float y_end) noexcept {
855  pt1.x = x_c, pt1.y = y_c;
856  pt2.x = x_end, pt2.y = y_end;
857  }
858  // Operations
859  QBezierSegment& operator=(const SDKQBezierSegment& src) noexcept {
860  *static_cast<SDKQBezierSegment*>(this) = src;
861  return *this;
862  }
863 
864  typedef std::vector<QBezierSegment> container;
865 };
866 
870 public:
871  // Constructors
872  // Uninitialized segment
873  CuBezierSegment() noexcept {
874  pt1.x = pt1.y = pt2.x = pt2.y = pt3.x = pt3.y = 0.0f;
875  }
876  // Copy constructor
877  CuBezierSegment(const SDKCuBezierSegment& src) noexcept : SDKCuBezierSegment(src) {}
878  // From three points
880  const SDKPointF2D& init_pt1, const SDKPointF2D& init_pt2, const SDKPointF2D& init_pt3) noexcept {
881  pt1 = init_pt1;
882  pt2 = init_pt2;
883  pt3 = init_pt3;
884  }
885  // From 6 coordinates
886  CuBezierSegment(float x_c1, float y_c1, float x_c2, float y_c2,
887  float x_end, float y_end) noexcept {
888  pt1.x = x_c1, pt1.y = y_c1;
889  pt2.x = x_c2, pt2.y = y_c2;
890  pt3.x = x_end, pt3.y = y_end;
891  }
892  // Operations
893  CuBezierSegment& operator=(const SDKCuBezierSegment& src) noexcept {
894  *static_cast<SDKCuBezierSegment*>(this) = src;
895  return *this;
896  }
897 
898  typedef std::vector<CuBezierSegment> container;
899 };
900 
901 class GeoPoint : public SDKGeoPoint {
902 public:
903  GeoPoint() noexcept {
904  x = SDK_MAX_DOUBLE;
905  y = SDK_MAX_DOUBLE;
906  }
907 
908  GeoPoint(double _x, double _y) noexcept {
909  x = _x;
910  y = _y;
911  }
912 
913  GeoPoint(const GeoPoint& src) noexcept {
914  x = src.x;
915  y = src.y;
916  }
917 
918  GeoPoint(const SDKGeoPoint& src) noexcept {
919  x = src.x;
920  y = src.y;
921  }
922 
923  GeoPoint(const SDKPointD2D& src) noexcept {
924  x = src.x;
925  y = src.y;
926  }
927 
928  #if 0
929  bool IsValid() const
930  {
931  return (x > kDegLonMax || x < kDegLonMin
932  || y > kDegLatMax || y < kDegLatMin) ? false : true;
933  }
934 
935  // Returns true if geopoint is equal to another geopoint
936  bool IsEqual(const GeoPoint& pt) const noexcept {
937  if (IsValid() != pt.IsValid())
938  return false;
939  if (!IsValid())
940  return true; // Both of points are not valid
941 
942  // Both of points are valid
943  if (fabs(x - pt.x) >= FLT_EPSILON)
944  return false;
945  if (fabs(y - pt.y) >= FLT_EPSILON)
946  return false;
947 
948  return true;
949  }
950  #endif
951  // Operations
952  GeoPoint& operator=(const SDKGeoPoint& src) noexcept {
953  *static_cast<SDKGeoPoint*>(this) = src;
954  return *this;
955  }
956  #if 0
957  bool operator==(const GeoPoint& pt) const noexcept { return IsEqual(pt); }
958  bool operator!=(const GeoPoint& pt) const noexcept { return !IsEqual(pt); }
959  #endif
960  typedef std::vector<GeoPoint> container;
961 
962 private:
963 
964  GeoPoint(SDKInt32 x, SDKInt32 y) {
965  }
966 };
967 
968 template <typename _GeoDistance, typename _GeoCoordinate>
969 static inline _GeoDistance GeoLonDistance(_GeoCoordinate lon1, _GeoCoordinate lon2);
970 
971 static inline GeoIntDistance GeoIntLonDistance(GeoInt lon1, GeoInt lon2) {
972  //return (lon1 <= lon2) ? lon2 - lon1 : kGeoIntLonMax - lon1 + lon2 - kGeoIntLonMin;
973  // The same but for what?
974  //return lon2 - lon1 - GeoInt(lon2 < lon1);
975  return GeoIntDistance(lon2 - lon1);
976 }
977 
978 static inline GeoIntDistance GeoLonDistance(GeoInt lon1, GeoInt lon2) {
979  return GeoIntLonDistance(lon1, lon2);
980 }
981 
982 static inline double GeoLonDistance(double lon1, double lon2) {
983  //return lon2 - lon1 + ((lon2 - lon1) < 0 ? kDegLonFull : 0);
984  // Commented formula (above) give different results in the following cases:
985  // 179.97777777777779 -> +180.0 = 0.022222222222211485
986  // 179.97777777777779 -> -180.0 = 0.022222222222239907
987  // Formula below works better, it gives the same results
988  return (lon1 <= lon2) ? lon2 - lon1 : kDegLonMax - lon1 + lon2 - kDegLonMin;
989 }
990 
991 static inline double GeoLonDistanceMin(double lon1, double lon2)
992 {
993  double dist1 = GeoLonDistance(lon1, lon2);
994  double dist2 = GeoLonDistance(lon2, lon1);
995  return (dist1 <= dist2) ? dist1 : dist2;
996 }
997 
998 static inline GeoIntDistance GeoIntLonComplimentDistance(GeoIntDistance lon_distance) {
999  //return kGeoIntLonFull - lon_distance;
1000  return GeoIntDistance(-GeoInt(lon_distance));
1001 }
1002 
1003 static inline GeoIntDistance GeoLonComplimentDistance(GeoIntDistance lon_distance) {
1004  return GeoIntLonComplimentDistance(lon_distance);
1005 }
1006 
1007 static inline double GeoLonComplimentDistance(double lon_distance) {
1008  return kDegLonFull - lon_distance;
1009 }
1010 
1011 static inline GeoInt GeoIntLonShift(GeoInt lon, GeoInt shift) {
1012  return lon + shift;
1013 }
1014 
1015 static inline GeoInt GeoLonShift(GeoInt lon, GeoInt shift) {
1016  return GeoIntLonShift(lon, shift);
1017 }
1018 
1019 static inline double GeoLonShift(double lon, double shift) {
1020  //double new_lon = lon + shift;
1021  //return (new_lon > kDegLonMax) ? kDegLonMin + new_lon - kDegLonMax : new_lon;
1022  using std::fmod;
1023  double new_lon = fmod(lon + shift, kDegLonFull);
1024  if (new_lon >= kDegLonMax)
1025  new_lon -= kDegLonFull;
1026  else if (new_lon < kDegLonMin)
1027  new_lon += kDegLonFull;
1028  return new_lon;
1029 }
1030 
1031 static inline bool IsGeoIntLonInside(GeoInt lon, GeoInt lon1, GeoInt lon2) {
1032  //if (lon1 <= lon2)
1033  // return ((lon >= lon1) && (lon <= lon2));
1034  //return ((lon >= kGeoIntLonMin) && (lon <= lon2)) ||
1035  // ((lon >= lon1) && (lon <= kGeoIntLonMax));
1036  return GeoIntDistance(lon - lon1) <= GeoIntDistance(lon2 - lon1);
1037 }
1038 
1039 static inline bool IsGeoLonInside(GeoInt lon, GeoInt lon1, GeoInt lon2) {
1040  return IsGeoIntLonInside(lon, lon1, lon2);
1041 }
1042 
1043 // Simple version which does not take into account that -180/180 is the same
1044 static inline bool IsGeoLonInsideR(double lon, double lon1, double lon2) {
1045  if (lon1 <= lon2)
1046  return ((lon1 <= lon) && (lon <= lon2));
1047  return ((kDegLonMin <= lon) && (lon <= lon2)) ||
1048  ((lon1 <= lon) && (lon <= kDegLonMax));
1049 }
1050 
1051 static inline bool IsGeoLonInside(double lon, double lon1, double lon2) {
1052  //
1053  //return GeoLonDistance(lon1, lon) <= GeoLonDistance(lon1, lon2);
1054  //
1055  // Version with distances (commented) seem to be more simple but it is affected
1056  // by double accuracy, because it uses double calculations.
1057  // Version with ranges (below) work in 100% cases and any accuracy.
1058  // 'If' solves the problem of -180/180 w/o adding any calculations.
1059  if (kDegLonMin == lon || kDegLonMax == lon)
1060  return IsGeoLonInsideR(lon, lon1, lon2) || IsGeoLonInsideR(-lon, lon1, lon2);
1061  return IsGeoLonInsideR(lon, lon1, lon2);
1062 }
1063 
1064 static inline GeoIntDistance GeoIntLatDistance(GeoInt lat1, GeoInt lat2) {
1065  return (lat1 <= lat2) ? lat2 - lat1 : lat1 - lat2;
1066 }
1067 
1068 static inline GeoIntDistance GeoLatDistance(GeoInt lat1, GeoInt lat2) {
1069  using std::abs;
1070  return abs(lat2 - lat1);
1071 }
1072 
1073 static inline double GeoLatDistance(double lat1, double lat2) {
1074  //return (lat1 <= lat2) ? lat2 - lat1 : lat1 - lat2;
1075  using std::abs;
1076  return abs(lat2 - lat1);
1077 }
1078 
1079 static inline GeoInt GeoIntLatShift(GeoInt lat, GeoInt shift) {
1080  if (shift >= 0)
1081  return (GeoIntLatDistance(lat, kGeoIntLatMax) > GeoIntDistance(shift))
1082  ? lat + shift : kGeoIntLatMax;
1083  else
1084  return (GeoIntLatDistance(kGeoIntLatMin, lat) > GeoIntDistance(-shift))
1085  ? lat + shift : kGeoIntLatMin;
1086 }
1087 
1088 static inline GeoInt GeoLatShift(GeoInt lat, GeoInt shift) {
1089  return GeoIntLatShift(lat, shift);
1090 }
1091 
1092 static inline double GeoLatShift(double lat, const double& shift) {
1093  double new_lat = lat + shift;
1094  if (new_lat > kDegLatMax)
1095  return kDegLatMax;
1096  if (new_lat < kDegLatMin)
1097  return kDegLatMin;
1098  return new_lat;
1099 }
1100 
1101 static inline bool IsGeoIntLatInside(GeoInt lat, GeoInt lat1, GeoInt lat2) {
1102  if (lat1 <= lat2)
1103  return ((lat >= lat1) && (lat <= lat2));
1104  else
1105  return ((lat >= lat2) && (lat <= lat1));
1106 }
1107 
1108 static inline bool IsGeoLatInside(GeoInt lat, GeoInt lat1, GeoInt lat2) {
1109  return IsGeoIntLatInside(lat, lat1, lat2);
1110 }
1111 
1112 static inline bool IsGeoLatInside(double lat, double lat1, double lat2) {
1113  if (lat1 <= lat2)
1114  return ((lat >= lat1) && (lat <= lat2));
1115  else
1116  return ((lat >= lat2) && (lat <= lat1));
1117 }
1118 
1119 static inline double NormalizeGeoLon(double lon) {
1120  using std::fmod;
1121  lon = fmod(lon, kDegLonFull);
1122  if (lon >= kDegLonMax)
1123  lon -= kDegLonFull;
1124  else if (lon < kDegLonMin)
1125  lon += kDegLonFull;
1126  //while (lon > kDegLonMax)
1127  // lon -= kDegLonFull;
1128  //while (lon < kDegLonMin)
1129  // lon += kDegLonFull;
1130  return lon;
1131 }
1132 
1133 static inline double NormalizeGeoLat(double lat) {
1134  if (lat > kDegLatMax)
1135  lat = kDegLatMax;
1136  else if (lat < kDegLatMin)
1137  lat = kDegLatMin;
1138  return lat;
1139 }
1140 
1141 class GeoIntPoint : public SDKGeoIntPoint {
1142 public:
1143  GeoIntPoint() noexcept {
1144  x = y = 0;
1145  }
1146  GeoIntPoint(GeoInt _x, GeoInt _y) noexcept {
1147  x = _x; y = _y;
1148  }
1149  GeoIntPoint(const SDKGeoIntPoint& src) noexcept {
1150  x = src.x; y = src.y;
1151  }
1152  GeoIntPoint(const GeoIntPoint& src) noexcept {
1153  x = src.x; y = src.y;
1154  }
1155  // Operations
1156  void operator=(const GeoIntPoint& src) noexcept {
1157  x = src.x; y = src.y;
1158  }
1159 
1160  typedef std::vector<GeoIntPoint> container;
1161 };
1162 
1163 class GeoIntPoint3D : public SDKGeoIntPoint3D {
1164 public:
1165  GeoIntPoint3D() noexcept {
1166  x = y = 0; z = 0.0;
1167  }
1168  GeoIntPoint3D(GeoInt _x, GeoInt _y, double _z) noexcept {
1169  x = _x; y = _y; z = _z;
1170  }
1171  GeoIntPoint3D(const GeoIntPoint3D& src) noexcept {
1172  x = src.x; y = src.y; z = src.z;
1173  }
1174  // Operations
1175  void operator=(const GeoIntPoint3D& src) noexcept {
1176  x = src.x; y = src.y; z = src.z;
1177  }
1178 
1179  typedef std::vector<GeoIntPoint3D> container;
1180 };
1181 
1182 class GeoPoint3D : public SDKGeoPoint3D {
1183 public:
1184  GeoPoint3D() {
1185  x = y = z = 0.0;
1186  }
1187  GeoPoint3D(double _x, double _y, double _z) {
1188  x = _x; y = _y; z = _z;
1189  }
1190  GeoPoint3D(const GeoPoint3D& src) {
1191  x = src.x; y = src.y; z = src.z;
1192  }
1193  // Operations
1194  void operator=(const GeoPoint3D& src) {
1195  x = src.x; y = src.y; z = src.z;
1196  }
1197 
1198  typedef std::vector<GeoPoint3D> container;
1199 };
1200 
1201 class GeoIntRect : public SDKGeoIntRect {
1202 public:
1203  GeoIntRect() noexcept {
1204  sw.x = sw.y = ne.x = ne.y = 0;
1205  }
1206 
1207  GeoIntRect(const GeoIntPoint& _sw, const GeoIntPoint& _ne) noexcept {
1208  sw = _sw; ne = _ne;
1209  }
1210 
1211  GeoIntRect(GeoInt sw_lon, GeoInt sw_lat, GeoInt ne_lon, GeoInt ne_lat
1212  ) noexcept {
1213  SetRect(sw_lon, sw_lat, ne_lon, ne_lat);
1214  }
1215 
1216  GeoIntRect(const SDKGeoIntRect& src) noexcept {
1217  SetRect(src.sw.lon, src.sw.lat, src.ne.lon, src.ne.lat);
1218  }
1219 
1220  // Default copy constructor is suitable here
1221  //GeoIntRect(const GeoIntRect& src) noexcept { *this = src; }
1222 
1223  // Operations
1224  // Default operator=() is suitable here
1225  //void operator=(const GeoIntRect& src) noexcept { sw = src.sw; ne = src.ne; }
1226  bool operator&(const GeoIntRect& src) noexcept {
1227  return IsIntersected(*this, src);
1228  }
1229 
1230  void SetRect(GeoInt sw_lon, GeoInt sw_lat, GeoInt ne_lon, GeoInt ne_lat
1231  ) noexcept {
1232  sw.lat = sw_lat; sw.lon = sw_lon; ne.lat = ne_lat; ne.lon = ne_lon;
1233  }
1234 
1235  bool IsNormalized() const noexcept {
1236  return (sw.lon <= ne.lon) && (sw.lat <= ne.lat);
1237  }
1238 
1239  // returns TRUE if rectangle has no area
1240  bool IsRectEmpty() const noexcept {
1241  return ((min.x == max.x) || (min.y == max.y)) ? true : false;
1242  }
1243 
1244  // returns TRUE if rectangle is at (0,0) and has no area
1245  bool IsRectNull() const noexcept {
1246  return (min.x == 0 && min.y == 0 &&
1247  max.x == 0 && max.y == 0) ? true : false;
1248  }
1249 
1250  // pointer to the array of 2 rectangles.
1251 #ifndef SDK_CC_BCC
1252  SDKUInt32 Normalize(GeoIntRect (&rects)[2]) const noexcept {
1253 #else
1254  SDKUInt32 Normalize(GeoIntRect* rects) const noexcept {
1255 #endif
1256  if (ne.lat < sw.lat) {
1257  return 0; // Wrong case
1258  }
1259  if (sw.lon <= ne.lon) {
1260  rects[0] = *this;
1261  return 1;
1262  }
1263  rects[0] = GeoIntRect(sw.lon, sw.lat, kGeoIntLonMax, ne.lat);
1264  rects[1] = GeoIntRect(kGeoIntLonMin, sw.lat, ne.lon, ne.lat);
1265  return 2;
1266  }
1267 
1268  bool IsIntersected(const SDKGeoIntRect& r) const noexcept {
1269  return IsIntersected(*this, r);
1270  }
1271 
1272  static bool IsIntersected(
1273  const SDKGeoIntRect& r1,
1274  const SDKGeoIntRect& r2) noexcept {
1275 
1276  if (r1.sw.lon > r1.ne.lon) // over 180 rectangle
1277  return IsIntersected(r2,
1278  GeoIntRect(r1.sw.lon, r1.sw.lat, kGeoIntLonMax, r1.ne.lat))
1279  || IsIntersected(r2,
1280  GeoIntRect(kGeoIntLonMin, r1.sw.lat, r1.ne.lon, r1.ne.lat));
1281 
1282  if (r2.sw.lon > r2.ne.lon) // over 180 rectangle
1283  return IsIntersected(r2, r1);
1284 
1285  return ((r1.sw.lon <= r2.ne.lon && r1.ne.lon >= r2.sw.lon) &&
1286  (r1.sw.lat <= r2.ne.lat && r1.ne.lat >= r2.sw.lat));
1287  }
1288 
1289  static SDKGeoIntRect Union(const SDKGeoIntRect& r1,
1290  const SDKGeoIntRect& r2) noexcept {
1291 
1292  GeoIntRect res = r1;
1293  res.Union(r2);
1294  return res;
1295  }
1296 
1297  GeoIntRect& Union(const SDKGeoIntRect& _r2) noexcept {
1298 
1299  GeoIntRect& r1 = *this;
1300  const GeoIntRect& r2 = static_cast<const SDKGeoIntRect&>(_r2);
1301 
1302  if (r1.IsRectNull())
1303  return (*this = r2), *this;
1304  if (r2.IsRectNull())
1305  return *this;
1306 
1307  if (r1.ne.lat < r1.sw.lat || r2.ne.lat < r2.sw.lat) {
1308  this->~GeoIntRect();
1309  new (this) GeoIntRect();
1310  return *this;
1311  }
1312 
1313  // at first check cases when rects are intersected along longitude.
1314  GeoInt sw_lon = 0, ne_lon = 0;
1315  if ((r1.sw.lon == r2.sw.lon) && (r1.ne.lon == r2.ne.lon)) {
1316  sw_lon = r1.sw.lon, ne_lon = r1.ne.lon;
1317  } else {
1318  bool is_r1_lon_tail_in_r2 = IsGeoIntLonInside(r1.ne.lon, r2.sw.lon, r2.ne.lon);
1319  bool is_r2_lon_tail_in_r1 = IsGeoIntLonInside(r2.ne.lon, r1.sw.lon, r1.ne.lon);
1320  bool is_r1_lon_nose_in_r2 = IsGeoIntLonInside(r1.sw.lon, r2.sw.lon, r2.ne.lon);
1321  bool is_r2_lon_nose_in_r1 = IsGeoIntLonInside(r2.sw.lon, r1.sw.lon, r1.ne.lon);
1322  if (is_r1_lon_tail_in_r2 && is_r2_lon_tail_in_r1 &&
1323  is_r1_lon_nose_in_r2 && is_r2_lon_nose_in_r1)
1324  sw_lon = kGeoIntLonMin, ne_lon = kGeoIntLonMax;
1325  else if (is_r1_lon_nose_in_r2 && is_r1_lon_tail_in_r2)
1326  sw_lon = r2.sw.lon, ne_lon = r2.ne.lon; // r1 is inside r2
1327  else if (is_r2_lon_nose_in_r1 && is_r2_lon_tail_in_r1)
1328  sw_lon = r1.sw.lon, ne_lon = r1.ne.lon; // r2 is inside r1
1329  else if (is_r1_lon_tail_in_r2)
1330  sw_lon = r1.sw.lon, ne_lon = r2.ne.lon; // partly intersected
1331  else if (is_r2_lon_tail_in_r1)
1332  sw_lon = r2.sw.lon, ne_lon = r1.ne.lon; // partly intersected
1333  else // not intersected along longitude.
1334  if (GeoIntLonDistance(r1.ne.lon, r2.sw.lon) < GeoIntLonDistance(r2.ne.lon, r1.sw.lon))
1335  sw_lon = r1.sw.lon, ne_lon = r2.ne.lon; // r1 on the left of r2
1336  else
1337  sw_lon = r2.sw.lon, ne_lon = r1.ne.lon; // r1 on the right of r2
1338  }
1339 
1340  // then check cases when rects are intersected along latitude.
1341 #if 1
1342  // Latitudes are comparable in the Cartesian style so it is no need
1343  // to calculate them in a such complicated manner.
1344  GeoInt sw_lat = (r1.sw.lat <= r2.sw.lat) ? r1.sw.lat : r2.sw.lat;
1345  GeoInt ne_lat = (r1.ne.lat >= r2.ne.lat) ? r1.ne.lat : r2.ne.lat;
1346 #else
1347  GeoInt sw_lat = 0, ne_lat = 0;
1348  if ((r1.sw.lat == r2.sw.lat) && (r1.ne.lat == r2.ne.lat)) {
1349  sw_lat = r1.sw.lat, ne_lat = r1.ne.lat;
1350  } else {
1351  bool is_r1_lat_tail_in_r2 = IsGeoIntLatInside(r1.ne.lat, r2.sw.lat, r2.ne.lat);
1352  bool is_r2_lat_tail_in_r1 = IsGeoIntLatInside(r2.ne.lat, r1.sw.lat, r1.ne.lat);
1353  bool is_r1_lat_nose_in_r2 = IsGeoIntLatInside(r1.sw.lat, r2.sw.lat, r2.ne.lat);
1354  bool is_r2_lat_nose_in_r1 = IsGeoIntLatInside(r2.sw.lat, r1.sw.lat, r1.ne.lat);
1355  if (is_r1_lat_tail_in_r2 && is_r2_lat_tail_in_r1 &&
1356  is_r1_lat_nose_in_r2 && is_r2_lat_nose_in_r1)
1357  sw_lat = kGeoIntLatMin, ne_lat = kGeoIntLatMax;
1358  else if (is_r1_lat_nose_in_r2 && is_r1_lat_tail_in_r2)
1359  sw_lat = r2.sw.lat, ne_lat = r2.ne.lat; // r1 is inside r2
1360  else if (is_r2_lat_nose_in_r1 && is_r2_lat_tail_in_r1)
1361  sw_lat = r1.sw.lat, ne_lat = r1.ne.lat; // r2 is inside r1
1362  else if (is_r1_lat_tail_in_r2)
1363  sw_lat = r1.sw.lat, ne_lat = r2.ne.lat; // partly intersected
1364  else if (is_r2_lat_tail_in_r1)
1365  sw_lat = r2.sw.lat, ne_lat = r1.ne.lat; // partly intersected
1366  else // not intersected along latitude
1367  if (GeoIntLatDistance(r1.ne.lat, r2.sw.lat) < GeoIntLatDistance(r2.ne.lat, r1.sw.lat))
1368  sw_lat = r1.sw.lat, ne_lat = r2.ne.lat; // r1 below r2
1369  else
1370  sw_lat = r2.sw.lat, ne_lat = r1.ne.lat; // r1 above r2
1371  }
1372 #endif
1373 
1374  //return sdk::GeoIntRect(sw_lon, sw_lat, ne_lon, ne_lat);
1375  sw.lon = sw_lon;
1376  sw.lat = sw_lat;
1377  ne.lon = ne_lon;
1378  ne.lat = ne_lat;
1379  return *this;
1380  }
1381 
1382  bool PointInRect(const GeoIntPoint& p) const noexcept {
1383  return PointInRect(p, *this);
1384  }
1385 
1386  static bool PointInRect(
1387  const SDKGeoIntPoint& p,
1388  const SDKGeoIntRect& r) noexcept {
1389 #if 1
1390  if (GeoIntDistance(p.lon - r.sw.lon)
1391  > GeoIntDistance(r.ne.lon - r.sw.lon))
1392  return false;
1393  return r.sw.lat <= p.lat && p.lat <= r.ne.lat;
1394 #else
1395  if (r.IsRectNull())
1396  return false;
1397  if (r.ne.lat < r.sw.lat) // Wrong case
1398  return false;
1399  if (r.sw.lon > r.ne.lon) // over 180 rectangle
1400  return PointInRect(p,
1401  GeoIntRect(r.sw.lon, r.sw.lat, kGeoIntLonMax, r.ne.lat))
1402  || PointInRect(p,
1403  GeoIntRect(kGeoIntLonMin, r.sw.lat, r.ne.lon, r.ne.lat));
1404  return (p.lon >= r.sw.lon && p.lon <= r.ne.lon &&
1405  p.lat >= r.sw.lat && p.lat <= r.ne.lat);
1406 #endif
1407  }
1408 
1409  GeoIntPoint Center() const noexcept {
1410 #if 1
1411  GeoIntPoint center(
1412  GeoInt(sw.lon + (GeoIntDistance(ne.lon - sw.lon) >> 1)),
1413  (sw.lat + ne.lat) / 2);
1414  return center;
1415 #else
1416  GeoIntPoint center;
1417  if (sw.x == ne.x) {
1418  center.x = sw.x;
1419  } else {
1420  double sw_x = DegFromGeoInt(sw.x);
1421  double ne_x = DegFromGeoInt(ne.x);
1422  if (sw_x > ne_x)
1423  ne_x += 360.0;
1424 
1425  double center_x = sw_x + ((ne_x - sw_x) / 2);
1426  while(center_x >= 360.0) // Normalize x
1427  center_x -= 360.0;
1428 
1429  center.x = GeoIntFromDeg(center_x);
1430  }
1431 
1432  if (sw.y == ne.y)
1433  center.y = sw.y;
1434  else
1435  center.y = (sw.y + ne.y) / 2;
1436 #endif
1437  return center;
1438  }
1439 
1440  typedef std::vector<GeoIntRect> container;
1441 };
1442 
1443 inline bool operator==(const GeoIntRect& r1, const GeoIntRect& r2) {
1444  return (r1.sw.lon == r2.sw.lon) && (r1.sw.lat == r2.sw.lat) &&
1445  (r1.ne.lon == r2.ne.lon) && (r1.ne.lat == r2.ne.lat);
1446 }
1447 
1448 class GeoPointRect;
1449 inline bool operator==(const GeoPointRect& r1, const GeoPointRect& r2);
1450 
1451 class GeoPointRect : public SDKGeoPointRect {
1452 public:
1453  GeoPointRect() noexcept { sw.lat = sw.lon = ne.lat = ne.lon = 0.0; }
1454  GeoPointRect(const GeoPoint& _sw, const GeoPoint& _ne) noexcept {
1455  sw = _sw; ne = _ne;
1456  }
1457 
1458  GeoPointRect(double sw_lon, double sw_lat, double ne_lon, double ne_lat
1459  ) noexcept {
1460  SetRect(sw_lon, sw_lat, ne_lon, ne_lat);
1461  }
1462 
1463  GeoPointRect(const SDKGeoPointRect& src) noexcept {
1464  sw.lon = src.sw.lon; sw.lat = src.sw.lat;
1465  ne.lon = src.ne.lon; ne.lat = src.ne.lat; }
1466 
1467  // Default copy constructor is suitable here
1468  //GeoPointRect(const GeoPointRect& src) noexcept { *this = src; }
1469  // Operations
1470  // Default copy operator is suitable here
1471  //void operator=(const GeoPointRect& src) noexcept { sw = src.sw; ne = src.ne; }
1472 
1473  void SetRect(double sw_lon, double sw_lat, double ne_lon, double ne_lat
1474  ) noexcept {
1475  sw.lat = sw_lat; sw.lon = sw_lon; ne.lat = ne_lat; ne.lon = ne_lon;
1476  }
1477 
1478  // returns TRUE if rectangle has no area
1479  bool IsRectEmpty() const noexcept {
1480  return ((min.x == max.x) || (min.y == max.y));
1481  }
1482 
1483  // returns TRUE if rectangle is at (0,0) and has no area
1484  bool IsRectNull() const noexcept {
1485  return (min.x == 0.0 && min.y == 0.0 &&
1486  max.x == 0.0 && max.y == 0.0);
1487  }
1488 
1489  // pointer to the array of 2 rectangles.
1490 #ifndef SDK_CC_BCC
1491  SDKUInt32 Normalize(GeoPointRect (&rects)[2]) const noexcept {
1492 #else
1493  SDKUInt32 Normalize(GeoPointRect* rects) const noexcept {
1494 #endif
1495  if (ne.lat < sw.lat) {
1496  return 0;
1497  }
1498 
1499  if (sw.lon <= ne.lon) {
1500  rects[0] = *this;
1501  return 1;
1502  }
1503 
1504  rects[0] = GeoPointRect(sw.lon, sw.lat, kDegLonMax, ne.lat);
1505  rects[1] = GeoPointRect(kDegLonMin, sw.lat, ne.lon, ne.lat);
1506  return 2;
1507  }
1508 
1509  bool IsIntersected(const SDKGeoPointRect& r) const noexcept {
1510  return IsIntersected(*this, r);
1511  }
1512 
1513  static bool IsIntersectedSimple(const SDKGeoPointRect& r1,
1514  const SDKGeoPointRect& r2) noexcept {
1515 
1516  return ((r1.sw.lon <= r2.ne.lon && r1.ne.lon >= r2.sw.lon) &&
1517  (r1.sw.lat <= r2.ne.lat && r1.ne.lat >= r2.sw.lat));
1518  }
1519 
1520  static bool IsIntersected(const SDKGeoPointRect& r1,
1521  const SDKGeoPointRect& r2) noexcept {
1522 
1523  auto right_rect = [](const SDKGeoPointRect& r) {
1524  return GeoPointRect(r.sw.lon, r.sw.lat, kDegLonMax, r.ne.lat); };
1525  auto left_rect = [](const SDKGeoPointRect& r) {
1526  return GeoPointRect(kDegLonMin, r.sw.lat, r.ne.lon, r.ne.lat); };
1527 
1528  if ((r1.sw.lon > r1.ne.lon) && // over 180
1529  (r2.sw.lon > r2.ne.lon)) // over 180
1530  {
1531  return IsIntersectedSimple(right_rect(r1), right_rect(r2))
1532  || IsIntersectedSimple(right_rect(r1), left_rect(r2))
1533  || IsIntersectedSimple(left_rect(r1), right_rect(r2))
1534  || IsIntersectedSimple(left_rect(r1), left_rect(r2));
1535  }
1536 
1537  if (r1.sw.lon > r1.ne.lon) // over 180
1538  {
1539  return IsIntersectedSimple(right_rect(r1), r2)
1540  || IsIntersectedSimple(left_rect(r1), r2);
1541  }
1542 
1543  if (r2.sw.lon > r2.ne.lon) // over 180
1544  {
1545  return IsIntersectedSimple(r1, right_rect(r2))
1546  || IsIntersectedSimple(r1, left_rect(r2));
1547  }
1548 
1549  return IsIntersectedSimple(r1, r2);
1550  }
1551 
1552  static bool PointInRect(const GeoPoint& p,
1553  const GeoPointRect& r) noexcept {
1554 
1555  if (r.IsRectNull())
1556  return false;
1557  if (r.sw.lon > r.ne.lon) // over 180 rectangle
1558  return PointInRect(p,
1559  GeoPointRect(r.sw.lon, r.sw.lat, kDegLonMax, r.ne.lat))
1560  || PointInRect(p,
1561  GeoPointRect(kDegLonMin, r.sw.lat, r.ne.lon, r.ne.lat));
1562  return (p.lon >= r.sw.lon && p.lon <= r.ne.lon &&
1563  p.lat >= r.sw.lat && p.lat <= r.ne.lat);
1564  }
1565 
1566  // Returns True if r1 is completely inside r2
1567  static bool RectInRect(const GeoPointRect& r1,
1568  const GeoPointRect& r2) noexcept {
1569 
1570  GeoPointRect r = GeoPointRect::Union(r1, r2);
1571  return r == r2;
1572  }
1573 
1574  static GeoPointRect Union(
1575  const SDKGeoPointRect& r1,
1576  const SDKGeoPointRect& r2) noexcept {
1577 
1578  GeoPointRect res(r1);
1579  res.Union(r2);
1580  return res;
1581  }
1582 
1583  GeoPointRect& Union(const SDKGeoPointRect& r) noexcept {
1584 
1585  GeoPointRect& r1 = *this;
1586  const GeoPointRect& r2 = static_cast<const GeoPointRect&>(r);
1587  if (r1.IsRectNull())
1588  return r1 = r2;
1589  if (r2.IsRectNull())
1590  return r1;
1591  if (r1.ne.lat < r1.sw.lat || r2.ne.lat < r2.sw.lat) {
1592  this->~GeoPointRect();
1593  new (this) GeoPointRect();
1594  return *this;
1595  }
1596 
1597  // at first check cases when rects are intersected along longitude.
1598  double sw_lon = 0, ne_lon = 0;
1599  if ((r1.sw.lon == r2.sw.lon) && (r1.ne.lon == r2.ne.lon)) {
1600  sw_lon = r1.sw.lon, ne_lon = r1.ne.lon;
1601  } else {
1602  bool is_r1_lon_tail_in_r2 = IsGeoLonInside(r1.ne.lon, r2.sw.lon, r2.ne.lon);
1603  bool is_r2_lon_tail_in_r1 = IsGeoLonInside(r2.ne.lon, r1.sw.lon, r1.ne.lon);
1604  bool is_r1_lon_nose_in_r2 = IsGeoLonInside(r1.sw.lon, r2.sw.lon, r2.ne.lon);
1605  bool is_r2_lon_nose_in_r1 = IsGeoLonInside(r2.sw.lon, r1.sw.lon, r1.ne.lon);
1606  if (is_r1_lon_tail_in_r2 && is_r2_lon_tail_in_r1 &&
1607  is_r1_lon_nose_in_r2 && is_r2_lon_nose_in_r1)
1608  sw_lon = kDegLonMin, ne_lon = kDegLonMax;
1609  else if (is_r1_lon_nose_in_r2 && is_r1_lon_tail_in_r2)
1610  sw_lon = r2.sw.lon, ne_lon = r2.ne.lon; // r1 is inside r2
1611  else if (is_r2_lon_nose_in_r1 && is_r2_lon_tail_in_r1)
1612  sw_lon = r1.sw.lon, ne_lon = r1.ne.lon; // r2 is inside r1
1613  else if (is_r1_lon_tail_in_r2)
1614  sw_lon = r1.sw.lon, ne_lon = r2.ne.lon; // partly intersected
1615  else if (is_r2_lon_tail_in_r1)
1616  sw_lon = r2.sw.lon, ne_lon = r1.ne.lon; // partly intersected
1617  else // not intersected along longitude.
1618  if (GeoLonDistance(r1.ne.lon, r2.sw.lon) < GeoLonDistance(r2.ne.lon, r1.sw.lon))
1619  sw_lon = r1.sw.lon, ne_lon = r2.ne.lon; // r1 on the left of r2
1620  else
1621  sw_lon = r2.sw.lon, ne_lon = r1.ne.lon; // r1 on the right of r2
1622  }
1623 
1624  double sw_lat = r1.sw.lat < r2.sw.lat ? r1.sw.lat : r2.sw.lat;
1625  double ne_lat = r1.ne.lat > r2.ne.lat ? r1.ne.lat : r2.ne.lat;
1626 
1627  //return sdk::GeoPointRect(sw_lon, sw_lat, ne_lon, ne_lat);
1628  sw.lon = sw_lon;
1629  sw.lat = sw_lat;
1630  ne.lon = ne_lon;
1631  ne.lat = ne_lat;
1632  return *this;
1633  }
1634 
1635  sdk::GeoPoint Center() const noexcept {
1636  sdk::GeoPoint center;
1637  if (sw.x == ne.x) {
1638  center.x = sw.x;
1639  } else {
1640  double sw_x = sw.x;
1641  double ne_x = ne.x;
1642  if (sw_x > ne_x)
1643  ne_x += kDegLonFull;
1644 
1645  double center_x = sw_x + ((ne_x - sw_x) / 2);
1646  while(center_x >= kDegLonMax) // Normalize x
1647  center_x -= kDegLonFull;
1648 
1649  center.x = center_x;
1650  }
1651 
1652  if (sw.y == ne.y)
1653  center.y = sw.y;
1654  else
1655  center.y = (sw.y + ne.y) / 2;
1656 
1657  return center;
1658  }
1659 
1660  typedef std::vector<GeoPointRect> container;
1661 };
1662 
1663 inline bool operator==(const GeoPointRect& r1, const GeoPointRect& r2) {
1664  return (r1.sw.lon == r2.sw.lon) && (r1.sw.lat == r2.sw.lat) &&
1665  (r1.ne.lon == r2.ne.lon) && (r1.ne.lat == r2.ne.lat);
1666 }
1667 
1668 inline GeoPointRect RectD2DToGeoPointRect(const RectD2D& geo_rect) {
1669  return GeoPointRect(geo_rect.x, geo_rect.y,
1670  GeoLonShift(geo_rect.x, geo_rect.width),
1671  GeoLatShift(geo_rect.y, geo_rect.height));
1672 }
1673 
1674 inline GeoPointRect GeoPointRectFromRectD2D(const RectD2D& geo_rect) {
1675  return RectD2DToGeoPointRect(geo_rect);
1676 }
1677 
1678 inline RectD2D GeoPointRectToRectD2D(const GeoPointRect& geo_rect) {
1679  return RectD2D(geo_rect.sw.x, geo_rect.sw.y,
1680  GeoLonDistance(geo_rect.sw.x, geo_rect.ne.x),
1681  GeoLatDistance(geo_rect.sw.y, geo_rect.ne.y));
1682 }
1683 
1684 inline RectD2D RectD2DFromGeoPointRect(const GeoPointRect& geo_rect) {
1685  return GeoPointRectToRectD2D(geo_rect);
1686 }
1687 
1688 inline GeoIntRect GeoPointRectToGeoIntRect(const GeoPointRect& geo_rect) {
1689  return GeoIntRect(
1690  GeoIntFromDeg(geo_rect.sw.x), GeoIntFromDeg(geo_rect.sw.y),
1691  GeoIntFromDeg(geo_rect.ne.x), GeoIntFromDeg(geo_rect.ne.y));
1692 }
1693 
1694 inline GeoIntRect GeoIntRectFromGeoPointRect(const GeoPointRect& geo_rect) {
1695  return GeoPointRectToGeoIntRect(geo_rect);
1696 }
1697 
1698 inline GeoPointRect GeoIntRectToGeoPointRect(const GeoIntRect& geo_rect) {
1699  return GeoPointRect(
1700  DegFromGeoInt(geo_rect.sw.x), DegFromGeoInt(geo_rect.sw.y),
1701  DegFromGeoInt(geo_rect.ne.x), DegFromGeoInt(geo_rect.ne.y));
1702 }
1703 
1704 inline GeoPointRect GeoPointRectFromGeoIntRect(const GeoIntRect& geo_rect) {
1705  return GeoIntRectToGeoPointRect(geo_rect);
1706 }
1707 
1708 } // namespace sdk
1709 
1710 #endif // SDK_GEOMETRY_TYPES_HELPERS_H_
sdk::QBezierSegment
A quadratic Bezier curve segment.
Definition: geometry_base_types_helpers.h:841
SDKGeoIntPoint
Definition of geographic points.
Definition: geometry_base_types.h:1555
SDKGeoPointRect
Geo rectangle in degree units.
Definition: geometry_base_types.h:1801
kGeoIntLatMin
static const GeoInt kGeoIntLatMin
Min latitude, integer.
Definition: geometry_base_types.h:1531
kDegLonFull
static const double kDegLonFull
Full range of longitudes around the globe, float.
Definition: geometry_base_types.h:1534
base_types.h
SDK base types.
sdk::RoundRectF2D
A 2-D rounded rectangle.
Definition: geometry_base_types_helpers.h:793
sdk::CuBezierSegment
A cubic Bezier curve segment.
Definition: geometry_base_types_helpers.h:869
sdk::PointI2D
A 2-D point.
Definition: geometry_base_types_helpers.h:165
crs_basic_transformation.inl
The basic transformations inline functions.
sdk::SizeF
SizeF.
Definition: geometry_base_types_helpers.h:238
sdk::PointF2D
A 2-D point.
Definition: geometry_base_types_helpers.h:58
kDegLonMax
static const double kDegLonMax
Max longitude, float.
Definition: geometry_base_types.h:1538
kGeoIntLonMin
static const GeoInt kGeoIntLonMin
Min longitude, integer.
Definition: geometry_base_types.h:1525
SDKRectD2D
2D Rectangle
Definition: geometry_base_types.h:1356
SDK_MAX_DOUBLE
static const double SDK_MAX_DOUBLE
Max limit of double.
Definition: platform.h:202
SDKRectF2D
2D Rectangle
Definition: geometry_base_types.h:1295
sdk::RectI2D
A 2-D rectangle.
Definition: geometry_base_types_helpers.h:732
SDKGeoPoint3D
3D point in degrees.
Definition: geometry_base_types.h:1852
SDKGeoIntRect
Rectangle in GeoInt units.
Definition: geometry_base_types.h:1674
SDKQBezierSegment
Quadratic Bezier curve segment.
Definition: geometry_base_types.h:1495
kDegLatMax
static const double kDegLatMax
Max latitude, float.
Definition: geometry_base_types.h:1542
SDKRectI2D
2D Rectangle
Definition: geometry_base_types.h:1417
sdk::RectF2D
A 2-D Rectangle.
Definition: geometry_base_types_helpers.h:423
sdk::PointD2D
A 2-D point.
Definition: geometry_base_types_helpers.h:109
SDKGeoPoint
Geo point in degree units.
Definition: geometry_base_types.h:1727
kGeoIntLonMax
static const GeoInt kGeoIntLonMax
Max longitude, integer.
Definition: geometry_base_types.h:1522
SDKCuBezierSegment
Cubic Bezier curve segment.
Definition: geometry_base_types.h:1502
kGeoIntLatMax
static const GeoInt kGeoIntLatMax
Max latitude, integer.
Definition: geometry_base_types.h:1528
SDKSizeD
SizeD.
Definition: geometry_base_types.h:1173
kDegLatMin
static const double kDegLatMin
Min latitude, float.
Definition: geometry_base_types.h:1544
SDKPointF3D
Single 3D point.
Definition: geometry_base_types.h:101
SDKPointF2D
Single 2D point.
Definition: geometry_base_types.h:33
sdk::EllipseF2D
A 2-D ellipse.
Definition: geometry_base_types_helpers.h:818
sdk::RectD2D
A 2-D Rectangle.
Definition: geometry_base_types_helpers.h:563
platform.h
Describes the platform constants.
SDKGeoIntPoint3D
3D point in GeoInt units.
Definition: geometry_base_types.h:1609
geometry_base_types.h
Geometry base types.
SDKPointI2D
Single 2D point.
Definition: geometry_base_types.h:178
kDegLonMin
static const double kDegLonMin
Min longitude, float.
Definition: geometry_base_types.h:1540
SDKRoundRectF2D
Rounded 2D rectangle.
Definition: geometry_base_types.h:1479
sdk::SizeD
SizeF.
Definition: geometry_base_types_helpers.h:300
GeoIntFromDeg
SDKInt32 SDK_CDECL GeoIntFromDeg(double deg)
Transforms a geographic position in degree units to GeoInt units.
Definition: crs_basic_transformation.inl:64
SDKSize
SizeUI.
Definition: geometry_base_types.h:1235
SDKPointD3D
A three dimensional point.
Definition: geometry_base_types.h:306
SDKPointD2D
A two dimensional point.
Definition: geometry_base_types.h:242
sdk::Size
Size.
Definition: geometry_base_types_helpers.h:361
SDKSizeF
SizeF.
Definition: geometry_base_types.h:1111
SDKEllipseF2D
2D ellipse
Definition: geometry_base_types.h:1487
DegFromGeoInt
double SDK_CDECL DegFromGeoInt(SDKInt32 geoint)
Transforms a geographic position in GeoInt units to degree units.
Definition: crs_basic_transformation.inl:130