예제 #1
0
파일: Thread.cpp 프로젝트: kwtskran/XCSoar
void
TopographyThread::Trigger(const WindowProjection &_projection)
{
  assert(_projection.IsValid());

  const GeoBounds new_bounds = _projection.GetScreenBounds();
  if (last_bounds.IsValid() && last_bounds.IsInside(new_bounds)) {
    /* still inside cache bounds - now check if we crossed a scale
       threshold for at least one file, which would mean we have to
       update a file which was not updated for the current cache
       bounds */
    if (scale_threshold < 0 ||
        _projection.GetMapScale() >= scale_threshold)
      /* the cache is still fresh */
      return;
  }

  last_bounds = new_bounds.Scale(1.1);
  scale_threshold = store.GetNextScaleThreshold(_projection.GetMapScale());

  {
    const ScopeLock protect(mutex);
    next_projection = _projection;
    StandbyThread::Trigger();
  }
}
예제 #2
0
static void
GetPolygonPoints(std::vector<RasterPoint> &pts,
                 const AirspacePolygon &airspace,
                 const RasterPoint pt, unsigned radius)
{
  GeoBounds bounds = airspace.GetGeoBounds();
  GeoPoint center = bounds.GetCenter();

  fixed geo_heigth = bounds.GetGeoHeight();
  fixed geo_width = bounds.GetGeoWidth();

  fixed geo_size = std::max(geo_heigth, geo_width);

  WindowProjection projection;
  projection.SetScreenSize({radius * 2, radius * 2});
  projection.SetScreenOrigin(pt.x, pt.y);
  projection.SetGeoLocation(center);
  projection.SetScale(fixed(radius * 2) / geo_size);
  projection.SetScreenAngle(Angle::Zero());
  projection.UpdateScreenBounds();

  const SearchPointVector &border = airspace.GetPoints();

  pts.reserve(border.size());
  for (auto it = border.begin(), it_end = border.end(); it != it_end; ++it)
    pts.push_back(projection.GeoToScreen(it->GetLocation()));
}
예제 #3
0
int main(int argc, char **argv)
{
  Args args(argc, argv, "PATH");
  const char *map_path = args.ExpectNext();
  args.ExpectEnd();

  char jp2_path[4096];
  strcpy(jp2_path, map_path);
  strcat(jp2_path, DIR_SEPARATOR_S "terrain.jp2");

  TCHAR j2w_path[4096];
  _tcscpy(j2w_path, PathName(map_path));
  _tcscat(j2w_path, _T(DIR_SEPARATOR_S) _T("terrain.j2w"));

  NullOperationEnvironment operation;
  RasterTileCache rtc;
  if (!rtc.LoadOverview(jp2_path, j2w_path, operation)) {
    fprintf(stderr, "LoadOverview failed\n");
    return EXIT_FAILURE;
  }

  GeoBounds bounds = rtc.GetBounds();
  printf("bounds = %f|%f - %f|%f\n",
         (double)bounds.GetWest().Degrees(),
         (double)bounds.GetNorth().Degrees(),
         (double)bounds.GetEast().Degrees(),
         (double)bounds.GetSouth().Degrees());

  do {
    rtc.UpdateTiles(jp2_path, rtc.GetWidth() / 2, rtc.GetHeight() / 2,
                    1000);
  } while (rtc.IsDirty());

  return EXIT_SUCCESS;
}
예제 #4
0
GeoBounds
SearchPointVector::CalculateGeoBounds() const
{
  GeoBounds bb = GeoBounds::Invalid();
  for (const auto &i : *this)
    bb.Extend(i.GetLocation());

  return bb;
}
예제 #5
0
void
DrawGeoBitmap(const RawBitmap &bitmap, PixelSize bitmap_size,
              const GeoBounds &bounds,
              const Projection &projection)
{
  assert(bounds.IsValid());

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

  const ScopeVertexPointer vp(vertices);

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

  const GLfloat src_x = 0, src_y = 0, src_width = bitmap_size.cx,
    src_height = bitmap_size.cy;

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

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

#ifdef USE_GLSL
  OpenGL::texture_shader->Use();
  glEnableVertexAttribArray(OpenGL::Attribute::TEXCOORD);
  glVertexAttribPointer(OpenGL::Attribute::TEXCOORD, 2, GL_FLOAT, GL_FALSE,
                        0, coord);
#else
  const GLEnable<GL_TEXTURE_2D> scope;
  OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

  glEnableClientState(GL_TEXTURE_COORD_ARRAY);
  glTexCoordPointer(2, GL_FLOAT, 0, coord);
#endif

  glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

#ifdef USE_GLSL
  glDisableVertexAttribArray(OpenGL::Attribute::TEXCOORD);
  OpenGL::solid_shader->Use();
#else
  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
#endif
}
예제 #6
0
void
RasterProjection::Set(const GeoBounds &bounds,
                      unsigned width, unsigned height)
{
  x_scale = fixed(width) / bounds.GetWidth().Native();
  left = int(bounds.GetWest().Native() * x_scale);

  y_scale = fixed(height) / bounds.GetHeight().Native();
  top = int(bounds.GetNorth().Native() * y_scale);
}
예제 #7
0
void
RasterProjection::Set(const GeoBounds &bounds,
                      unsigned width, unsigned height)
{
  x_scale = double(width) / bounds.GetWidth().Native();
  left = AngleToWidth(bounds.GetWest());

  y_scale = double(height) / bounds.GetHeight().Native();
  top = AngleToHeight(bounds.GetNorth());
}
예제 #8
0
FlatBoundingBox
FlatProjection::Project(const GeoBounds &bb) const
{
    assert(IsValid());

    FlatBoundingBox fb(ProjectInteger(bb.GetSouthWest()),
                       ProjectInteger(bb.GetNorthEast()));
    fb.ExpandByOne(); // prevent rounding
    return fb;
}
예제 #9
0
파일: Convert.hpp 프로젝트: Adrien81/XCSoar
gcc_pure
static inline rectObj
ConvertRect(const GeoBounds &br)
{
  rectObj dest;
  dest.minx = (double)br.GetWest().Degrees();
  dest.maxx = (double)br.GetEast().Degrees();
  dest.miny = (double)br.GetSouth().Degrees();
  dest.maxy = (double)br.GetNorth().Degrees();
  return dest;
}
예제 #10
0
void
OZPreviewRenderer::Draw(Canvas &canvas, const ObservationZonePoint &oz,
                        const RasterPoint pt, unsigned radius,
                        const TaskLook &look,
                        const AirspaceRendererSettings &airspace_settings,
                        const AirspaceLook &airspace_look)
{
  fixed scale;
  GeoPoint center;

  if (IsAncientHardware()) {
    scale = fixed(radius) / ((const CylinderZone &)oz).GetRadius();
    center = oz.GetReference();
  } else {
    OZBoundary boundary = oz.GetBoundary();

    GeoBounds bounds = GeoBounds::Invalid();
    for (auto i = boundary.begin(), end = boundary.end(); i != end; ++i)
      bounds.Extend(*i);

    center = bounds.GetCenter();

    fixed geo_width = bounds.GetGeoWidth();
    fixed geo_heigth = bounds.GetGeoHeight();

    scale = fixed(radius * 2) / std::max(geo_heigth, geo_width);
  }

  WindowProjection projection;
  projection.SetScreenSize({radius * 2, radius * 2});
  projection.SetScreenOrigin(pt.x, pt.y);
  projection.SetGeoLocation(center);
  projection.SetScale(scale);
  projection.SetScreenAngle(Angle::Zero());
  projection.UpdateScreenBounds();

  OZRenderer ozv(look, airspace_look, airspace_settings);
  ozv.Draw(canvas, OZRenderer::LAYER_SHADE, projection, oz, 1);
  ozv.Draw(canvas, OZRenderer::LAYER_INACTIVE, projection, oz, 1);
  ozv.Draw(canvas, OZRenderer::LAYER_ACTIVE, projection, oz, 1);
}
예제 #11
0
FlatBoundingBox 
OrderedTask::GetBoundingBox(const GeoBounds &bounds) const
{
  if (!TaskSize()) {
    // undefined!
    return FlatBoundingBox(FlatGeoPoint(0,0),FlatGeoPoint(0,0));
  }

  FlatGeoPoint ll = task_projection.ProjectInteger(bounds.GetSouthWest());
  FlatGeoPoint lr = task_projection.ProjectInteger(bounds.GetSouthEast());
  FlatGeoPoint ul = task_projection.ProjectInteger(bounds.GetNorthWest());
  FlatGeoPoint ur = task_projection.ProjectInteger(bounds.GetNorthEast());
  FlatGeoPoint fmin(std::min(ll.longitude, ul.longitude),
                    std::min(ll.latitude, lr.latitude));
  FlatGeoPoint fmax(std::max(lr.longitude, ur.longitude),
                    std::max(ul.latitude, ur.latitude));
  // note +/- 1 to ensure rounding keeps bb valid 
  fmin.longitude -= 1; fmin.latitude -= 1;
  fmax.longitude += 1; fmax.latitude += 1;
  return FlatBoundingBox (fmin, fmax);
}
예제 #12
0
/**
 * Checks if the size difference of any dimension is more than a
 * factor of two.  This is used to check whether the terrain has to be
 * redrawn after zooming in.
 */
