示例#1
0
  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);
  }
示例#2
0
  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);
  }
示例#3
0
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};
}
示例#4
0
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);
}