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