static bool
IsLargeSizeDifference(const GeoBounds &a, const GeoBounds &b)
{
  assert(a.IsValid());
  assert(b.IsValid());

  return a.GetWidth().Native() > Double(b.GetWidth().Native()) ||
    a.GetHeight().Native() > Double(b.GetHeight().Native());
}
예제 #13
0
static void
DrawPolygon(Canvas &canvas, const AirspacePolygon &airspace,
            const RasterPoint pt, unsigned radius)
{
  if (IsAncientHardware()) {
    canvas.Rectangle(pt.x - radius, pt.y - radius,
                     pt.x + radius, pt.y + radius);
    return;
  }

  GeoBounds bounds = airspace.GetGeoBounds();
  GeoPoint center = bounds.GetCenter();

  fixed geo_heigth = GeoPoint(center.longitude, bounds.north).Distance(
                     GeoPoint(center.longitude, bounds.south));
  fixed geo_width = GeoPoint(bounds.west, center.latitude).Distance(
                    GeoPoint(bounds.east, center.latitude));

  fixed geo_size = std::max(geo_heigth, geo_width);

  WindowProjection projection;
  projection.SetScreenSize(radius * 2, radius * 2);
  projection.SetScreenOrigin(pt.x, pt.y);
  projection.SetGeoLocation(center);
  projection.SetScale(fixed(radius * 2) / geo_size);
  projection.SetScreenAngle(Angle::Zero());
  projection.UpdateScreenBounds();

  const SearchPointVector &border = airspace.GetPoints();

  std::vector<RasterPoint> pts;
  pts.reserve(border.size());
  for (auto it = border.begin(), it_end = border.end(); it != it_end; ++it)
    pts.push_back(projection.GeoToScreen(it->get_location()));

  canvas.polygon(&pts[0], (unsigned)pts.size());
}
예제 #14
0
int main(int argc, char **argv)
{
  Args args(argc, argv, "PATH");
  const auto map_path = args.ExpectNext();
  args.ExpectEnd();

  ZZIP_DIR *dir = zzip_dir_open(map_path, nullptr);
  if (dir == nullptr) {
    fprintf(stderr, "Failed to open %s\n", map_path);
    return EXIT_FAILURE;
  }

  NullOperationEnvironment operation;
  RasterTileCache rtc;
  if (!LoadTerrainOverview(dir, rtc, operation)) {
    fprintf(stderr, "LoadOverview failed\n");
    zzip_dir_close(dir);
    return EXIT_FAILURE;
  }

  GeoBounds bounds = rtc.GetBounds();
  printf("bounds = %f|%f - %f|%f\n",
         (double)bounds.GetWest().Degrees(),
         (double)bounds.GetNorth().Degrees(),
         (double)bounds.GetEast().Degrees(),
         (double)bounds.GetSouth().Degrees());

  SharedMutex mutex;
  do {
    UpdateTerrainTiles(dir, rtc, mutex,
                       rtc.GetWidth() / 2, rtc.GetHeight() / 2, 1000);
  } while (rtc.IsDirty());
  zzip_dir_close(dir);

  return EXIT_SUCCESS;
}
예제 #15
0
  const GeoBounds &GetBounds() const {
    assert(bounds.IsValid());

    return bounds;
  }
