Beispiel #1
0
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();
  }
}
Beispiel #2
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;
}