35 unsigned int height) {
46 p_gridSize = (
unsigned long)(ceil(width * height / 8.0) + 0.5);
49 p_grid =
new char[p_gridSize];
52 p_latLinesGrid =
new char[p_gridSize];
53 p_lonLinesGrid =
new char[p_gridSize];
56 for (
unsigned long i = 0; i < p_gridSize; i++) {
57 if (p_grid) p_grid[i] = 0;
58 if (p_latLinesGrid) p_latLinesGrid[i] = 0;
59 if (p_lonLinesGrid) p_lonLinesGrid[i] = 0;
63 p_reinitialize =
false;
76 if (p_groundMap->Camera()) {
78 p_groundMap->Camera()->BasicMapping(tmp);
82 *p_mapping = p_groundMap->Projection()->Mapping();
90 if (p_mapping->hasKeyword(
"MinimumLatitude")) {
94 Latitude::AllowPastPole);
100 if (p_mapping->hasKeyword(
"MaximumLatitude")) {
109 if (p_mapping->hasKeyword(
"MinimumLongitude")) {
118 if (p_mapping->hasKeyword(
"MaximumLongitude")) {
127 if (p_minLon->isValid() && p_maxLon->isValid()) {
128 if (*p_minLon > *p_maxLon) {
130 *p_minLon = *p_maxLon;
135 Distance largerRadius = max(radius1, radius2);
139 if (p_groundMap->HasCamera()) {
140 p_defaultResolution =
141 (p_groundMap->Camera()->HighestImageResolution() /
142 largerRadius.
meters()) * 10;
145 p_defaultResolution = (p_groundMap->Resolution() /
146 largerRadius.
meters()) * 10;
149 if (p_defaultResolution < 0) {
150 p_defaultResolution = 10.0 / largerRadius.
meters();
157 GroundGrid::~GroundGrid() {
188 if (p_latLinesGrid) {
189 delete[] p_latLinesGrid;
190 p_latLinesGrid = NULL;
193 if (p_lonLinesGrid) {
194 delete[] p_lonLinesGrid;
195 p_lonLinesGrid = NULL;
213 CreateGrid(baseLat, baseLon, latInc, lonInc, progress,
Angle(),
Angle());
236 if (p_groundMap == NULL ||
237 (p_grid == NULL && p_latLinesGrid == NULL && p_lonLinesGrid == NULL)) {
238 IString msg =
"GroundGrid::CreateGrid missing ground map or grid array";
242 if (p_reinitialize) {
243 for (
unsigned long i = 0; i < p_gridSize; i++) {
244 if (p_grid) p_grid[i] = 0;
245 if (p_latLinesGrid) p_latLinesGrid[i] = 0;
246 if (p_lonLinesGrid) p_lonLinesGrid[i] = 0;
251 bool badLatLonRange =
false;
253 if (!p_minLat || !p_minLat->isValid()) {
254 badLatLonValues.append(
"MinimumLatitude");
255 badLatLonRange =
true;
258 if (!p_maxLat || !p_maxLat->isValid()) {
259 badLatLonValues.append(
"MaximumLatitude");
260 badLatLonRange =
true;
263 if (!p_minLon || !p_minLon->isValid()) {
264 badLatLonValues.append(
"MinimumLongitude");
265 badLatLonRange =
true;
268 if (!p_maxLon || !p_maxLon->isValid()) {
269 badLatLonValues.append(
"MaximumLongitude");
270 badLatLonRange =
true;
274 if (badLatLonRange) {
275 IString msg =
"Could not determine values for [";
276 for (
int i = 0; i < badLatLonValues.size(); i++) {
280 msg += badLatLonValues[i];
283 msg +=
"], please specify them explicitly";
291 p_reinitialize =
true;
296 Latitude::AllowPastPole);
300 if (!latRes.
isValid() || latRes <=
Angle(0, Angle::Degrees)) {
301 latRes =
Angle(p_defaultResolution,
305 if (!lonRes.
isValid() || lonRes <=
Angle(0, Angle::Degrees)) {
306 lonRes =
Angle(p_defaultResolution,
310 Latitude endLat =
Latitude((
long)((*p_maxLat - startLat) / latInc) * latInc + startLat,
313 (long)((*p_maxLon - startLon) / lonInc) * lonInc + startLon;
316 double numSteps = (double)((endLat - startLat) / latInc) + 1;
317 numSteps += (double)((endLon - startLon) / lonInc) + 1;
320 IString msg =
"No gridlines would intersect the image";
328 for (
Latitude lat = startLat; lat <= endLat + latInc / 2; lat += latInc) {
329 unsigned int previousX = 0;
330 unsigned int previousY = 0;
331 bool havePrevious =
false;
333 for (
Longitude lon = *p_minLon; lon <= *p_maxLon; lon += latRes) {
336 bool valid = GetXY(lat, lon, x, y);
338 if (valid && havePrevious) {
339 if (previousX != x || previousY != y) {
340 DrawLineOnGrid(previousX, previousY, x, y,
true);
344 havePrevious = valid;
354 for (
Longitude lon = startLon; lon <= endLon + lonInc / 2; lon += lonInc) {
355 unsigned int previousX = 0;
356 unsigned int previousY = 0;
357 bool havePrevious =
false;
359 for (
Latitude lat = *p_minLat; lat <= *p_maxLat; lat += lonRes) {
363 bool valid = GetXY(lat, lon, x, y);
365 if (valid && havePrevious) {
366 if (previousX == x && previousY == y) {
370 DrawLineOnGrid(previousX, previousY, x, y,
false);
373 havePrevious = valid;
395 if (minLat.
isValid()) *p_minLat = minLat;
396 if (maxLat.
isValid()) *p_maxLat = maxLat;
397 if (minLon.
isValid()) *p_minLon = minLon;
398 if (maxLon.
isValid()) *p_maxLon = maxLon;
400 if (p_minLat->isValid() && p_maxLat->isValid() && *p_minLat > *p_maxLat) {
402 *p_minLat = *p_maxLat;
406 if (p_minLon->isValid() && p_maxLon->isValid() && *p_minLon > *p_maxLon) {
408 *p_minLon = *p_maxLon;
416 void GroundGrid::WalkBoundary() {
417 Angle latRes =
Angle(p_defaultResolution, Angle::Degrees);
418 Angle lonRes =
Angle(p_defaultResolution, Angle::Degrees);
426 for (
Latitude lat = minLat; lat <= maxLat; lat += (maxLat - minLat)) {
427 unsigned int previousX = 0;
428 unsigned int previousY = 0;
429 bool havePrevious =
false;
431 for (
Longitude lon = minLon; lon <= maxLon; lon += latRes) {
434 bool valid = GetXY(lat, lon, x, y);
436 if (valid && havePrevious) {
437 if (previousX != x || previousY != y) {
438 DrawLineOnGrid(previousX, previousY, x, y,
true);
442 havePrevious = valid;
449 for (
Longitude lon = minLon; lon <= maxLon; lon += (maxLon - minLon)) {
450 unsigned int previousX = 0;
451 unsigned int previousY = 0;
452 bool havePrevious =
false;
454 for (
Latitude lat = minLat; lat <= maxLat; lat += lonRes) {
457 bool valid = GetXY(lat, lon, x, y);
459 if (valid && havePrevious) {
460 if (previousX != x || previousY != y) {
461 DrawLineOnGrid(previousX, previousY, x, y,
false);
465 havePrevious = valid;
484 bool GroundGrid::PixelOnGrid(
int x,
int y,
bool latGrid) {
485 if (x < 0)
return false;
486 if (y < 0)
return false;
488 if (x >= (
int)p_width)
return false;
489 if (y >= (
int)p_height)
return false;
491 return GetGridBit(x, y, latGrid);
503 bool GroundGrid::PixelOnGrid(
int x,
int y) {
504 if (x < 0)
return false;
505 if (y < 0)
return false;
507 if (x >= (
int)p_width)
return false;
508 if (y >= (
int)p_height)
return false;
510 return GetGridBit(x, y,
true);
536 unsigned int &x,
unsigned int &y) {
537 if (!GroundMap())
return false;
538 if (!GroundMap()->SetGround(lat, lon))
return false;
539 if (p_groundMap->Sample() < 0.5 || p_groundMap->Line() < 0.5)
return false;
540 if (p_groundMap->Sample() < 0.5 || p_groundMap->Line() < 0.5)
return false;
542 x = (int)(p_groundMap->Sample() - 0.5);
543 y = (int)(p_groundMap->Line() - 0.5);
545 if (x >= p_width || y >= p_height)
return false;
567 void GroundGrid::SetGridBit(
unsigned int x,
unsigned int y,
bool latGrid) {
568 unsigned long bitPosition = (y * p_width) + x;
569 unsigned long byteContainer = bitPosition / 8;
570 unsigned int bitOffset = bitPosition % 8;
572 if (byteContainer > p_gridSize)
return;
575 char &importantByte = p_grid[byteContainer];
576 importantByte |= (1 << bitOffset);
578 else if (latGrid && p_latLinesGrid) {
579 char &importantByte = p_latLinesGrid[byteContainer];
580 importantByte |= (1 << bitOffset);
582 else if (!latGrid && p_lonLinesGrid) {
583 char &importantByte = p_lonLinesGrid[byteContainer];
584 importantByte |= (1 << bitOffset);
587 IString msg =
"GroundGrid::SetGridBit no grids available";
603 bool GroundGrid::GetGridBit(
unsigned int x,
unsigned int y,
bool latGrid) {
604 unsigned long bitPosition = (y * p_width) + x;
605 unsigned long byteContainer = bitPosition / 8;
606 unsigned int bitOffset = bitPosition % 8;
608 if (byteContainer > p_gridSize)
return false;
613 char &importantByte = p_grid[byteContainer];
614 result = (importantByte >> bitOffset) & 1;
616 else if (latGrid && p_latLinesGrid) {
617 char &importantByte = p_latLinesGrid[byteContainer];
618 result = (importantByte >> bitOffset) & 1;
620 else if (!latGrid && p_lonLinesGrid) {
621 char &importantByte = p_lonLinesGrid[byteContainer];
622 result = (importantByte >> bitOffset) & 1;
625 IString msg =
"GroundGrid::GetGridBit no grids available";
642 void GroundGrid::DrawLineOnGrid(
unsigned int x1,
unsigned int y1,
643 unsigned int x2,
unsigned int y2,
648 SetGridBit(x1, y1, isLatLine);
651 double m = (double)dy / (
double)dx;
652 double b = y1 - m * x1;
654 dx = (x2 > x1) ? 1 : -1;
657 y1 = (int)(m * x1 + b + 0.5);
658 SetGridBit(x1, y1, isLatLine);
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.
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.
double meters() const
Get the distance in meters.
Contains multiple PvlContainers.
#define _FILEINFO_
Macro for the filename and line number.
Container for cube-like labels.
bool isValid() const
This indicates whether we have a legitimate angle stored or are in an unset, or invalid, state.
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.
Unless noted otherwise, the portions of Isis written by the USGS are public domain.