CompareProjection::CompareProjection(const WindowProjection &projection)
  :corners(projection),
   latitude_cos(corners.top_left.latitude.fastcosine()),
   max_delta(SimpleSquareDistance(corners.top_left, corners.top_right,
                                  latitude_cos) /
             (projection.GetScreenWidth() * projection.GetScreenWidth()))
{
}
Exemple #2
0
void
RasterRenderer::ScanMap(const RasterMap &map, const WindowProjection &projection)
{
  // Coordinates of the MapWindow center
  unsigned x = projection.GetScreenWidth() / 2;
  unsigned y = projection.GetScreenHeight() / 2;
  // GeoPoint corresponding to the MapWindow center
  GeoPoint center = projection.ScreenToGeo(x, y);
  // GeoPoint "next to" Gmid (depends on terrain resolution)
  GeoPoint neighbor = projection.ScreenToGeo(x + quantisation_pixels,
                                             y + quantisation_pixels);

  // Geographical edge length of pixel in the MapWindow center in meters
  pixel_size = M_SQRT1_2 * center.DistanceS(neighbor);

  // set resolution

  if (pixel_size < 3000) {
    // Data point size of the (terrain) map in meters multiplied by 256
    auto map_pixel_size = map.PixelDistance(center, 1);

    // How many screen pixels does one data point stretch?
    auto q = map_pixel_size / pixel_size;

    /* round down to reduce slope shading artefacts (caused by
       RasterBuffer interpolation) */
    quantisation_effective = std::max(1, (int)q);

    /* disable slope shading when zoomed in very near (not enough
       terrain resolution to make a useful slope calculation) */
    if (quantisation_effective > 25)
      quantisation_effective = 0;

  } else
    /* disable slope shading when zoomed out very far (too tiny) */
    quantisation_effective = 0;

#ifdef ENABLE_OPENGL
  bounds = projection.GetScreenBounds().Scale(1.5);
  bounds.IntersectWith(map.GetBounds());

  height_matrix.Fill(map, bounds,
                     projection.GetScreenWidth() / quantisation_pixels,
                     projection.GetScreenHeight() / quantisation_pixels,
                     true);

  last_quantisation_pixels = quantisation_pixels;
#else
  height_matrix.Fill(map, projection, quantisation_pixels, true);
#endif
}
Exemple #3
0
void
RasterRenderer::ScanMap(const RasterMap &map, const WindowProjection &projection)
{
  // Coordinates of the MapWindow center
  unsigned x = projection.GetScreenWidth() / 2;
  unsigned y = projection.GetScreenHeight() / 2;
  // GeoPoint corresponding to the MapWindow center
  GeoPoint Gmid = projection.ScreenToGeo(x, y);
  // GeoPoint "next to" Gmid (depends on terrain resolution)
  GeoPoint Gneighbor = projection.ScreenToGeo(x + quantisation_pixels,
                                              y + quantisation_pixels);

  // Geographical edge length of pixel in the MapWindow center in meters
  pixel_size = fixed_sqrt_half * Gmid.Distance(Gneighbor);

  // set resolution

  fixed map_pixel_size = map.pixel_distance(Gmid, 1);
  fixed q = map_pixel_size / pixel_size;
  if (pixel_size < fixed(3000)) {
    /* round down to reduce slope shading artefacts (caused by
       RasterBuffer interpolation) */
    quantisation_effective = std::max(1, (int)q);

    if (quantisation_effective > 25)
      /* disable slope shading when zoomed in very near (not enough
         terrain resolution to make a useful slope calculation) */
      quantisation_effective = 0;
  } else
    /* disable slope shading when zoomed out very far (too tiny) */
    quantisation_effective = 0;

  height_matrix.Fill(map, projection, quantisation_pixels, true);
}
Exemple #4
0
/**
 * Draws the terrain to the given canvas
 * @param canvas The drawing canvas
 * @param map_projection The Projection
 * @param sunazimuth Azimuth of the sun (for terrain shading)
 */