예제 #16
0
void
TrailRenderer::Draw(Canvas &canvas, const TraceComputer &trace_computer,
                    const WindowProjection &projection, unsigned min_time,
                    bool enable_traildrift, const RasterPoint pos,
                    const NMEAInfo &basic, const DerivedInfo &calculated,
                    const MapSettings &settings)
{
  if (settings.trail_length == TRAIL_OFF)
    return;

  if (!LoadTrace(trace_computer, min_time, projection))
    return;

  if (!calculated.wind_available)
    enable_traildrift = false;

  GeoPoint traildrift;
  if (enable_traildrift) {
    GeoPoint tp1 = FindLatitudeLongitude(basic.location,
                                         calculated.wind.bearing,
                                         calculated.wind.norm);
    traildrift = basic.location - tp1;
  }

  fixed value_max, value_min;

  if (settings.snail_type == stAltitude) {
    value_max = fixed(1000);
    value_min = fixed(500);
    for (auto it = trace.begin(); it != trace.end(); ++it) {
      value_max = max(it->GetAltitude(), value_max);
      value_min = min(it->GetAltitude(), value_min);
    }
  } else {
    value_max = fixed(0.75);
    value_min = fixed(-2.0);
    for (auto it = trace.begin(); it != trace.end(); ++it) {
      value_max = max(it->GetVario(), value_max);
      value_min = min(it->GetVario(), value_min);
    }
    value_max = min(fixed(7.5), value_max);
    value_min = max(fixed(-5.0), value_min);
  }

  bool scaled_trail = settings.snail_scaling_enabled &&
                      projection.GetMapScale() <= fixed_int_constant(6000);

  const GeoBounds bounds = projection.GetScreenBounds().Scale(fixed_four);

  RasterPoint last_point;
  bool last_valid = false;
  for (auto it = trace.begin(), end = trace.end(); it != end; ++it) {
    const GeoPoint gp = enable_traildrift
      ? it->get_location().Parametric(traildrift,
                                      it->CalculateDrift(basic.time))
      : it->get_location();
    if (!bounds.IsInside(gp)) {
      /* the point is outside of the MapWindow; don't paint it */
      last_valid = false;
      continue;
    }

    RasterPoint pt = projection.GeoToScreen(gp);

    if (last_valid) {
      if (settings.snail_type == stAltitude) {
        unsigned index((it->GetAltitude() - value_min) / (value_max - value_min)
                       * (TrailLook::NUMSNAILCOLORS - 1));
        index = max(0u, min(TrailLook::NUMSNAILCOLORS - 1, index));
        canvas.Select(look.hpSnail[index]);
      } else {
        const fixed colour_vario = negative(it->GetVario())
          ? - it->GetVario() / value_min
          : it->GetVario() / value_max ;

        if (!scaled_trail)
          canvas.Select(look.hpSnail[GetSnailColorIndex(colour_vario)]);
        else
          canvas.Select(look.hpSnailVario[GetSnailColorIndex(colour_vario)]);
      }
      canvas.line_piece(last_point, pt);
    }
    last_point = pt;
    last_valid = true;
  }

  canvas.line(last_point, pos);
}
예제 #17
0
 bool IsValid() const {
   return bounds.IsValid();
 }
