OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimIrect.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 // Copyright (C) 2000 ImageLinks Inc.
3 //
4 // License: See top level LICENSE.txt file.
5 //
6 // Author: David Burken
7 //
8 // Description:
9 //
10 // Contains class definition for ossimIrect.
11 //
12 //*******************************************************************
13 // $Id: ossimIrect.cpp 21560 2012-08-30 12:09:03Z gpotts $
14 
15 #include <ostream>
16 #include <sstream>
17 #include <ossim/base/ossimIrect.h>
18 #include <ossim/base/ossimDrect.h>
20 #include <ossim/base/ossimString.h>
22 
23 // nonstandard versions that use operator>, so they behave differently
24 // than std:::min/max and ossim::min/max. kept here for now for that
25 // reason.
26 #ifndef MAX
27 # define MAX(x,y) ((x)>(y)?(x):(y))
28 # define MIN(x,y) ((x)>(y)?(y):(x))
29 #endif
30 
32  :
33  theUlCorner(rect.ul()),
34  theUrCorner(rect.ur()),
35  theLrCorner(rect.lr()),
36  theLlCorner(rect.ll()),
37  theOrientMode(rect.orientMode())
38 {}
39 
40 ossimIrect::ossimIrect(const std::vector<ossimIpt>& points,
42  :
43  theOrientMode (mode)
44 {
45  if(points.size())
46  {
47  ossim_uint32 index;
48  ossim_int32 minx = points[0].x;
49  ossim_int32 miny = points[0].y;
50  ossim_int32 maxx = points[0].x;
51  ossim_int32 maxy = points[0].y;
52 
53  // find the bounds
54  for(index = 1; index < points.size();index++)
55  {
56  minx = ossim::min(minx, points[index].x);
57  miny = ossim::min(miny, points[index].y);
58  maxx = ossim::max(maxx, points[index].x);
59  maxy = ossim::max(maxy, points[index].y);
60 
61  }
63  {
64  *this = ossimIrect(minx, miny, maxx, maxy, mode);
65  }
66  else
67  {
68  *this = ossimIrect(minx,maxy, maxx, miny, mode);
69  }
70  }
71  else
72  {
73  makeNan();
74  }
75 }
76 
78  const ossimIpt& p2,
79  const ossimIpt& p3,
80  const ossimIpt& p4,
82  :theOrientMode(mode)
83 {
84  if(p1.hasNans()||p2.hasNans()||p3.hasNans()||p4.hasNans())
85  {
86  makeNan();
87  }
88  else
89  {
90  ossim_int32 minx, miny;
91  ossim_int32 maxx, maxy;
92 
93  minx = ossim::min( p1.x, ossim::min(p2.x, ossim::min(p3.x, p4.x)));
94  miny = ossim::min( p1.y, ossim::min(p2.y, ossim::min(p3.y, p4.y)));
95  maxx = ossim::max( p1.x, ossim::max(p2.x, ossim::max(p3.x, p4.x)));
96  maxy = ossim::max( p1.y, ossim::max(p2.y, ossim::max(p3.y, p4.y)));
97 
99  {
100  *this = ossimIrect(minx, miny, maxx, maxy, mode);
101  }
102  else
103  {
104  *this = ossimIrect(minx,maxy, maxx, miny, mode);
105  }
106  }
107 }
108 
110 {
111 }
112 
113 //*******************************************************************
115 //*******************************************************************
117  ossim_uint32 size_x,
118  ossim_uint32 size_y,
120 : theOrientMode (mode)
121 {
122  ossim_int32 minx = center.x - size_x/2;
123  ossim_int32 maxx = minx + size_x - 1;
124 
125  ossim_int32 miny = center.y - size_y/2;
126  ossim_int32 maxy = miny + size_y - 1;
127 
128  if(mode == OSSIM_LEFT_HANDED)
129  *this = ossimIrect(minx, miny, maxx, maxy, mode);
130  else
131  *this = ossimIrect(minx,maxy, maxx, miny, mode);
132 }
133 
134 
135 //*************************************************************************************************
139 //*************************************************************************************************
140 bool ossimIrect::insureMinimumSize(const ossimIpt& width_height)
141 {
144  bool resized = false;
145 
146  int dx = width_height.x - width();
147  int dy = width_height.y - height();
148 
149  if (dx > 0)
150  {
151  dx = (int) ceil((double)dx/2.0);
152  ul.x -= dx;
153  lr.x += dx;
154  resized = true;
155  }
156 
157  if (dy > 0)
158  {
159  resized = true;
161  {
162  dy = (int) ceil((double)dy/2.0);
163  ul.y -= dy;
164  lr.y += dy;
165  }
166  else
167  {
168  dy = (int) ceil((double)dy/2.0);
169  ul.y += dy;
170  lr.y -= dy;
171  }
172  }
173 
174  if (resized)
175  *this = ossimIrect(ul, lr, theOrientMode);
176 
177  return resized;
178 }
179 
180 //*******************************************************************
181 // Public Method:
182 //*******************************************************************
183 bool ossimIrect::intersects(const ossimIrect& rect) const
184 {
185  if(rect.hasNans() || hasNans())
186  {
187  return false;
188  }
189  if (theOrientMode != rect.theOrientMode)
190  return false;
191 
192  ossim_int32 ulx = ossim::max(rect.ul().x,ul().x);
193  ossim_int32 lrx = ossim::min(rect.lr().x,lr().x);
194  ossim_int32 uly, lry;
195  bool rtn=false;
197  {
198  uly = ossim::max(rect.ul().y,ul().y);
199  lry = ossim::min(rect.lr().y,lr().y);
200  rtn = ((ulx <= lrx) && (uly <= lry));
201  }
202  else
203  {
204  uly = ossim::max(rect.ll().y,ll().y);
205  lry = ossim::min(rect.ur().y,ur().y);
206  rtn = ((ulx <= lrx) && (uly <= lry));
207  }
208 
209  return (rtn);
210 }
211 
212 void ossimIrect::stretchToTileBoundary(const ossimIpt& tileWidthHeight)
213 {
214  ossimIpt ul;
215  ossimIpt lr;
216 
218  {
219  ul.x = theUlCorner.x;
220  if( (theUlCorner.x % tileWidthHeight.x) != 0)
221  {
222  ul.x = ((ul.x / tileWidthHeight.x))*tileWidthHeight.x;
223  if(ul.x > theUlCorner.x)
224  {
225  ul.x -= tileWidthHeight.x;
226  }
227  }
228  ul.y = theUlCorner.y;
229  if( (theUlCorner.y % tileWidthHeight.y) != 0)
230  {
231  ul.y = ((ul.y / tileWidthHeight.y))*tileWidthHeight.y;
232  if(ul.y > theUlCorner.y)
233  {
234  ul.y -= tileWidthHeight.y;
235  }
236  }
237  ossim_int32 w = (theLrCorner.x - ul.x) + 1;
238  ossim_int32 h = (theLrCorner.y - ul.y) + 1;
239 
240  ossim_int32 nw = (w / tileWidthHeight.x)*tileWidthHeight.x;
241  ossim_int32 nh = (h / tileWidthHeight.y)*tileWidthHeight.y;
242 
243  if(w%tileWidthHeight.x)
244  {
245  nw += tileWidthHeight.x;
246  }
247  if(h%tileWidthHeight.y)
248  {
249  nh += tileWidthHeight.y;
250  }
251 
252  lr.x = ul.x + (nw-1);
253  lr.y = ul.y + (nh-1);
254  }
255  else
256  {
257  ul.x = theUlCorner.x;
258  ul.y = theUlCorner.y;
259  if( (theUlCorner.x%tileWidthHeight.x)!= 0)
260  {
261  ul.x = ((ul.x/ tileWidthHeight.x))*tileWidthHeight.x;
262  if(ul.x > theUlCorner.x)
263  {
264  ul.x -= tileWidthHeight.x;
265  }
266  }
267  if( (theUlCorner.y%tileWidthHeight.y)!=0 )
268  {
269  ul.y = ((ul.y / tileWidthHeight.y))*tileWidthHeight.y;
270  if(ul.y < theUlCorner.y)
271  {
272  ul.y += tileWidthHeight.y;
273  }
274  }
275  ossim_int32 w = theLrCorner.x - ul.x;
276  if (w < 0)
277  {
278  w = -w;
279  }
280  w += 1;
281  ossim_int32 h = theLrCorner.y - ul.y;
282  if (h < 0)
283  {
284  h = -h;
285  }
286  h += 1;
287 
288  ossim_int32 nw = (w / tileWidthHeight.x)*tileWidthHeight.x;
289  ossim_int32 nh = (h / tileWidthHeight.y)*tileWidthHeight.y;
290 
291  if(w%tileWidthHeight.x)
292  {
293  nw += tileWidthHeight.x;
294  }
295  if(h%tileWidthHeight.y)
296  {
297  nh += tileWidthHeight.y;
298  }
299 
300  lr.x = ul.x + (nw-1);
301  lr.y = ul.y - (nh-1);
302  }
303 
304  *this = ossimIrect(ul, lr, theOrientMode);
305 }
306 
307 
308 const ossimIrect& ossimIrect::expand(const ossimIpt& padding)
309 {
310  theUlCorner.x -= padding.x;
311  theUrCorner.x += padding.x;
312  theLrCorner.x += padding.x;
313  theLlCorner.x -= padding.x;
315  {
316  theUlCorner.y -= padding.y;
317  theUrCorner.y -= padding.y;
318  theLrCorner.y += padding.y;
319  theLlCorner.y += padding.y;
320  }
321  else
322  {
323  theUlCorner.y += padding.y;
324  theUrCorner.y += padding.y;
325  theLrCorner.y -= padding.y;
326  theLlCorner.y -= padding.y;
327  }
328 
329  return *this;
330 }
331 
333 {
334  ossimString result="(";
335 
337  {
338  ossimIpt origin = ul();
339  result += (ossimString::toString(origin.x) + ",");
340  result += (ossimString::toString(origin.y) + ",");
341  result += (ossimString::toString(width()) + ",");
342  result += (ossimString::toString(height()) + ",");
343  result += "LH";
344  }
345  else
346  {
347  ossimIpt origin = ll();
348  result += (ossimString::toString(origin.x) + ",");
349  result += (ossimString::toString(origin.y) + ",");
350  result += (ossimString::toString(width()) + ",");
351  result += (ossimString::toString(height()) + ",");
352  result += "RH";
353  }
354 
355  result += ")";
356  return result;
357 }
358 
359 bool ossimIrect::toRect(const ossimString& rectString)
360 {
361  bool result = false;
362  makeNan();
363 
364  std::istringstream in(rectString);
365  ossim::skipws(in);
366  char charString[2];
367  charString[1] = '\0';
368  ossimString interior;
369  if(in.peek() == '(')
370  {
371  in.ignore();
372  while((in.peek() != ')')&&
373  (in.peek() != '\n') &&
374  in.good())
375  {
376  charString[0] = in.get();
377  interior += charString;
378  }
379  if(in.peek() == ')')
380  {
381  result = true;
382  }
383  }
384  if(result)
385  {
386  std::vector<ossimString> splitArray;
387  interior.split(splitArray, ",");
388 
389  // assume left handed
390  if(splitArray.size() >= 4)
391  {
392  ossim_int64 x = splitArray[0].toInt64();
393  ossim_int64 y = splitArray[1].toInt64();
394  ossim_int64 w = splitArray[2].toInt64();
395  ossim_int64 h = splitArray[3].toInt64();
396  ossimString orientation = "lh";
397  if(splitArray.size() == 5)
398  {
399  orientation = splitArray[4].downcase();
400  }
401  if(orientation == "lh")
402  {
403  // origin upper left
404  *this = ossimIrect(x,y,x + (w-1), y+h-1, OSSIM_LEFT_HANDED);
405  }
406  else
407  {
408  // origin lower left
409  *this = ossimIrect(x,y+(h-1),x + (w-1), y, OSSIM_RIGHT_HANDED);
410  }
411 
412  }
413  else
414  {
415  result = false;
416  }
417 
418  }
419  return result;
420 }
421 
422 //*******************************************************************
423 // Public Method:
424 //*******************************************************************
426 {
427  if(hasNans() || rect.hasNans())
428  {
429  return false;
430  }
431  if (theOrientMode != rect.theOrientMode)
432  return false;
433 
434  /* --------------
435  | 1 |
436  | ---------- |
437  | | | |
438  | | | |
439  | | 2 | |
440  | | | |
441  | | | |
442  | ---------- |
443  | |
444  -------------- */
445 
446  bool rtn = true;
447  if ((theUlCorner.x > rect.ur().x)||
448  (theUlCorner.x < rect.ul().x))
449  rtn = false;
450 
451  else if ((theLrCorner.x > rect.lr().x)||
452  (theLrCorner.x < rect.ll().x))
453  rtn = false;
454 
455  else if (theOrientMode == OSSIM_LEFT_HANDED)
456  {
457  if ((theUlCorner.y < rect.ul().y)||
458  (theUlCorner.y > rect.lr().y))
459  rtn = false;
460 
461  else if ((theLrCorner.y > rect.lr().y)||
462  (theLrCorner.y < rect.ul().y))
463  rtn = false;
464  }
465 
466  else
467  {
468  if ( (theUlCorner.y > rect.ul().y)||
469  (theUlCorner.y < rect.lr().y))
470  rtn = false;
471 
472  else if ((theLrCorner.y < rect.lr().y)||
473  (theLrCorner.y > rect.ul().y))
474  rtn = false;
475  }
476 
477  return rtn;
478 }
479 
480 //*******************************************************************
481 // Public Method:
482 //*******************************************************************
484 {
485  os << toString();
486 }
487 
488 //*******************************************************************
489 // friend function: operator<<
490 //*******************************************************************
492 {
493  rect.print(os);
494 
495  return os;
496 }
497 
498 //*******************************************************************
499 // Method: ossimIrect::clipToRect
500 //*******************************************************************
502 {
503  if (theOrientMode != rect.theOrientMode)
504  return (*this);
505 
506  int x0 = MAX(rect.ul().x, ul().x);
507  int x1 = MIN(rect.lr().x, lr().x);
508  int y0, y1;
509 
510  if(!this->intersects(rect))
511  {
512  return ossimIrect(OSSIM_INT_NAN,
515  OSSIM_INT_NAN);
516 
517  }
519  {
520  y0 = MAX(rect.ul().y, ul().y);
521  y1 = MIN(rect.lr().y, lr().y);
522 
523  if( (x1 < x0) || (y1 < y0) )
524  return ossimIrect(ossimIpt(0,0), ossimIpt(0,0), theOrientMode);
525  else
526  return ossimIrect(x0, y0, x1, y1, theOrientMode);
527  }
528  else
529  {
530  y1 = MIN(rect.ul().y,ul().y);
531  y0 = MAX(rect.lr().y,lr().y);
532 
533  if((x1 < x0) || (y1 < y0))
534  return ossimIrect(ossimIpt(0,0), ossimIpt(0,0), theOrientMode);
535  else
536  return ossimIrect(x0, y1, x1, y0, theOrientMode);
537  }
538 }
539 
540 //*******************************************************************
541 // Returns the minimum bounding rect that includes this and arg rect.
542 //*******************************************************************
544 {
545  // If any rect has NANs, it is assumed uninitialized, so assign the result to just the other
546  if (hasNans())
547  return rect;
548  if(rect.hasNans())
549  return *this;
550 
551  if (theOrientMode != rect.theOrientMode)
552  return(*this);
553 
554  ossimIpt ulCombine;
555  ossimIpt lrCombine;
556 
558  {
559  ulCombine.x = ((ul().x <= rect.ul().x)?ul().x:rect.ul().x);
560  ulCombine.y = ((ul().y <= rect.ul().y)?ul().y:rect.ul().y);
561  lrCombine.x = ((lr().x >= rect.lr().x)?lr().x:rect.lr().x);
562  lrCombine.y = ((lr().y >= rect.lr().y)?lr().y:rect.lr().y);
563  }
564  else
565  {
566  ulCombine.x = ((ul().x <= rect.ul().x)?ul().x:rect.ul().x);
567  ulCombine.y = ((ul().y >= rect.ul().y)?ul().y:rect.ul().y);
568  lrCombine.x = ((lr().x >= rect.lr().x)?lr().x:rect.lr().x);
569  lrCombine.y = ((lr().y <= rect.lr().y)?lr().y:rect.lr().y);
570  }
571 
572  return ossimIrect(ulCombine, lrCombine, theOrientMode);
573 }
574 
575 //*******************************************************************
576 // Inline Method: ossimIrect::operator=(const ossimDrect& rect)
577 //*******************************************************************
579 {
580  theUlCorner = rect.ul();
581  theUrCorner = rect.ur();
582  theLrCorner = rect.lr();
583  theLlCorner = rect.ll();
584  theOrientMode = rect.orientMode();
585 
586  return *this;
587 }
588 
590  const char* prefix)const
591 {
592  kwl.add(prefix,
594  "ossimIrect",
595  true);
596 
597  kwl.add(prefix, "rect", toString());
598  #if 0
599  if(hasNans())
600  {
601  kwl.add(prefix,
602  "ul_x",
603  "nan",
604  true);
605  kwl.add(prefix,
606  "ul_y",
607  "nan",
608  true);
609  kwl.add(prefix,
610  "lr_x",
611  "nan",
612  true);
613  kwl.add(prefix,
614  "lr_y",
615  "nan",
616  true);
617  }
618  else
619  {
620  kwl.add(prefix,
621  "ul_x",
622  theUlCorner.x,
623  true);
624  kwl.add(prefix,
625  "ul_y",
626  theUlCorner.y,
627  true);
628  kwl.add(prefix,
629  "lr_x",
630  theLrCorner.x,
631  true);
632  kwl.add(prefix,
633  "lr_y",
634  theLrCorner.y,
635  true);
636  }
637 #endif
638  return true;
639 }
640 
642  const char* prefix)
643 {
644  makeNan();
645  const char* ulx = kwl.find(prefix, "ul_x");
646  const char* uly = kwl.find(prefix, "ul_y");
647  const char* lrx = kwl.find(prefix, "lr_x");
648  const char* lry = kwl.find(prefix, "lr_y");
649  const char* rect = kwl.find(prefix, "rect");
650 
651  if(ulx&&uly&&lrx&&lry)
652  {
653  if( (ossimString(ulx).trim().upcase() != "NAN") &&
654  (ossimString(uly).trim().upcase() != "NAN") &&
655  (ossimString(lrx).trim().upcase() != "NAN") &&
656  (ossimString(lry).trim().upcase() != "NAN"))
657  {
658  *this = ossimIrect(ossimString(ulx).toInt32(),
659  ossimString(uly).toInt32(),
660  ossimString(lrx).toInt32(),
661  ossimString(lry).toInt32());
662  }
663  }
664  else if(rect)
665  {
666  toRect(rect);
667  }
668 
669  return true;
670 }
671 
672 void ossimIrect::getCenter(ossimDpt& center_point) const
673 {
674  if (hasNans())
675  {
676  center_point.makeNan();
677  return;
678  }
679 
680  double d = (theUlCorner.x + theUrCorner.x + theLrCorner.x + theLlCorner.x);
681  center_point.x = d / 4.0;
682 
684  center_point.y = d / 4.0;
685 }
void print(std::ostream &os) const
Definition: ossimIrect.cpp:483
ossim_uint32 x
T max(T a, T b)
Definition: ossimCommon.h:236
bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
Definition: ossimIrect.cpp:589
std::ostream & operator<<(std::ostream &os, const ossimIrect &rect)
Definition: ossimIrect.cpp:491
ossimIpt theUrCorner
Definition: ossimIrect.h:533
Represents serializable keyword/value map.
ossim_uint32 y
const char * find(const char *key) const
const ossimDpt & ul() const
Definition: ossimDrect.h:339
double y
Definition: ossimDpt.h:165
ossim_uint32 height() const
Definition: ossimIrect.h:487
static ossimString toString(bool aValue)
Numeric to string methods.
#define OSSIM_INT_NAN
const ossimIpt & ul() const
Definition: ossimIrect.h:274
void split(std::vector< ossimString > &result, const ossimString &separatorList, bool skipBlankFields=false) const
Splits this string into a vector of strings (fields) using the delimiter list specified.
bool intersects(const ossimIrect &rect) const
Definition: ossimIrect.cpp:183
const ossimIpt & ll() const
Definition: ossimIrect.h:277
static const char * TYPE_KW
const ossimIrect & expand(const ossimIpt &padding)
Definition: ossimIrect.cpp:308
ossimCoordSysOrientMode orientMode() const
Definition: ossimDrect.h:414
bool insureMinimumSize(const ossimIpt &width_height)
Guarantees that this rect will be at least w X h big.
Definition: ossimIrect.cpp:140
ossimCoordSysOrientMode
bool completely_within(const ossimIrect &rect) const
Definition: ossimIrect.cpp:425
ossimString toString() const
Definition: ossimIrect.cpp:332
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
ossimIpt theLrCorner
Definition: ossimIrect.h:534
OSSIM_DLL std::istream & skipws(std::istream &in)
Definition: ossimCommon.cpp:38
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
Definition: ossimIrect.cpp:641
unsigned int ossim_uint32
const ossimIrect & operator=(const ossimIrect &rect)
Definition: ossimIrect.h:543
const ossimIpt & lr() const
Definition: ossimIrect.h:276
ossimIpt theLlCorner
Definition: ossimIrect.h:535
static ossimString downcase(const ossimString &aString)
Definition: ossimString.cpp:48
T min(T a, T b)
Definition: ossimCommon.h:203
ossim_uint32 width() const
Definition: ossimIrect.h:500
ossimIrect clipToRect(const ossimIrect &rect) const
Definition: ossimIrect.cpp:501
const ossimIpt & ur() const
Definition: ossimIrect.h:275
ossimIpt theUlCorner
Definition: ossimIrect.h:532
ossimCoordSysOrientMode theOrientMode
Definition: ossimIrect.h:537
ossim_int32 y
Definition: ossimIpt.h:142
~ossimIrect()
destructor
Definition: ossimIrect.cpp:109
void makeNan()
Definition: ossimIrect.h:329
const ossimDpt & ur() const
Definition: ossimDrect.h:340
#define MAX(x, y)
Definition: ossimIrect.cpp:27
double x
Definition: ossimDpt.h:164
long long ossim_int64
bool toRect(const ossimString &rectString)
expected Format: form 1: ( 30, -90, 512, 512, [LH|RH] ) -x- -y- -w- -h- -Right or left handed- ...
Definition: ossimIrect.cpp:359
void stretchToTileBoundary(const ossimIpt &tileWidthHeight)
Definition: ossimIrect.cpp:212
bool hasNans() const
Definition: ossimIrect.h:337
ossim_int32 x
Definition: ossimIpt.h:141
const ossimDpt & ll() const
Definition: ossimDrect.h:342
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
#define MIN(x, y)
Definition: ossimIrect.cpp:28
bool hasNans() const
Definition: ossimIpt.h:58
const ossimDpt & lr() const
Definition: ossimDrect.h:341
ossimIrect combine(const ossimIrect &rect) const
Definition: ossimIrect.cpp:543
void makeNan()
Definition: ossimDpt.h:65
void getCenter(ossimDpt &center_point) const
Definition: ossimIrect.cpp:672
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32