Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 48 additions & 7 deletions s57_layer/src/s57_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,14 @@ void S57Layer::updateBounds(double, double, double, double* min_x, double* min_y
{
tide_offset_ = new_offset;
RCLCPP_INFO_STREAM(logger_, "Tide offset updated: " << tide_offset_ << " m (water above chart datum)");
// Mark tiles for regeneration but keep the cached costmap as a
// fallback so the controller has a usable costmap during regen.
// generateTile rebuilds the costmap from grids when chart_count=0,
// and the empty-charts early-return clears the pointer for safety.
for(auto& t: tiles_)
{
t.second.complete = false;
t.second.chart_count = 0;
t.second.costmap = nullptr;
t.second.needs_update = true;
}
current_ = false;
Expand Down Expand Up @@ -303,9 +306,10 @@ void S57Layer::generateTile(TileID id)
if(current_charts_.empty())
{
tiles_[id].complete = true;
// No tile costmap is created. In updateCosts, a nullptr tile
// with complete=true is recognized as uncharted territory and
// handled according to allow_uncharted_.
// Clear any stale costmap from a prior era when this tile had
// chart coverage. updateCosts treats nullptr+complete as uncharted
// and handles it according to allow_uncharted_.
tiles_[id].costmap = nullptr;
return;
}

Expand Down Expand Up @@ -336,6 +340,19 @@ void S57Layer::generateTile(TileID id)
else
all_charts_available = false;
}

// No chart from current_charts_ overlaps this tile. Treat as uncharted —
// same handling as the empty-current_charts_ early return — and clear
// any costmap left over from a prior era when this tile had coverage.
if(grids.empty() && all_charts_available)
{
tiles_[id].complete = true;
tiles_[id].costmap = nullptr;
tiles_[id].chart_count = 0;
tiles_[id].needs_update = true;
return;
}

tiles_[id].complete = all_charts_available;
if(grids.size() > tiles_[id].chart_count)
{
Expand Down Expand Up @@ -523,6 +540,17 @@ void S57Layer::getDatasetsCallback(GetDatasetsClient::SharedFuture future)
RCLCPP_DEBUG_STREAM(logger_, "Received " << result->datasets.size() << " datasets from service");
}

// Compare new dataset labels against current_charts_ before overwriting.
// bounds_need_update fires every ~5% of window movement, so this callback
// runs frequently while the boat moves; in steady-state survey areas the
// label set rarely changes. If unchanged, skip the per-tile invalidation
// at the end of this function so the cache survives.
std::unordered_set<std::string> new_labels;
for(const auto& d: result->datasets) new_labels.insert(d.label);
std::unordered_set<std::string> old_labels;
for(const auto& c: current_charts_) old_labels.insert(c.label);
bool chart_list_unchanged = (new_labels == old_labels);

current_charts_ = result->datasets;
chart_bounds_.clear();

Expand Down Expand Up @@ -593,9 +621,22 @@ void S57Layer::getDatasetsCallback(GetDatasetsClient::SharedFuture future)
grids_.erase(grid);
}

// mark all tiles as needing regeneration
for(auto& t: tiles_)
t.second.complete = false;
// Mark tiles as needing regeneration only when the chart set actually
// changed — unchanged callbacks are common while the boat moves and
// would otherwise force a full re-evaluation of every cached tile.
// Also reset chart_count so the rebuild branch in generateTile fires
// unconditionally; otherwise a same-count chart swap (one chart removed,
// one added) would leave stale tile costmaps because grids.size() would
// equal the previous chart_count.
if(!chart_list_unchanged)
{
for(auto& t: tiles_)
{
t.second.complete = false;
Comment on lines +633 to +635
t.second.chart_count = 0;
t.second.needs_update = true;
}
}

}

Expand Down
Loading