USGS

Isis 3.0 Object Programmers' Reference

Home

LimitPolygonSeeder.cpp
Go to the documentation of this file.
1 
24 #include <string>
25 #include <vector>
26 #include <cmath>
27 #include <iomanip>
28 
29 #include "geos/util/TopologyException.h"
30 
31 #include "Pvl.h"
32 #include "PvlGroup.h"
33 #include "IException.h"
34 #include "PolygonTools.h"
35 #include "LimitPolygonSeeder.h"
36 
37 namespace Isis {
38 
47  Parse(pvl);
48  };
49 
50 
63  std::vector<geos::geom::Point *> LimitPolygonSeeder::Seed(const geos::geom::MultiPolygon *multiPoly) {
64 
65  // Storage for the points to be returned
66  std::vector<geos::geom::Point *> points;
67 
68  // Create some things we will need shortly
69  const geos::geom::Envelope *polyBoundBox = multiPoly->getEnvelopeInternal();
70 
71  // Call the parents standardTests member
72  QString msg = StandardTests(multiPoly, polyBoundBox);
73  if(!msg.isEmpty()) {
74  return points;
75  }
76 
77  // Do limit seeder specific tests to make sure this poly should be seeded
78  // (none for now)
79 
80  int xSteps = 0;
81  int ySteps = 0;
82 
83  // Test if X is major axis
84  if(fabs(polyBoundBox->getMaxX() - polyBoundBox->getMinX()) > fabs((polyBoundBox->getMaxY() - polyBoundBox->getMinY()))) {
85  xSteps = p_majorAxisPts;
86  ySteps = p_minorAxisPts;
87  }
88  else {
89  xSteps = p_minorAxisPts;
90  ySteps = p_majorAxisPts;
91  }
92 
93  double xSpacing = (polyBoundBox->getMaxX() - polyBoundBox->getMinX()) / (xSteps);
94  double ySpacing = (polyBoundBox->getMaxY() - polyBoundBox->getMinY()) / (ySteps);
95 
96  double realMinX = polyBoundBox->getMinX() + xSpacing / 2;
97  double realMinY = polyBoundBox->getMinY() + ySpacing / 2;
98  double maxY = polyBoundBox->getMaxY();
99  double maxX = polyBoundBox->getMaxX();
100 
101  for(double y = realMinY; y < maxY; y += ySpacing) {
102  for(double x = realMinX; x < maxX; x += xSpacing) {
103  geos::geom::Geometry *gridSquarePolygon = GetMultiPolygon(x - xSpacing / 2.0, y - ySpacing / 2,
104  x + xSpacing / 2.0, y + ySpacing / 2, *multiPoly);
105 
106  geos::geom::Point *centroid = gridSquarePolygon->getCentroid();
107 
108  delete gridSquarePolygon;
109  if(centroid == NULL) continue;
110 
111  double gridCenterX = centroid->getX();
112  double gridCenterY = centroid->getY();
113  delete centroid;
114 
115  geos::geom::Coordinate c(gridCenterX, gridCenterY);
116  points.push_back(Isis::globalFactory.createPoint(c));
117  }
118  }
119 
120  return points;
121  }
122 
137  geos::geom::Geometry *LimitPolygonSeeder::GetMultiPolygon(double dMinX, double dMinY,
138  double dMaxX, double dMaxY,
139  const geos::geom::MultiPolygon &orig) {
140  geos::geom::CoordinateSequence *points = new geos::geom::CoordinateArraySequence();
141 
142  points->add(geos::geom::Coordinate(dMinX, dMinY));
143  points->add(geos::geom::Coordinate(dMaxX, dMinY));
144  points->add(geos::geom::Coordinate(dMaxX, dMaxY));
145  points->add(geos::geom::Coordinate(dMinX, dMaxY));
146  points->add(geos::geom::Coordinate(dMinX, dMinY));
147 
148  geos::geom::Polygon *poly = Isis::globalFactory.createPolygon(Isis::globalFactory.createLinearRing(points), NULL);
149  geos::geom::Geometry *overlap = poly->intersection(&orig);
150 
151  return overlap;
152  }
153 
161  // Call the parents Parse method
163 
164  // Pull parameters specific to this algorithm out
165  try {
166  // Get info from Algorithm group
167  PvlGroup &algo = pvl.findGroup("PolygonSeederAlgorithm", Pvl::Traverse);
168  PvlGroup &invalgo = invalidInput->findGroup("PolygonSeederAlgorithm",
169  Pvl::Traverse);
170 
171  // Set the spacing
172  p_majorAxisPts = 0;
173  if(algo.hasKeyword("MajorAxisPoints")) {
174  p_majorAxisPts = (int) algo["MajorAxisPoints"];
175  if(invalgo.hasKeyword("MajorAxisPoints")) {
176  invalgo.deleteKeyword("MajorAxisPoints");
177  }
178  }
179  else {
180  QString msg = "PVL for LimitPolygonSeeder must contain [MajorAxisPoints] in [";
181  msg += pvl.fileName() + "]";
183  }
184 
185  p_minorAxisPts = 0;
186  if(algo.hasKeyword("MinorAxisPoints")) {
187  p_minorAxisPts = (int) algo["MinorAxisPoints"];
188  if(invalgo.hasKeyword("MinorAxisPoints")) {
189  invalgo.deleteKeyword("MinorAxisPoints");
190  }
191  }
192  else {
193  QString msg = "PVL for LimitPolygonSeeder must contain [MinorAxisPoints] in [";
194  msg += pvl.fileName() + "]";
196  }
197  }
198  catch(IException &e) {
199  QString msg = "Improper format for PolygonSeeder PVL [" + pvl.fileName() + "]";
201  }
202 
203  if(p_majorAxisPts < 1.0) {
204  IString msg = "Major axis points must be greater that 0.0 [(" + IString(p_majorAxisPts) + "]";
206  }
207 
208  if(p_minorAxisPts <= 0.0) {
209  IString msg = "Minor axis points must be greater that 0.0 [(" + IString(p_minorAxisPts) + "]";
211  }
212  }
213 
215  PvlGroup pluginInfo(grpName);
216 
217  PvlKeyword name("Name", Algorithm());
218  PvlKeyword minThickness("MinimumThickness", toString(MinimumThickness()));
219  PvlKeyword minArea("MinimumArea", toString(MinimumArea()));
220  PvlKeyword majAxis("MajorAxisPoints", toString(p_majorAxisPts));
221  PvlKeyword minAxis("MinorAxisPoints", toString(p_minorAxisPts));
222 
223  pluginInfo.addKeyword(name);
224  pluginInfo.addKeyword(minThickness);
225  pluginInfo.addKeyword(minArea);
226  pluginInfo.addKeyword(majAxis);
227  pluginInfo.addKeyword(minAxis);
228 
229  return pluginInfo;
230  }
231 
232 }; // End of namespace Isis
233 
234 
247  return new Isis::LimitPolygonSeeder(pvl);
248 }
249