예제 #18
0
void
TrailRenderer::Draw(Canvas &canvas, const TraceComputer &trace_computer,
                    const WindowProjection &projection, unsigned min_time,
                    bool enable_traildrift, const RasterPoint pos,
                    const NMEAInfo &basic, const DerivedInfo &calculated,
                    const TrailSettings &settings)
{
  if (settings.length == TrailSettings::Length::OFF)
    return;

  if (!LoadTrace(trace_computer, min_time, projection))
    return;

  if (!calculated.wind_available)
    enable_traildrift = false;

  GeoPoint traildrift;
  if (enable_traildrift) {
    GeoPoint tp1 = FindLatitudeLongitude(basic.location,
                                         calculated.wind.bearing,
                                         calculated.wind.norm);
    traildrift = basic.location - tp1;
  }

  fixed value_max, value_min;
  GetMinMax(value_min, value_max, settings.type, trace);

  bool scaled_trail = settings.scaling_enabled &&
                      projection.GetMapScale() <= fixed_int_constant(6000);

  const GeoBounds bounds = projection.GetScreenBounds().Scale(fixed_four);

  RasterPoint last_point;
  bool last_valid = false;
  for (auto it = trace.begin(), end = trace.end(); it != end; ++it) {
    const GeoPoint gp = enable_traildrift
      ? it->GetLocation().Parametric(traildrift,
                                     it->CalculateDrift(basic.time))
      : it->GetLocation();
    if (!bounds.IsInside(gp)) {
      /* the point is outside of the MapWindow; don't paint it */
      last_valid = false;
      continue;
    }

    RasterPoint pt = projection.GeoToScreen(gp);

    if (last_valid) {
      if (settings.type == TrailSettings::Type::ALTITUDE) {
        unsigned index((it->GetAltitude() - value_min) / (value_max - value_min)
                       * (TrailLook::NUMSNAILCOLORS - 1));
        index = max(0u, min(TrailLook::NUMSNAILCOLORS - 1, index));
        canvas.Select(look.trail_pens[index]);
        canvas.DrawLinePiece(last_point, pt);
      } else {
        const fixed colour_vario = negative(it->GetVario())
          ? - it->GetVario() / value_min
          : it->GetVario() / value_max ;

        unsigned color_index = GetSnailColorIndex(colour_vario);
        if (negative(it->GetVario()) &&
            (settings.type == TrailSettings::Type::VARIO_1_DOTS ||
             settings.type == TrailSettings::Type::VARIO_2_DOTS)) {
          canvas.SelectNullPen();
          canvas.Select(look.trail_brushes[color_index]);
          canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2,
                            look.trail_widths[color_index]);

        } else {
          if (!scaled_trail)
            canvas.Select(look.trail_pens[color_index]);
          else
            canvas.Select(look.scaled_trail_pens[color_index]);

          canvas.DrawLinePiece(last_point, pt);
        }
      }
    }
    last_point = pt;
    last_valid = true;
  }

  if (last_valid)
    canvas.DrawLine(last_point, pos);
}
예제 #19
0
void
TrailRenderer::Draw(Canvas &canvas, const TraceComputer &trace_computer,
                    const WindowProjection &projection, unsigned min_time,
                    bool enable_traildrift, const RasterPoint pos,
                    const NMEAInfo &basic, const DerivedInfo &calculated,
                    const TrailSettings &settings)
{
  if (settings.length == TrailSettings::Length::OFF)
    return;

  if (!LoadTrace(trace_computer, min_time, projection))
    return;

  if (!calculated.wind_available)
    enable_traildrift = false;

  GeoPoint traildrift;
  if (enable_traildrift) {
    GeoPoint tp1 = FindLatitudeLongitude(basic.location,
                                         calculated.wind.bearing,
                                         calculated.wind.norm);
    traildrift = basic.location - tp1;
  }

  auto minmax = GetMinMax(settings.type, trace);
  auto value_min = minmax.first;
  auto value_max = minmax.second;

  bool scaled_trail = settings.scaling_enabled &&
                      projection.GetMapScale() <= 6000;

  const GeoBounds bounds = projection.GetScreenBounds().Scale(4);

  RasterPoint last_point = RasterPoint(0, 0);
  bool last_valid = false;
  for (auto it = trace.begin(), end = trace.end(); it != end; ++it) {
    const GeoPoint gp = enable_traildrift
      ? it->GetLocation().Parametric(traildrift,
                                     it->CalculateDrift(basic.time))
      : it->GetLocation();
    if (!bounds.IsInside(gp)) {
      /* the point is outside of the MapWindow; don't paint it */
      last_valid = false;
      continue;
    }

    RasterPoint pt = projection.GeoToScreen(gp);

    if (last_valid) {
      if (settings.type == TrailSettings::Type::ALTITUDE) {
        unsigned index = GetAltitudeColorIndex(it->GetAltitude(),
                                               value_min, value_max);
        canvas.Select(look.trail_pens[index]);
        canvas.DrawLinePiece(last_point, pt);
      } else {
        unsigned color_index = GetSnailColorIndex(it->GetVario(),
                                                  value_min, value_max);
        if (it->GetVario() < 0 &&
            (settings.type == TrailSettings::Type::VARIO_1_DOTS ||
             settings.type == TrailSettings::Type::VARIO_2_DOTS ||
             settings.type == TrailSettings::Type::VARIO_DOTS_AND_LINES)) {
          canvas.SelectNullPen();
          canvas.Select(look.trail_brushes[color_index]);
          canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2,
                            look.trail_widths[color_index]);
        } else {
          // positive vario case

          if (settings.type == TrailSettings::Type::VARIO_DOTS_AND_LINES) {
            canvas.Select(look.trail_brushes[color_index]);
            canvas.Select(look.trail_pens[color_index]); //fixed-width pen
            canvas.DrawCircle((pt.x + last_point.x) / 2, (pt.y + last_point.y) / 2,
                              look.trail_widths[color_index]);
          } else if (scaled_trail)
            // width scaled to vario
            canvas.Select(look.scaled_trail_pens[color_index]);
          else
            // fixed-width pen
            canvas.Select(look.trail_pens[color_index]);

          canvas.DrawLinePiece(last_point, pt);
        }
      }
    }
    last_point = pt;
    last_valid = true;
  }

  if (last_valid)
    canvas.DrawLine(last_point, pos);
}
예제 #20
0
/**
 * Convert a #GeoBounds instance to a boost::geometry box.
 */
