14#include "IException.h"
15#include "PolygonTools.h"
18#include "GridPolygonSeeder.h"
61 return SeedGrid(lonLatPoly);
68 std::vector<geos::geom::Point *> GridPolygonSeeder::SeedGrid(
const geos::geom::MultiPolygon *multiPoly) {
71 std::vector<geos::geom::Point *> points;
74 const geos::geom::Envelope *mPolyBoundBox = multiPoly->getEnvelopeInternal();
85 for(
unsigned int i = 0; i < multiPoly->getNumGeometries(); ++i) {
86 const geos::geom::Polygon *poly = multiPoly->getGeometryN(i);
89 geos::geom::Point *centroid = poly->getCentroid().release();
90 double centerX = centroid->getX();
91 double centerY = centroid->getY();
93 const geos::geom::Envelope *polyBoundBox = poly->getEnvelopeInternal();
95 int xStepsLeft = (int)((centerX - polyBoundBox->getMinX()) / p_Xspacing + 0.5);
96 int yStepsLeft = (int)((centerY - polyBoundBox->getMinY()) / p_Yspacing + 0.5);
97 double dRealMinX = centerX - (xStepsLeft * p_Xspacing);
98 double dRealMinY = centerY - (yStepsLeft * p_Yspacing);
100 for(
double y = dRealMinY; y <= polyBoundBox->getMaxY(); y += p_Yspacing) {
101 for(
double x = dRealMinX; x <= polyBoundBox->getMaxX(); x += p_Xspacing) {
102 geos::geom::Coordinate c(x, y);
103 geos::geom::Point *p = Isis::globalFactory->createPoint(c).release();
105 if(p->within(multiPoly)) {
106 points.push_back(Isis::globalFactory->createPoint(c).release());
129 std::vector<geos::geom::Point *> points;
133 const geos::geom::Envelope *mPolyBoundBox = multiPoly->getEnvelopeInternal();
141 for(
unsigned int i = 0; i < multiPoly->getNumGeometries(); ++i) {
142 const geos::geom::Polygon *poly = multiPoly->getGeometryN(i);
143 geos::geom::Point *centroid = poly->getCentroid().release();
144 double centerX = centroid->getX();
145 double centerY = centroid->getY();
148 const geos::geom::Envelope *polyBoundBox = poly->getEnvelopeInternal();
162 pointShouldSubGridCheck,
170 int xSteps = (int)((polyBoundBox->getMaxX() - polyBoundBox->getMinX()) / p_Xspacing + 1.5);
171 int ySteps = (int)((polyBoundBox->getMaxY() - polyBoundBox->getMinY()) / p_Yspacing + 1.5);
172 PointStatus pointCheck[xSteps][ySteps];
175 for(
int y = 0; y < ySteps; y++) {
176 for(
int x = 0; x < xSteps; x++) {
177 pointCheck[x][y] = pointShouldCheck;
190 bool bGridCleared =
true;
191 int xStepsToCentroid = (int)((centerX - polyBoundBox->getMinX()) / p_Xspacing + 0.5);
192 int yStepsToCentroid = (int)((centerY - polyBoundBox->getMinY()) / p_Yspacing + 0.5);
193 double dRealMinX = centerX - (xStepsToCentroid * p_Xspacing);
194 double dRealMinY = centerY - (yStepsToCentroid * p_Yspacing);
201 for(
int y = 0; y < ySteps; y++) {
202 double centerY = dRealMinY + p_Yspacing * y;
203 for(
int x = 0; x < xSteps; x++) {
204 double centerX = dRealMinX + p_Xspacing * x;
205 geos::geom::Point *p = NULL;
209 if(pointCheck[x][y] == pointShouldCheck) {
214 else if(pointCheck[x][y] == pointShouldSubGridCheck) {
231 points.push_back(Isis::globalFactory->createPoint(
232 geos::geom::Coordinate(p->getX(), p->getY())).release());
235 bGridCleared =
false;
236 pointCheck[x][y] = pointFound;
239 if(pointCheck[x][y] == pointShouldCheck) {
240 pointCheck[x][y] = pointNotFound;
242 else if(pointCheck[x][y] == pointShouldSubGridCheck) {
243 pointCheck[x][y] = pointCantFind;
250 for(
int y = 0; y < ySteps; y++) {
251 for(
int x = 0; x < xSteps; x++) {
252 if(pointCheck[x][y] == pointFound) {
253 for(
int yOff = -1; yOff <= 1; yOff++) {
254 for(
int xOff = -1; xOff <= 1; xOff++) {
255 if(x + xOff >= 0 && x + xOff < xSteps &&
256 y + yOff >= 0 && y + yOff < ySteps &&
257 pointCheck[x+xOff][y+yOff] == pointNotFound) {
259 pointCheck[x+xOff][y+yOff] = pointShouldSubGridCheck;
262 bGridCleared =
false;
271 while(!bGridCleared);
299 const double ¢erY,
const int &precision) {
303 for(
int prec = 0; prec < precision && prec < 6; prec ++) {
305 gridSize = gridSize * 2 + 1;
316 GridPoint grid[gridSize][gridSize];
318 for(
int y = 0; y < gridSize; y++) {
319 for(
int x = 0; x < gridSize; x++) {
320 grid[x][y] = gridEmpty;
325 grid[gridSize/2][gridSize/2] = gridCheckPt;
328 for(
int prec = 0; prec < precision; prec ++) {
330 int checkDist = (gridSize + 1) / (
int)(4 * (pow(2.0, prec)) + 0.5);
333 for(
int y = 0; y < gridSize; y++) {
334 for(
int x = 0; x < gridSize; x++) {
335 if(grid[x][y] == gridCheckPt) {
337 if(x - checkDist > 0) grid[x-checkDist][y] = gridNewCheckPt;
338 if(y - checkDist > 0) grid[x][y-checkDist] = gridNewCheckPt;
339 if(x + checkDist < gridSize) grid[x+checkDist][y] = gridNewCheckPt;
340 if(y + checkDist < gridSize) grid[x][y+checkDist] = gridNewCheckPt;
347 for(
int y = 0; y < gridSize; y++) {
348 for(
int x = 0; x < gridSize; x++) {
349 if(grid[x][y] == gridNewCheckPt) grid[x][y] = gridCheckPt;
356 double deltaXSize = p_Xspacing / (gridSize + 1);
357 double deltaYSize = p_Yspacing / (gridSize + 1);
359 geos::geom::Point *result = NULL;
361 for(
int y = 0; !result && y < gridSize; y++) {
362 for(
int x = 0; !result && x < gridSize; x++) {
363 if(grid[x][y] != gridCheckPt)
continue;
365 double xPos = centerX + (x - gridSize / 2) * deltaXSize;
366 double yPos = centerY + (y - gridSize / 2) * deltaYSize;
367 geos::geom::Coordinate c(xPos, yPos);
368 geos::geom::Point *p = Isis::globalFactory->createPoint(c).release();
369 if(p->within(&xyp)) {
370 result = p->clone().release();
392 PvlGroup &algo = pvl.findGroup(
"PolygonSeederAlgorithm", Pvl::Traverse);
393 PvlGroup &invalgo =
invalidInput->findGroup(
"PolygonSeederAlgorithm",
398 if(algo.hasKeyword(
"XSpacing")) {
399 p_Xspacing = (double) algo[
"XSpacing"];
400 if(invalgo.hasKeyword(
"XSpacing")) {
401 invalgo.deleteKeyword(
"XSpacing");
405 QString msg =
"PVL for GridPolygonSeeder must contain [XSpacing] in [";
406 msg += pvl.fileName() +
"]";
407 throw IException(IException::User, msg, _FILEINFO_);
411 if(algo.hasKeyword(
"YSpacing")) {
412 p_Yspacing = (double) algo[
"YSpacing"];
413 if(invalgo.hasKeyword(
"YSpacing")) {
414 invalgo.deleteKeyword(
"YSpacing");
418 QString msg =
"PVL for GridPolygonSeeder must contain [YSpacing] in [";
419 msg += pvl.fileName() +
"]";
420 throw IException(IException::User, msg, _FILEINFO_);
424 if(algo.hasKeyword(
"SubGrid")) {
425 p_subGrid = IString((QString)algo[
"SubGrid"]).UpCase() !=
"FALSE";
426 if(invalgo.hasKeyword(
"SubGrid")) {
427 invalgo.deleteKeyword(
"SubGrid");
431 catch(IException &e) {
432 QString msg =
"Improper format for PolygonSeeder PVL [" + pvl.fileName() +
"]";
433 throw IException(e, IException::User, msg, _FILEINFO_);
436 if(p_Xspacing <= 0.0) {
437 IString msg =
"X Spacing must be greater that 0.0 [(" + IString(p_Xspacing) +
"]";
438 throw IException(IException::User, msg, _FILEINFO_);
440 if(p_Yspacing <= 0.0) {
441 IString msg =
"Y Spacing must be greater that 0.0 [(" + IString(p_Yspacing) +
"]";
442 throw IException(IException::User, msg, _FILEINFO_);
447 PvlGroup pluginInfo(grpName);
452 PvlKeyword xSpac(
"XSpacing",
toString(p_Xspacing));
453 PvlKeyword ySpac(
"YSpacing",
toString(p_Yspacing));
454 PvlKeyword subGrid(
"SubGrid",
toString(p_subGrid));
456 pluginInfo.addKeyword(name);
457 pluginInfo.addKeyword(minThickness);
458 pluginInfo.addKeyword(minArea);
459 pluginInfo.addKeyword(xSpac);
460 pluginInfo.addKeyword(ySpac);
461 pluginInfo.addKeyword(subGrid);
Seed points using a grid.
std::vector< geos::geom::Point * > Seed(const geos::geom::MultiPolygon *mp)
Seed a polygon with points.
virtual void Parse(Pvl &pvl)
Parse the GridPolygonSeeder spicific parameters from the PVL.
virtual PvlGroup PluginParameters(QString grpName)
Plugin parameters.
GridPolygonSeeder(Pvl &pvl)
Construct a GridPolygonSeeder algorithm.
std::vector< geos::geom::Point * > SeedSubGrid(const geos::geom::MultiPolygon *mp)
This method works a lot like SeedGrid, except around the edges of known polygons.
geos::geom::Point * CheckSubGrid(const geos::geom::Polygon &, const double &, const double &, const int &)
This method is used to search for a valid point, on the polygon, within the square whose center is de...
This class is used as the base class for all PolygonSeeder objects.
virtual void Parse(Pvl &pvl)
Initialize parameters in the PolygonSeeder class using a PVL specification.
Pvl * invalidInput
The Pvl passed in by the constructor minus what was used.
QString StandardTests(const geos::geom::MultiPolygon *multiPoly, const geos::geom::Envelope *polyBoundBox)
Check the polygon to see if it meets standard criteria.
PolygonSeeder(Pvl &pvl)
Create PolygonSeeder object.
double MinimumArea()
Return the minimum allowed area of the polygon.
double MinimumThickness()
Return the minimum allowed thickness of the polygon.
QString Algorithm() const
The name of the algorithm, read from the Name Keyword in the PolygonSeeder Pvl passed into the constr...
This is free and unencumbered software released into the public domain.
QString toString(const LinearAlgebra::Vector &vector, int precision)
A global function to format LinearAlgebra::Vector as a QString with the given precision.