1
2 ///////////////////////////////////////////////////////////
3 // //
4 // SAGA //
5 // //
6 // System for Automated Geoscientific Analyses //
7 // //
8 // Application Programming Interface //
9 // //
10 // Library: SAGA_API //
11 // //
12 //-------------------------------------------------------//
13 // //
14 // geo_classes.cpp //
15 // //
16 // Copyright (C) 2005 by Olaf Conrad //
17 // //
18 //-------------------------------------------------------//
19 // //
20 // This file is part of 'SAGA - System for Automated //
21 // Geoscientific Analyses'. //
22 // //
23 // This library is free software; you can redistribute //
24 // it and/or modify it under the terms of the GNU Lesser //
25 // General Public License as published by the Free //
26 // Software Foundation, either version 2.1 of the //
27 // License, or (at your option) any later version. //
28 // //
29 // This library is distributed in the hope that it will //
30 // be useful, but WITHOUT ANY WARRANTY; without even the //
31 // implied warranty of MERCHANTABILITY or FITNESS FOR A //
32 // PARTICULAR PURPOSE. See the GNU Lesser General Public //
33 // License for more details. //
34 // //
35 // You should have received a copy of the GNU Lesser //
36 // General Public License along with this program; if //
37 // not, see <http://www.gnu.org/licenses/>. //
38 // //
39 //-------------------------------------------------------//
40 // //
41 // contact: Olaf Conrad //
42 // Institute of Geography //
43 // University of Goettingen //
44 // Goldschmidtstr. 5 //
45 // 37077 Goettingen //
46 // Germany //
47 // //
48 // e-mail: oconrad@saga-gis.org //
49 // //
50 ///////////////////////////////////////////////////////////
51
52 //---------------------------------------------------------
53 #include "parameters.h"
54
55 #include "geo_tools.h"
56
57
58 ///////////////////////////////////////////////////////////
59 // //
60 // //
61 // //
62 ///////////////////////////////////////////////////////////
63
64 //---------------------------------------------------------
65 #define BUFFER_SIZE_GROW(size) (size < 1024 ? 32 : 1024)
66
67
68 ///////////////////////////////////////////////////////////
69 // //
70 // CSG_Point //
71 // //
72 ///////////////////////////////////////////////////////////
73
74 //---------------------------------------------------------
CSG_Point(void)75 CSG_Point::CSG_Point(void)
76 {
77 Assign(0., 0.);
78 }
79
CSG_Point(const CSG_Point & Point)80 CSG_Point::CSG_Point(const CSG_Point &Point)
81 {
82 Assign(Point);
83 }
84
CSG_Point(const TSG_Point & Point)85 CSG_Point::CSG_Point(const TSG_Point &Point)
86 {
87 Assign(Point.x, Point.y);
88 }
89
CSG_Point(double _x,double _y)90 CSG_Point::CSG_Point(double _x, double _y)
91 {
92 Assign(_x, _y);
93 }
94
95 //---------------------------------------------------------
Assign(double _x,double _y)96 void CSG_Point::Assign(double _x, double _y)
97 {
98 x = _x;
99 y = _y;
100 }
101
Assign(const CSG_Point & Point)102 void CSG_Point::Assign(const CSG_Point &Point)
103 {
104 x = Point.x;
105 y = Point.y;
106 }
107
108 //---------------------------------------------------------
Add(const CSG_Point & Point)109 void CSG_Point::Add(const CSG_Point &Point)
110 {
111 x += Point.x;
112 y += Point.y;
113 }
114
Subtract(const CSG_Point & Point)115 void CSG_Point::Subtract(const CSG_Point &Point)
116 {
117 x -= Point.x;
118 y -= Point.y;
119 }
120
Multiply(const CSG_Point & Point)121 void CSG_Point::Multiply(const CSG_Point &Point)
122 {
123 x *= Point.x;
124 y *= Point.y;
125 }
126
Multiply(double Value)127 void CSG_Point::Multiply(double Value)
128 {
129 x *= Value;
130 y *= Value;
131 }
132
Divide(double Value)133 void CSG_Point::Divide(double Value)
134 {
135 x /= Value;
136 y /= Value;
137 }
138
139 //---------------------------------------------------------
Get_Length(void) const140 double CSG_Point::Get_Length(void) const
141 {
142 return( sqrt(x*x + y*y) );
143 }
144
145
146 ///////////////////////////////////////////////////////////
147 // //
148 ///////////////////////////////////////////////////////////
149
150 //---------------------------------------------------------
CSG_Point_Z(void)151 CSG_Point_Z::CSG_Point_Z(void)
152 {
153 Assign(0., 0., 0.);
154 }
155
CSG_Point_Z(const CSG_Point_Z & Point)156 CSG_Point_Z::CSG_Point_Z(const CSG_Point_Z &Point)
157 {
158 Assign(Point);
159 }
160
CSG_Point_Z(const TSG_Point_Z & Point)161 CSG_Point_Z::CSG_Point_Z(const TSG_Point_Z &Point)
162 {
163 Assign(Point.x, Point.y, Point.z);
164 }
165
CSG_Point_Z(double _x,double _y,double _z)166 CSG_Point_Z::CSG_Point_Z(double _x, double _y, double _z)
167 {
168 Assign(_x, _y, _z);
169 }
170
171 //---------------------------------------------------------
Assign(double _x,double _y,double _z)172 void CSG_Point_Z::Assign(double _x, double _y, double _z)
173 {
174 x = _x;
175 y = _y;
176 z = _z;
177 }
178
Assign(const CSG_Point_Z & Point)179 void CSG_Point_Z::Assign(const CSG_Point_Z &Point)
180 {
181 x = Point.x;
182 y = Point.y;
183 z = Point.z;
184 }
185
186 //---------------------------------------------------------
Add(const CSG_Point_Z & Point)187 void CSG_Point_Z::Add(const CSG_Point_Z &Point)
188 {
189 x += Point.x;
190 y += Point.y;
191 z += Point.z;
192 }
193
Subtract(const CSG_Point_Z & Point)194 void CSG_Point_Z::Subtract(const CSG_Point_Z &Point)
195 {
196 x -= Point.x;
197 y -= Point.y;
198 z -= Point.z;
199 }
200
Multiply(const CSG_Point_Z & Point)201 void CSG_Point_Z::Multiply(const CSG_Point_Z &Point)
202 {
203 x *= Point.x;
204 y *= Point.y;
205 z *= Point.z;
206 }
207
Multiply(double Value)208 void CSG_Point_Z::Multiply(double Value)
209 {
210 x *= Value;
211 y *= Value;
212 z *= Value;
213 }
214
Divide(double Value)215 void CSG_Point_Z::Divide(double Value)
216 {
217 x /= Value;
218 y /= Value;
219 z /= Value;
220 }
221
222 //---------------------------------------------------------
Get_Length(void) const223 double CSG_Point_Z::Get_Length(void) const
224 {
225 return( sqrt(x*x + y*y + z*z) );
226 }
227
228
229 ///////////////////////////////////////////////////////////
230 // //
231 ///////////////////////////////////////////////////////////
232
233 //---------------------------------------------------------
CSG_Point_ZM(void)234 CSG_Point_ZM::CSG_Point_ZM(void)
235 {
236 Assign(0., 0., 0., 0.);
237 }
238
CSG_Point_ZM(const CSG_Point_ZM & Point)239 CSG_Point_ZM::CSG_Point_ZM(const CSG_Point_ZM &Point)
240 {
241 Assign(Point);
242 }
243
CSG_Point_ZM(const TSG_Point_ZM & Point)244 CSG_Point_ZM::CSG_Point_ZM(const TSG_Point_ZM &Point)
245 {
246 Assign(Point.x, Point.y, Point.z, Point.m);
247 }
248
CSG_Point_ZM(double _x,double _y,double _z,double _m)249 CSG_Point_ZM::CSG_Point_ZM(double _x, double _y, double _z, double _m)
250 {
251 Assign(_x, _y, _z, _m);
252 }
253
254 //---------------------------------------------------------
Assign(double _x,double _y,double _z,double _m)255 void CSG_Point_ZM::Assign(double _x, double _y, double _z, double _m)
256 {
257 x = _x;
258 y = _y;
259 z = _z;
260 m = _m;
261 }
262
Assign(const CSG_Point_ZM & Point)263 void CSG_Point_ZM::Assign(const CSG_Point_ZM &Point)
264 {
265 x = Point.x;
266 y = Point.y;
267 z = Point.z;
268 m = Point.m;
269 }
270
271 //---------------------------------------------------------
Add(const CSG_Point_ZM & Point)272 void CSG_Point_ZM::Add(const CSG_Point_ZM &Point)
273 {
274 x += Point.x;
275 y += Point.y;
276 z += Point.z;
277 m += Point.m;
278 }
279
Subtract(const CSG_Point_ZM & Point)280 void CSG_Point_ZM::Subtract(const CSG_Point_ZM &Point)
281 {
282 x -= Point.x;
283 y -= Point.y;
284 z -= Point.z;
285 m -= Point.m;
286 }
287
Multiply(const CSG_Point_ZM & Point)288 void CSG_Point_ZM::Multiply(const CSG_Point_ZM &Point)
289 {
290 x *= Point.x;
291 y *= Point.y;
292 z *= Point.z;
293 m *= Point.m;
294 }
295
Multiply(double Value)296 void CSG_Point_ZM::Multiply(double Value)
297 {
298 x *= Value;
299 y *= Value;
300 z *= Value;
301 m *= Value;
302 }
303
Divide(double Value)304 void CSG_Point_ZM::Divide(double Value)
305 {
306 x /= Value;
307 y /= Value;
308 z /= Value;
309 m /= Value;
310 }
311
312 //---------------------------------------------------------
Get_Length(void) const313 double CSG_Point_ZM::Get_Length(void) const
314 {
315 return( sqrt(x*x + y*y + z*z + m*m) );
316 }
317
318
319 ///////////////////////////////////////////////////////////
320 // //
321 // //
322 // //
323 ///////////////////////////////////////////////////////////
324
325 //---------------------------------------------------------
CSG_Points(void)326 CSG_Points::CSG_Points(void)
327 {
328 m_nBuffer = 0;
329 m_nPoints = 0;
330 m_Points = NULL;
331 }
332
333 //---------------------------------------------------------
~CSG_Points(void)334 CSG_Points::~CSG_Points(void)
335 {
336 Clear();
337 }
338
339 //---------------------------------------------------------
Clear(void)340 void CSG_Points::Clear(void)
341 {
342 if( m_Points )
343 {
344 SG_Free(m_Points);
345 }
346
347 m_nBuffer = 0;
348 m_nPoints = 0;
349 m_Points = NULL;
350 }
351
352 //---------------------------------------------------------
Assign(const CSG_Points & Points)353 bool CSG_Points::Assign(const CSG_Points &Points)
354 {
355 Set_Count(Points.m_nPoints);
356
357 if( m_nPoints > 0 )
358 {
359 memcpy(m_Points, Points.m_Points, m_nPoints * sizeof(TSG_Point));
360 }
361
362 return( true );
363 }
364
365 //---------------------------------------------------------
operator =(const CSG_Points & Points)366 CSG_Points & CSG_Points::operator = (const CSG_Points &Points)
367 {
368 Assign(Points);
369
370 return( *this );
371 }
372
373 //---------------------------------------------------------
Set_Count(int nPoints)374 bool CSG_Points::Set_Count(int nPoints)
375 {
376 if( m_nPoints == nPoints )
377 {
378 return( true );
379 }
380
381 if( nPoints <= 0 )
382 {
383 Clear();
384
385 return( true );
386 }
387
388 TSG_Point *Points = (TSG_Point *)SG_Realloc(m_Points, nPoints * sizeof(TSG_Point));
389
390 if( Points )
391 {
392 m_Points = Points;
393 m_nPoints = nPoints;
394 m_nBuffer = nPoints;
395
396 return( true );
397 }
398
399 return( false );
400 }
401
402 //---------------------------------------------------------
Add(double x,double y)403 bool CSG_Points::Add(double x, double y)
404 {
405 if( m_nPoints >= m_nBuffer - 1 )
406 {
407 TSG_Point *Points = (TSG_Point *)SG_Realloc(m_Points, (m_nBuffer + BUFFER_SIZE_GROW(m_nBuffer)) * sizeof(TSG_Point));
408
409 if( Points == NULL )
410 {
411 return( false );
412 }
413
414 m_Points = Points;
415 m_nBuffer += BUFFER_SIZE_GROW(m_nBuffer);
416 }
417
418 m_Points[m_nPoints].x = x;
419 m_Points[m_nPoints].y = y;
420 m_nPoints++;
421
422 return( true );
423 }
424
425 //---------------------------------------------------------
Add(const TSG_Point & Point)426 bool CSG_Points::Add(const TSG_Point &Point)
427 {
428 return( Add(Point.x, Point.y) );
429 }
430
431 //---------------------------------------------------------
Del(int Index)432 bool CSG_Points::Del(int Index)
433 {
434 if( Index >= 0 && Index < m_nPoints )
435 {
436 m_nPoints--;
437
438 if( m_nPoints > 0 )
439 {
440 for(TSG_Point *A=m_Points+Index, *B=m_Points+Index+1; Index<m_nPoints; Index++, A++, B++)
441 {
442 *A = *B;
443 }
444
445 m_Points = (TSG_Point *)SG_Realloc(m_Points, m_nPoints * sizeof(TSG_Point));
446 }
447 else
448 {
449 SG_Free(m_Points);
450 }
451
452 return( true );
453 }
454
455 return( false );
456 }
457
458
459 ///////////////////////////////////////////////////////////
460 // //
461 // //
462 // //
463 ///////////////////////////////////////////////////////////
464
465 //---------------------------------------------------------
CSG_Points_Int(void)466 CSG_Points_Int::CSG_Points_Int(void)
467 {
468 m_nBuffer = 0;
469 m_nPoints = 0;
470 m_Points = NULL;
471 }
472
473 //---------------------------------------------------------
~CSG_Points_Int(void)474 CSG_Points_Int::~CSG_Points_Int(void)
475 {
476 Clear();
477 }
478
479 //---------------------------------------------------------
Clear(void)480 void CSG_Points_Int::Clear(void)
481 {
482 if( m_Points )
483 {
484 SG_Free(m_Points);
485 }
486
487 m_nBuffer = 0;
488 m_nPoints = 0;
489 m_Points = NULL;
490 }
491
492 //---------------------------------------------------------
Assign(const CSG_Points_Int & Points)493 bool CSG_Points_Int::Assign(const CSG_Points_Int &Points)
494 {
495 Set_Count(Points.m_nPoints);
496
497 if( m_nPoints > 0 )
498 {
499 memcpy(m_Points, Points.m_Points, m_nPoints * sizeof(TSG_Point_Int));
500 }
501
502 return( true );
503 }
504
505 //---------------------------------------------------------
operator =(const CSG_Points_Int & Points)506 CSG_Points_Int & CSG_Points_Int::operator = (const CSG_Points_Int &Points)
507 {
508 Assign(Points);
509
510 return( *this );
511 }
512
513 //---------------------------------------------------------
Set_Count(int nPoints)514 bool CSG_Points_Int::Set_Count(int nPoints)
515 {
516 if( m_nPoints == nPoints )
517 {
518 return( true );
519 }
520
521 if( nPoints <= 0 )
522 {
523 Clear();
524
525 return( true );
526 }
527
528 TSG_Point_Int *Points = (TSG_Point_Int *)SG_Realloc(m_Points, nPoints * sizeof(TSG_Point_Int));
529
530 if( Points )
531 {
532 m_Points = Points;
533 m_nPoints = nPoints;
534 m_nBuffer = nPoints;
535
536 return( true );
537 }
538
539 return( false );
540 }
541
542 //---------------------------------------------------------
Add(int x,int y)543 bool CSG_Points_Int::Add(int x, int y)
544 {
545 if( m_nPoints >= m_nBuffer - 1 )
546 {
547 TSG_Point_Int *Points = (TSG_Point_Int *)SG_Realloc(m_Points, (m_nBuffer + BUFFER_SIZE_GROW(m_nBuffer)) * sizeof(TSG_Point_Int));
548
549 if( Points == NULL )
550 {
551 return( false );
552 }
553
554 m_Points = Points;
555 m_nBuffer += BUFFER_SIZE_GROW(m_nBuffer);
556 }
557
558 m_Points[m_nPoints].x = x;
559 m_Points[m_nPoints].y = y;
560 m_nPoints++;
561
562 return( true );
563 }
564
565 //---------------------------------------------------------
Add(const TSG_Point_Int & Point)566 bool CSG_Points_Int::Add(const TSG_Point_Int &Point)
567 {
568 return( Add(Point.x, Point.y) );
569 }
570
571 //---------------------------------------------------------
Del(int Index)572 bool CSG_Points_Int::Del(int Index)
573 {
574 if( Index >= 0 && Index < m_nPoints )
575 {
576 m_nPoints--;
577
578 if( m_nPoints > 0 )
579 {
580 for(TSG_Point_Int *A=m_Points+Index, *B=m_Points+Index+1; Index<m_nPoints; Index++, A++, B++)
581 {
582 *A = *B;
583 }
584
585 m_Points = (TSG_Point_Int *)SG_Realloc(m_Points, m_nPoints * sizeof(TSG_Point_Int));
586 }
587 else
588 {
589 SG_Free(m_Points);
590 }
591
592 return( true );
593 }
594
595 return( false );
596 }
597
598
599 ///////////////////////////////////////////////////////////
600 // //
601 // //
602 // //
603 ///////////////////////////////////////////////////////////
604
605 //---------------------------------------------------------
CSG_Points_Z(void)606 CSG_Points_Z::CSG_Points_Z(void)
607 {
608 m_nBuffer = 0;
609 m_nPoints = 0;
610 m_Points = NULL;
611 }
612
613 //---------------------------------------------------------
~CSG_Points_Z(void)614 CSG_Points_Z::~CSG_Points_Z(void)
615 {
616 Clear();
617 }
618
619 //---------------------------------------------------------
Clear(void)620 void CSG_Points_Z::Clear(void)
621 {
622 if( m_Points )
623 {
624 SG_Free(m_Points);
625 }
626
627 m_nBuffer = 0;
628 m_nPoints = 0;
629 m_Points = NULL;
630 }
631
632 //---------------------------------------------------------
Assign(const CSG_Points_Z & Points)633 bool CSG_Points_Z::Assign(const CSG_Points_Z &Points)
634 {
635 Set_Count(Points.m_nPoints);
636
637 if( m_nPoints > 0 )
638 {
639 memcpy(m_Points, Points.m_Points, m_nPoints * sizeof(TSG_Point_Z));
640 }
641
642 return( true );
643 }
644
645 //---------------------------------------------------------
operator =(const CSG_Points_Z & Points)646 CSG_Points_Z & CSG_Points_Z::operator = (const CSG_Points_Z &Points)
647 {
648 Assign(Points);
649
650 return( *this );
651 }
652
653 //---------------------------------------------------------
Set_Count(int nPoints)654 bool CSG_Points_Z::Set_Count(int nPoints)
655 {
656 if( m_nPoints == nPoints )
657 {
658 return( true );
659 }
660
661 if( nPoints <= 0 )
662 {
663 Clear();
664
665 return( true );
666 }
667
668 TSG_Point_Z *Points = (TSG_Point_Z *)SG_Realloc(m_Points, nPoints * sizeof(TSG_Point_Z));
669
670 if( Points )
671 {
672 m_Points = Points;
673 m_nPoints = nPoints;
674 m_nBuffer = nPoints;
675
676 return( true );
677 }
678
679 return( false );
680 }
681
682 //---------------------------------------------------------
Add(double x,double y,double z)683 bool CSG_Points_Z::Add(double x, double y, double z)
684 {
685 if( m_nPoints >= m_nBuffer - 1 )
686 {
687 TSG_Point_Z *Points = (TSG_Point_Z *)SG_Realloc(m_Points, (m_nBuffer + BUFFER_SIZE_GROW(m_nBuffer)) * sizeof(TSG_Point_Z));
688
689 if( Points == NULL )
690 {
691 return( false );
692 }
693
694 m_Points = Points;
695 m_nBuffer += BUFFER_SIZE_GROW(m_nBuffer);
696 }
697
698 m_Points[m_nPoints].x = x;
699 m_Points[m_nPoints].y = y;
700 m_Points[m_nPoints].z = z;
701 m_nPoints++;
702
703 return( true );
704 }
705
706 //---------------------------------------------------------
Add(const TSG_Point_Z & Point)707 bool CSG_Points_Z::Add(const TSG_Point_Z &Point)
708 {
709 return( Add(Point.x, Point.y, Point.z) );
710 }
711
712 //---------------------------------------------------------
Del(int Index)713 bool CSG_Points_Z::Del(int Index)
714 {
715 if( Index >= 0 && Index < m_nPoints )
716 {
717 m_nPoints--;
718
719 if( m_nPoints > 0 )
720 {
721 for(TSG_Point_Z *A=m_Points+Index, *B=m_Points+Index+1; Index<m_nPoints; Index++, A++, B++)
722 {
723 *A = *B;
724 }
725
726 m_Points = (TSG_Point_Z *)SG_Realloc(m_Points, m_nPoints * sizeof(TSG_Point_Z));
727 }
728 else
729 {
730 SG_Free(m_Points);
731 }
732
733 return( true );
734 }
735
736 return( false );
737 }
738
739
740 ///////////////////////////////////////////////////////////
741 // //
742 // CSG_Rect //
743 // //
744 ///////////////////////////////////////////////////////////
745
746 //---------------------------------------------------------
CSG_Rect(void)747 CSG_Rect::CSG_Rect(void)
748 {
749 Assign(0., 0., 0., 0.);
750 }
751
CSG_Rect(const CSG_Rect & Rect)752 CSG_Rect::CSG_Rect(const CSG_Rect &Rect)
753 {
754 Assign(Rect.m_rect);
755 }
756
CSG_Rect(const TSG_Rect & Rect)757 CSG_Rect::CSG_Rect(const TSG_Rect &Rect)
758 {
759 Assign(Rect.xMin, Rect.yMin, Rect.xMax, Rect.yMax);
760 }
761
CSG_Rect(const CSG_Point & A,const CSG_Point & B)762 CSG_Rect::CSG_Rect(const CSG_Point &A, const CSG_Point &B)
763 {
764 Assign(A.Get_X(), A.Get_Y(), B.Get_X(), B.Get_Y());
765 }
766
CSG_Rect(double xMin,double yMin,double xMax,double yMax)767 CSG_Rect::CSG_Rect(double xMin, double yMin, double xMax, double yMax)
768 {
769 Assign(xMin, yMin, xMax, yMax);
770 }
771
772 //---------------------------------------------------------
~CSG_Rect(void)773 CSG_Rect::~CSG_Rect(void)
774 {}
775
776 //---------------------------------------------------------
operator ==(const CSG_Rect & Rect) const777 bool CSG_Rect::operator == (const CSG_Rect &Rect) const
778 {
779 return( is_Equal(Rect) );
780 }
781
operator !=(const CSG_Rect & Rect) const782 bool CSG_Rect::operator != (const CSG_Rect &Rect) const
783 {
784 return( !is_Equal(Rect) );
785 }
786
operator =(const CSG_Rect & Rect)787 CSG_Rect & CSG_Rect::operator = (const CSG_Rect &Rect)
788 {
789 Assign(Rect);
790
791 return( *this );
792 }
793
operator +=(const CSG_Point & Point)794 void CSG_Rect::operator += (const CSG_Point &Point)
795 {
796 Move( Point.Get_X(), Point.Get_Y());
797 }
798
operator -=(const CSG_Point & Point)799 void CSG_Rect::operator -= (const CSG_Point &Point)
800 {
801 Move(-Point.Get_Y(), -Point.Get_Y());
802 }
803
804 //---------------------------------------------------------
Assign(double xMin,double yMin,double xMax,double yMax)805 void CSG_Rect::Assign(double xMin, double yMin, double xMax, double yMax)
806 {
807 if( xMin < xMax )
808 {
809 m_rect.xMin = xMin;
810 m_rect.xMax = xMax;
811 }
812 else
813 {
814 m_rect.xMin = xMax;
815 m_rect.xMax = xMin;
816 }
817
818 if( yMin < yMax )
819 {
820 m_rect.yMin = yMin;
821 m_rect.yMax = yMax;
822 }
823 else
824 {
825 m_rect.yMin = yMax;
826 m_rect.yMax = yMin;
827 }
828 }
829
Assign(const CSG_Point & A,const CSG_Point & B)830 void CSG_Rect::Assign(const CSG_Point &A, const CSG_Point &B)
831 {
832 Assign(A.Get_X(), A.Get_Y(), B.Get_X(), B.Get_Y());
833 }
834
Assign(const CSG_Rect & Rect)835 void CSG_Rect::Assign(const CSG_Rect &Rect)
836 {
837 Assign(Rect.Get_XMin(), Rect.Get_YMin(), Rect.Get_XMax(), Rect.Get_YMax());
838 }
839
840 //---------------------------------------------------------
Set_BottomLeft(double x,double y)841 void CSG_Rect::Set_BottomLeft(double x, double y)
842 {
843 Assign(x, y, m_rect.xMax, m_rect.yMax);
844 }
845
Set_BottomLeft(const CSG_Point & Point)846 void CSG_Rect::Set_BottomLeft(const CSG_Point &Point)
847 {
848 Set_BottomLeft(Point.Get_X(), Point.Get_Y() );
849 }
850
Set_TopRight(double x,double y)851 void CSG_Rect::Set_TopRight(double x, double y)
852 {
853 Assign(m_rect.xMin, m_rect.yMin, x, y);
854 }
855
Set_TopRight(const CSG_Point & Point)856 void CSG_Rect::Set_TopRight(const CSG_Point &Point)
857 {
858 Set_TopRight(Point.Get_X(), Point.Get_Y() );
859 }
860
861 //---------------------------------------------------------
is_Equal(double xMin,double yMin,double xMax,double yMax,double epsilon) const862 bool CSG_Rect::is_Equal(double xMin, double yMin, double xMax, double yMax, double epsilon) const
863 {
864 return( SG_Is_Equal(m_rect.xMin, xMin, epsilon) && SG_Is_Equal(m_rect.yMin, yMin, epsilon)
865 && SG_Is_Equal(m_rect.xMax, xMax, epsilon) && SG_Is_Equal(m_rect.yMax, yMax, epsilon) );
866 }
867
is_Equal(const CSG_Rect & Rect,double epsilon) const868 bool CSG_Rect::is_Equal(const CSG_Rect &Rect, double epsilon) const
869 {
870 return( is_Equal(Rect.Get_XMin(), Rect.Get_YMin(), Rect.Get_XMax(), Rect.Get_YMax(), epsilon) );
871 }
872
873 //---------------------------------------------------------
Move(double dx,double dy)874 void CSG_Rect::Move(double dx, double dy)
875 {
876 m_rect.xMin += dx;
877 m_rect.yMin += dy;
878 m_rect.xMax += dx;
879 m_rect.yMax += dy;
880 }
881
Move(const CSG_Point & Point)882 void CSG_Rect::Move(const CSG_Point &Point)
883 {
884 Move(Point.Get_X(), Point.Get_Y());
885 }
886
887 //---------------------------------------------------------
Inflate(double dx,double dy,bool bPercent)888 void CSG_Rect::Inflate(double dx, double dy, bool bPercent)
889 {
890 if( bPercent )
891 {
892 dx = (Get_XRange() * 0.01 * dx) / 2.;
893 dy = (Get_YRange() * 0.01 * dy) / 2.;
894 }
895
896 Assign(
897 m_rect.xMin - dx, m_rect.yMin - dy,
898 m_rect.xMax + dx, m_rect.yMax + dy
899 );
900 }
901
Inflate(double d,bool bPercent)902 void CSG_Rect::Inflate(double d, bool bPercent)
903 {
904 Inflate(d, d, bPercent);
905 }
906
Deflate(double dx,double dy,bool bPercent)907 void CSG_Rect::Deflate(double dx, double dy, bool bPercent)
908 {
909 Inflate(-dx, -dy, bPercent);
910 }
911
Deflate(double d,bool bPercent)912 void CSG_Rect::Deflate(double d, bool bPercent)
913 {
914 Deflate(d, d, bPercent);
915 }
916
917 //---------------------------------------------------------
Union(const CSG_Point & Point)918 void CSG_Rect::Union(const CSG_Point &Point)
919 {
920 if( m_rect.xMin > Point.Get_X() )
921 {
922 m_rect.xMin = Point.Get_X();
923 }
924 else if( m_rect.xMax < Point.Get_X() )
925 {
926 m_rect.xMax = Point.Get_X();
927 }
928
929 if( m_rect.yMin > Point.Get_Y() )
930 {
931 m_rect.yMin = Point.Get_Y();
932 }
933 else if( m_rect.yMax < Point.Get_Y() )
934 {
935 m_rect.yMax = Point.Get_Y();
936 }
937 }
938
939 //---------------------------------------------------------
Union(const CSG_Rect & Rect)940 void CSG_Rect::Union(const CSG_Rect &Rect)
941 {
942 if( m_rect.xMin > Rect.Get_XMin() )
943 {
944 m_rect.xMin = Rect.Get_XMin();
945 }
946
947 if( m_rect.yMin > Rect.Get_YMin() )
948 {
949 m_rect.yMin = Rect.Get_YMin();
950 }
951
952 if( m_rect.xMax < Rect.Get_XMax() )
953 {
954 m_rect.xMax = Rect.Get_XMax();
955 }
956
957 if( m_rect.yMax < Rect.Get_YMax() )
958 {
959 m_rect.yMax = Rect.Get_YMax();
960 }
961 }
962
963 //---------------------------------------------------------
Intersect(const CSG_Rect & Rect)964 bool CSG_Rect::Intersect(const CSG_Rect &Rect)
965 {
966 switch( Intersects(Rect) )
967 {
968 case INTERSECTION_None: default:
969 return( false );
970
971 case INTERSECTION_Identical:
972 case INTERSECTION_Contained:
973 break;
974
975 case INTERSECTION_Contains:
976 m_rect = Rect.m_rect;
977 break;
978
979 case INTERSECTION_Overlaps:
980 if( m_rect.xMin < Rect.Get_XMin() )
981 {
982 m_rect.xMin = Rect.Get_XMin();
983 }
984
985 if( m_rect.yMin < Rect.Get_YMin() )
986 {
987 m_rect.yMin = Rect.Get_YMin();
988 }
989
990 if( m_rect.xMax > Rect.Get_XMax() )
991 {
992 m_rect.xMax = Rect.Get_XMax();
993 }
994
995 if( m_rect.yMax > Rect.Get_YMax() )
996 {
997 m_rect.yMax = Rect.Get_YMax();
998 }
999 break;
1000 }
1001
1002 return( true );
1003 }
1004
1005 //---------------------------------------------------------
Intersects(const CSG_Rect & Rect) const1006 TSG_Intersection CSG_Rect::Intersects(const CSG_Rect &Rect) const
1007 {
1008 if( m_rect.xMax < Rect.Get_XMin() || Rect.Get_XMax() < m_rect.xMin
1009 || m_rect.yMax < Rect.Get_YMin() || Rect.Get_YMax() < m_rect.yMin )
1010 {
1011 return( INTERSECTION_None );
1012 }
1013
1014 if( is_Equal(Rect) )
1015 {
1016 return( INTERSECTION_Identical );
1017 }
1018
1019 if( Contains(Rect.Get_XMin(), Rect.Get_YMin())
1020 && Contains(Rect.Get_XMax(), Rect.Get_YMax()) )
1021 {
1022 return( INTERSECTION_Contains );
1023 }
1024
1025 if( Rect.Contains(Get_XMin(), Get_YMin())
1026 && Rect.Contains(Get_XMax(), Get_YMax()) )
1027 {
1028 return( INTERSECTION_Contained );
1029 }
1030
1031 return( INTERSECTION_Overlaps );
1032 }
1033
1034 //---------------------------------------------------------
Contains(double x,double y) const1035 bool CSG_Rect::Contains(double x, double y) const
1036 {
1037 return( m_rect.xMin <= x && x <= m_rect.xMax
1038 && m_rect.yMin <= y && y <= m_rect.yMax
1039 );
1040 }
1041
Contains(const CSG_Point & Point) const1042 bool CSG_Rect::Contains(const CSG_Point &Point) const
1043 {
1044 return( Contains(Point.Get_X(), Point.Get_Y()) );
1045 }
1046
1047
1048 ///////////////////////////////////////////////////////////
1049 // //
1050 // //
1051 // //
1052 ///////////////////////////////////////////////////////////
1053
1054 //---------------------------------------------------------
CSG_Rects(void)1055 CSG_Rects::CSG_Rects(void)
1056 {
1057 m_nRects = 0;
1058 m_Rects = NULL;
1059 }
1060
1061 //---------------------------------------------------------
~CSG_Rects(void)1062 CSG_Rects::~CSG_Rects(void)
1063 {
1064 Clear();
1065 }
1066
1067 //---------------------------------------------------------
Clear(void)1068 void CSG_Rects::Clear(void)
1069 {
1070 if( m_Rects )
1071 {
1072 for(int i=0; i<m_nRects; i++)
1073 {
1074 delete(m_Rects[i]);
1075 }
1076
1077 SG_Free(m_Rects);
1078 }
1079
1080 m_nRects = 0;
1081 m_Rects = NULL;
1082 }
1083
1084 //---------------------------------------------------------
Assign(const CSG_Rects & Rects)1085 bool CSG_Rects::Assign(const CSG_Rects &Rects)
1086 {
1087 Clear();
1088
1089 for(int i=0; i<Rects.m_nRects; i++)
1090 {
1091 Add(*Rects.m_Rects[i]);
1092 }
1093
1094 return( true );
1095 }
1096
1097 //---------------------------------------------------------
operator =(const CSG_Rects & Rects)1098 CSG_Rects & CSG_Rects::operator = (const CSG_Rects &Rects)
1099 {
1100 Assign(Rects);
1101
1102 return( *this );
1103 }
1104
1105 //---------------------------------------------------------
Add(void)1106 bool CSG_Rects::Add(void)
1107 {
1108 return( Add(CSG_Rect()) );
1109 }
1110
1111 //---------------------------------------------------------
Add(double xMin,double yMin,double xMax,double yMax)1112 bool CSG_Rects::Add(double xMin, double yMin, double xMax, double yMax)
1113 {
1114 return( Add(CSG_Rect(xMin, yMin, xMax, yMax)) );
1115 }
1116
1117 //---------------------------------------------------------
Add(const CSG_Rect & Rect)1118 bool CSG_Rects::Add(const CSG_Rect &Rect)
1119 {
1120 m_Rects = (CSG_Rect **)SG_Realloc(m_Rects, (m_nRects + 1) * sizeof(CSG_Rect *));
1121 m_Rects[m_nRects] = new CSG_Rect(Rect);
1122 m_nRects++;
1123
1124 return( true );
1125 }
1126
1127
1128 ///////////////////////////////////////////////////////////
1129 // //
1130 // //
1131 // //
1132 ///////////////////////////////////////////////////////////
1133
1134 //---------------------------------------------------------
CSG_Distance_Weighting(void)1135 CSG_Distance_Weighting::CSG_Distance_Weighting(void)
1136 {
1137 m_Weighting = SG_DISTWGHT_None;
1138
1139 m_IDW_Power = 2.;
1140 m_IDW_bOffset = true;
1141
1142 m_Bandwidth = 1.;
1143 }
1144
1145 //---------------------------------------------------------
~CSG_Distance_Weighting(void)1146 CSG_Distance_Weighting::~CSG_Distance_Weighting(void)
1147 {}
1148
1149 //---------------------------------------------------------
Create_Parameters(CSG_Parameters & Parameters,const CSG_String & Parent,bool bIDW_Offset)1150 bool CSG_Distance_Weighting::Create_Parameters(CSG_Parameters &Parameters, const CSG_String &Parent, bool bIDW_Offset)
1151 {
1152 if( Add_Parameters(Parameters, Parent, bIDW_Offset) )
1153 {
1154 if( Parameters("DW_WEIGHTING" ) ) { Parameters("DW_WEIGHTING" )->Set_Value((int)m_Weighting ); }
1155 if( Parameters("DW_IDW_POWER" ) ) { Parameters("DW_IDW_POWER" )->Set_Value( m_IDW_Power ); }
1156 if( Parameters("DW_IDW_OFFSET") ) { Parameters("DW_IDW_OFFSET")->Set_Value( m_IDW_bOffset); }
1157 if( Parameters("DW_BANDWIDTH" ) ) { Parameters("DW_BANDWIDTH" )->Set_Value( m_Bandwidth ); }
1158
1159 return( true );
1160 }
1161
1162 return( false );
1163 }
1164
1165 //---------------------------------------------------------
Add_Parameters(CSG_Parameters & Parameters,const CSG_String & Parent,bool bIDW_Offset)1166 bool CSG_Distance_Weighting::Add_Parameters(CSG_Parameters &Parameters, const CSG_String &Parent, bool bIDW_Offset)
1167 {
1168 Parameters.Add_Choice(Parent,
1169 "DW_WEIGHTING" , _TL("Weighting Function"),
1170 _TL(""),
1171 CSG_String::Format("%s|%s|%s|%s",
1172 _TL("no distance weighting"),
1173 _TL("inverse distance to a power"),
1174 _TL("exponential"),
1175 _TL("gaussian")
1176 ), 0
1177 );
1178
1179 Parameters.Add_Double("DW_WEIGHTING",
1180 "DW_IDW_POWER" , _TL("Power"),
1181 _TL(""),
1182 2., 0., true
1183 );
1184
1185 if( bIDW_Offset )
1186 {
1187 Parameters.Add_Bool ("DW_WEIGHTING",
1188 "DW_IDW_OFFSET" , _TL("Offset"),
1189 _TL("Calculates weights for distance plus one, avoiding division by zero for zero distances"),
1190 true
1191 );
1192 }
1193
1194 Parameters.Add_Double("DW_WEIGHTING",
1195 "DW_BANDWIDTH" , _TL("Bandwidth"),
1196 _TL("Bandwidth for exponential and Gaussian weighting"),
1197 1., 0., true
1198 );
1199
1200 return( true );
1201 }
1202
1203 //---------------------------------------------------------
Enable_Parameters(CSG_Parameters & Parameters)1204 bool CSG_Distance_Weighting::Enable_Parameters(CSG_Parameters &Parameters)
1205 {
1206 if( Parameters("DW_WEIGHTING") )
1207 {
1208 int Method = Parameters("DW_WEIGHTING")->asInt();
1209
1210 Parameters.Set_Enabled("DW_IDW_OFFSET", Method == 1);
1211 Parameters.Set_Enabled("DW_IDW_POWER" , Method == 1);
1212 Parameters.Set_Enabled("DW_BANDWIDTH" , Method >= 2);
1213 }
1214
1215 return( true );
1216 }
1217
1218 //---------------------------------------------------------
Set_Parameters(CSG_Parameters & Parameters)1219 bool CSG_Distance_Weighting::Set_Parameters(CSG_Parameters &Parameters)
1220 {
1221 if( Parameters("DW_WEIGHTING") )
1222 {
1223 switch( Parameters("DW_WEIGHTING")->asInt() )
1224 {
1225 case 0: Set_Weighting(SG_DISTWGHT_None ); break;
1226 case 1: Set_Weighting(SG_DISTWGHT_IDW ); break;
1227 case 2: Set_Weighting(SG_DISTWGHT_EXP ); break;
1228 case 3: Set_Weighting(SG_DISTWGHT_GAUSS); break;
1229 }
1230 }
1231
1232 if( Parameters("DW_IDW_OFFSET") )
1233 {
1234 Set_IDW_Offset(Parameters("DW_IDW_OFFSET")->asBool ());
1235 }
1236
1237 if( Parameters("DW_IDW_POWER" ) )
1238 {
1239 Set_IDW_Power (Parameters("DW_IDW_POWER" )->asDouble());
1240 }
1241
1242 if( Parameters("DW_BANDWIDTH" ) )
1243 {
1244 Set_BandWidth (Parameters("DW_BANDWIDTH" )->asDouble());
1245 }
1246
1247 return( true );
1248 }
1249
1250
1251 ///////////////////////////////////////////////////////////
1252 // //
1253 ///////////////////////////////////////////////////////////
1254
1255 //---------------------------------------------------------
Set_Weighting(TSG_Distance_Weighting Weighting)1256 bool CSG_Distance_Weighting::Set_Weighting(TSG_Distance_Weighting Weighting)
1257 {
1258 m_Weighting = Weighting;
1259
1260 return( true );
1261 }
1262
1263 //---------------------------------------------------------
Set_IDW_Power(double Value)1264 bool CSG_Distance_Weighting::Set_IDW_Power(double Value)
1265 {
1266 if( Value <= 0. )
1267 {
1268 return( false );
1269 }
1270
1271 m_IDW_Power = Value;
1272
1273 return( true );
1274 }
1275
1276 //---------------------------------------------------------
Set_IDW_Offset(bool bOn)1277 bool CSG_Distance_Weighting::Set_IDW_Offset(bool bOn)
1278 {
1279 m_IDW_bOffset = bOn;
1280
1281 return( true );
1282 }
1283
1284 //---------------------------------------------------------
Set_BandWidth(double Value)1285 bool CSG_Distance_Weighting::Set_BandWidth(double Value)
1286 {
1287 if( Value <= 0. )
1288 {
1289 return( false );
1290 }
1291
1292 m_Bandwidth = Value;
1293
1294 return( true );
1295 }
1296
1297
1298 ///////////////////////////////////////////////////////////
1299 // //
1300 // //
1301 // //
1302 ///////////////////////////////////////////////////////////
1303
1304 //---------------------------------------------------------
1305