OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimPolyLine.cpp
Go to the documentation of this file.
1 //*******************************************************************
2 //
3 // License: See top level LICENSE.txt file.
4 //
5 // AUTHOR: Garrett Potts (gpotts@imagelinks.com)
6 //
7 //*****************************************************************************
8 // $Id: ossimPolyLine.cpp 22532 2013-12-28 20:46:11Z dburken $
9 //
11 #include <ossim/base/ossimCommon.h>
12 #include <algorithm>
15 #include <ossim/base/ossimLine.h>
17 #include <sstream>
18 #include <iterator>
19 using namespace std;
20 
21 static const char* NUMBER_VERTICES_KW = "number_vertices";
22 
23 ossimPolyLine::ossimPolyLine(const vector<ossimIpt>& polyLine)
24  :theCurrentVertex(0)
25 {
26  for (std::vector<ossimIpt>::const_iterator iter = polyLine.begin();
27  iter != polyLine.end(); ++iter)
28  {
29  theVertexList.push_back(ossimDpt(*iter));
30  }
31 }
32 
33 ossimPolyLine::ossimPolyLine(const vector<ossimDpt>& polyLine)
34  :theCurrentVertex(0)
35 {
36  theVertexList = polyLine;
37 }
38 
39 //*****************************************************************************
40 // CONSTRUCTOR: ossimPolyLine(int numVertices, const ossimDpt* vertex_array)
41 //
42 //*****************************************************************************
43 ossimPolyLine::ossimPolyLine(int numVertices, const ossimDpt* v)
44  : theCurrentVertex(0)
45 {
46  theVertexList.insert(theVertexList.begin(),
47  v, v+numVertices);
48 }
49 
50 //*****************************************************************************
51 // COPY CONSTRUCTOR: ossimPolyLine(ossimPolyLine)
52 //
53 //*****************************************************************************
55  :theCurrentVertex(0)
56 {
57  *this = polyLine;
58 }
59 
61  ossimDpt v2,
62  ossimDpt v3,
63  ossimDpt v4)
64  : theVertexList(4),
65  theCurrentVertex(0)
66 {
67  theVertexList[0] = v1;
68  theVertexList[1] = v2;
69  theVertexList[2] = v3;
70  theVertexList[3] = v4;
71 }
72 
74  : theVertexList(4),
75  theCurrentVertex(0)
76 {
77  theVertexList[0] = rect.ul();
78  theVertexList[1] = rect.ur();
79  theVertexList[2] = rect.lr();
80  theVertexList[3] = rect.ll();
81 }
82 
84  : theVertexList(4),
85  theCurrentVertex(0)
86 {
87  theVertexList[0] = rect.ul();
88  theVertexList[1] = rect.ur();
89  theVertexList[2] = rect.lr();
90  theVertexList[3] = rect.ll();
91 }
92 
94  :theVertexList(polygon.getNumberOfVertices()+1),
95  theCurrentVertex(0)
96 {
98 
99  if(n)
100  {
101  for(ossim_uint32 i = 0; i < n; ++i)
102  {
103  theVertexList[i] = polygon[i];
104  }
105 
106  theVertexList[n] = polygon[n-1];
107  }
108  else
109  {
110  theVertexList.clear();
111  }
112 }
113 
114 //*****************************************************************************
115 // DESTRUCTOR: ~ossimPolyLine
116 //
117 //*****************************************************************************
119 {
120 }
121 
123 {
124  int i = 0;
125  for(i = 0; i < (int)theVertexList.size(); ++i)
126  {
128  }
129  if(compress&&theVertexList.size())
130  {
131  vector<ossimDpt> polyLine;
132 
133  polyLine.push_back(theVertexList[0]);
134  ossimDpt testPt = theVertexList[0];
135  for(i=1; i < (int)theVertexList.size(); ++i)
136  {
137  if(testPt!=theVertexList[i])
138  {
139  testPt = theVertexList[i];
140  polyLine.push_back(testPt);
141  }
142  }
143  theVertexList = polyLine;
144  theCurrentVertex = 0;
145  }
146 }
147 
149 {
150  int upper = (int)theVertexList.size();
151  int i = 0;
152 
153  for(i = 0; i < upper; ++i)
154  {
155  if(theVertexList[i].hasNans())
156  {
157  return true;
158  }
159  }
160 
161  return false;
162 }
163 
165  ossim_int32& minY,
166  ossim_int32& maxX,
167  ossim_int32& maxY)const
168 {
169  ossim_int32 npoly = (ossim_int32)theVertexList.size();
170  int i = 0;
171 
172  if(npoly)
173  {
174  minX = (ossim_int32)floor(theVertexList[0].x);
175  maxX = (ossim_int32)ceil(theVertexList[0].x);
176  minY = (ossim_int32)floor(theVertexList[0].y);
177  maxY = (ossim_int32)ceil(theVertexList[0].y);
178 
179  for(i =1; i < npoly; ++i)
180  {
181  minX = std::min((ossim_int32)floor(theVertexList[i].x),
182  (ossim_int32)minX);
183  maxX = std::max((ossim_int32)ceil(theVertexList[i].x),
184  (ossim_int32)maxX);
185  minY = std::min((ossim_int32)floor(theVertexList[i].y),
186  (ossim_int32)minY);
187  maxY = std::max((ossim_int32)ceil(theVertexList[i].y),
188  (ossim_int32)maxY);
189  }
190  }
191  else
192  {
193  minX = OSSIM_INT_NAN;
194  minY = OSSIM_INT_NAN;
195  maxX = OSSIM_INT_NAN;
196  maxY = OSSIM_INT_NAN;
197  }
198 }
199 
200 void ossimPolyLine::getBounds(double& minX,
201  double& minY,
202  double& maxX,
203  double& maxY)const
204 {
205  ossim_int32 npoly = (ossim_int32)theVertexList.size();
206 
207  if(npoly)
208  {
209  int i = 0;
210  minX = theVertexList[0].x;
211  maxX = theVertexList[0].x;
212  minY = theVertexList[0].y;
213  maxY = theVertexList[0].y;
214 
215  for(i =1; i < npoly; ++i)
216  {
217  minX = std::min(theVertexList[i].x, minX);
218  maxX = std::max(theVertexList[i].x, maxX);
219  minY = std::min(theVertexList[i].y, minY);
220  maxY = std::max(theVertexList[i].y, maxY);
221  }
222  }
223  else
224  {
225  minX = ossim::nan();
226  minY = ossim::nan();
227  maxX = ossim::nan();
228  maxY = ossim::nan();
229  }
230 }
231 
232 bool ossimPolyLine::isWithin(const ossimDrect& rect)const
233 {
234  if(theVertexList.size() == 1)
235  {
236  return rect.pointWithin(theVertexList[0]);
237  }
238  else if(theVertexList.size() > 1)
239  {
240  for(ossim_uint32 i = 0; i < (theVertexList.size() - 1); ++i)
241  {
242  ossimDpt p1 = theVertexList[i];
243  ossimDpt p2 = theVertexList[i+1];
244 
245  if(rect.clip(p1, p2))
246  {
247  return true;
248  }
249  }
250  }
251 
252  return false;
253 }
254 
255 
256 bool ossimPolyLine::clipToRect(vector<ossimPolyLine>& result,
257  const ossimDrect& rect)const
258 {
259  result.clear();
260 
261  if(theVertexList.size() <1) return false;
262 
263  ossimPolyLine currentPoly;
264 
265  if(theVertexList.size() == 1)
266  {
267  rect.pointWithin(theVertexList[0]);
268  currentPoly.addPoint(theVertexList[0]);
269  result.push_back(currentPoly);
270  }
271  else
272  {
273  ossimDpt pt1 = theVertexList[0];
274  ossimDpt pt2 = theVertexList[1];
275  ossim_uint32 i = 1;
276 
277  while(i < theVertexList.size())
278  {
279 
280  bool p1Inside = rect.pointWithin(pt1);
281  bool p2Inside = rect.pointWithin(pt2);
282 
283  if(p1Inside&&p2Inside) // both inside so save the first
284  {
285  currentPoly.addPoint(pt1);
286  pt1 = pt2;
287  }
288  // going from inside to outside
289  else if(p1Inside&&
290  !p2Inside)
291  {
292  currentPoly.addPoint(pt1);
293  ossimDpt save = pt2;
294  if(rect.clip(pt1, pt2))
295  {
296  currentPoly.addPoint(pt2);
297  result.push_back(currentPoly);
298 
299  currentPoly.clear();
300  }
301  pt2 = save;
302  pt1 = save;
303  }// going outside to the inside
304  else if(!p1Inside&&
305  p2Inside)
306  {
307  if(rect.clip(pt1, pt2))
308  {
309  currentPoly.addPoint(pt1);
310  }
311  pt1 = pt2;
312 
313  }
314  else // both outside must do a clip to see if crosses rect
315  {
316  ossimDpt p1 = pt1;
317  ossimDpt p2 = pt2;
318 
319  if(rect.clip(p1, p2))
320  {
321  currentPoly.addPoint(p1);
322  currentPoly.addPoint(p2);
323  }
324  pt1 = pt2;
325  }
326  ++i;
327 
328  if(i < theVertexList.size())
329  {
330  pt2 = theVertexList[i];
331  }
332  }
333  if(rect.pointWithin(pt2))
334  {
335  currentPoly.addPoint(pt2);
336  }
337  }
338 
339  if(currentPoly.getNumberOfVertices() > 0)
340  {
341  result.push_back(currentPoly);
342  }
343 
344  return (result.size()>0);
345 }
346 
347 bool ossimPolyLine::isPointWithin(const ossimDpt& point) const
348 {
349  if(theVertexList.size() == 1)
350  {
351  return (point == theVertexList[0]);
352  }
353  else
354  {
355  for(ossim_uint32 i = 1; i < theVertexList.size(); ++i)
356  {
357  if(ossimLine(theVertexList[i-1],
358  theVertexList[i]).isPointWithin(point))
359  {
360  return true;
361  }
362  }
363  }
364 
365  return false;
366 }
367 
368 bool ossimPolyLine::vertex(int index, ossimDpt& tbd_vertex) const
369 {
370  if((index >= (int)theVertexList.size()) ||
371  (index < 0))
372  {
373  return false;
374  }
375 
376  tbd_vertex = theVertexList[index];
377  theCurrentVertex = index;
378 
379  return true;
380 }
381 
382 bool ossimPolyLine::nextVertex(ossimDpt& tbd_vertex) const
383 {
386  {
387  return false;
388  }
389  tbd_vertex = theVertexList[theCurrentVertex];
390 
391  return true;
392 }
393 
394 
396 {
397  theCurrentVertex = 0;
398  ossim_uint32 n = polygon.getNumberOfVertices();
399 
400  if(n)
401  {
402  theVertexList.resize(n+1);
403 
404  for(ossim_uint32 i = 0; i < n; ++i)
405  {
406  theVertexList[i] = polygon[i];
407  }
408 
409  theVertexList[n] = polygon[n-1];
410  }
411  else
412  {
413  theVertexList.clear();
414  }
415 
416  return *this;
417 }
418 
420 {
421  theVertexList = polyLine.theVertexList;
424 
425  return *this;
426 }
427 
428 const ossimPolyLine& ossimPolyLine::operator= (const vector<ossimDpt>& vertexList)
429 {
430  theVertexList = vertexList;
431  theCurrentVertex = 0;
432 
433  return *this;
434 }
435 
436 const ossimPolyLine& ossimPolyLine::operator= (const vector<ossimIpt>& vertexList)
437 {
438  theVertexList.clear();
439  for (std::vector<ossimIpt>::const_iterator iter = vertexList.begin();
440  iter != vertexList.end(); ++iter)
441  {
442  theVertexList.push_back(*iter);
443  }
444 
445  theCurrentVertex = 0;
446 
447  return *this;
448 }
449 
450 //*****************************************************************************
451 // METHOD: operator==()
452 //
453 //*****************************************************************************
454 bool ossimPolyLine::operator==(const ossimPolyLine& polyLine) const
455 {
456  if( (theVertexList.size() != polyLine.theVertexList.size()))
457  {
458  return false;
459  }
460  if(!theVertexList.size() && polyLine.theVertexList.size())
461  {
462  return true;
463  }
464 
465  return (theVertexList == polyLine.theVertexList);
466 }
467 
469 {
470  int upper = (int)theVertexList.size();
471  int i = 0;
472 
473  for(i = 0; i < upper; ++i)
474  {
475  theVertexList[i].x*=scale.x;
476  theVertexList[i].y*=scale.y;
477  }
478 
479  return *this;
480 }
481 
483 {
484  ossimPolyLine result(*this);
485 
486  int i = 0;
487  int upper = (int)theVertexList.size();
488  for(i = 0; i < upper; ++i)
489  {
490  result.theVertexList[i].x*=scale.x;
491  result.theVertexList[i].y*=scale.y;
492  }
493 
494  return result;
495 }
496 
497 
499 {
500  std::reverse(theVertexList.begin(), theVertexList.end());
501 }
502 
503 //*****************************************************************************
504 // METHOD: ossimPolyLine::print(ostream)
505 //
506 //*****************************************************************************
508 {
509  copy(theVertexList.begin(),
510  theVertexList.end(),
511  ostream_iterator<ossimDpt>(os, "\n"));
512 }
513 
515  const char* prefix)const
516 {
517  int i = 0;
518  kwl.add(prefix,
520  "ossimPolyLine",
521  true);
522  kwl.add(prefix,
523  NUMBER_VERTICES_KW,
524  (int)theVertexList.size(),
525  true);
526  for(i = 0; i < (int)theVertexList.size();++i)
527  {
528  ossimString vert = "v"+ossimString::toString(i);;
529  ossimString value = (ossimString::toString(theVertexList[i].x) + " " +
531  kwl.add(prefix,
532  vert.c_str(),
533  value.c_str(),
534  true);
535  }
536  ossimString order = "";
537 
538  return true;
539 }
540 
542  const char* prefix)
543 {
544  const char* number_vertices = kwl.find(prefix, NUMBER_VERTICES_KW);
545  int i = 0;
546 
547  theVertexList.clear();
548  int vertexCount = ossimString(number_vertices).toLong();
549  double x = 0.0, y =0.0;
550  for(i = 0; i < vertexCount; ++i)
551  {
552  ossimString v = kwl.find(prefix, (ossimString("v")+ossimString::toString(i)).c_str());
553  v = v.trim();
554 
555  istringstream vStream(v);
556  vStream >> x >> y;
557  theVertexList.push_back(ossimDpt(x,y));
558  }
559 
560  return true;
561 }
ossim_uint32 x
void getBounds(double &minX, double &minY, double &maxX, double &maxY) const
bool pointWithin(const ossimDpt &pt, double epsilon=0.0) const
Definition: ossimDrect.h:781
Represents serializable keyword/value map.
ossim_uint32 y
const char * find(const char *key) const
bool hasNans() const
double nan()
Method to return ieee floating point double precision NAN.
Definition: ossimCommon.h:135
const ossimDpt & ul() const
Definition: ossimDrect.h:339
bool isWithin(const ossimDrect &rect) const
double y
Definition: ossimDpt.h:165
static ossimString toString(bool aValue)
Numeric to string methods.
#define OSSIM_INT_NAN
const ossimIpt & ul() const
Definition: ossimIrect.h:274
ossim_int32 theCurrentVertex
void roundToIntegerBounds(bool compress=true)
const ossimIpt & ll() const
Definition: ossimIrect.h:277
ossim_uint32 getNumberOfVertices() const
Definition: ossimPolyLine.h:70
static const char * TYPE_KW
const ossimPolyLine & operator=(const ossimPolyLine &copy_this)
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
os2<< "> n<< " > nendobj n
unsigned int ossim_uint32
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
bool nextVertex(ossimDpt &tbd_vertex) const
const ossimIpt & lr() const
Definition: ossimIrect.h:276
vector< ossimDpt > theVertexList
bool isPointWithin(const ossimDpt &point, double delta=FLT_EPSILON) const
Definition: ossimLine.cpp:79
vector< ossimString > theAttributeList
const ossimIpt & ur() const
Definition: ossimIrect.h:275
bool vertex(int index, ossimDpt &tbd_vertex) const
ossimPolyLine operator*(const ossimDpt &scale) const
bool clip(ossimDpt &p1, ossimDpt &p2) const
Definition: ossimDrect.cpp:653
void addPoint(const ossimDpt &pt)
ossim_uint32 getNumberOfVertices() const
long toLong() const
toLong&#39;s deprecated, please use the toInts...
bool clipToRect(vector< ossimPolyLine > &result, const ossimDrect &rect) const
bool isPointWithin(const ossimDpt &point) const
#define max(a, b)
Definition: auxiliary.h:76
void print(ostream &os) const
const ossimDpt & ur() const
Definition: ossimDrect.h:340
const ossimPolyLine & operator*=(const ossimDpt &scale)
double x
Definition: ossimDpt.h:164
const char * c_str() const
Returns a pointer to a null-terminated array of characters representing the string&#39;s contents...
Definition: ossimString.h:396
const ossimDpt & ll() const
Definition: ossimDrect.h:342
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
void getIntegerBounds(ossim_int32 &minX, ossim_int32 &minY, ossim_int32 &maxX, ossim_int32 &maxY) const
const ossimDpt & lr() const
Definition: ossimDrect.h:341
bool operator==(const ossimPolyLine &compare_this) const
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
#define min(a, b)
Definition: auxiliary.h:75
int ossim_int32
bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const