33 unsigned int width,
unsigned int height) {
44 p_gridSize = (
unsigned long)(ceil(width * height / 8.0) + 0.5);
47 p_grid =
new char[p_gridSize];
50 p_latLinesGrid =
new char[p_gridSize];
51 p_lonLinesGrid =
new char[p_gridSize];
54 for(
unsigned long i = 0; i < p_gridSize; i++) {
55 if(p_grid) p_grid[i] = 0;
56 if(p_latLinesGrid) p_latLinesGrid[i] = 0;
57 if(p_lonLinesGrid) p_lonLinesGrid[i] = 0;
61 p_reinitialize =
false;
74 if(p_groundMap->Camera()) {
76 p_groundMap->Camera()->BasicMapping(tmp);
80 *p_mapping = p_groundMap->Projection()->Mapping();
88 if(p_mapping->hasKeyword(
"MinimumLatitude")) {
90 toDouble((*p_mapping)[
"MinimumLatitude"][0]), *p_mapping,
97 if(p_mapping->hasKeyword(
"MaximumLatitude")) {
99 toDouble((*p_mapping)[
"MaximumLatitude"][0]), *p_mapping,
106 if(p_mapping->hasKeyword(
"MinimumLongitude")) {
108 toDouble((*p_mapping)[
"MinimumLongitude"][0]), *p_mapping,
115 if(p_mapping->hasKeyword(
"MaximumLongitude")) {
117 toDouble((*p_mapping)[
"MaximumLongitude"][0]), *p_mapping,
124 if(p_minLon->isValid() && p_maxLon->isValid()) {
125 if(*p_minLon > *p_maxLon) {
127 *p_minLon = *p_maxLon;
132 Distance largerRadius = max(radius1, radius2);
136 if(p_groundMap->HasCamera()) {
137 p_defaultResolution =
138 (p_groundMap->Camera()->HighestImageResolution() /
139 largerRadius.
meters()) * 10;
142 p_defaultResolution = (p_groundMap->Resolution() /
143 largerRadius.
meters()) * 10;
146 if(p_defaultResolution < 0) {
147 p_defaultResolution = 10.0 / largerRadius.
meters();
154 GroundGrid::~GroundGrid() {
186 delete [] p_latLinesGrid;
187 p_latLinesGrid = NULL;
191 delete [] p_lonLinesGrid;
192 p_lonLinesGrid = NULL;
208 CreateGrid(baseLat, baseLon, latInc, lonInc, progress,
Angle(),
Angle());
228 if(p_groundMap == NULL ||
229 (p_grid == NULL && p_latLinesGrid == NULL && p_lonLinesGrid == NULL)) {
230 IString msg =
"GroundGrid::CreateGrid missing ground map or grid array";
235 for(
unsigned long i = 0; i < p_gridSize; i++) {
236 if(p_grid) p_grid[i] = 0;
237 if(p_latLinesGrid) p_latLinesGrid[i] = 0;
238 if(p_lonLinesGrid) p_lonLinesGrid[i] = 0;
243 bool badLatLonRange =
false;
245 if(!p_minLat || !p_minLat->isValid()) {
246 badLatLonValues.append(
"MinimumLatitude");
247 badLatLonRange =
true;
250 if(!p_maxLat || !p_maxLat->isValid()) {
251 badLatLonValues.append(
"MaximumLatitude");
252 badLatLonRange =
true;
255 if(!p_minLon || !p_minLon->isValid()) {
256 badLatLonValues.append(
"MinimumLongitude");
257 badLatLonRange =
true;
260 if(!p_maxLon || !p_maxLon->isValid()) {
261 badLatLonValues.append(
"MaximumLongitude");
262 badLatLonRange =
true;
267 IString msg =
"Could not determine values for [";
268 for(
int i = 0; i < badLatLonValues.size(); i++) {
272 msg += badLatLonValues[i];
275 msg +=
"], please specify them explicitly";
283 p_reinitialize =
true;
287 baseLat -
Angle(floor((baseLat - *p_minLat) / latInc) * latInc),
291 baseLon -
Angle(floor((baseLon - *p_minLon) / lonInc) * lonInc));
293 if(!latRes.
isValid() || latRes <=
Angle(0, Angle::Degrees)) {
294 latRes =
Angle(p_defaultResolution, Angle::Degrees);
297 if(!lonRes.
isValid() || lonRes <=
Angle(0, Angle::Degrees)) {
298 lonRes =
Angle(p_defaultResolution, Angle::Degrees);
302 (
long)((*p_maxLat - startLat) / latInc) * latInc + startLat,
305 (long)((*p_maxLon - startLon) / lonInc) * lonInc + startLon;
308 double numSteps = (double)((endLat - startLat) / latInc) + 1;
309 numSteps += (double)((endLon - startLon) / lonInc) + 1;
312 IString msg =
"No gridlines would intersect the image";
320 for(
Latitude lat = startLat; lat <= endLat + latInc / 2; lat += latInc) {
321 unsigned int previousX = 0;
322 unsigned int previousY = 0;
323 bool havePrevious =
false;
325 for(
Longitude lon = *p_minLon; lon <= *p_maxLon; lon += latRes) {
328 bool valid = GetXY(lat, lon, x, y);
330 if(valid && havePrevious) {
331 if(previousX != x || previousY != y) {
332 DrawLineOnGrid(previousX, previousY, x, y,
true);
336 havePrevious = valid;
346 for(
Longitude lon = startLon; lon <= endLon + lonInc / 2; lon += lonInc) {
347 unsigned int previousX = 0;
348 unsigned int previousY = 0;
349 bool havePrevious =
false;
351 for(
Latitude lat = *p_minLat; lat <= *p_maxLat; lat += lonRes) {
355 bool valid = GetXY(lat, lon, x, y);
357 if(valid && havePrevious) {
358 if(previousX == x && previousY == y) {
362 DrawLineOnGrid(previousX, previousY, x, y,
false);
365 havePrevious = valid;
387 if(minLat.
isValid()) *p_minLat = minLat;
388 if(maxLat.
isValid()) *p_maxLat = maxLat;
389 if(minLon.
isValid()) *p_minLon = minLon;
390 if(maxLon.
isValid()) *p_maxLon = maxLon;
392 if(p_minLat->isValid() && p_maxLat->isValid() && *p_minLat > *p_maxLat) {
394 *p_minLat = *p_maxLat;
398 if(p_minLon->isValid() && p_maxLon->isValid() && *p_minLon > *p_maxLon) {
400 *p_minLon = *p_maxLon;
408 void GroundGrid::WalkBoundary() {
409 Angle latRes =
Angle(p_defaultResolution, Angle::Degrees);
410 Angle lonRes =
Angle(p_defaultResolution, Angle::Degrees);
418 for(
Latitude lat = minLat; lat <= maxLat; lat += (maxLat - minLat)) {
419 unsigned int previousX = 0;
420 unsigned int previousY = 0;
421 bool havePrevious =
false;
423 for(
Longitude lon = minLon; lon <= maxLon; lon += latRes) {
426 bool valid = GetXY(lat, lon, x, y);
428 if(valid && havePrevious) {
429 if(previousX != x || previousY != y) {
430 DrawLineOnGrid(previousX, previousY, x, y,
true);
434 havePrevious = valid;
441 for(
Longitude lon = minLon; lon <= maxLon; lon += (maxLon - minLon)) {
442 unsigned int previousX = 0;
443 unsigned int previousY = 0;
444 bool havePrevious =
false;
446 for(
Latitude lat = minLat; lat <= maxLat; lat += lonRes) {
449 bool valid = GetXY(lat, lon, x, y);
451 if(valid && havePrevious) {
452 if(previousX != x || previousY != y) {
453 DrawLineOnGrid(previousX, previousY, x, y,
false);
457 havePrevious = valid;
476 bool GroundGrid::PixelOnGrid(
int x,
int y,
bool latGrid) {
477 if(x < 0)
return false;
478 if(y < 0)
return false;
480 if(x >= (
int)p_width)
return false;
481 if(y >= (
int)p_height)
return false;
483 return GetGridBit(x, y, latGrid);
495 bool GroundGrid::PixelOnGrid(
int x,
int y) {
496 if(x < 0)
return false;
497 if(y < 0)
return false;
499 if(x >= (
int)p_width)
return false;
500 if(y >= (
int)p_height)
return false;
502 return GetGridBit(x, y,
true);
518 unsigned int &x,
unsigned int &y) {
519 if(!GroundMap())
return false;
520 if(!GroundMap()->SetGround(lat, lon))
return false;
521 if(p_groundMap->Sample() < 0.5 || p_groundMap->Line() < 0.5)
return false;
522 if(p_groundMap->Sample() < 0.5 || p_groundMap->Line() < 0.5)
return false;
524 x = (int)(p_groundMap->Sample() - 0.5);
525 y = (int)(p_groundMap->Line() - 0.5);
527 if(x >= p_width || y >= p_height)
return false;
540 void GroundGrid::SetGridBit(
unsigned int x,
unsigned int y,
bool latGrid) {
541 unsigned long bitPosition = (y * p_width) + x;
542 unsigned long byteContainer = bitPosition / 8;
543 unsigned int bitOffset = bitPosition % 8;
545 if(byteContainer < 0 || byteContainer > p_gridSize)
return;
548 char &importantByte = p_grid[byteContainer];
549 importantByte |= (1 << bitOffset);
551 else if(latGrid && p_latLinesGrid) {
552 char &importantByte = p_latLinesGrid[byteContainer];
553 importantByte |= (1 << bitOffset);
555 else if(!latGrid && p_lonLinesGrid) {
556 char &importantByte = p_lonLinesGrid[byteContainer];
557 importantByte |= (1 << bitOffset);
560 IString msg =
"GroundGrid::SetGridBit no grids available";
576 bool GroundGrid::GetGridBit(
unsigned int x,
unsigned int y,
bool latGrid) {
577 unsigned long bitPosition = (y * p_width) + x;
578 unsigned long byteContainer = bitPosition / 8;
579 unsigned int bitOffset = bitPosition % 8;
581 if(byteContainer < 0 || byteContainer > p_gridSize)
return false;
586 char &importantByte = p_grid[byteContainer];
587 result = (importantByte >> bitOffset) & 1;
589 else if(latGrid && p_latLinesGrid) {
590 char &importantByte = p_latLinesGrid[byteContainer];
591 result = (importantByte >> bitOffset) & 1;
593 else if(!latGrid && p_lonLinesGrid) {
594 char &importantByte = p_lonLinesGrid[byteContainer];
595 result = (importantByte >> bitOffset) & 1;
598 IString msg =
"GroundGrid::GetGridBit no grids available";
615 void GroundGrid::DrawLineOnGrid(
unsigned int x1,
unsigned int y1,
616 unsigned int x2,
unsigned int y2,
621 SetGridBit(x1, y1, isLatLine);
624 double m = (double)dy / (
double)dx;
625 double b = y1 - m * x1;
627 dx = (x2 > x1) ? 1 : -1;
630 y1 = (int)(m * x1 + b + 0.5);
631 SetGridBit(x1, y1, isLatLine);