@page "/maps"
@rendermode InteractiveWebAssemblyNoPrerender
@using MudBlazor
@using RobotNet10.RobotApp.Client.Shared.SLAM
@using RobotNet10.RobotApp.Client.Clients
@using RobotNet10.RobotApp.Client.Components.SLAM
@implements IAsyncDisposable
@inject SLAMClient CartographerClient
@inject ISnackbar Snackbar
@inject IDialogService DialogService
Map Management
Map Management
Refresh
@if (IsLoading)
{
}
else if (Maps.Count == 0)
{
No maps found. Create a map by starting scan mapping.
}
else
{
Name
Created
Resolution
Size
Trajectory Nodes
@context.Name
@context.CreatedDate.ToString("yyyy-MM-dd HH:mm")
@context.Resolution.ToString("F3") m/p
@context.Width.ToString("F1") x @context.Height.ToString("F1") m
@context.TrajectoryNodeCount
}
@code {
private List Maps { get; set; } = new();
private bool IsLoading { get; set; } = false;
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await CartographerClient.StartAsync();
await RefreshMapsAsync();
}
}
private async Task RefreshMapsAsync()
{
if (!CartographerClient.IsConnected)
{
Snackbar.Add("Not connected to server", Severity.Warning);
return;
}
try
{
IsLoading = true;
StateHasChanged();
Maps = (await CartographerClient.ListMapsAsync()).ToList();
}
catch (Exception ex)
{
Snackbar.Add($"Failed to load maps: {ex.Message}", Severity.Error);
}
finally
{
IsLoading = false;
StateHasChanged();
}
}
private async Task LoadMapAsync(string mapName)
{
try
{
var success = await CartographerClient.StartLocalizationAsync(mapName);
if (success)
{
Snackbar.Add($"Started localization with map: {mapName}", Severity.Success);
}
else
{
Snackbar.Add($"Failed to start localization with map: {mapName}", Severity.Error);
}
}
catch (Exception ex)
{
Snackbar.Add($"Failed to load map: {ex.Message}", Severity.Error);
}
}
private async Task DeleteMapAsync(string mapName)
{
var parameters = new DialogParameters
{
["MapName"] = mapName
};
var options = new DialogOptions
{
CloseOnEscapeKey = true,
MaxWidth = MaxWidth.Small,
FullWidth = true
};
var dialog = await DialogService.ShowAsync("Delete Map", parameters, options);
var result = await dialog.Result;
if (result != null && !result.Canceled)
{
try
{
var success = await CartographerClient.DeleteMapAsync(mapName);
if (success)
{
Snackbar.Add($"Map deleted: {mapName}", Severity.Success);
await RefreshMapsAsync();
}
else
{
Snackbar.Add($"Failed to delete map: {mapName}", Severity.Error);
}
}
catch (Exception ex)
{
Snackbar.Add($"Failed to delete map: {ex.Message}", Severity.Error);
}
}
}
private string FormatFileSize(long bytes)
{
string[] sizes = { "B", "KB", "MB", "GB" };
double len = bytes;
int order = 0;
while (len >= 1024 && order < sizes.Length - 1)
{
order++;
len = len / 1024;
}
return $"{len:0.##} {sizes[order]}";
}
public async ValueTask DisposeAsync()
{
// CartographerClient is scoped, will be disposed by DI
}
}