GeoTessCPP: rstt/GeoTessCPP/include/GeoTessPolygon.h Source File

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
113 class GEOTESS_EXP_IMP GeoTessPolygon
114 {
115 protected:
116
120 vector<GeoTessGreatCircle*> edges;
121
128 double* referencePoint;
129
133 bool referenceIn;
134
138 static double TOLERANCE;
139
144 bool global;
145
149 bool lonFirst;
150
154 void setup(vector<double*>& points);
155
156 int edgeCrossings(GeoTessGreatCircle& gcRef);
157
161 int refCount;
162
163 public:
164
165 virtual ~GeoTessPolygon();
166
171 void* attachment;
172
173 GeoTessPolygon();
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
225 void removeReference()
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
293 bool getReferencePointIn()
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
399 bool onBoundary(GeoTessGreatCircle& gcRef)
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