38 unsigned int height) {
41 m_extendGrid = extendGrid;
50 p_gridSize = (
unsigned long)(ceil(width * height / 8.0) + 0.5);
53 p_grid =
new char[p_gridSize];
56 p_latLinesGrid =
new char[p_gridSize];
57 p_lonLinesGrid =
new char[p_gridSize];
60 for (
unsigned long i = 0; i < p_gridSize; i++) {
61 if (p_grid) p_grid[i] = 0;
62 if (p_latLinesGrid) p_latLinesGrid[i] = 0;
63 if (p_lonLinesGrid) p_lonLinesGrid[i] = 0;
67 p_reinitialize =
false;
80 if (p_groundMap->Camera()) {
82 p_groundMap->Camera()->BasicMapping(tmp);
86 *p_mapping = p_groundMap->Projection()->Mapping();
94 if (p_mapping->hasKeyword(
"MinimumLatitude")) {
98 Latitude::AllowPastPole);
104 if (p_mapping->hasKeyword(
"MaximumLatitude")) {
113 if (p_mapping->hasKeyword(
"MinimumLongitude")) {
122 if (p_mapping->hasKeyword(
"MaximumLongitude")) {
131 if (p_minLon->isValid() && p_maxLon->isValid()) {
132 if (*p_minLon > *p_maxLon) {
134 *p_minLon = *p_maxLon;
139 Distance largerRadius = max(radius1, radius2);
143 if (p_groundMap->HasCamera()) {
144 p_defaultResolution =
145 (p_groundMap->Camera()->HighestImageResolution() /
146 largerRadius.
meters()) * 10;
149 p_defaultResolution = (p_groundMap->Resolution() /
150 largerRadius.
meters()) * 10;
153 if (p_defaultResolution < 0) {
154 p_defaultResolution = 10.0 / largerRadius.
meters();
161 GroundGrid::~GroundGrid() {
192 if (p_latLinesGrid) {
193 delete[] p_latLinesGrid;
194 p_latLinesGrid = NULL;
197 if (p_lonLinesGrid) {
198 delete[] p_lonLinesGrid;
199 p_lonLinesGrid = NULL;
217 CreateGrid(baseLat, baseLon, latInc, lonInc, progress,
Angle(),
Angle());
240 if (p_groundMap == NULL ||
241 (p_grid == NULL && p_latLinesGrid == NULL && p_lonLinesGrid == NULL)) {
242 IString msg =
"GroundGrid::CreateGrid missing ground map or grid array";
246 if (p_reinitialize) {
247 for (
unsigned long i = 0; i < p_gridSize; i++) {
248 if (p_grid) p_grid[i] = 0;
249 if (p_latLinesGrid) p_latLinesGrid[i] = 0;
250 if (p_lonLinesGrid) p_lonLinesGrid[i] = 0;
255 bool badLatLonRange =
false;
257 if (!p_minLat || !p_minLat->isValid()) {
258 badLatLonValues.append(
"MinimumLatitude");
259 badLatLonRange =
true;
262 if (!p_maxLat || !p_maxLat->isValid()) {
263 badLatLonValues.append(
"MaximumLatitude");
264 badLatLonRange =
true;
267 if (!p_minLon || !p_minLon->isValid()) {
268 badLatLonValues.append(
"MinimumLongitude");
269 badLatLonRange =
true;
272 if (!p_maxLon || !p_maxLon->isValid()) {
273 badLatLonValues.append(
"MaximumLongitude");
274 badLatLonRange =
true;
278 if (badLatLonRange) {
279 IString msg =
"Could not determine values for [";
280 for (
int i = 0; i < badLatLonValues.size(); i++) {
284 msg += badLatLonValues[i];
287 msg +=
"], please specify them explicitly";
295 p_reinitialize =
true;
300 Latitude::AllowPastPole);
304 if (!latRes.
isValid() || latRes <=
Angle(0, Angle::Degrees)) {
305 latRes =
Angle(p_defaultResolution,
309 if (!lonRes.
isValid() || lonRes <=
Angle(0, Angle::Degrees)) {
310 lonRes =
Angle(p_defaultResolution,
314 Latitude endLat =
Latitude((
long)((*p_maxLat - startLat) / latInc) * latInc + startLat,
317 (long)((*p_maxLon - startLon) / lonInc) * lonInc + startLon;
320 double numSteps = (double)((endLat - startLat) / latInc) + 1;
321 numSteps += (double)((endLon - startLon) / lonInc) + 1;
324 IString msg =
"No gridlines would intersect the image";
336 for (; latStep <= endLat + latInc / 2; latStep += latInc) {
337 unsigned int previousX = 0;
338 unsigned int previousY = 0;
339 bool havePrevious =
false;
341 for (
Longitude lon = *p_minLon; lon <= *p_maxLon; lon += latRes) {
344 bool valid = GetXY(latStep, lon, x, y);
346 if (valid && havePrevious) {
347 if (previousX != x || previousY != y) {
348 DrawLineOnGrid(previousX, previousY, x, y,
true);
352 havePrevious = valid;
362 for (
Longitude lon = startLon; lon <= endLon + lonInc / 2; lon += lonInc) {
363 unsigned int previousX = 0;
364 unsigned int previousY = 0;
365 bool havePrevious =
false;
371 for (; latStep <= *p_maxLat; latStep += lonRes) {
375 bool valid = GetXY(latStep, lon, x, y);
377 if (valid && havePrevious) {
378 if (previousX == x && previousY == y) {
382 DrawLineOnGrid(previousX, previousY, x, y,
false);
385 havePrevious = valid;
407 if (minLat.
isValid()) *p_minLat = minLat;
408 if (maxLat.
isValid()) *p_maxLat = maxLat;
409 if (minLon.
isValid()) *p_minLon = minLon;
410 if (maxLon.
isValid()) *p_maxLon = maxLon;
412 if (p_minLat->isValid() && p_maxLat->isValid() && *p_minLat > *p_maxLat) {
414 *p_minLat = *p_maxLat;
418 if (p_minLon->isValid() && p_maxLon->isValid() && *p_minLon > *p_maxLon) {
420 *p_minLon = *p_maxLon;
428 void GroundGrid::WalkBoundary() {
429 Angle latRes =
Angle(p_defaultResolution, Angle::Degrees);
430 Angle lonRes =
Angle(p_defaultResolution, Angle::Degrees);
442 for (; latStep <= maxLat; latStep += (maxLat - minLat)) {
443 unsigned int previousX = 0;
444 unsigned int previousY = 0;
445 bool havePrevious =
false;
447 for (
Longitude lon = minLon; lon <= maxLon; lon += latRes) {
450 bool valid = GetXY(latStep, lon, x, y);
452 if (valid && havePrevious) {
453 if (previousX != x || previousY != y) {
454 DrawLineOnGrid(previousX, previousY, x, y,
true);
458 havePrevious = valid;
465 for (
Longitude lon = minLon; lon <= maxLon; lon += (maxLon - minLon)) {
466 unsigned int previousX = 0;
467 unsigned int previousY = 0;
468 bool havePrevious =
false;
474 for (; latStep <= maxLat; latStep += lonRes) {
477 bool valid = GetXY(latStep, lon, x, y);
479 if (valid && havePrevious) {
480 if (previousX != x || previousY != y) {
481 DrawLineOnGrid(previousX, previousY, x, y,
false);
485 havePrevious = valid;
504 bool GroundGrid::PixelOnGrid(
int x,
int y,
bool latGrid) {
505 if (x < 0)
return false;
506 if (y < 0)
return false;
508 if (x >= (
int)p_width)
return false;
509 if (y >= (
int)p_height)
return false;
511 return GetGridBit(x, y, latGrid);
523 bool GroundGrid::PixelOnGrid(
int x,
int y) {
524 if (x < 0)
return false;
525 if (y < 0)
return false;
527 if (x >= (
int)p_width)
return false;
528 if (y >= (
int)p_height)
return false;
530 return GetGridBit(x, y,
true);
613 unsigned int &x,
unsigned int &y) {
614 if (!GroundMap())
return false;
616 if (!GroundMap()->SetUnboundGround(lat, lon))
return false;
619 if (!GroundMap()->SetGround(lat, lon))
return false;
621 if (p_groundMap->Sample() < 0.5 || p_groundMap->Line() < 0.5)
return false;
622 if (p_groundMap->Sample() < 0.5 || p_groundMap->Line() < 0.5)
return false;
624 x = (int)(p_groundMap->Sample() - 0.5);
625 y = (int)(p_groundMap->Line() - 0.5);
627 if (x >= p_width || y >= p_height)
return false;
649 void GroundGrid::SetGridBit(
unsigned int x,
unsigned int y,
bool latGrid) {
650 unsigned long bitPosition = (y * p_width) + x;
651 unsigned long byteContainer = bitPosition / 8;
652 unsigned int bitOffset = bitPosition % 8;
654 if (byteContainer > p_gridSize)
return;
657 char &importantByte = p_grid[byteContainer];
658 importantByte |= (1 << bitOffset);
660 else if (latGrid && p_latLinesGrid) {
661 char &importantByte = p_latLinesGrid[byteContainer];
662 importantByte |= (1 << bitOffset);
664 else if (!latGrid && p_lonLinesGrid) {
665 char &importantByte = p_lonLinesGrid[byteContainer];
666 importantByte |= (1 << bitOffset);
669 IString msg =
"GroundGrid::SetGridBit no grids available";
685 bool GroundGrid::GetGridBit(
unsigned int x,
unsigned int y,
bool latGrid) {
686 unsigned long bitPosition = (y * p_width) + x;
687 unsigned long byteContainer = bitPosition / 8;
688 unsigned int bitOffset = bitPosition % 8;
690 if (byteContainer > p_gridSize)
return false;
695 char &importantByte = p_grid[byteContainer];
696 result = (importantByte >> bitOffset) & 1;
698 else if (latGrid && p_latLinesGrid) {
699 char &importantByte = p_latLinesGrid[byteContainer];
700 result = (importantByte >> bitOffset) & 1;
702 else if (!latGrid && p_lonLinesGrid) {
703 char &importantByte = p_lonLinesGrid[byteContainer];
704 result = (importantByte >> bitOffset) & 1;
707 IString msg =
"GroundGrid::GetGridBit no grids available";
724 void GroundGrid::DrawLineOnGrid(
unsigned int x1,
unsigned int y1,
725 unsigned int x2,
unsigned int y2,
730 SetGridBit(x1, y1, isLatLine);
733 double m = (double)dy / (
double)dx;
734 double b = y1 - m * x1;
736 dx = (x2 > x1) ? 1 : -1;
739 y1 = (int)(m * x1 + b + 0.5);
740 SetGridBit(x1, y1, isLatLine);
void setErrorChecking(ErrorChecking errors)
Set the error checking status.
double meters() const
Get the distance in meters.
void SetMaximumSteps(const int steps)
This sets the maximum number of steps in the process.
PvlGroupIterator findGroup(const QString &name, PvlGroupIterator beg, PvlGroupIterator end)
Find a group with the specified name, within these indexes.
Namespace for the standard library.
This class is designed to encapsulate the concept of a Latitude.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
double toDouble(const QString &string)
Global function to convert from a string to a double.
Distance measurement, usually in meters.
void CheckStatus()
Checks and updates the status.
This class is designed to encapsulate the concept of a Longitude.
Program progress reporter.
Contains multiple PvlContainers.
#define _FILEINFO_
Macro for the filename and line number.
Container for cube-like labels.
Defines an angle and provides unit conversions.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.
Adds specific functionality to C++ strings.
Namespace for ISIS/Bullet specific routines.
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.