void
TerrainRenderer::Draw(Canvas &canvas,
                      const WindowProjection &map_projection,
                      const Angle sunazimuth)
{
    const bool do_water = true;
    const unsigned height_scale = 4;
    const int interp_levels = 2;
    const bool is_terrain = true;
    const bool do_shading = is_terrain && SlopeShading;

    const COLORRAMP *const color_ramp = &terrain_colors[TerrainRamp][0];
    if (color_ramp != last_color_ramp) {
        raster_renderer.ColorTable(color_ramp, do_water,
                                   height_scale, interp_levels);
        last_color_ramp = color_ramp;
    }

    {
        RasterTerrain::Lease map(*terrain);
        raster_renderer.ScanMap(map, map_projection);
    }

    raster_renderer.GenerateImage(is_terrain, do_shading, height_scale,
                                  TerrainContrast, TerrainBrightness,
                                  sunazimuth);

    CopyTo(canvas, map_projection.GetScreenWidth(),
           map_projection.GetScreenHeight());
}
void
TransparentRendererCache::AlphaBlendTo(Canvas &canvas,
                                       const WindowProjection &projection,
                                       uint8_t alpha) const
{
    assert(canvas.IsDefined());
    assert(buffer.IsDefined());
    assert(projection.IsValid());
    assert(compare_projection.IsDefined());
    assert(Check(projection));

    if (empty)
        return;

    const unsigned width = projection.GetScreenWidth(),
                   height = projection.GetScreenHeight();

#ifdef USE_MEMORY_CANVAS
    canvas.AlphaBlendNotWhite(0, 0, width, height,
                              buffer, 0, 0, width, height,
                              alpha);
#else
    canvas.AlphaBlend(0, 0, width, height,
                      buffer, 0, 0, width, height,
                      alpha);
#endif
}
bool
TransparentRendererCache::Check(const WindowProjection &projection) const
{
    assert(projection.IsValid());

    return buffer.IsDefined() &&
           buffer.GetWidth() == projection.GetScreenWidth() &&
           buffer.GetHeight() == projection.GetScreenHeight() &&
           compare_projection.Compare(projection);
}
void
TransparentRendererCache::CopyAndTo(Canvas &canvas,
                                    const WindowProjection &projection) const
{
    if (empty)
        return;

    canvas.CopyAnd(0, 0,
                   projection.GetScreenWidth(), projection.GetScreenHeight(),
                   buffer, 0, 0);
}
Exemple #8
0
void
HeightMatrix::Fill(const RasterMap &map, const WindowProjection &projection,
                   unsigned quantisation_pixels, bool interpolate)
{
  const unsigned screen_width = projection.GetScreenWidth();
  const unsigned screen_height = projection.GetScreenHeight();

  SetSize((screen_width + quantisation_pixels - 1) / quantisation_pixels,
          (screen_height + quantisation_pixels - 1) / quantisation_pixels);

  minimum = 0x7fff;
  maximum = 0;

  for (unsigned y = 0; y < screen_height; y += quantisation_pixels) {
    const FastRowRotation rotation =
      projection.GetScreenAngleRotation(y - projection.GetScreenOrigin().y);

    short *p = data.begin() + y * width / quantisation_pixels;

    for (unsigned x = 0; x < screen_width; x += quantisation_pixels) {
#ifndef SLOW_TERRAIN_STUFF
      const FastRowRotation::Pair r =
        rotation.Rotate(x - projection.GetScreenOrigin().x);

      GeoPoint gp;
       gp.Latitude = projection.GetGeoLocation().Latitude
         - projection.PixelsToAngle(r.second);
       gp.Longitude = projection.GetGeoLocation().Longitude
         + projection.PixelsToAngle(r.first)
        * gp.Latitude.invfastcosine();
#else
      GeoPoint gp = projection.ScreenToGeo(x, y);
#endif

      short h = interpolate ? map.GetFieldInterpolated(gp) : map.GetField(gp);
      if (!RasterBuffer::is_special(h)) {
        if (h < minimum)
          minimum = h;
        if (h > maximum)
          maximum = h;
      }

      *p++ = h;
    }

    assert(p <= data.end());
  }
}
Exemple #9
0
/**
 * Draws the terrain to the given canvas
 * @param canvas The drawing canvas
 * @param map_projection The Projection
 * @param sunazimuth Azimuth of the sun (for terrain shading)
 */
