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 *polyBoundBox = multiPoly->getEnvelopeInternal();
87 geos::geom::Point *centroid = multiPoly->getCentroid().release();
88 double centerX = centroid->getX();
89 double centerY = centroid->getY();
92 int xStepsLeft = (int)((centerX - polyBoundBox->getMinX()) / p_Xspacing + 0.5);
93 int yStepsLeft = (int)((centerY - polyBoundBox->getMinY()) / p_Yspacing + 0.5);
94 double dRealMinX = centerX - (xStepsLeft * p_Xspacing);
95 double dRealMinY = centerY - (yStepsLeft * p_Yspacing);
97 for(
double y = dRealMinY; y <= polyBoundBox->getMaxY(); y += p_Yspacing) {
98 for(
double x = dRealMinX; x <= polyBoundBox->getMaxX(); x += p_Xspacing) {
99 geos::geom::Coordinate c(x, y);
100 geos::geom::Point *p = Isis::globalFactory->createPoint(c).release();
102 if(p->within(multiPoly)) {
103 points.push_back(Isis::globalFactory->createPoint(c).release());
127 std::vector<geos::geom::Point *> points;
131 const geos::geom::Envelope *polyBoundBox = multiPoly->getEnvelopeInternal();
139 geos::geom::Point *centroid = multiPoly->getCentroid().release();
140 double centerX = centroid->getX();
141 double centerY = centroid->getY();
157 pointShouldSubGridCheck,
165 int xSteps = (int)((polyBoundBox->getMaxX() - polyBoundBox->getMinX()) / p_Xspacing + 1.5);
166 int ySteps = (int)((polyBoundBox->getMaxY() - polyBoundBox->getMinY()) / p_Yspacing + 1.5);
167 PointStatus pointCheck[xSteps][ySteps];
170 for(
int y = 0; y < ySteps; y++) {
171 for(
int x = 0; x < xSteps; x++) {
172 pointCheck[x][y] = pointShouldCheck;
185 bool bGridCleared =
true;
186 int xStepsToCentroid = (int)((centerX - polyBoundBox->getMinX()) / p_Xspacing + 0.5);
187 int yStepsToCentroid = (int)((centerY - polyBoundBox->getMinY()) / p_Yspacing + 0.5);
188 double dRealMinX = centerX - (xStepsToCentroid * p_Xspacing);
189 double dRealMinY = centerY - (yStepsToCentroid * p_Yspacing);
196 for(
int y = 0; y < ySteps; y++) {
197 double centerY = dRealMinY + p_Yspacing * y;
198 for(
int x = 0; x < xSteps; x++) {
199 double centerX = dRealMinX + p_Xspacing * x;
200 geos::geom::Point *p = NULL;
204 if(pointCheck[x][y] == pointShouldCheck) {
209 else if(pointCheck[x][y] == pointShouldSubGridCheck) {
210 p =
CheckSubGrid(*multiPoly, centerX, centerY, precision);
226 points.push_back(Isis::globalFactory->createPoint(
227 geos::geom::Coordinate(p->getX(), p->getY())).release());
230 bGridCleared =
false;
231 pointCheck[x][y] = pointFound;
234 if(pointCheck[x][y] == pointShouldCheck) {
235 pointCheck[x][y] = pointNotFound;
237 else if(pointCheck[x][y] == pointShouldSubGridCheck) {
238 pointCheck[x][y] = pointCantFind;
245 for(
int y = 0; y < ySteps; y++) {
246 for(
int x = 0; x < xSteps; x++) {
247 if(pointCheck[x][y] == pointFound) {
248 for(
int yOff = -1; yOff <= 1; yOff++) {
249 for(
int xOff = -1; xOff <= 1; xOff++) {
250 if(x + xOff >= 0 && x + xOff < xSteps &&
251 y + yOff >= 0 && y + yOff < ySteps &&
252 pointCheck[x+xOff][y+yOff] == pointNotFound) {
254 pointCheck[x+xOff][y+yOff] = pointShouldSubGridCheck;
257 bGridCleared =
false;
266 while(!bGridCleared);
293 const double ¢erY,
const int &precision) {
297 for(
int prec = 0; prec < precision && prec < 6; prec ++) {
299 gridSize = gridSize * 2 + 1;
310 GridPoint grid[gridSize][gridSize];
312 for(
int y = 0; y < gridSize; y++) {
313 for(
int x = 0; x < gridSize; x++) {
314 grid[x][y] = gridEmpty;
319 grid[gridSize/2][gridSize/2] = gridCheckPt;
322 for(
int prec = 0; prec < precision; prec ++) {
324 int checkDist = (gridSize + 1) / (
int)(4 * (pow(2.0, prec)) + 0.5);
327 for(
int y = 0; y < gridSize; y++) {
328 for(
int x = 0; x < gridSize; x++) {
329 if(grid[x][y] == gridCheckPt) {
331 if(x - checkDist > 0) grid[x-checkDist][y] = gridNewCheckPt;
332 if(y - checkDist > 0) grid[x][y-checkDist] = gridNewCheckPt;
333 if(x + checkDist < gridSize) grid[x+checkDist][y] = gridNewCheckPt;
334 if(y + checkDist < gridSize) grid[x][y+checkDist] = gridNewCheckPt;
341 for(
int y = 0; y < gridSize; y++) {
342 for(
int x = 0; x < gridSize; x++) {
343 if(grid[x][y] == gridNewCheckPt) grid[x][y] = gridCheckPt;
350 double deltaXSize = p_Xspacing / (gridSize + 1);
351 double deltaYSize = p_Yspacing / (gridSize + 1);
353 geos::geom::Point *result = NULL;
355 for(
int y = 0; !result && y < gridSize; y++) {
356 for(
int x = 0; !result && x < gridSize; x++) {
357 if(grid[x][y] != gridCheckPt)
continue;
359 double xPos = centerX + (x - gridSize / 2) * deltaXSize;
360 double yPos = centerY + (y - gridSize / 2) * deltaYSize;
361 geos::geom::Coordinate c(xPos, yPos);
362 geos::geom::Point *p = Isis::globalFactory->createPoint(c).release();
363 if(p->within(&xymp)) {
364 result = p->clone().release();
394 if(algo.hasKeyword(
"XSpacing")) {
395 p_Xspacing = (double) algo[
"XSpacing"];
396 if(invalgo.hasKeyword(
"XSpacing")) {
397 invalgo.deleteKeyword(
"XSpacing");
401 QString msg =
"PVL for GridPolygonSeeder must contain [XSpacing] in [";
402 msg += pvl.fileName() +
"]";
407 if(algo.hasKeyword(
"YSpacing")) {
408 p_Yspacing = (double) algo[
"YSpacing"];
409 if(invalgo.hasKeyword(
"YSpacing")) {
410 invalgo.deleteKeyword(
"YSpacing");
414 QString msg =
"PVL for GridPolygonSeeder must contain [YSpacing] in [";
415 msg += pvl.fileName() +
"]";
420 if(algo.hasKeyword(
"SubGrid")) {
421 p_subGrid =
IString((QString)algo[
"SubGrid"]).
UpCase() !=
"FALSE";
422 if(invalgo.hasKeyword(
"SubGrid")) {
423 invalgo.deleteKeyword(
"SubGrid");
428 QString msg =
"Improper format for PolygonSeeder PVL [" + pvl.fileName() +
"]";
432 if(p_Xspacing <= 0.0) {
433 IString msg =
"X Spacing must be greater that 0.0 [(" +
IString(p_Xspacing) +
"]";
436 if(p_Yspacing <= 0.0) {
437 IString msg =
"Y Spacing must be greater that 0.0 [(" +
IString(p_Yspacing) +
"]";
452 pluginInfo.addKeyword(name);
453 pluginInfo.addKeyword(minThickness);
454 pluginInfo.addKeyword(minArea);
455 pluginInfo.addKeyword(xSpac);
456 pluginInfo.addKeyword(ySpac);
457 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::MultiPolygon &, 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...
@ User
A type of error that could only have occurred due to a mistake on the user's part (e....
Adds specific functionality to C++ strings.
IString UpCase()
Converst any lower case characters in the object IString with uppercase characters.
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.
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...
Contains multiple PvlContainers.
Container for cube-like labels.
A single keyword-value pair.
@ Traverse
Search child objects.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
This is free and unencumbered software released into the public domain.
QString toString(bool boolToConvert)
Global function to convert a boolean to a string.