GeoTessCPP 2.6.1 Software to facilitate storage and retrieval of 3D information about the Earth.

Loading...
Searching...
No Matches
GeoTessPolygon.h
Go to the documentation of this file.
1//- ****************************************************************************
2//-
3//- Copyright 2009 Sandia Corporation. Under the terms of Contract
4//- DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
5//- 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//- * Redistributions of source code must retain the above copyright notice,
14//- this list of conditions and the following disclaimer.
15//- * Redistributions in binary form must reproduce the above copyright
16//- notice, this list of conditions and the following disclaimer in the
17//- documentation and/or other materials provided with the distribution.
18//- * Neither the name of Sandia National Laboratories nor the names of its
19//- contributors may be used to endorse or promote products derived from
20//- this software without specific prior written permission.
21//-
22//- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23//- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24//- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25//- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
26//- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27//- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28//- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29//- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30//- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31//- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32//- POSSIBILITY OF SUCH DAMAGE.
33//-
34//- ****************************************************************************
35
36#ifndef POLYGON_H_
37#define POLYGON_H_
38
39// **** _SYSTEM INCLUDES_ ******************************************************
40
41#include <cstdio>
42#include <iostream>
43#include <iomanip>
44#include <vector>
45
46// use standard library objects
47 using namespace std;
48
49// **** _LOCAL INCLUDES_ *******************************************************
50
51#include "CPPUtils.h"
52#include "GeoTessUtils.h"
53#include "GeoTessGreatCircle.h"
54#include "IFStreamAscii.h"
55
56// **** _BEGIN GEOTESS NAMESPACE_ **********************************************
57
58 namespace geotess {
59
60// **** _FORWARD REFERENCES_ ***************************************************
61
62// **** _CLASS DEFINITION_ *****************************************************
63
111 class GEOTESS_EXP_IMP GeoTessPolygon
112{
113 protected:
114
118 vector<GeoTessGreatCircle*> edges;
119
126 double* referencePoint;
127
131 bool referenceIn;
132
136 static double TOLERANCE;
137
142 bool global;
143
147 bool lonFirst;
148
152 void setup(vector<double*>& points);
153
154 int edgeCrossings(GeoTessGreatCircle& gcRef);
155
159 int refCount;
160
161 public:
162
163 virtual ~GeoTessPolygon();
164
169 void* attachment;
170
171 GeoTessPolygon();
172
185 GeoTessPolygon(vector<double*>& points);
186
198 GeoTessPolygon(const double* center, double radius, int nEdges);
199
208 GeoTessPolygon(string filename);
209
213 virtual string class_name() { return "Polygon"; };
214
218 void addReference() { ++refCount; }
219
223 void removeReference()
224 {
225 if (isNotReferenced())
226 {
227 ostringstream os;
228 os << endl << "ERROR in Polygon::removeReference" << endl
229 << "Reference count (" << refCount << ") is already zero." << endl;
230 throw GeoTessException(os, __FILE__, __LINE__, 10001);
231 }
232
233 --refCount;
234 }
235
239 bool isNotReferenced() { return refCount == 0; }
240
241 int getRefCount() { return refCount; }
242
250 int size()
251 {
252 return edges.size();
253 }
254
258 static double getTolerance()
259 {
260 return TOLERANCE;
261 }
262
269 const double* const getReferencePoint()
270 {
271 return referencePoint;
272 }
273
280 const void getReferencePoint(double *u)
281 {
282 u[0] = referencePoint[0];
283 u[1] = referencePoint[1];
284 u[2] = referencePoint[2];
285 }
286
291 bool getReferencePointIn()
292 {
293 return referenceIn;
294 }
295
300 void invert()
301 {
302 referenceIn = !referenceIn;
303 }
304
317 void setReferencePoint(const double* refPoint, const bool &inside)
318 {
319 if (referencePoint == NULL)
320 referencePoint = new double[3];
321
322 referencePoint[0] = refPoint[0];
323 referencePoint[1] = refPoint[1];
324 referencePoint[2] = refPoint[2];
325 referenceIn = inside;
326 }
327
337 void setReferencePoint(double lat, double lon, bool inside)
338 {
339 double r[3];
340 GeoTessUtils::getVectorDegrees(lat, lon, r);
341 setReferencePoint(r, inside);
342 }
343
352 bool containsAny(const vector<double*>& points)
353 {
354 for (int i=0; i<(int)points.size(); ++i)
355 if (contains(points[i]))
356 return true;
357 return false;
358 }
359
366 bool containsAll(const vector<double*>& positions)
367 {
368 for (int i=0; i<(int)positions.size(); ++i)
369 if (!contains(positions[i]))
370 return false;
371 return true;
372 }
373
380 bool contains(const double* x)
381 {
382 if (global || GeoTessUtils::dot(referencePoint, x) > cos(TOLERANCE))
383 return referenceIn;
384
385 GeoTessGreatCircle gcRef(referencePoint, x);
386
387 return onBoundary(gcRef) || ((edgeCrossings(gcRef) % 2 == 0) == referenceIn);
388 }
389
397 bool onBoundary(GeoTessGreatCircle& gcRef)
398 {
399 // point being evaluated is gcRef.getLast()
400 for (int i=0; i<(int)edges.size(); ++i)
401 {
402 // if point is very close to a polygon point, return true
403 if (GeoTessUtils::dot(gcRef.getLast(), edges[i]->getFirst()) >= cos(TOLERANCE))
404 return true;
405
406 // if gcRef and edge are coincident, i.e., their normals are parallel or
407 // anti-parallel, and the point being evaluated is between first and last
408 // point of the edge, then return true;
409 if (abs(GeoTessUtils::dot(gcRef.getNormal(), edges[i]->getNormal())) >= cos(TOLERANCE)
410 && edges[i]->getDistance(gcRef.getLast()) <= edges[i]->getDistance())
411 return true;
412 }
413 return false;
414 }
415
423 bool onBoundary(const double* x)
424 {
425 GeoTessGreatCircle gc(referencePoint, x);
426 return onBoundary(gc);
427 }
428
443 void getPoints(vector<double*> &points, const bool &repeatFirstPoint)
444 {
445 points.reserve(points.size()+edges.size()+1);
446
447 for (int i = 0; i < (int)edges.size(); ++i)
448 {
449 double* point = new double[3];
450 point[0] = edges[i]->getFirst()[0];
451 point[1] = edges[i]->getFirst()[1];
452 point[2] = edges[i]->getFirst()[2];
453 points.push_back(point);
454 }
455
456 if (repeatFirstPoint)
457 {
458 double* point = new double[3];
459 point[0] = edges[0]->getFirst()[0];
460 point[1] = edges[0]->getFirst()[1];
461 point[2] = edges[0]->getFirst()[2];
462 points.push_back(point);
463 }
464 }
465
481 void getPoints(vector<double*> &points, const bool &repeatFirstPoint, const double &maxSpacing)
482 {
483 points.reserve(points.size()+edges.size()+1);
484
485 int n;
486 double dx;
487 for (int i = 0; i < (int)edges.size(); ++i)
488 {
489 n = (int)ceil(edges[i]->getDistance()/maxSpacing);
490 dx = edges[i]->getDistance()/n;
491 for (int j=0; j<n; ++j)
492 points.push_back(edges[i]->getPoint(j*dx));
493 }
494
495 if (repeatFirstPoint)
496 {
497 double* point = new double[3];
498 point[0] = edges[0]->getFirst()[0];
499 point[1] = edges[0]->getFirst()[1];
500 point[2] = edges[0]->getFirst()[2];
501 points.push_back(point);
502 }
503 }
504
512 const double* getPoint(int index)
513 {
514 return edges[index]->getFirst();
515 }
516
529 double getArea()
530 {
531 double a, area = 0;
532 GeoTessGreatCircle* edge;
533 GeoTessGreatCircle* previous = edges[edges.size()-1];
534
535 for (int i=0; i<(int)edges.size(); ++i)
536 {
537 edge = edges[i];
538 a = PI - GeoTessUtils::angle(previous->getNormal(), edge->getNormal());
539
540 if (GeoTessUtils::scalarTripleProduct(previous->getNormal(), edge->getNormal(),
541 edge->getFirst()) < 0)
542 area += a;
543 else
544 area += 2*PI - a;
545
546 previous = edge;
547 }
548 area -= (edges.size()-2)*PI;
549 return area;
550 }
551
561 double getAreaSmall()
562 {
563 double area = getArea();
564 return area <= 2*PI ? area : 4*PI-area;
565 }
566
576 double getAreaLarge()
577 {
578 double area = getArea();
579 return area >= 2*PI ? area : 4*PI-area;
580 }
581
600 string str(const bool& repeatFirstPoint, const bool& latFirst,
601 const double& minLongitude = -180);
602
603 virtual void write(const string& outputFileName);
604
606
607 virtual void loadAscii(vector<string>& records);
608
610
611}; // end class Polygon
612
613} // end namespace geotess
614
615#endif /* POLYGON_H_ */
GEOTESS_EXP_IMP
#define GEOTESS_EXP_IMP
Definition CPPGlobals.h:71
CPPUtils.h
GeoTessGreatCircle.h
GeoTessUtils.h
IFStreamAscii.h
geotess::GeoTessException
An exception class for all GeoTess objects.
Definition GeoTessException.h:66
geotess::GeoTessGreatCircle
Manages information about a great circle path that extends from one point to another point,...
Definition GeoTessGreatCircle.h:169
geotess::GeoTessGreatCircle::getLast
double * getLast()
Definition GeoTessGreatCircle.h:494
geotess::GeoTessGreatCircle::getFirst
double * getFirst()
Definition GeoTessGreatCircle.h:482
geotess::GeoTessGreatCircle::getNormal
const double * getNormal()
Definition GeoTessGreatCircle.h:508
geotess::GeoTessPolygon::removeReference
void removeReference()
Definition GeoTessPolygon.h:223
geotess::GeoTessPolygon::getReferencePointIn
bool getReferencePointIn()
Definition GeoTessPolygon.h:291
geotess::GeoTessPolygon::getAreaSmall
double getAreaSmall()
Definition GeoTessPolygon.h:561
geotess::GeoTessPolygon::attachment
void * attachment
Definition GeoTessPolygon.h:169
geotess::GeoTessPolygon::~GeoTessPolygon
virtual ~GeoTessPolygon()
geotess::GeoTessPolygon::getReferencePoint
const double *const getReferencePoint()
Definition GeoTessPolygon.h:269
geotess::GeoTessPolygon::setReferencePoint
void setReferencePoint(const double *refPoint, const bool &inside)
Definition GeoTessPolygon.h:317
geotess::GeoTessPolygon::getReferencePoint
const void getReferencePoint(double *u)
Definition GeoTessPolygon.h:280
geotess::GeoTessPolygon::getPoints
void getPoints(vector< double * > &points, const bool &repeatFirstPoint)
Definition GeoTessPolygon.h:443
geotess::GeoTessPolygon::referencePoint
double * referencePoint
Definition GeoTessPolygon.h:126
geotess::GeoTessPolygon::edges
vector< GeoTessGreatCircle * > edges
Definition GeoTessPolygon.h:118
geotess::GeoTessPolygon::getTolerance
static double getTolerance()
Definition GeoTessPolygon.h:258
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon(vector< double * > &points)
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon(const double *center, double radius, int nEdges)
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon()
geotess::GeoTessPolygon::getAreaLarge
double getAreaLarge()
Definition GeoTessPolygon.h:576
geotess::GeoTessPolygon::getPoints
void getPoints(vector< double * > &points, const bool &repeatFirstPoint, const double &maxSpacing)
Definition GeoTessPolygon.h:481
geotess::GeoTessPolygon::class_name
virtual string class_name()
Definition GeoTessPolygon.h:213
geotess::GeoTessPolygon::setReferencePoint
void setReferencePoint(double lat, double lon, bool inside)
Definition GeoTessPolygon.h:337
geotess::GeoTessPolygon::lonFirst
bool lonFirst
Definition GeoTessPolygon.h:147
geotess::GeoTessPolygon::addReference
void addReference()
Definition GeoTessPolygon.h:218
geotess::GeoTessPolygon::referenceIn
bool referenceIn
Definition GeoTessPolygon.h:131
geotess::GeoTessPolygon::size
int size()
Definition GeoTessPolygon.h:250
geotess::GeoTessPolygon::str
string str(const bool &repeatFirstPoint, const bool &latFirst, const double &minLongitude=-180)
geotess::GeoTessPolygon::contains
bool contains(const double *x)
Definition GeoTessPolygon.h:380
geotess::GeoTessPolygon::containsAll
bool containsAll(const vector< double * > &positions)
Definition GeoTessPolygon.h:366
geotess::GeoTessPolygon::getRefCount
int getRefCount()
Definition GeoTessPolygon.h:241
geotess::GeoTessPolygon::getArea
double getArea()
Definition GeoTessPolygon.h:529
geotess::GeoTessPolygon::edgeCrossings
int edgeCrossings(GeoTessGreatCircle &gcRef)
geotess::GeoTessPolygon::TOLERANCE
static double TOLERANCE
Definition GeoTessPolygon.h:136
geotess::GeoTessPolygon::refCount
int refCount
Definition GeoTessPolygon.h:159
geotess::GeoTessPolygon::GeoTessPolygon
GeoTessPolygon(string filename)
geotess::GeoTessPolygon::onBoundary
bool onBoundary(const double *x)
Definition GeoTessPolygon.h:423
geotess::GeoTessPolygon::containsAny
bool containsAny(const vector< double * > &points)
Definition GeoTessPolygon.h:352
geotess::GeoTessPolygon::invert
void invert()
Definition GeoTessPolygon.h:300
geotess::GeoTessPolygon::getPoint
const double * getPoint(int index)
Definition GeoTessPolygon.h:512
geotess::GeoTessPolygon::setup
void setup(vector< double * > &points)
geotess::GeoTessPolygon::global
bool global
Definition GeoTessPolygon.h:142
geotess::GeoTessPolygon::write
virtual void write(const string &outputFileName)
geotess::GeoTessPolygon::onBoundary
bool onBoundary(GeoTessGreatCircle &gcRef)
Definition GeoTessPolygon.h:397
geotess::GeoTessPolygon::isNotReferenced
bool isNotReferenced()
Definition GeoTessPolygon.h:239
geotess::GeoTessUtils::angle
static double angle(const double *const v0, const double *const v1)
Definition GeoTessUtils.h:497
geotess::GeoTessUtils::dot
static double dot(const double *const v0, const double *const v1)
Definition GeoTessUtils.h:134
geotess::GeoTessUtils::getVectorDegrees
static double * getVectorDegrees(const double &lat, const double &lon)
Definition GeoTessUtils.h:610
geotess::GeoTessUtils::scalarTripleProduct
static double scalarTripleProduct(const double *const v0, const double *const v1, const double *const v2)
Definition GeoTessUtils.h:146
geotess
Definition ArrayReuse.h:55