GeoTessCPP  2.2.3
Software to facilitate storage and retrieval of 3D information about the Earth.
GeoTessPolygon.h
Go to the documentation of this file.
1 //- ****************************************************************************
2 //-
3 //- Copyright 2009 National Technology & Engineering Solutions of Sandia, LLC
4 //- (NTESS). Under the terms of Contract DE-NA0003525 with NTESS, the U.S.
5 //- Government retains certain rights in this software.
6 //-
7 //- BSD Open Source License
8 //- All rights reserved.
9 //-
10 //- Redistribution and use in source and binary forms, with or without
11 //- modification, are permitted provided that the following conditions are met:
12 //-
13 //- 1. Redistributions of source code must retain the above copyright notice,
14 //- this list of conditions and the following disclaimer.
15 //-
16 //- 2. Redistributions in binary form must reproduce the above copyright
17 //- notice, this list of conditions and the following disclaimer in the
18 //- documentation and/or other materials provided with the distribution.
19 //-
20 //- 3. Neither the name of the copyright holder nor the names of its
21 //- contributors may be used to endorse or promote products derived from
22 //- this software without specific prior written permission.
23 //-
24 //- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25 //- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 //- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 //- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
28 //- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29 //- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 //- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 //- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32 //- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 //- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 //- POSSIBILITY OF SUCH DAMAGE.
35 //-
36 //- ****************************************************************************
37 
38 #ifndef POLYGON_H_
39 #define POLYGON_H_
40 
41 // **** _SYSTEM INCLUDES_ ******************************************************
42 
43 #include <cstdio>
44 #include <iostream>
45 #include <iomanip>
46 #include <vector>
47 
48 // use standard library objects
49 using namespace std;
50 
51 // **** _LOCAL INCLUDES_ *******************************************************
52 
53 #include "CPPUtils.h"
54 #include "GeoTessUtils.h"
55 #include "GeoTessGreatCircle.h"
56 #include "IFStreamAscii.h"
57 
58 // **** _BEGIN GEOTESS NAMESPACE_ **********************************************
59 
60 namespace geotess {
61 
62 // **** _FORWARD REFERENCES_ ***************************************************
63 
64 // **** _CLASS DEFINITION_ *****************************************************
65 
114 {
115 protected:
116 
120  vector<GeoTessGreatCircle*> edges;
121 
128  double* referencePoint;
129 
134 
138  static double TOLERANCE;
139 
144  bool global;
145 
149  bool lonFirst;
150 
154  void setup(vector<double*>& points);
155 
157 
161  int refCount;
162 
163  public:
164 
165  virtual ~GeoTessPolygon();
166 
171  void* attachment;
172 
174 
187  GeoTessPolygon(vector<double*>& points);
188 
200  GeoTessPolygon(const double* center, double radius, int nEdges);
201 
210  GeoTessPolygon(string filename);
211 
215  virtual string class_name() { return "Polygon"; };
216 
220  void addReference() { ++refCount; }
221 
226  {
227  if (isNotReferenced())
228  {
229  ostringstream os;
230  os << endl << "ERROR in Polygon::removeReference" << endl
231  << "Reference count (" << refCount << ") is already zero." << endl;
232  throw GeoTessException(os, __FILE__, __LINE__, 10001);
233  }
234 
235  --refCount;
236  }
237 
241  bool isNotReferenced() { return refCount == 0; }
242 
243  int getRefCount() { return refCount; }
244 
252  int size()
253  {
254  return edges.size();
255  }
256 
260  static double getTolerance()
261  {
262  return TOLERANCE;
263  }
264 
271  const double* const getReferencePoint()
272  {
273  return referencePoint;
274  }
275 
282  const void getReferencePoint(double *u)
283  {
284  u[0] = referencePoint[0];
285  u[1] = referencePoint[1];
286  u[2] = referencePoint[2];
287  }
288 
294  {
295  return referenceIn;
296  }
297 
302  void invert()
303  {
304  referenceIn = !referenceIn;
305  }
306 
319  void setReferencePoint(const double* refPoint, const bool &inside)
320  {
321  if (referencePoint == NULL)
322  referencePoint = new double[3];
323 
324  referencePoint[0] = refPoint[0];
325  referencePoint[1] = refPoint[1];
326  referencePoint[2] = refPoint[2];
327  referenceIn = inside;
328  }
329 
339  void setReferencePoint(double lat, double lon, bool inside)
340  {
341  double r[3];
342  GeoTessUtils::getVectorDegrees(lat, lon, r);
343  setReferencePoint(r, inside);
344  }
345 
354  bool containsAny(const vector<double*>& points)
355  {
356  for (int i=0; i<(int)points.size(); ++i)
357  if (contains(points[i]))
358  return true;
359  return false;
360  }
361 
368  bool containsAll(const vector<double*>& positions)
369  {
370  for (int i=0; i<(int)positions.size(); ++i)
371  if (!contains(positions[i]))
372  return false;
373  return true;
374  }
375 
382  bool contains(const double* x)
383  {
384  if (global || GeoTessUtils::dot(referencePoint, x) > cos(TOLERANCE))
385  return referenceIn;
386 
387  GeoTessGreatCircle gcRef(referencePoint, x);
388 
389  return onBoundary(gcRef) || ((edgeCrossings(gcRef) % 2 == 0) == referenceIn);
390  }
391 
400  {
401  // point being evaluated is gcRef.getLast()
402  for (int i=0; i<(int)edges.size(); ++i)
403  {
404  // if point is very close to a polygon point, return true
405  if (GeoTessUtils::dot(gcRef.getLast(), edges[i]->getFirst()) >= cos(TOLERANCE))
406  return true;
407 
408  // if gcRef and edge are coincident, i.e., their normals are parallel or
409  // anti-parallel, and the point being evaluated is between first and last
410  // point of the edge, then return true;
411  if (abs(GeoTessUtils::dot(gcRef.getNormal(), edges[i]->getNormal())) >= cos(TOLERANCE)
412  && edges[i]->getDistance(gcRef.getLast()) <= edges[i]->getDistance())
413  return true;
414  }
415  return false;
416  }
417 
425  bool onBoundary(const double* x)
426  {
427  GeoTessGreatCircle gc(referencePoint, x);
428  return onBoundary(gc);
429  }
430 
445  void getPoints(vector<double*> &points, const bool &repeatFirstPoint)
446  {
447  points.reserve(points.size()+edges.size()+1);
448 
449  for (int i = 0; i < (int)edges.size(); ++i)
450  {
451  double* point = new double[3];
452  point[0] = edges[i]->getFirst()[0];
453  point[1] = edges[i]->getFirst()[1];
454  point[2] = edges[i]->getFirst()[2];
455  points.push_back(point);
456  }
457 
458  if (repeatFirstPoint)
459  {
460  double* point = new double[3];
461  point[0] = edges[0]->getFirst()[0];
462  point[1] = edges[0]->getFirst()[1];
463  point[2] = edges[0]->getFirst()[2];
464  points.push_back(point);
465  }
466  }
467 
483  void getPoints(vector<double*> &points, const bool &repeatFirstPoint, const double &maxSpacing)
484  {
485  points.reserve(points.size()+edges.size()+1);
486 
487  int n;
488  double dx;
489  for (int i = 0; i < (int)edges.size(); ++i)
490  {
491  n = (int)ceil(edges[i]->getDistance()/maxSpacing);
492  dx = edges[i]->getDistance()/n;
493  for (int j=0; j<n; ++j)
494  points.push_back(edges[i]->getPoint(j*dx));
495  }
496 
497  if (repeatFirstPoint)
498  {
499  double* point = new double[3];
500  point[0] = edges[0]->getFirst()[0];
501  point[1] = edges[0]->getFirst()[1];
502  point[2] = edges[0]->getFirst()[2];
503  points.push_back(point);
504  }
505  }
506 
514  const double* getPoint(int index)
515  {
516  return edges[index]->getFirst();
517  }
518 
531  double getArea()
532  {
533  double a, area = 0;
534  GeoTessGreatCircle* edge;
535  GeoTessGreatCircle* previous = edges[edges.size()-1];
536 
537  for (int i=0; i<(int)edges.size(); ++i)
538  {
539  edge = edges[i];
540  a = PI - GeoTessUtils::angle(previous->getNormal(), edge->getNormal());
541 
542  if (GeoTessUtils::scalarTripleProduct(previous->getNormal(), edge->getNormal(),
543  edge->getFirst()) < 0)
544  area += a;
545  else
546  area += 2*PI - a;
547 
548  previous = edge;
549  }
550  area -= (edges.size()-2)*PI;
551  return area;
552  }
553 
563  double getAreaSmall()
564  {
565  double area = getArea();
566  return area <= 2*PI ? area : 4*PI-area;
567  }
568 
578  double getAreaLarge()
579  {
580  double area = getArea();
581  return area >= 2*PI ? area : 4*PI-area;
582  }
583 
602  string str(const bool& repeatFirstPoint, const bool& latFirst,
603  const double& minLongitude = -180);
604 
605  virtual void write(const string& outputFileName);
606 
608 
609  virtual void loadAscii(vector<string>& records);
610 
612 
613 }; // end class Polygon
614 
615 } // end namespace geotess
616 
617 #endif /* POLYGON_H_ */
geotess::GeoTessPolygon::setReferencePoint
void setReferencePoint(const double *refPoint, const bool &inside)
Definition: GeoTessPolygon.h:319
geotess::GeoTessPolygon::global
bool global
Definition: GeoTessPolygon.h:144
geotess::GeoTessGreatCircle::getFirst
double * getFirst()
Definition: GeoTessGreatCircle.h:484
geotess::GeoTessPolygon::getArea
double getArea()
Definition: GeoTessPolygon.h:531
geotess
Definition: ArrayReuse.h:57
geotess::GeoTessGreatCircle::getLast
double * getLast()
Definition: GeoTessGreatCircle.h:496
geotess::GeoTessPolygon::onBoundary
bool onBoundary(const double *x)
Definition: GeoTessPolygon.h:425
geotess::GeoTessPolygon::referencePoint
double * referencePoint
Definition: GeoTessPolygon.h:128
geotess::GeoTessPolygon::write
virtual void write(const string &outputFileName)
geotess::GeoTessPolygon::contains
bool contains(const double *x)
Definition: GeoTessPolygon.h:382
geotess::GeoTessPolygon::invert
void invert()
Definition: GeoTessPolygon.h:302
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon(vector< double * > &points)
geotess::GeoTessPolygon::getAreaSmall
double getAreaSmall()
Definition: GeoTessPolygon.h:563
geotess::GeoTessPolygon::getPoints
void getPoints(vector< double * > &points, const bool &repeatFirstPoint)
Definition: GeoTessPolygon.h:445
geotess::GeoTessGreatCircle::getNormal
const double * getNormal()
Definition: GeoTessGreatCircle.h:510
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon()
geotess::GeoTessPolygon::getPoints
void getPoints(vector< double * > &points, const bool &repeatFirstPoint, const double &maxSpacing)
Definition: GeoTessPolygon.h:483
geotess::GeoTessPolygon::size
int size()
Definition: GeoTessPolygon.h:252
geotess::GeoTessPolygon::removeReference
void removeReference()
Definition: GeoTessPolygon.h:225
geotess::GeoTessPolygon::containsAll
bool containsAll(const vector< double * > &positions)
Definition: GeoTessPolygon.h:368
geotess::GeoTessPolygon::containsAny
bool containsAny(const vector< double * > &points)
Definition: GeoTessPolygon.h:354
geotess::GeoTessPolygon::getPoint
const double * getPoint(int index)
Definition: GeoTessPolygon.h:514
GeoTessUtils.h
geotess::GeoTessPolygon
An ordered list of points on the surface of a unit sphere that define a closed polygon.
Definition: GeoTessPolygon.h:114
geotess::GeoTessGreatCircle
Manages information about a great circle path that extends from one point to another point,...
Definition: GeoTessGreatCircle.h:171
geotess::GeoTessPolygon::setup
void setup(vector< double * > &points)
geotess::GeoTessPolygon::class_name
virtual string class_name()
Definition: GeoTessPolygon.h:215
geotess::GeoTessPolygon::edges
vector< GeoTessGreatCircle * > edges
Definition: GeoTessPolygon.h:120
geotess::GeoTessPolygon::getReferencePointIn
bool getReferencePointIn()
Definition: GeoTessPolygon.h:293
geotess::GeoTessPolygon::getRefCount
int getRefCount()
Definition: GeoTessPolygon.h:243
geotess::GeoTessPolygon::lonFirst
bool lonFirst
Definition: GeoTessPolygon.h:149
geotess::GeoTessPolygon::getReferencePoint
const void getReferencePoint(double *u)
Definition: GeoTessPolygon.h:282
geotess::GeoTessPolygon::attachment
void * attachment
Definition: GeoTessPolygon.h:171
geotess::GeoTessPolygon::~GeoTessPolygon
virtual ~GeoTessPolygon()
geotess::GeoTessPolygon::getTolerance
static double getTolerance()
Definition: GeoTessPolygon.h:260
GEOTESS_EXP_IMP
#define GEOTESS_EXP_IMP
Definition: CPPGlobals.h:73
IFStreamAscii.h
geotess::GeoTessPolygon::addReference
void addReference()
Definition: GeoTessPolygon.h:220
geotess::GeoTessPolygon::getAreaLarge
double getAreaLarge()
Definition: GeoTessPolygon.h:578
geotess::GeoTessPolygon::isNotReferenced
bool isNotReferenced()
Definition: GeoTessPolygon.h:241
geotess::GeoTessPolygon::setReferencePoint
void setReferencePoint(double lat, double lon, bool inside)
Definition: GeoTessPolygon.h:339
geotess::GeoTessPolygon::onBoundary
bool onBoundary(GeoTessGreatCircle &gcRef)
Definition: GeoTessPolygon.h:399
geotess::GeoTessPolygon::referenceIn
bool referenceIn
Definition: GeoTessPolygon.h:133
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon(string filename)
geotess::GeoTessPolygon::TOLERANCE
static double TOLERANCE
Definition: GeoTessPolygon.h:138
geotess::GeoTessException
An exception class for all GeoTess objects.
Definition: GeoTessException.h:68
GeoTessGreatCircle.h
geotess::GeoTessPolygon::edgeCrossings
int edgeCrossings(GeoTessGreatCircle &gcRef)
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon(const double *center, double radius, int nEdges)
CPPUtils.h
geotess::GeoTessPolygon::str
string str(const bool &repeatFirstPoint, const bool &latFirst, const double &minLongitude=-180)
geotess::GeoTessPolygon::refCount
int refCount
Definition: GeoTessPolygon.h:161
geotess::GeoTessPolygon::getReferencePoint
const double *const getReferencePoint()
Definition: GeoTessPolygon.h:271