Isis 3 Programmer Reference
LimitPolygonSeeder.cpp
1 
6 /* SPDX-License-Identifier: CC0-1.0 */
7 
8 #include <string>
9 #include <vector>
10 #include <cmath>
11 #include <iomanip>
12 
13 #include <geos/util/TopologyException.h>
14 
15 #include "IException.h"
16 #include "LimitPolygonSeeder.h"
17 #include "PolygonTools.h"
18 #include "Pvl.h"
19 #include "PvlGroup.h"
20 
21 namespace Isis {
22 
31  Parse(pvl);
32  };
33 
34 
47  std::vector<geos::geom::Point *> LimitPolygonSeeder::Seed(const geos::geom::MultiPolygon *multiPoly) {
48 
49  // Storage for the points to be returned
50  std::vector<geos::geom::Point *> points;
51 
52  // Create some things we will need shortly
53  const geos::geom::Envelope *polyBoundBox = multiPoly->getEnvelopeInternal();
54 
55  // Call the parents standardTests member
56  QString msg = StandardTests(multiPoly, polyBoundBox);
57  if(!msg.isEmpty()) {
58  return points;
59  }
60 
61  // Do limit seeder specific tests to make sure this poly should be seeded
62  // (none for now)
63 
64  int xSteps = 0;
65  int ySteps = 0;
66 
67  // Test if X is major axis
68  if(fabs(polyBoundBox->getMaxX() - polyBoundBox->getMinX()) > fabs((polyBoundBox->getMaxY() - polyBoundBox->getMinY()))) {
69  xSteps = p_majorAxisPts;
70  ySteps = p_minorAxisPts;
71  }
72  else {
73  xSteps = p_minorAxisPts;
74  ySteps = p_majorAxisPts;
75  }
76 
77  double xSpacing = (polyBoundBox->getMaxX() - polyBoundBox->getMinX()) / (xSteps);
78  double ySpacing = (polyBoundBox->getMaxY() - polyBoundBox->getMinY()) / (ySteps);
79 
80  double realMinX = polyBoundBox->getMinX() + xSpacing / 2;
81  double realMinY = polyBoundBox->getMinY() + ySpacing / 2;
82  double maxY = polyBoundBox->getMaxY();
83  double maxX = polyBoundBox->getMaxX();
84 
85  for(double y = realMinY; y < maxY; y += ySpacing) {
86  for(double x = realMinX; x < maxX; x += xSpacing) {
87  geos::geom::Geometry *gridSquarePolygon = GetMultiPolygon(x - xSpacing / 2.0, y - ySpacing / 2,
88  x + xSpacing / 2.0, y + ySpacing / 2, *multiPoly);
89 
90  geos::geom::Point *centroid = gridSquarePolygon->getCentroid();
91 
92  delete gridSquarePolygon;
93  if(centroid == NULL) continue;
94 
95  double gridCenterX = centroid->getX();
96  double gridCenterY = centroid->getY();
97  delete centroid;
98 
99  geos::geom::Coordinate c(gridCenterX, gridCenterY);
100  points.push_back(Isis::globalFactory->createPoint(c));
101  }
102  }
103 
104  return points;
105  }
106 
121  geos::geom::Geometry *LimitPolygonSeeder::GetMultiPolygon(double dMinX, double dMinY,
122  double dMaxX, double dMaxY,
123  const geos::geom::MultiPolygon &orig) {
124  geos::geom::CoordinateSequence *points = new geos::geom::CoordinateArraySequence();
125 
126  points->add(geos::geom::Coordinate(dMinX, dMinY));
127  points->add(geos::geom::Coordinate(dMaxX, dMinY));
128  points->add(geos::geom::Coordinate(dMaxX, dMaxY));
129  points->add(geos::geom::Coordinate(dMinX, dMaxY));
130  points->add(geos::geom::Coordinate(dMinX, dMinY));
131 
132  geos::geom::Polygon *poly = Isis::globalFactory->createPolygon(Isis::globalFactory->createLinearRing(points), NULL);
133  geos::geom::Geometry *overlap = poly->intersection(&orig);
134 
135  return overlap;
136  }
137 
145  // Call the parents Parse method
147 
148  // Pull parameters specific to this algorithm out
149  try {
150  // Get info from Algorithm group
151  PvlGroup &algo = pvl.findGroup("PolygonSeederAlgorithm", Pvl::Traverse);
152  PvlGroup &invalgo = invalidInput->findGroup("PolygonSeederAlgorithm",
153  Pvl::Traverse);
154 
155  // Set the spacing
156  p_majorAxisPts = 0;
157  if(algo.hasKeyword("MajorAxisPoints")) {
158  p_majorAxisPts = (int) algo["MajorAxisPoints"];
159  if(invalgo.hasKeyword("MajorAxisPoints")) {
160  invalgo.deleteKeyword("MajorAxisPoints");
161  }
162  }
163  else {
164  QString msg = "PVL for LimitPolygonSeeder must contain [MajorAxisPoints] in [";
165  msg += pvl.fileName() + "]";
166  throw IException(IException::User, msg, _FILEINFO_);
167  }
168 
169  p_minorAxisPts = 0;
170  if(algo.hasKeyword("MinorAxisPoints")) {
171  p_minorAxisPts = (int) algo["MinorAxisPoints"];
172  if(invalgo.hasKeyword("MinorAxisPoints")) {
173  invalgo.deleteKeyword("MinorAxisPoints");
174  }
175  }
176  else {
177  QString msg = "PVL for LimitPolygonSeeder must contain [MinorAxisPoints] in [";
178  msg += pvl.fileName() + "]";
179  throw IException(IException::User, msg, _FILEINFO_);
180  }
181  }
182  catch(IException &e) {
183  QString msg = "Improper format for PolygonSeeder PVL [" + pvl.fileName() + "]";
184  throw IException(IException::User, msg, _FILEINFO_);
185  }
186 
187  if(p_majorAxisPts < 1.0) {
188  IString msg = "Major axis points must be greater that 0.0 [(" + IString(p_majorAxisPts) + "]";
189  throw IException(IException::User, msg, _FILEINFO_);
190  }
191 
192  if(p_minorAxisPts <= 0.0) {
193  IString msg = "Minor axis points must be greater that 0.0 [(" + IString(p_minorAxisPts) + "]";
194  throw IException(IException::User, msg, _FILEINFO_);
195  }
196  }
197 
199  PvlGroup pluginInfo(grpName);
200 
201  PvlKeyword name("Name", Algorithm());
202  PvlKeyword minThickness("MinimumThickness", toString(MinimumThickness()));
203  PvlKeyword minArea("MinimumArea", toString(MinimumArea()));
204  PvlKeyword majAxis("MajorAxisPoints", toString(p_majorAxisPts));
205  PvlKeyword minAxis("MinorAxisPoints", toString(p_minorAxisPts));
206 
207  pluginInfo.addKeyword(name);
208  pluginInfo.addKeyword(minThickness);
209  pluginInfo.addKeyword(minArea);
210  pluginInfo.addKeyword(majAxis);
211  pluginInfo.addKeyword(minAxis);
212 
213  return pluginInfo;
214  }
215 
216 }; // End of namespace Isis
217 
218 
230 extern "C" Isis::PolygonSeeder *LimitPolygonSeederPlugin(Isis::Pvl &pvl) {
231  return new Isis::LimitPolygonSeeder(pvl);
232 }
233 
Isis::LimitPolygonSeeder
Seed points using a grid.
Definition: LimitPolygonSeeder.h:47
Isis::PvlObject::findGroup
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Definition: PvlObject.h:129
Isis::LimitPolygonSeeder::Parse
virtual void Parse(Pvl &pvl)
Parse the LimitPolygonSeeder spicific parameters from the PVL.
Definition: LimitPolygonSeeder.cpp:144
Isis::PvlKeyword
A single keyword-value pair.
Definition: PvlKeyword.h:82
Isis::PvlContainer::addKeyword
void addKeyword(const PvlKeyword &keyword, const InsertMode mode=Append)
Add a keyword to the container.
Definition: PvlContainer.cpp:202
Isis::PvlContainer::hasKeyword
bool hasKeyword(const QString &name) const
Check to see if a keyword exists.
Definition: PvlContainer.cpp:159
Isis::Pvl
Container for cube-like labels.
Definition: Pvl.h:119
Isis::PolygonSeeder::MinimumArea
double MinimumArea()
Return the minimum allowed area of the polygon.
Definition: PolygonSeeder.cpp:195
Isis::LimitPolygonSeeder::p_minorAxisPts
int p_minorAxisPts
Number of points to place on minor axis.
Definition: LimitPolygonSeeder.h:66
Isis::LimitPolygonSeeder::PluginParameters
virtual PvlGroup PluginParameters(QString grpName)
Plugin parameters.
Definition: LimitPolygonSeeder.cpp:198
Isis::toString
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.
Definition: IString.cpp:211
Isis::PvlObject::Traverse
@ Traverse
Search child objects.
Definition: PvlObject.h:158
Isis::PolygonSeeder::MinimumThickness
double MinimumThickness()
Return the minimum allowed thickness of the polygon.
Definition: PolygonSeeder.cpp:183
Isis::PvlGroup
Contains multiple PvlContainers.
Definition: PvlGroup.h:41
Isis::PolygonSeeder::invalidInput
Pvl * invalidInput
The Pvl passed in by the constructor minus what was used.
Definition: PolygonSeeder.h:78
Isis::LimitPolygonSeeder::GetMultiPolygon
geos::geom::Geometry * GetMultiPolygon(double dMinX, double dMinY, double dMaxX, double dMaxY, const geos::geom::MultiPolygon &orig)
This method returns the overlap between the x/y range specified and the "orig" polygon.
Definition: LimitPolygonSeeder.cpp:121
Isis::PvlContainer::fileName
QString fileName() const
Returns the filename used to initialise the Pvl object.
Definition: PvlContainer.h:232
Isis::IException
Isis exception class.
Definition: IException.h:91
Isis::PolygonSeeder::Parse
virtual void Parse(Pvl &pvl)
Initialize parameters in the PolygonSeeder class using a PVL specification.
Definition: PolygonSeeder.cpp:85
Isis::LimitPolygonSeeder::Seed
std::vector< geos::geom::Point * > Seed(const geos::geom::MultiPolygon *mp)
Seed a polygon with points.
Definition: LimitPolygonSeeder.cpp:47
Isis::PvlContainer::deleteKeyword
void deleteKeyword(const QString &name)
Remove a specified keyword.
Definition: PvlContainer.cpp:97
Isis::PolygonSeeder::Algorithm
QString Algorithm() const
The name of the algorithm, read from the Name Keyword in the PolygonSeeder Pvl passed into the constr...
Definition: PolygonSeeder.cpp:172
Isis::PolygonSeeder::StandardTests
QString StandardTests(const geos::geom::MultiPolygon *multiPoly, const geos::geom::Envelope *polyBoundBox)
Check the polygon to see if it meets standard criteria.
Definition: PolygonSeeder.cpp:146
Isis::LimitPolygonSeeder::p_majorAxisPts
int p_majorAxisPts
Number of points to place on major axis.
Definition: LimitPolygonSeeder.h:65
Isis::IString
Adds specific functionality to C++ strings.
Definition: IString.h:165
Isis::LimitPolygonSeeder::LimitPolygonSeeder
LimitPolygonSeeder(Pvl &pvl)
Construct a LimitPolygonSeeder algorithm.
Definition: LimitPolygonSeeder.cpp:30
Isis::PolygonSeeder
This class is used as the base class for all PolygonSeeder objects.
Definition: PolygonSeeder.h:47
Isis
This is free and unencumbered software released into the public domain.
Definition: Apollo.h:16
Isis::IException::User
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Definition: IException.h:126