gcc_const
static boost::geometry::model::box<DoublePoint2D>
ToBox(const GeoBounds b)
{
  return {GeoTo2D(b.GetSouthWest()), GeoTo2D(b.GetNorthEast())};
}
예제 #21
0
  void SetBounds(const GeoBounds &_bounds) {
    assert(_bounds.IsValid());

    bounds = _bounds;
  }
예제 #22
0
bool
TopographyFile::Update(const WindowProjection &map_projection)
{
    if (IsEmpty())
        return false;

    if (map_projection.GetMapScale() > scale_threshold)
        /* not visible, don't update cache now */
        return false;

    const GeoBounds screenRect =
        map_projection.GetScreenBounds();
    if (cache_bounds.IsValid() && cache_bounds.IsInside(screenRect))
        /* the cache is still fresh */
        return false;

    cache_bounds = screenRect.Scale(2);

    rectObj deg_bounds = ConvertRect(cache_bounds);

    // Test which shapes are inside the given bounds and save the
    // status to file.status
    switch (msShapefileWhichShapes(&file, dir, deg_bounds, 0)) {
    case MS_FAILURE:
        ClearCache();
        return false;

    case MS_DONE:
        /* screen is outside of map bounds */
        return false;

    case MS_SUCCESS:
        break;
    }

    assert(file.status != nullptr);

    // Iterate through the shapefile entries
    const ShapeList **current = &first;
    auto it = shapes.begin();
    for (int i = 0; i < file.numshapes; ++i, ++it) {
        if (!msGetBit(file.status, i)) {
            // If the shape is outside the bounds
            // delete the shape from the cache
            if (it->shape != nullptr) {
                assert(*current == it);

                /* remove from linked list (protected) */
                {
                    const ScopeLock lock(mutex);
                    *current = it->next;
                    ++serial;
                }

                /* now it's unreachable, and we can delete the XShape without
                   holding a lock */
                delete it->shape;
                it->shape = nullptr;
            }
        } else {
            // is inside the bounds
            if (it->shape == nullptr) {
                assert(*current != it);

                // shape isn't cached yet -> cache the shape
                it->shape = LoadShape(&file, center, i, label_field);
                it->next = *current;

                /* insert into linked list (protected) */
                {
                    const ScopeLock lock(mutex);
                    *current = it;
                    ++serial;
                }
            }

            current = &it->next;
        }
    }
    // end of list marker
    assert(*current == nullptr);

    return true;
}
 void Invalidate() {
   bounds.SetInvalid();
 }
