File failed to load: https://isis.astrogeology.usgs.gov/9.0.0/Object/assets/jax/output/NativeMML/config.js
Isis 3 Programmer Reference
GisGeometry.cpp
1
5
6/* SPDX-License-Identifier: CC0-1.0 */
7#include "GisGeometry.h"
8
9// Qt library
10#include <QDebug>
11#include <QScopedPointer>
12#include <QString>
13
14// geos library
15#include <geos_c.h>
16
17// other ISIS
18#include "Cube.h"
19#include "IException.h"
20#include "ImagePolygon.h"
21#include "GisTopology.h"
22#include "SpecialPixel.h"
23
24//#define DISABLE_PREPARED_GEOMETRY 1
25
26using namespace std;
27
28namespace Isis {
29
34 // Must ensure GEOS is initialized
36 }
37
38
50 GisGeometry::GisGeometry(const double xlongitude, const double ylatitude) :
52
54 m_geom = makePoint(xlongitude, ylatitude);
56 return;
57 }
58
59
75
76
85 GisGeometry::GisGeometry(const QString &gisSource, const GisGeometry::Type t) :
86 m_type(t), m_geom(0), m_preparedGeom(0) {
88 if (WKT == t) {
89 m_geom = gis->geomFromWKT(gisSource);
90 }
91 else if (WKB == t) {
92 m_geom = gis->geomFromWKB(gisSource);
93 }
94 else if (IsisCube == t) {
95 Cube cube;
96 cube.open(gisSource);
97 m_geom = fromCube(cube);
98 }
99 else {
101 QString("Unknown GIS type given [%1]").arg(typeToString(t)),
102 _FILEINFO_);
103 }
104
105 // Get the prepared geometry
107 m_type = t;
108 return;
109 }
110
111
121 m_geom(0),
122 m_preparedGeom(0) {
123
125 if ( geom.isDefined() ) {
126 m_geom = gis->clone(geom.m_geom);
128 }
129 }
130
131
140 GisGeometry::GisGeometry(GEOSGeometry *geom) : m_type(GeosGis), m_geom(geom),
141 m_preparedGeom(0) {
144 return;
145 }
146
147
154
155
165 if ( this != &geom ) {
166 destroy();
167 m_type = geom.m_type;
168 if ( geom.isDefined() ) {
170 m_geom = gis->clone(geom.m_geom);
172 }
173 }
174 return (*this);
175 }
176
177
187 void GisGeometry::setGeometry(GEOSGeometry *geom) {
188 destroy();
189 m_geom = geom;
191 return;
192 }
193
194
201 return (m_geom != 0);
202 }
203
204
217 bool GisGeometry::isValid() const {
218 if (!isDefined()) {
219 return (false);
220 }
221
222 int valid(0);
223 try {
224 valid = GEOSisValid(this->m_geom);
225 } catch (...) {
226 valid = 0;
227 }
228 return (1 == valid);
229 }
230
231
238 QString result = "Not defined!";
239 if ( isDefined() ) {
241 char *reason = GEOSisValidReason(this->m_geom);
242 result = reason;
243 gis->destroy(reason);
244 }
245 return (result);
246 }
247
248
255 return (m_type);
256 }
257
258
266 GisGeometry::Type GisGeometry::type(const QString &gstrType) {
267 QString gtype = gstrType.toLower();
268 if ("wkt" == gtype) return (WKT);
269 if ("wkb" == gtype) return (WKB);
270 if ("cube" == gtype) return (IsisCube);
271 if ("isiscube" == gtype) return (IsisCube);
272 if ("geometry" == gtype) return (GeosGis);
273 if ("geosgis" == gtype) return (GeosGis);
274 if ("gis" == gtype) return (GeosGis);
275 if ("geos" == gtype) return (GeosGis);
276 return (None);
277 }
278
279
288 if (WKT == type) return "WKT";
289 if (WKB == type) return "WKB";
290 if (IsisCube == type) return "IsisCube";
291 if (GeosGis == type) return "GeosGis";
292 return "None";
293 }
294
295
301 const GEOSGeometry *GisGeometry::geometry() const {
302 return (m_geom);
303 }
304
305
315 const GEOSPreparedGeometry *GisGeometry::preparedGeometry() const {
316 return (m_preparedGeom);
317 }
318
319
329 if (!isDefined()) {
330 return (new GisGeometry());
331 }
332
334 QScopedPointer<GisGeometry> geom(new GisGeometry());
335
336 geom->m_type = m_type;
337 geom->m_geom = gis->clone(m_geom);
338 geom->m_preparedGeom = makePrepared(geom->m_geom);
339 return (geom.take());
340 }
341
342
348 bool GisGeometry::isEmpty() const {
349 if ( !isValid() ) {
350 return (true);
351 }
352 return (1 == GEOSisEmpty(this->m_geom));
353 }
354
355
369 double GisGeometry::area( ) const {
370 if ( !isValid() ) {
371 return (0.0);
372 }
373
374 int result = 0;
375 double gisArea = 0.0;
376 result = GEOSArea(this->m_geom, &gisArea);
377 if (1 != result) {
378 gisArea = 0.0;
379 }
380 return (gisArea);
381 }
382
383
392 double GisGeometry::length( ) const {
393 if ( !isValid() ) {
394 return (0.0);
395 }
396
397 int result = 0;
398 double gisLength = 0.0;
399 result = GEOSLength(this->m_geom, &gisLength);
400 if (1 != result) {
401 gisLength = 0.0;
402 }
403 return (gisLength);
404 }
405
406
416 double GisGeometry::distance(const GisGeometry &target) const {
417 if ( !isValid() ) {
418 return (false);
419 }
420 if ( !target.isValid() ) {
421 return (false);
422 }
423
424 int result = 0;
425 double dist = Null;
426 result = GEOSDistance(this->m_geom, target.geometry(), &dist);
427 if ( 1 != result ) {
428 dist = Null;
429 }
430 return (dist);
431 }
432
433
440 if (!isValid() ) { return (0); }
441
442 int ngeoms = GEOSGetNumGeometries(m_geom);
443 int npoints = 0;
444 for (int i = 0 ; i < ngeoms ; i++) {
445 npoints += GEOSGetNumCoordinates(GEOSGetGeometryN(m_geom, i));
446 }
447
448 return ( npoints );
449 }
450
451
461 bool GisGeometry::intersects(const GisGeometry &target) const {
462 if ( !isValid() ) {
463 return (false);
464 }
465 if ( !target.isValid() ) {
466 return (false);
467 }
468
469 int result = 0;
470 if ( 0 != this->m_preparedGeom) {
471 result = GEOSPreparedIntersects(this->m_preparedGeom, target.geometry());
472 }
473 else {
474 result = GEOSIntersects(this->m_geom, target.geometry());
475 }
476
477 return (1 == result);
478 }
479
480
488 bool GisGeometry::contains(const GisGeometry &target) const {
489 if ( !isValid() ) {
490 return (false);
491 }
492 if ( !target.isValid() ) {
493 return (false);
494 }
495
496 int result = 0;
497 if ( 0 != this->m_preparedGeom) {
498 result = GEOSPreparedContains(this->m_preparedGeom, target.geometry());
499 }
500 else {
501 result = GEOSContains(this->m_geom, target.geometry());
502 }
503
504 return (1 == result);
505 }
506
507
514 bool GisGeometry::disjoint(const GisGeometry &target) const {
515 if ( !isValid() ) {
516 return (false);
517 }
518 if ( !target.isValid() ) {
519 return (false);
520 }
521
522 int result = 0;
523 if ( 0 != m_preparedGeom) {
524 result = GEOSPreparedDisjoint(m_preparedGeom, target.geometry());
525 }
526 else {
527 result = GEOSDisjoint(m_geom, target.geometry());
528 }
529
530 return (1 == result);
531 }
532
533
541 bool GisGeometry::overlaps(const GisGeometry &target) const {
542 if ( !isValid() ) {
543 return (false);
544 }
545 if ( !target.isValid() ) {
546 return (false);
547 }
548
549 int result = 0;
550 if ( 0 != m_preparedGeom) {
551 result = GEOSPreparedOverlaps(m_preparedGeom, target.geometry());
552 }
553 else {
554 result = GEOSOverlaps(m_geom, target.geometry());
555 }
556
557 return (1 == result);
558 }
559
560
567 bool GisGeometry::equals(const GisGeometry &target) const {
568 if ( !isValid() ) {
569 return (false);
570 }
571
572 if ( !target.isValid() ) {
573 return (false);
574 }
575
576 int result = GEOSEquals(this->m_geom, target.geometry());
577 return ( 1 == result );
578 }
579
580
592 double GisGeometry::intersectRatio(const GisGeometry &target) const {
593 if ( !isValid() ) {
594 return (0.0);
595 }
596 if ( !target.isValid() ) {
597 return (0.0);
598 }
599
600 // Check for any intersection at all
601 // if ( !intersects(target) ) {
602 // return (0.0);
603 // }
604
605 // Prevent dividing by 0
606 if (this->area() == 0) {
607 return (0.0);
608 }
609
610 QScopedPointer<GisGeometry> inCommon(intersection(target));
611 double ratio = inCommon->area() / this->area();
612 return (ratio);
613 }
614
615
631 GisGeometry *GisGeometry::buffer(const double width,const int quadsegs) const {
632 // If there is no geometry, return a null geometry
633 if ( !isDefined()) {
634 return (new GisGeometry());
635 }
636
637 // Create the buffer around the geom
638 GEOSGeometry *geom = GEOSBuffer(m_geom, width, quadsegs);
639 return (new GisGeometry(geom));
640 }
641
656 if ( !isValid() ) {
657 return (new GisGeometry());
658 }
659
660 GEOSGeometry *geom = GEOSEnvelope(m_geom);
661 return (new GisGeometry(geom));
662 }
663
664
673 if ( !isValid() ) {
674 return (new GisGeometry());
675 }
676
677 GEOSGeometry *geom = GEOSConvexHull(m_geom);
678 return (new GisGeometry(geom));
679 }
680
681
695 GisGeometry *GisGeometry::simplify(const double &tolerance) const {
696 if ( !isValid() ) {
697 return (0);
698 }
699 GEOSGeometry *geom = GEOSTopologyPreserveSimplify(m_geom, tolerance);
700 if ( 0 == geom ) {
701 return (0);
702 }
703
704 return (new GisGeometry(geom));
705 }
706
707
718 // Non-valid geometries return empty geometries
719 if ( !isValid() ) {
720 return (new GisGeometry());
721 }
722 if ( !target.isValid() ) {
723 return (new GisGeometry());
724 }
725
726 GEOSGeometry *geom = GEOSIntersection(m_geom, target.geometry());
727 return (new GisGeometry(geom));
728 }
729
730
738 if ( !isValid() ) {
739 return (new GisGeometry());
740 }
741 if ( !target.isValid() ) {
742 return (new GisGeometry());
743 }
744
745 GEOSGeometry *geom = GEOSUnion(m_geom, target.geometry());
746 return (new GisGeometry(geom));
747 }
748
749
759 bool GisGeometry::centroid(double &xlongitude, double &ylatitude) const {
760 xlongitude = ylatitude = Null;
761 if ( !isValid() ) {
762 return (false);
763 }
764
765 GEOSGeometry *center = GEOSGetCentroid(m_geom);
766 if ( 0 != center ) {
767 GEOSGeomGetX(center, &xlongitude);
768 GEOSGeomGetY(center, &ylatitude);
770 return (true);
771 }
772
773 return (false);
774 }
775
776
783 if ( !isValid() ) {
784 return (new GisGeometry());
785 }
786
787 GEOSGeometry *center = GEOSGetCentroid(m_geom);
788 return (new GisGeometry(center));
789 }
790
791
798 GEOSPreparedGeometry const *GisGeometry::makePrepared(const GEOSGeometry *geom)
799 const {
800 #if defined(DISABLE_PREPARED_GEOMETRY)
801 return (0);
802 #else
804 return (gis->preparedGeometry(geom));
805 #endif
806 }
807
808
815 GEOSGeometry *GisGeometry::makePoint(const double x, const double y) const {
816
817 GEOSCoordSequence *point = GEOSCoordSeq_create(1, 2);
818 GEOSCoordSeq_setX(point, 0, x);
819 GEOSCoordSeq_setY(point, 0, y);
820
821 return (GEOSGeom_createPoint(point));
822 }
823
824
831 GEOSGeometry *GisGeometry::fromCube(Cube &cube) const {
832 ImagePolygon myGis = cube.readFootprint();
834 QString polyStr = QString::fromStdString(myGis.polyStr());
835 return (gis->geomFromWKT(polyStr));
836 }
837
838
844 gis->destroy(m_geom);
846 m_geom = 0;
847 m_preparedGeom = 0;
848 return;
849 }
850
851} //namespace Isis
IO Handler for Isis Cubes.
Definition Cube.h:168
ImagePolygon readFootprint() const
Read the footprint polygon for the Cube.
Definition Cube.cpp:879
void open(const QString &cfile, QString access="r")
This method will open an existing isis cube for reading or reading/writing.
Definition Cube.cpp:629
GEOSPreparedGeometry const * makePrepared(const GEOSGeometry *geom) const
Creates a prepared geometry of current geometry.
static QString typeToString(const Type &type)
Returns the type of the Geometry as a QString.
virtual ~GisGeometry()
Destructor.
double intersectRatio(const GisGeometry &geom) const
Computes intersect ratio between two geometries.
bool overlaps(const GisGeometry &target) const
Test for overlapping geometries.
GisGeometry * centroid() const
Computes the centroid of the geometry and returns it as a new geometry.
GEOSGeometry * fromCube(Cube &cube) const
Reads Polygon from ISIS Cube and returns geometry from contents.
bool contains(const GisGeometry &target) const
Test if the target geometry is contained within this geometry.
double area() const
Computes the area of a geometry.
Type type() const
Returns the type (origin) of the geometry.
bool equals(const GisGeometry &target) const
Test if target and this geometry are equal.
bool disjoint(const GisGeometry &target) const
Tests for disjoint geometries.
bool intersects(const GisGeometry &target) const
Computes a new geometry from the intersection of the two geomtries.
GisGeometry * convexHull() const
Computes the convex hull of the geometry.
void destroy()
Destroys the GEOS elements of this geometry object.
GisGeometry * g_union(const GisGeometry &geom) const
Computes the union of two geometries.
Type
Source type of the geometry.
Definition GisGeometry.h:61
@ IsisCube
An ISIS Cube is used to create the geometry.
Definition GisGeometry.h:65
@ GeosGis
GEOS GIS. A geometry object cannot be created with this geometry type.
Definition GisGeometry.h:66
@ None
No geometry. A geometry object cannot be created with this geometry type.
Definition GisGeometry.h:62
@ WKB
The GEOS library WKB reader is used to create the geometry.
Definition GisGeometry.h:64
@ WKT
The GEOS library WKT reader is used to create the geometry.
Definition GisGeometry.h:63
GisGeometry * clone() const
Clones the contents of this geometry to a new instance.
const GEOSGeometry * geometry() const
Returns the GEOSGeometry object to extend functionality.
GisGeometry & operator=(GisGeometry const &geom)
Assignment operator for GISGeomtries.
double distance(const GisGeometry &target) const
Computes the distance between two geometries.
double length() const
Computes the length of a geometry.
GEOSGeometry * m_geom
Pointer to GEOS-C opaque structure.
bool isValid() const
Determines validity of the geometry contained in this object.
const GEOSPreparedGeometry * preparedGeometry() const
Returns special GEOS prepared geometry if it exists.
void setGeometry(GEOSGeometry *geom)
Set the geometry directly taking ownership.
GisGeometry * envelope() const
Computes the envelope or bounding box of this geometry.
GEOSPreparedGeometry const * m_preparedGeom
A prepared geometry from the GEOS library.
GisGeometry * buffer(const double width=0.0, const int quadsegs=16) const
Compute a buffer around an existing geometry.
int points() const
Get number of points in geometry.
GisGeometry * simplify(const double &tolerance) const
Simplify complex or overdetermined geoemtry.
bool isDefined() const
Determines if the current geometry is valid.
bool isEmpty() const
Tests for a defined but empty geometry.
Type m_type
Geometry type of GIS source.
GisGeometry * intersection(const GisGeometry &geom) const
Computes the intersection of two geometries.
QString isValidReason() const
Returns a string describing reason for invalid geometry.
GEOSGeometry * makePoint(const double x, const double y) const
Create a point geometry.
GisGeometry()
Fundamental constructor of an empty object.
This class models GIS topology.
Definition GisTopology.h:34
static GisTopology * instance()
Gets the singleton instance of this class.
GEOSGeometry * geomFromWKT(const QString &wkt)
Reads in the geometry from the given well-known text formatted string.
void destroy(GEOSGeometry *geom) const
Destroys the given GEOS geometry.
GEOSGeometry * clone(const GEOSGeometry *geom) const
Clones the given GEOSGeometry pointer.
const GEOSPreparedGeometry * preparedGeometry(const GEOSGeometry *geom) const
Gets a GEOSPreparedGeometry from the given GEOSGeometry.
GEOSGeometry * geomFromWKB(const QString &wkb)
Reads in the geometry from the given well-known binary formatted string.
Isis exception class.
Definition IException.h:91
@ Programmer
This error is for when a programmer made an API call that was illegal.
Definition IException.h:146
Create cube polygons, read/write polygons to blobs.
std::string polyStr() const
Return a geos Multipolygon.
This is free and unencumbered software released into the public domain.
Definition Apollo.h:16
const double Null
Value for an Isis Null pixel.
Namespace for the standard library.