OSSIM - Open Source Software Image Map  Version 1.9.0 (20180803)
ossimGeoPolygon.cpp
Go to the documentation of this file.
1 //*****************************************************************************
2 // FILE: ossimPolygon.h
3 //
4 // License: See top level LICENSE.txt file.
5 //
6 // AUTHOR: Garrett Potts
7 //
8 //*****************************************************************************
9 // $Id: ossimGeoPolygon.cpp 23170 2015-02-25 20:59:10Z dburken $
10 
11 #include <ostream>
12 #include <sstream>
13 #include <algorithm>
16 #include <ossim/base/ossimDatum.h>
19 
20 static const char* NUMBER_VERTICES_KW = "number_vertices";
21 
23 {
24  if(poly.size())
25  {
26  if(poly.size() >1)
27  {
28  for(ossim_uint32 i = 0; i < poly.size()-1; ++i)
29  {
30  out << "P" << i << ": " << poly[i] << std::endl;
31  }
32  out << "P" << (poly.size()-1)
33  << ": " << poly[poly.size()-1] << std::endl;
34  }
35  else
36  {
37  out << "P0: " << poly[0] << std::endl;
38  }
39  }
40 
41  return out;
42 }
43 
45  :
46  theVertexList(),
47  theAttributeList(),
48  theHoleList(),
49  theCurrentVertex(-1),
50  theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
51 {
52 }
53 
54 ossimGeoPolygon::ossimGeoPolygon(const std::vector<ossimGpt>& points)
55  :
56  theVertexList(points),
57  theAttributeList(),
58  theHoleList(),
59  theCurrentVertex(0),
60  theOrderingType(OSSIM_VERTEX_ORDER_UNKNOWN)
61 {
62 }
63 
65  :
66  theVertexList(rhs.theVertexList),
67  theAttributeList(rhs.theAttributeList),
68  theHoleList(rhs.theHoleList),
69  theCurrentVertex(rhs.theCurrentVertex),
70  theOrderingType(rhs.theOrderingType)
71 {
72 }
73 
75 {
76  if ( this != &rhs )
77  {
83  }
84  return *this;
85 }
86 
88 {
89  std::vector<ossimString> splitArray = wmsBbox.split(",");
90  bool result = true;
91  if(splitArray.size()>=4)
92  {
93  double minx = splitArray[0].trim().toDouble();
94  double miny = splitArray[1].trim().toDouble();
95  double maxx = splitArray[2].trim().toDouble();
96  double maxy = splitArray[3].trim().toDouble();
97 
98  addPoint(miny, minx);//lower left
99  addPoint(maxy, minx);//upper left
100  addPoint(maxy, maxx);//upper right
101  addPoint(miny, maxx);//lower right
102  }
103  else
104  {
105  // error
106  result = false;
107  }
108 
109  return result;
110 }
111 
113 {
114  int upper = (int)theVertexList.size();
115  int i = 0;
116 
117  for(i = 0; i < upper; ++i)
118  {
119  if(theVertexList[i].hasNans())
120  {
121  return true;
122  }
123  }
124 
125  return false;
126 }
127 
128 bool ossimGeoPolygon::vertex(int index, ossimGpt& v) const
129 {
130  if((index >= (int)theVertexList.size()) ||
131  (index < 0))
132  {
133  return false;
134  }
135 
136  v = theVertexList[index];
137  theCurrentVertex = index;
138 
139  return true;
140 }
141 
143 {
146  {
147  return false;
148  }
150 
151  return true;
152 }
153 
155  double displacement)
156 {
157  newPolygon.resize(size());
158  if(size() >= 3)
159  {
160  const ossimDatum* datum = theVertexList[0].datum();
161  checkOrdering();
162  double signMult = 1.0;
164  {
165  signMult = -1.0;
166  }
167 
168  ossimDpt prev, current, next;
169 
170  ossim_uint32 prevI;
171  ossim_uint32 currentI;
172  ossim_uint32 nextI;
173  ossim_uint32 i = 0;
174  ossim_uint32 upper = size();
175 
176  bool equalEndsFlag = false;
177  if(theVertexList[0] == theVertexList[theVertexList.size()-1])
178  {
179  equalEndsFlag = true;
180  prevI = 0;
181  currentI = 1;
182  nextI = 2;
183  i = 1;
184  --upper;
185  }
186  else
187  {
188  equalEndsFlag = false;
189  prevI = size()-1;
190  currentI = 0;
191  nextI = 1;
192  }
193  for(; i < upper;++i)
194  {
195  prev = theVertexList[prevI];
196  current = theVertexList[currentI];
197  next = theVertexList[nextI];
198 
199  ossimDpt averageNormal;
200 
201  ossimDpt diffPrev = current - prev;
202  ossimDpt diffNext = next - current;
203 
204  diffPrev = diffPrev*(1.0/diffPrev.length());
205  diffNext = diffNext*(1.0/diffNext.length());
206 
207  ossimDpt diffPrevNormal(-diffPrev.y,
208  diffPrev.x);
209  ossimDpt diffNextNormal(-diffNext.y,
210  diffNext.x);
211 
212  averageNormal = (diffPrevNormal + diffNextNormal);
213  averageNormal = averageNormal*(signMult*(1.0/averageNormal.length()));
214  ossimDpt newPoint = ossimDpt( theVertexList[i].lond(),
215  theVertexList[i].latd()) +
216  averageNormal*displacement;
217  newPolygon[i].latd(newPoint.lat);
218  newPolygon[i].lond(newPoint.lon);
219  newPolygon[i].height(theVertexList[i].height());
220  newPolygon[i].datum(datum);
221 
222  ++prevI;
223  ++currentI;
224  ++nextI;
225 
226  prevI%=size();
227  nextI%=size();
228  }
229  if(equalEndsFlag)
230  {
231 
232  prev = theVertexList[theVertexList.size()-2];
233  current = theVertexList[0];
234  next = theVertexList[1];
235 
236  ossimDpt averageNormal;
237 
238  ossimDpt diffPrev = current - prev;
239  ossimDpt diffNext = next - current;
240 
241  diffPrev = diffPrev*(1.0/diffPrev.length());
242  diffNext = diffNext*(1.0/diffNext.length());
243 
244  ossimDpt diffPrevNormal(-diffPrev.y,
245  diffPrev.x);
246  ossimDpt diffNextNormal(-diffNext.y,
247  diffNext.x);
248 
249  averageNormal = (diffPrevNormal + diffNextNormal);
250  averageNormal = averageNormal*(signMult*(1.0/averageNormal.length()));
251  ossimDpt newPoint = ossimDpt( theVertexList[i].lond(),
252  theVertexList[i].latd()) +
253  averageNormal*displacement;
254  newPolygon[0].latd(newPoint.lat);
255  newPolygon[0].lond(newPoint.lon);
256  newPolygon[0].height(theVertexList[i].height());
257  newPolygon[0].datum(datum);
258 
259  newPolygon[(int)theVertexList.size()-1] = newPolygon[0];
260  }
261  }
262 }
263 
264 
266 {
267  double area = 0;
268  ossim_uint32 i=0;
269  ossim_uint32 j=0;
271 
272  for (i=0;i<size;i++)
273  {
274  j = (i + 1) % size;
275  area += theVertexList[i].lon * theVertexList[j].lat;
276  area -= theVertexList[i].lat * theVertexList[j].lon;
277  }
278 
279  area /= 2;
280 
281  return area;
282 }
283 
285 {
286  std::reverse(theVertexList.begin(), theVertexList.end());
287 
289  {
291  }
293  {
295  }
296 
297 }
298 
300 {
302  {
303  double areaValue = area();
304  if(areaValue > 0)
305  {
307  }
308  else if(areaValue <= 0)
309  {
311  }
312  }
313 }
314 
316 {
317  if(!size())
318  {
319  return ossimGpt();
320  }
321  ossimDpt average(0.0,0.0);
322  double height=0.0;
323  for(ossim_uint32 i = 0; i < size(); ++i)
324  {
325  average += ossimDpt(theVertexList[i]);
326  height += theVertexList[i].height();
327  }
328 
329 
330  average.x /= size();
331  average.y /= size();
332  height /= size();
333 
334  return ossimGpt(average.y, average.x, height, theVertexList[0].datum());
335 }
336 
338  const char* prefix)const
339 {
340  int i = 0;
341 
342  kwl.add(prefix,
344  "ossimGeoPolygon",
345  true);
346  kwl.add(prefix,
347  NUMBER_VERTICES_KW,
348  static_cast<ossim_uint32>(theVertexList.size()),
349  true);
350  if(theVertexList.size())
351  {
352  kwl.add(prefix,
354  theVertexList[0].datum()->code(),
355  true);
356  }
357  else
358  {
359  kwl.add(prefix,
361  "WGE",
362  true);
363  }
364 
365  for(i = 0; i < (int)theVertexList.size();++i)
366  {
367  ossimString vert = "v"+ossimString::toString(i);
368  ossimString value = (ossimString::toString(theVertexList[i].latd()) + " " +
369  ossimString::toString(theVertexList[i].lond()) + " " +
370  ( theVertexList[i].isHgtNan()?ossimString("nan"):ossimString::toString(theVertexList[i].height())));
371  kwl.add(prefix,
372  vert.c_str(),
373  value.c_str(),
374  true);
375  }
376 
377  return true;
378 }
379 
381  const char* prefix)
382 {
383  const char* number_vertices = kwl.find(prefix, NUMBER_VERTICES_KW);
384  ossimString datumStr = kwl.find(prefix, ossimKeywordNames::DATUM_KW);
385  const ossimDatum* datum = ossimDatumFactoryRegistry::instance()->create(datumStr);
386 
387  theVertexList.clear();
388  int i = 0;
389  int vertexCount = ossimString(number_vertices).toLong();
390  ossimString lat, lon, height;
391  for(i = 0; i < vertexCount; ++i)
392  {
393  ossimString v = kwl.find(prefix, (ossimString("v")+ossimString::toString(i)).c_str());
394  ossimString latString, lonString, heightString;
395  v = v.trim();
396  std::istringstream in(v);
397  in>>lat>>lon>>height;
398  theVertexList.push_back(ossimGpt(lat.toDouble(), lon.toDouble(), height.toDouble(), datum));
399  }
400 
401  return true;
402 }
std::vector< ossimString > theAttributeList
ossimGpt computeCentroid() const
static const char * DATUM_KW
void stretchOut(ossimGeoPolygon &newPolygon, double displacement)
Represents serializable keyword/value map.
static ossimDatumFactoryRegistry * instance()
instance method
const char * find(const char *key) const
std::vector< ossimGeoPolygon > theHoleList
bool loadState(const ossimKeywordlist &kwl, const char *prefix=0)
double y
Definition: ossimDpt.h:165
static ossimString toString(bool aValue)
Numeric to string methods.
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.
double area() const
bool saveState(ossimKeywordlist &kwl, const char *prefix=0) const
static const char * TYPE_KW
double length() const
Definition: ossimDpt.h:81
void add(const char *prefix, const ossimKeywordlist &kwl, bool overwrite=true)
void resize(ossim_uint32 newSize)
double lat
Definition: ossimDpt.h:165
bool addWmsBbox(const ossimString &wmsBbox)
std::ostream & operator<<(std::ostream &out, const ossimGeoPolygon &poly)
bool hasNans() const
unsigned int ossim_uint32
virtual const ossimDatum * create(const ossimString &code) const
create method
ossimString trim(const ossimString &valueToTrim=ossimString(" \\)) const
this will strip lead and trailing character passed in.
bool vertex(int index, ossimGpt &v) const
double toDouble() const
std::vector< ossimGpt > theVertexList
void addPoint(const ossimGpt &pt)
void checkOrdering() const
double lon
Definition: ossimDpt.h:164
ossim_uint32 size() const
long toLong() const
toLong&#39;s deprecated, please use the toInts...
bool nextVertex(ossimDpt &v) const
ossimVertexOrdering theOrderingType
ossim_int32 theCurrentVertex
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 ossimGeoPolygon & operator=(const std::vector< ossimGpt > &rhs)
std::basic_istringstream< char > istringstream
Class for char input memory streams.
Definition: ossimIosFwd.h:32
std::basic_ostream< char > ostream
Base class for char output streams.
Definition: ossimIosFwd.h:23
int ossim_int32