Load offline POI tiles through the shared map worker with bounded PSRAM storage

This commit is contained in:
Trail Mate Dev
2026-09-15 00:00:57 +08:00
parent 3543c7ab82
commit 578bedcbad
23 changed files with 1409 additions and 9 deletions
@@ -0,0 +1,20 @@
#pragma once
#include "ui_map_runtime/map_poi/poi_types.h"
#include "ui_presentation/map/map_poi_snapshot.h"
namespace ui::map_poi
{
class SnapshotBuilder
{
public:
SnapshotBuilder(ui::map::MapPoiSnapshot& out, int width, int height);
void add(const Record& record, int x, int y);
void finish();
private:
ui::map::MapPoiSnapshot& out_;
int width_;
int height_;
bool better(uint8_t priority, int x, int y, const char* id, const ui::map::MapPoiItem& other) const;
};
} // namespace ui::map_poi
@@ -0,0 +1,28 @@
#pragma once
#include "ui_map_runtime/map_poi/poi_types.h"
#include "ui_map_runtime/map_tiles/map_tile_resolver.h"
#include "ui_map_runtime/map_tiles/map_tile_source.h"
namespace ui::map_poi
{
// Worker-owned source. Uses the same filesystem boundary as raster tiles;
// returns typed POI data so the UI does no JSON parsing or file access.
class PoiTileSource final : public map_tiles::IMapTileSource
{
public:
PoiTileSource(map_tiles::IMapTileFileSystem& files, const Parser& parser, const char* root = "/");
map_tiles::MapTileLookupResult lookup(const map_tiles::MapTileRef& ref) const override;
map_tiles::MapTileReadResult read(const map_tiles::MapTileRef& ref, uint8_t* buffer, std::size_t capacity) const override;
void reset();
private:
map_tiles::IMapTileFileSystem& files_;
const Parser& parser_;
const char* root_; // Borrowed; the root string must outlive this source.
mutable bool policy_checked_ = false;
mutable bool policy_valid_ = false;
mutable Policy policy_{};
};
static_assert(sizeof(PoiTileSource) <= 64, "POI source must not retain path or JSON buffers");
} // namespace ui::map_poi
@@ -0,0 +1,65 @@
#pragma once
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <type_traits>
namespace ui::map_poi
{
struct Policy
{
uint32_t enabled_levels = 0;
bool labels = true;
bool enabled(int zoom) const { return zoom >= 0 && zoom <= 18 && (enabled_levels & (1UL << zoom)) != 0; }
};
struct Record
{
char id[48]{};
char name[80]{};
char category[16]{};
double lat = 0;
double lon = 0;
uint8_t priority = 0;
};
// Small header followed by exactly `count` Records in an owned PSRAM buffer.
// There is deliberately no fixed array or large data object in this type.
struct alignas(8) TileHeader
{
static constexpr uint32_t kMagic = 0x504F4932U;
static constexpr std::size_t kMaxRecords = 200;
uint32_t magic = kMagic;
Policy policy{};
uint16_t count = 0;
uint16_t invalid_rows = 0;
bool truncated = false;
bool manifest_valid = false;
};
static_assert(sizeof(TileHeader) <= 32, "POI metadata must stay small");
static_assert(sizeof(Record) <= 168, "POI records must remain compact");
static_assert(std::is_trivially_copyable<Record>::value, "POI payload records have no hidden allocations");
inline const Record* payloadRecords(const uint8_t* data)
{
return reinterpret_cast<const Record*>(data + sizeof(TileHeader));
}
inline bool validPayload(const uint8_t* data, std::size_t size)
{
if (!data || size < sizeof(TileHeader)) return false;
TileHeader header{};
std::memcpy(&header, data, sizeof(header));
return header.magic == TileHeader::kMagic && header.count <= TileHeader::kMaxRecords &&
size == sizeof(TileHeader) + header.count * sizeof(Record);
}
class Parser
{
public:
virtual ~Parser() = default;
virtual bool manifest(const char* json, std::size_t size, Policy& out) const = 0;
virtual bool record(const char* json, std::size_t size, Record& out) const = 0;
};
} // namespace ui::map_poi
@@ -24,12 +24,15 @@ enum class MapTileLayer : uint8_t
ContourMinor20,
ContourMinor10,
ContourMinor5,
Poi,
};
enum class MapTileFormat : uint8_t
{
Unknown,
Png,
Jsonl,
PoiRecords,
};
enum class MapTileStatus : uint8_t