gcc_pure RasterLocation ProjectFine(const GeoPoint &location) const { const unsigned x = AngleToWidth(location.longitude) - left; const unsigned y = top - AngleToHeight(location.latitude); return RasterLocation(x, y); }
gcc_pure RasterLocation project(const GeoPoint &location) const { const unsigned x = ((int)(location.Longitude.value_native() * x_scale)) - left; const unsigned y = top - ((int)(location.Latitude.value_native() * y_scale)); return RasterLocation(x, y); }
SignedRasterLocation RasterTileCache::Intersection(const int x0, const int y0, const int x1, const int y1, const int h_origin, const int slope_fact) const { SignedRasterLocation location(x0, y0); if (!IsInside(location)) // origin is outside overall bounds return {-1, -1}; // line algorithm parameters const int dx = abs(x1-x0); const int dy = abs(y1-y0); int err = dx-dy; const int sx = (x0 < x1)? 1: -1; const int sy = (y0 < y1)? 1: -1; // max number of steps to walk const int max_steps = (dx+dy); // calculate number of fine steps to produce a step on the overview field // step size at selected refinement level const int refine_step = max_steps >> 5; // number of steps for update to the fine map const int step_fine = std::max(1, refine_step); // number of steps for update to the overview map const int step_coarse = std::max(1<< OVERVIEW_BITS, step_fine); // counter for steps to reach next position to be checked on the field. unsigned step_counter = 0; // total counter of fine steps int total_steps = 0; #ifdef DEBUG_TILE printf("# max steps %d\n", max_steps); printf("# step coarse %d\n", step_coarse); printf("# step fine %d\n", step_fine); #endif RasterLocation last_clear_location = location; int last_clear_h = h_origin; while (true) { if (!step_counter) { if (!IsInside(location)) break; const auto field_direct = GetFieldDirect(location.x, location.y); if (field_direct.first.IsInvalid()) break; const int h_terrain = field_direct.first.GetValueOr0(); step_counter = field_direct.second ? step_fine : step_coarse; // calculate height of glide so far const int dh = (total_steps * slope_fact) >> RASTER_SLOPE_FACT; // current aircraft height const int h_int = h_origin - dh; if (h_int < h_terrain) { if (refine_step<3) // can't refine any further return RasterLocation(last_clear_location.x, last_clear_location.y); // refine solution return Intersection(last_clear_location.x, last_clear_location.y, location.x, location.y, last_clear_h, slope_fact); } if (h_int <= 0) break; // reached max range last_clear_location = location; last_clear_h = h_int; } if (total_steps > max_steps) break; const int e2 = 2*err; if (e2 > -dy) { err -= dy; location.x += sx; if (step_counter>0) step_counter--; total_steps++; } if (e2 < dx) { err += dx; location.y += sy; if (step_counter>0) step_counter--; total_steps++; } } // if we reached invalid terrain, assume we can hit MSL return {-1, -1}; }
RasterLocation RasterTileCache::Intersection(int x0, int y0, int x1, int y1, short h_origin, const int slope_fact) const { unsigned _x = (unsigned)x0; unsigned _y = (unsigned)y0; if ((_x >= width) || (_y >= height)) { // origin is outside overall bounds return RasterLocation(_x, _y); } // remember index of active tile, so we dont need to scan each each time // (unless the guess fails) int tile_index = -1; // line algorithm parameters const int dx = abs(x1-x0); const int dy = abs(y1-y0); int err = dx-dy; const int sx = (x0 < x1)? 1: -1; const int sy = (y0 < y1)? 1: -1; // max number of steps to walk const int max_steps = (dx+dy); // calculate number of fine steps to produce a step on the overview field // step size at selected refinement level const int refine_step = max_steps >> 5; // number of steps for update to the fine map const int step_fine = std::max(1, refine_step); // number of steps for update to the overview map const int step_coarse = std::max(1<< OVERVIEW_BITS, step_fine); // counter for steps to reach next position to be checked on the field. unsigned step_counter = 0; // total counter of fine steps int total_steps = 0; #ifdef DEBUG_TILE printf("# max steps %d\n", max_steps); printf("# step coarse %d\n", step_coarse); printf("# step fine %d\n", step_fine); #endif short h_int= h_origin; short h_terrain = 1; unsigned last_clear_x = _x; unsigned last_clear_y = _y; short last_clear_h = h_int; while (h_terrain>=0) { if (!step_counter) { if ((_x >= width) || (_y >= height)) break; // outside bounds h_terrain = GetFieldDirect(_x, _y, tile_index); step_counter = tile_index<0? step_coarse: step_fine; // calculate height of glide so far const short dh = (short)((total_steps*slope_fact)>>RASTER_SLOPE_FACT); // current aircraft height h_int = h_origin-dh; if (h_int < h_terrain) { if (refine_step<3) // can't refine any further return RasterLocation(last_clear_x, last_clear_y); // refine solution return Intersection(last_clear_x, last_clear_y, _x, _y, last_clear_h, slope_fact); } if (h_int <= 0) break; // reached max range last_clear_x = _x; last_clear_y = _y; last_clear_h = h_int; } if (total_steps > max_steps) break; const int e2 = 2*err; if (e2 > -dy) { err -= dy; _x += sx; if (step_counter>0) step_counter--; total_steps++; } if (e2 < dx) { err += dx; _y += sy; if (step_counter>0) step_counter--; total_steps++; } } // if we reached invalid terrain, assume we can hit MSL return RasterLocation(x1, y1); }