void
TerrainRenderer::Draw(Canvas &canvas,
                      const WindowProjection &map_projection) const
{
#ifdef ENABLE_OPENGL
  const GeoBounds &bounds = raster_renderer.GetBounds();
  assert(bounds.IsValid());

  const RasterPoint vertices[] = {
    map_projection.GeoToScreen(bounds.GetNorthWest()),
    map_projection.GeoToScreen(bounds.GetNorthEast()),
    map_projection.GeoToScreen(bounds.GetSouthWest()),
    map_projection.GeoToScreen(bounds.GetSouthEast()),
  };

  glVertexPointer(2, GL_VALUE, 0, vertices);

  const GLTexture &texture = raster_renderer.BindAndGetTexture();
  const PixelSize allocated = texture.GetAllocatedSize();

  const int src_x = 0, src_y = 0, src_width = raster_renderer.GetWidth(),
    src_height = raster_renderer.GetHeight();

  GLfloat x0 = (GLfloat)src_x / allocated.cx;
  GLfloat y0 = (GLfloat)src_y / allocated.cy;
  GLfloat x1 = (GLfloat)(src_x + src_width) / allocated.cx;
  GLfloat y1 = (GLfloat)(src_y + src_height) / allocated.cy;

  const GLfloat coord[] = {
    x0, y0,
    x1, y0,
    x0, y1,
    x1, y1,
  };

  OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

  GLEnable scope(GL_TEXTURE_2D);
  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(2, GL_FLOAT, 0, coord);
  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#else
  CopyTo(canvas, map_projection.GetScreenWidth(),
         map_projection.GetScreenHeight());
#endif
}
Exemple #10
0
void
RasterRenderer::ScanMap(const RasterMap &map, const WindowProjection &projection)
{
  unsigned x = projection.GetScreenWidth() / 2;
  unsigned y = projection.GetScreenHeight() / 2;
  GeoPoint Gmid = projection.ScreenToGeo(x, y);

  pixel_size = fixed_sqrt_half *
    Distance(Gmid,
             projection.ScreenToGeo(x + quantisation_pixels,
                                      y + quantisation_pixels));

  // set resolution

  fixed map_pixel_size = map.pixel_distance(Gmid, 1);
  quantisation_effective = (int)ceil(map_pixel_size / pixel_size);

  height_matrix.Fill(map, projection, quantisation_pixels,
                     pixel_size * 3 < map_pixel_size * 2);
}
CompareProjection::FourCorners::FourCorners(const WindowProjection &projection)
  :top_left(projection.ScreenToGeo(0, 0)),
   top_right(projection.ScreenToGeo(projection.GetScreenWidth(), 0)),
   bottom_left(projection.ScreenToGeo(0, projection.GetScreenHeight())),
   bottom_right(projection.ScreenToGeo(projection.GetScreenWidth(),
                                       projection.GetScreenHeight())) {}
Exemple #12
0
CompareProjection::FourCorners::FourCorners(const WindowProjection &projection)
  :GeoQuadrilateral{projection.ScreenToGeo(0, 0),
    projection.ScreenToGeo(projection.GetScreenWidth(), 0),
    projection.ScreenToGeo(0, projection.GetScreenHeight()),
    projection.ScreenToGeo(projection.GetScreenWidth(),
                           projection.GetScreenHeight())} {}
void
WeatherTerrainRenderer::Draw(Canvas &canvas,
                             const WindowProjection &projection,
                             const Angle sunazimuth)
{
  bool do_water = false;
  unsigned height_scale;
  const int interp_levels = 5;
  const bool is_terrain = false;
  const bool do_shading = is_terrain;
  const COLORRAMP *color_ramp;

  switch (weather->GetParameter()) {
  case 1: // wstar
    height_scale = 2; // max range 256*(2**2) = 1024 cm/s = 10 m/s
    color_ramp = &weather_colors[0][0];
    break;

  case 2: // bl wind spd
    height_scale = 3;
    color_ramp = &weather_colors[1][0];
    break;

  case 3: // hbl
    height_scale = 4;
    color_ramp = &weather_colors[2][0];
    break;

  case 4: // dwcrit
    height_scale = 4;
    color_ramp = &weather_colors[2][0];
    break;

  case 5: // blcloudpct
    do_water = true;
    height_scale = 0;
    color_ramp = &weather_colors[3][0];
    break;

  case 6: // sfctemp
    height_scale = 0;
    color_ramp = &weather_colors[4][0];
    break;

  case 7: // hwcrit
    height_scale = 4;
    color_ramp = &weather_colors[2][0];
    break;

  case 8: // wblmaxmin
    height_scale = 1; // max range 256*(1**2) = 512 cm/s = 5.0 m/s
    color_ramp = &weather_colors[5][0];
    break;

  case 9: // blcwbase
    height_scale = 4;
    color_ramp = &weather_colors[2][0];
    break;

  default:
    TerrainRenderer::Draw(canvas, projection, sunazimuth);
    return;
  }

  const RasterMap *map = weather->GetMap();
  if (map == NULL) {
    TerrainRenderer::Draw(canvas, projection, sunazimuth);
    return;
  }

  if (color_ramp != last_color_ramp) {
    raster_renderer.ColorTable(color_ramp, do_water,
                               height_scale, interp_levels);
    last_color_ramp = color_ramp;
  }

  raster_renderer.ScanMap(*map, projection);

  raster_renderer.GenerateImage(is_terrain, do_shading, height_scale,
                                TerrainContrast, TerrainBrightness,
                                sunazimuth);

  CopyTo(canvas, projection.GetScreenWidth(), projection.GetScreenHeight());

  ScanSpotHeights();
}