예제 #24
0
int main(int argc, char **argv)
{
  plan_tests(38);

  GeoPoint g(Angle::Degrees(2), Angle::Degrees(4));

  GeoBounds b(g);

  ok1(equals(b.GetEast(), 2));
  ok1(equals(b.GetWest(), 2));
  ok1(equals(b.GetNorth(), 4));
  ok1(equals(b.GetSouth(), 4));

  ok1(b.IsEmpty());

  g.latitude = Angle::Degrees(6);
  g.longitude = Angle::Degrees(8);
  b.Extend(g);

  ok1(equals(b.GetEast(), 8));
  ok1(equals(b.GetWest(), 2));
  ok1(equals(b.GetNorth(), 6));
  ok1(equals(b.GetSouth(), 4));

  ok1(!b.IsEmpty());

  g = b.GetCenter();
  ok1(equals(g.latitude, 5));
  ok1(equals(g.longitude, 5));

  ok1(b.IsInside(Angle::Degrees(7), Angle::Degrees(4.5)));
  ok1(!b.IsInside(Angle::Degrees(9), Angle::Degrees(4.5)));
  ok1(!b.IsInside(Angle::Degrees(7), Angle::Degrees(1)));
  ok1(!b.IsInside(Angle::Degrees(9), Angle::Degrees(1)));

  b = b.Scale(2);

  ok1(equals(b.GetEast(), 11));
  ok1(equals(b.GetWest(), -1));
  ok1(equals(b.GetNorth(), 7));
  ok1(equals(b.GetSouth(), 3));

  b = b.Scale(0.5);

  ok1(equals(b.GetEast(), 8));
  ok1(equals(b.GetWest(), 2));
  ok1(equals(b.GetNorth(), 6));
  ok1(equals(b.GetSouth(), 4));

  GeoBounds c = MakeGeoBounds(2, 6, 8, 4);
  ok1(c.Overlaps(b));
  ok1(c.IntersectWith(b));
  ok1(equals(c.GetWest(), 2));
  ok1(equals(c.GetNorth(), 6));
  ok1(equals(c.GetEast(), 8));
  ok1(equals(c.GetSouth(), 4));

  GeoBounds d = MakeGeoBounds(2, 6, 7, 5);
  ok1(c.Overlaps(d));
  ok1(c.IntersectWith(d));
  ok1(equals(c.GetWest(), 2));
  ok1(equals(c.GetNorth(), 6));
  ok1(equals(c.GetEast(), 7));
  ok1(equals(c.GetSouth(), 5));

  d = MakeGeoBounds(8, 6, 1, 5);
  ok1(!c.Overlaps(d));
  ok1(!c.IntersectWith(d));

  return exit_status();
}