mirror of
https://github.com/vicliu624/trail-mate.git
synced 2026-10-09 12:07:18 +00:00
Render unified map annotations with stable bounded layouts and transparent text
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_map_runtime/map_poi/annotation_layout.h"
|
||||
#include "ui_presentation/map/map_poi_snapshot.h"
|
||||
|
||||
namespace ui::map_poi
|
||||
{
|
||||
// Ownership and publication of a prepared frame. The platform supplies a strict
|
||||
// PSRAM allocator; host tests inject allocation failures at this same boundary.
|
||||
class AnnotationFrame
|
||||
{
|
||||
public:
|
||||
using Allocate = void* (*)(std::size_t, void*);
|
||||
using Free = void (*)(void*, void*);
|
||||
AnnotationFrame(Allocate allocate, Free release, void* context = nullptr);
|
||||
~AnnotationFrame();
|
||||
AnnotationFrame(const AnnotationFrame&) = delete;
|
||||
AnnotationFrame& operator=(const AnnotationFrame&) = delete;
|
||||
bool begin(std::size_t needed, const ui::map::MapPoiSnapshot& metadata);
|
||||
void add(const AnnotationCandidate& candidate);
|
||||
bool finish(const AnnotationLayoutOptions& options, AnnotationMeasure measure, void* context);
|
||||
void clear();
|
||||
const ui::map::MapPoiSnapshot& snapshot() const { return snapshot_; }
|
||||
const AnnotationLayoutResult& result() const { return result_; }
|
||||
AnnotationCandidate* candidates() { return candidates_; }
|
||||
std::size_t candidate_count() const { return count_; }
|
||||
bool same_view(const ui::map::MapPoiSnapshot& metadata) const;
|
||||
|
||||
private:
|
||||
bool reserve(std::size_t candidates);
|
||||
bool better(const AnnotationCandidate& a, const AnnotationCandidate& b) const;
|
||||
int cell(const AnnotationCandidate& c) const;
|
||||
Allocate allocate_;
|
||||
Free release_;
|
||||
void* context_;
|
||||
AnnotationCandidate* candidates_ = nullptr;
|
||||
AnnotationPlacement* placements_ = nullptr;
|
||||
AnnotationPlacement* previous_ = nullptr;
|
||||
ui::map::MapPoiItem* front_ = nullptr;
|
||||
ui::map::MapPoiItem* back_ = nullptr;
|
||||
std::size_t capacity_ = 0, count_ = 0, previous_count_ = 0;
|
||||
ui::map::MapPoiSnapshot snapshot_{};
|
||||
ui::map::MapPoiSnapshot next_{};
|
||||
AnnotationLayoutResult result_{};
|
||||
};
|
||||
} // namespace ui::map_poi
|
||||
@@ -0,0 +1,74 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_presentation/map/map_annotation_kind.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
namespace ui::map_poi
|
||||
{
|
||||
struct AnnotationCandidate
|
||||
{
|
||||
uint64_t key = 0;
|
||||
uint64_t feature_key = 0;
|
||||
const char* name = nullptr;
|
||||
const char* category = nullptr;
|
||||
int16_t x = 0, y = 0;
|
||||
int16_t path[16]{}; // Already projected screen points; no projection in layout.
|
||||
uint8_t path_points = 0;
|
||||
uint8_t priority = 0;
|
||||
ui::map::AnnotationKind kind = ui::map::AnnotationKind::Poi;
|
||||
bool processed = false;
|
||||
bool retained = false;
|
||||
};
|
||||
|
||||
struct AnnotationPlacement
|
||||
{
|
||||
uint64_t key = 0;
|
||||
uint64_t feature_key = 0;
|
||||
uint16_t candidate = 0;
|
||||
int16_t x = 0, y = 0;
|
||||
int16_t text_x = 0, text_y = 0, text_width = 0, text_height = 0;
|
||||
uint16_t cluster_count = 1;
|
||||
uint8_t text_bytes = 0;
|
||||
bool ellipsis = false;
|
||||
bool marker = false;
|
||||
};
|
||||
|
||||
struct AnnotationLayoutOptions
|
||||
{
|
||||
static constexpr std::size_t kMaxCandidates = 192;
|
||||
static constexpr std::size_t kMaxPlacements = 48;
|
||||
int16_t width = 0, height = 0;
|
||||
uint8_t max_labels = 32;
|
||||
uint8_t max_unnamed_markers = 6;
|
||||
uint8_t road_reservation = 8;
|
||||
uint8_t place_reservation = 2;
|
||||
uint8_t poi_reservation = 12;
|
||||
uint8_t marker_size = 12;
|
||||
uint8_t padding = 2;
|
||||
uint8_t max_text_width = 128;
|
||||
uint8_t retention_bonus = 12;
|
||||
};
|
||||
|
||||
struct AnnotationLayoutResult
|
||||
{
|
||||
std::size_t count = 0;
|
||||
uint16_t labels = 0, road_labels = 0, place_labels = 0, poi_labels = 0;
|
||||
uint16_t unnamed_markers = 0, collisions = 0, outside = 0, truncated = 0;
|
||||
bool metrics_pending = false;
|
||||
};
|
||||
|
||||
// Measures a bounded UTF-8 prefix, optionally followed by an ellipsis.
|
||||
using AnnotationMeasure = bool (*)(void*, const char*, std::size_t, bool, int16_t&, int16_t&);
|
||||
using AnnotationConsumer = void (*)(void*, const AnnotationCandidate&);
|
||||
|
||||
// All bulk storage is caller-owned. Previous placements may alias output: only
|
||||
// stable keys are read into candidate flags before any placement is overwritten.
|
||||
AnnotationLayoutResult layout_annotations(AnnotationCandidate* candidates, std::size_t candidate_count,
|
||||
const AnnotationPlacement* previous, std::size_t previous_count,
|
||||
AnnotationPlacement* output, std::size_t capacity, const AnnotationLayoutOptions& options,
|
||||
AnnotationMeasure measure, void* measure_context);
|
||||
|
||||
static_assert(sizeof(AnnotationCandidate) <= 96, "Candidate geometry must stay compact");
|
||||
static_assert(sizeof(AnnotationPlacement) <= 48, "Layout must not embed strings or UI objects");
|
||||
} // namespace ui::map_poi
|
||||
@@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui_presentation/map/map_annotation_kind.h"
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
@@ -11,6 +12,7 @@ struct Policy
|
||||
{
|
||||
uint32_t enabled_levels = 0;
|
||||
bool labels = true;
|
||||
uint8_t schema_version = 1;
|
||||
bool enabled(int zoom) const { return zoom >= 0 && zoom <= 18 && (enabled_levels & (1UL << zoom)) != 0; }
|
||||
};
|
||||
|
||||
@@ -18,10 +20,16 @@ struct Record
|
||||
{
|
||||
char id[48]{};
|
||||
char name[80]{};
|
||||
char category[16]{};
|
||||
char category[24]{};
|
||||
double lat = 0;
|
||||
double lon = 0;
|
||||
uint8_t priority = 0;
|
||||
ui::map::AnnotationKind kind = ui::map::AnnotationKind::Poi;
|
||||
bool explicit_kind = false;
|
||||
uint8_t path_points = 0;
|
||||
uint64_t feature_key = 0;
|
||||
uint64_t key = 0;
|
||||
int16_t path[16]{}; // At most eight tile-local points, only used by roads.
|
||||
};
|
||||
|
||||
// Small header followed by exactly `count` Records in an owned PSRAM buffer.
|
||||
@@ -39,7 +47,7 @@ struct alignas(8) TileHeader
|
||||
};
|
||||
|
||||
static_assert(sizeof(TileHeader) <= 32, "POI metadata must stay small");
|
||||
static_assert(sizeof(Record) <= 168, "POI records must remain compact");
|
||||
static_assert(sizeof(Record) <= 224, "Annotation records must remain bounded and compact");
|
||||
static_assert(std::is_trivially_copyable<Record>::value, "POI payload records have no hidden allocations");
|
||||
|
||||
inline const Record* payloadRecords(const uint8_t* data)
|
||||
|
||||
Reference in New Issue
Block a user