mirror of
https://github.com/SikongJueluo/Mini-Nav.git
synced 2026-07-12 20:15:31 +08:00
85 lines
2.5 KiB
Python
85 lines
2.5 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
from importlib import import_module
|
|
from typing import Any, Sequence
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TopDownSceneElements:
|
|
room_nodes: Sequence[Any]
|
|
object_nodes: Sequence[Any] = field(default_factory=tuple)
|
|
edges: Sequence[tuple[str, str]] = field(default_factory=tuple)
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class TopDownRenderStyle:
|
|
room_color: str = "red"
|
|
room_label_color: str = "yellow"
|
|
room_marker_size: int = 50
|
|
room_label_offset: int = 2
|
|
figure_size: tuple[int, int] = (8, 8)
|
|
map_cmap: str = "gray"
|
|
title: str = "RoomNode Top-Down Map"
|
|
|
|
|
|
def render_topdown_scene_map(
|
|
pathfinder: Any,
|
|
elements: TopDownSceneElements,
|
|
meters_per_pixel: float,
|
|
style: TopDownRenderStyle | None = None,
|
|
maps_module: Any | None = None,
|
|
plt_module: Any | None = None,
|
|
) -> Any:
|
|
if not elements.room_nodes:
|
|
raise ValueError("room_nodes must not be empty")
|
|
|
|
if meters_per_pixel <= 0:
|
|
raise ValueError("meters_per_pixel must be greater than 0")
|
|
|
|
if elements.object_nodes:
|
|
raise NotImplementedError("object_nodes overlay is not implemented yet")
|
|
|
|
if elements.edges:
|
|
raise NotImplementedError("edge overlay is not implemented yet")
|
|
|
|
if style is None:
|
|
style = TopDownRenderStyle()
|
|
|
|
if maps_module is None:
|
|
maps_module = import_module("habitat.utils.visualizations.maps")
|
|
|
|
if plt_module is None:
|
|
plt_module = import_module("matplotlib.pyplot")
|
|
|
|
map_height = float(elements.room_nodes[0].center[1])
|
|
top_down_map = maps_module.get_topdown_map(
|
|
pathfinder,
|
|
height=map_height,
|
|
meters_per_pixel=meters_per_pixel,
|
|
)
|
|
|
|
plt_module.figure(figsize=style.figure_size)
|
|
plt_module.imshow(top_down_map, cmap=style.map_cmap)
|
|
|
|
for room_node in elements.room_nodes:
|
|
grid_y, grid_x = maps_module.to_grid(
|
|
float(room_node.center[2]),
|
|
float(room_node.center[0]),
|
|
top_down_map.shape,
|
|
pathfinder=pathfinder,
|
|
)
|
|
plt_module.scatter(grid_x, grid_y, c=style.room_color, s=style.room_marker_size)
|
|
plt_module.text(
|
|
grid_x + style.room_label_offset,
|
|
grid_y + style.room_label_offset,
|
|
room_node.room_id,
|
|
color=style.room_label_color,
|
|
fontsize=8,
|
|
)
|
|
|
|
plt_module.title(style.title)
|
|
plt_module.axis("off")
|
|
plt_module.show()
|
|
return top_down_map
|