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 = map_projection.GetScreenBounds().Scale(fixed(2)); rectObj deg_bounds = ConvertRect(cache_bounds); // Test which shapes are inside the given bounds and save the // status to file.status msShapefileWhichShapes(&file, dir, deg_bounds, 0); // If not a single shape is inside the bounds if (!file.status) { // ... clear the whole buffer ClearCache(); return false; } // 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 delete it->shape; it->shape = NULL; } else { // is inside the bounds if (it->shape == NULL) // shape isn't cached yet -> cache the shape it->shape = new XShape(&file, i, label_field); // update list pointer *current = it; current = &it->next; } } // end of list marker *current = NULL; ++serial; return true; }
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; }
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.inside(screenRect)) /* the cache is still fresh */ return false; cache_bounds = map_projection.GetScreenBounds().scale(fixed_two); rectObj deg_bounds = ConvertRect(cache_bounds); // Test which shapes are inside the given bounds and save the // status to file.status msShapefileWhichShapes(&file, dir, deg_bounds, 0); // If not a single shape is inside the bounds if (!file.status) { // ... clear the whole buffer ClearCache(); return false; } // Iterate through the shapefile entries for (int i = 0; i < file.numshapes; i++) { if (!msGetBit(file.status, i)) { // If the shape is outside the bounds // delete the shape from the cache delete shapes[i].shape; shapes[i].shape = NULL; } else if (shapes[i].shape == NULL) { // If the shape is inside the bounds and if the // shape isn't cached yet -> cache the shape shapes[i].shape = new XShape(&file, i, label_field); } } ShapeList::NotNull not_null; XShapePointerArray::iterator end = shapes.end(), it = shapes.begin(); it = std::find_if(it, end, not_null); if (it != shapes.end()) { ShapeList *current = &*it; first = current; while (true) { ++it; it = std::find_if(it, end, not_null); if (it == end) { current->next = NULL; break; } ShapeList *next = &*it; current->next = next; current = next; } } else first = NULL; return true; }