开发 AIoT 智能眼镜SDK 开发指南 屏显组件 RTOS 用户手册

RTOS SDK 接入与使用 最后更新时间: 2026年08月27日

一、概述

1.1 SDK 形态

SDK 以 C 语言静态库形式发布,对外仅暴露 C 头文件,作为静态库链入 RTOS 设备固件。

主要部署形态:

  • 手表:RTOS 手表设备(如 SiFli、杰理、聚芯、拓步、小牛等芯片平台)
  • 眼镜:RTOS 眼镜设备(rtosglass / Rokid 等)

两种形态均不依赖完整 libc / 文件系统 / 图形栈,全部通过 adapter 由厂商注入。

1.2 线程模型

单线程模型:SDK 的所有 API 必须在同一个线程("主流程线程")调用,不支持并发。

  • awk_init 在哪个线程调用,后续 API 就必须在该线程调用
  • 网络数据的接收可以在异步线程进行,但 awk_http_response_callback_t 的回调必须切回主流程线程
  • SDK 内部会校验线程一致性,违反时返回 -3

1.3 坐标系

  • 地理坐标:GCJ02 坐标系(高德/腾讯系)。如有 WGS84 数据,先调用 awk_map_wgs84_to_mgs 转换
  • 屏幕坐标:以左上角为原点 (0, 0),单位像素,x 向右,y 向下

1.4 版本检查

库与头文件必须严格匹配,否则行为未定义。集成方需在初始化前自检:

if (!awk_check_version_compatibility()) {
    // 头文件与库版本不一致,停止使用
}
const awk_version_info_t *v = awk_get_library_version();
printf("SDK version: %s build %s %s\n", v->version, v->build_date, v->build_time);

二、接入流程

2.1 调用链概览

            awk_check_version_compatibility()      ← 版本自检
                          │
                          ▼
            填充 awk_context_t                    ← 配置 + 注入 adapter
                          │
                          ▼
                  awk_init(&ctx)                   ← 初始化
                          │
                          ▼
            awk_check_device_activated() ── 已激活 ──┐
                          │ 未激活                    │
                          ▼                          ▼
              awk_activate_device()           awk_map_create_view()
                          │                          │
                          ▼                          ▼
                  (回调成功后)                  开始使用地图 API
                          │                          │
                          └────────────►─────────────┘
                          │
                          ▼
                  awk_uninit()                     ← 退出时反初始化

2.2 awk_context_t 字段

typedef struct _awk_context_t {
    char *device_id;                           // 必填:设备唯一 id
    char *key;                                 // 必填:高德开放平台智能硬件 key
    char *root_dir;                            // 必填:SDK 内部缓存/数据根目录
    char *offline_map_dir;                     // 可选:离线地图根目录,不要位于 root_dir 下
    char *language;                            // 可选:语言编码("zh"/"en"/...),NULL 默认 "zh"

    // 瓦片相关
    awk_map_tile_style_t tile_style;           // 必填:瓦片样式(见 §2.4)
    int32_t tile_load_mode;                    // 必填:AWK_MAP_TILE_LOAD_ONLINE / OFFLINE
    awk_pixel_mode_t tile_pixel_mode;          // 瓦片像素格式(如 ARGB_8888 / RGB_565)
    uint32_t tile_disk_cache_max_size;         // 瓦片磁盘缓存上限,单位 MB
    uint32_t tile_mem_cache_max_size;          // 瓦片内存缓存上限,单位 KB
    uint32_t poi_tile_disk_cache_max_size;     // POI 磁盘缓存上限,单位 MB
    uint32_t poi_tile_mem_cache_max_size;     // POI 内存缓存上限,单位 KB
    uint32_t poi_tile_density;                 // POI 精细度 0/1/2,越大越细
    uint32_t max_file_count_in_dir;            // 单目录文件数上限,0 不限
    uint32_t max_one_file_size;                // 单文件大小上限 MB,0 不限
    bool tile_zip;                             // 瓦片是否压缩
    bool tile_clip_load;                       // 加载时是否裁剪(仅 tile_mem_cache_max_size=0 生效)
    bool tile_background_custom_draw;          // 瓦片背景是否外部自绘
    bool tile_buff_mem_outer_free;             // 瓦片绘制内存外部释放(仅 tile_clip_load=false)
    bool tile_cache_decoded_bitmap;            // 缓存解码后的位图
    bool poi_labels_hidden;                    // 隐藏 POI 文字
    bool road_labels_hidden;                   // 隐藏路名
    bool disable_network_gzip_header;          // 关闭网络 gzip 头
    bool need_force_render;                    // 是否需要强制刷新
    float limit_min_zoom;                      // 限制最小级别,最小 3
    float limit_max_zoom;                      // 限制最大级别,最大 20

    // Adapter(必填,见 §3)
    awk_render_adapter_t       render_adapter;
    awk_file_adapter_t         file_adapter;
    awk_memory_adapter_t       memory_adapter;
    awk_fast_memory_adapter_t  fast_memory_adapter;     // 可选
    awk_network_adapter_t      network_adapter;
    awk_thread_adapter_t       thread_adapter;
    awk_system_adapter_t       system_adapter;
    awk_map_tile_file_adapter_t tile_file_adapter;       // 仅 POI 模式必填
    awk_map_custom_adapter_t    custom_adapter;          // 可选,仅部分厂商
} awk_context_t;

2.3 初始化与反初始化

awk_context_t ctx;
memset(&ctx, 0, sizeof(ctx));               // 务必先 memset 清零
ctx.device_id = "abc-1234";
ctx.key       = "your_amap_key";
ctx.root_dir  = "/data/awksdk";
ctx.tile_style = AWK_MAP_TILE_STYLE_GRID_AND_POI;
ctx.tile_load_mode = AWK_MAP_TILE_LOAD_ONLINE;
ctx.tile_pixel_mode = AWK_PIXEL_MODE_ARGB_8888;
ctx.tile_disk_cache_max_size = 200;         // 200 MB
ctx.tile_mem_cache_max_size  = 512;         // 512 KB
// ... 填充所有 adapter(见 §3)

int32_t ret = awk_init(&ctx);
if (ret != 0) {
    // 错误码对照见 §7
}

// ... 业务结束时
awk_uninit();                                // 必须在与 awk_init 相同线程调用

2.4 tile_style 选择

枚举

含义

依赖 feature

AWK_MAP_TILE_STYLE_STANDARD_GRID

0

1x 栅格

TILE

AWK_MAP_TILE_SATELLITE

1

1x 卫星

TILE

AWK_MAP_TILE_STYLE_GRID_AND_POI

2

无 POI 底图 + 动态 POI 文字

TILE + POI

AWK_MAP_TILE_STYLE_VECTOR

3

矢量地图

SVG

AWK_MAP_TILE_STYLE_ROAD_AND_POI

4

路网 + POI

POI

AWK_MAP_TILE_STYLE_ROAD_GRID

5

路网栅格

TILE

AWK_MAP_TILE_STYLE_IMAGE_BINARY

6

图片二进制

IMAGE_BIN

AWK_MAP_TILE_STYLE_IMAGE_BINARY_AND_POI

7

无 POI 图片二进制 + 动态 POI

IMAGE_BIN + POI

  • 手表:常用 GRID_AND_POI 或 VECTOR
  • 眼镜:常用 GRID_AND_POI 或 ROAD_AND_POI(SVG 默认关闭)

2.5 设备激活

设备首次使用需要联网激活:

awk_device_activate_param_t param = {
    .area      = "mainland",   // mainland / overseas
    .country   = "cn",
    .type      = 0,            // 0 新激活, 1 恢复出厂, 2 续约
    .data_type = "raster"      // raster / vector
};

awk_device_active_callback cb = {
    .awk_device_active_on_success = on_active_success,
    .awk_device_active_on_fail    = on_active_fail
};

awk_activate_device(&param, cb);

第二次启动时可先检查:

if (!awk_check_device_activated(&param, &ctx)) {
    awk_activate_device(&param, cb);
}

2.6 创建地图

awk_map_view_param_t mp;
mp.port.width  = 320;
mp.port.height = 320;
mp.map_view_rect = (awk_rect_area_t){ 0, 0, 320, 320 };

int32_t map_id = awk_map_create_view(mp);   // > 0 即为成功

后续地图 API 使用 map_id 作为目标。

三、Adapter 实现指南

所有 adapter 函数都是必填字段(除特别标注外),不填会导致 awk_init 返回 -200 ~ -800 系列错误码。

3.1 render_adapter — 渲染

struct _awk_render_adapter_t {
    void (*begin_drawing)        (uint32_t map_id, awk_render_context_t status);
    void (*commit_drawing)       (uint32_t map_id);
    void (*draw_point)           (uint32_t map_id, awk_point_t *point, uint32_t n, const awk_paint_style_t *style);
    void (*draw_polyline)        (uint32_t map_id, awk_point_t *points, uint32_t n, const awk_paint_style_t *style);
    void (*draw_polygon)         (uint32_t map_id, awk_point_t *points, uint32_t n, const awk_paint_style_t *style);
    void (*draw_bitmap)          (uint32_t map_id, awk_rect_area_t area, awk_bitmap_t bitmap, const awk_paint_style_t *style);
    void (*draw_image_buffer)    (uint32_t map_id, awk_rect_area_t area, const awk_image_buf_info_t *info, const awk_paint_style_t *style);
    void (*draw_text)            (uint32_t map_id, awk_point_t center, const char *text, const awk_paint_style_t *style);
    void (*draw_color)           (uint32_t map_id, awk_rect_area_t area, const awk_paint_style_t *style);
    bool (*measure_text)         (uint32_t map_id, const char *text, const awk_paint_style_t *style,
                                  int32_t *width, int32_t *ascender, int32_t *descender);
    void (*draw_svg_bitmap)      (uint32_t map_id, awk_rect_area_t area, awk_bitmap_t bitmap);
};

必填检查(awk_check_context 返回错误码):

字段

错误码

何时必填

begin_drawing

-200

始终

commit_drawing

-201

始终

draw_point

-202

始终

draw_polyline

-203

始终

draw_polygon

-204

始终

draw_bitmap

-205

始终

draw_color

-206

始终

draw_text

-207

tile_style = GRID_AND_POI / ROAD_AND_POI

measure_text

-208

同上

位图像素格式:awk_bitmap_t::pixel_mode 由 awk_context_t.tile_pixel_mode 决定。常见组合:

  • ARGB_8888 / RGBA_8888:彩屏 + 充足显存
  • RGB_565 / BGR_565:紧显存设备常用(16 位减少带宽)
  • GREY:单色屏

最小示例

static void render_begin(uint32_t map_id, awk_render_context_t status) {
    // 准备 Canvas/Context;status 含视口、地图姿态等
}
static void render_commit(uint32_t map_id) {
    // 把累积的绘制提交到屏幕(SwapBuffer 或刷新 framebuffer)
}
static void render_bitmap(uint32_t map_id, awk_rect_area_t area,
                          awk_bitmap_t bm, const awk_paint_style_t *style) {
    // 把 bm.buffer 按 bm.pixel_mode 拷到 area 区域
}
static void render_polyline(uint32_t map_id, awk_point_t *pts, uint32_t n,
                            const awk_paint_style_t *style) {
    // 颜色 style->color 是 ARGB;宽度 style->width
}
// 其他类似

真机实现:直接操作 framebuffer,或对接厂商 GUI 库(LVGL / NemaGFX / 厂商自研栈),把 area 转成 GUI 库的 update region 即可。measure_text 通常用 freetype 或厂商字体引擎实现。 仓库自带的 iOS 参考工程(见 §6.1)用 CoreGraphics 演示了一套实现,仅供对照;其他 PC 宿主(Mac CLI / Linux)也可以按相同接口自建。

3.2 file_adapter — 文件系统

struct _awk_file_adapter_t {
    void*  (*file_open)        (const char *filename, const char *mode);
    int    (*file_close)       (void *handler);
    size_t (*file_read)        (void *ptr, size_t size, void *handler);
    size_t (*file_write)       (void *ptr, size_t size, void *handler);
    long   (*file_tell)        (void *handler);
    int    (*file_seek)        (void *handler, long offset, int where);
    int    (*file_flush)       (void *handler);
    bool   (*file_exists)      (const char *path);
    int    (*file_remove)      (const char *path);
    bool   (*file_dir_exists)  (const char *path);
    int    (*file_mkdir)       (const char *path, uint16_t mode);
    int    (*file_rmdir)       (const char *path);
    void*  (*file_opendir)     (const char *path);
    int    (*file_closedir)    (void *dir);
    bool   (*file_readdir)     (void *dir, awk_readdir_result *result);
    size_t (*file_get_size)    (const char *path);
    long   (*file_get_last_access)(const char *path);
    int    (*file_rename)      (const char *old_name, const char *new_name);
    bool   (*file_unzip)       (const char *zip_file, const char *out_dir);  // 可选
};

必填检查:上表中除 file_unzip 外全部必填(错误码 -300 ~ -316)。

POSIX 参考实现(适用于支持完整 POSIX 的 RTOS,或 PC 宿主上的 Demo):

static void *fa_open(const char *p, const char *m)        { return fopen(p, m); }
static int   fa_close(void *h)                            { return fclose((FILE*)h); }
static size_t fa_read (void *b, size_t s, void *h)        { return fread (b, 1, s, (FILE*)h); }
static size_t fa_write(void *b, size_t s, void *h)        { return fwrite(b, 1, s, (FILE*)h); }
static long  fa_tell (void *h)                            { return ftell ((FILE*)h); }
static int   fa_seek (void *h, long o, int w)             { return fseek ((FILE*)h, o, w); }
static int   fa_flush(void *h)                            { return fflush((FILE*)h); }
static bool  fa_exists(const char *p)                     { return access(p, F_OK) == 0; }
static int   fa_remove(const char *p)                     { return remove(p); }
static int   fa_mkdir (const char *p, uint16_t m)         { return mkdir(p, m); }
static int   fa_rmdir (const char *p)                     { return rmdir(p); }

static bool fa_dir_exists(const char *p) {
    struct stat st;
    return stat(p, &st) == 0 && S_ISDIR(st.st_mode);
}
static void *fa_opendir (const char *p)                   { return opendir(p); }
static int   fa_closedir(void *d)                         { return closedir((DIR*)d); }

static bool fa_readdir(void *dir, awk_readdir_result *out) {
    // 把目录下所有条目填入 out->nodes(数组由外部分配并管理)
    // 实现示例略;注意越界检查
    return true;
}
static size_t fa_get_size(const char *p) {
    struct stat st; return stat(p, &st) == 0 ? (size_t)st.st_size : 0;
}
static long fa_get_last_access(const char *p) {
    struct stat st; return stat(p, &st) == 0 ? (long)st.st_atime : 0;
}
static int fa_rename(const char *a, const char *b)        { return rename(a, b); }

RTOS 适配:很多 RTOS 仅支持 POSIX 子集,opendir/readdir 等需要替换为厂商等价接口。若设备不支持目录遍历,可考虑维护一个文件清单文件作为 readdir 的模拟。多进程共享 root_dir:SDK 内部没有文件锁,若两个进程共用同一 root_dir 可能损坏 tile_cache.index。多进程场景建议各自使用独立 root_dir;offline_map_dir 因下载后只读可安全共享。

3.3 memory_adapter — 内存

struct _awk_memory_adapter_t {
    void  (*mem_free)   (void *ptr);
    void* (*mem_malloc) (size_t size);
    void* (*mem_calloc) (size_t count, size_t size);
    void* (*mem_realloc)(void *ptr, size_t size);
};

全部必填(错误码 -400 ~ -403)。最简单的实现:

static void  *ma_malloc (size_t s)            { return malloc(s); }
static void   ma_free   (void *p)             { free(p); }
static void  *ma_calloc (size_t n, size_t s)  { return calloc(n, s); }
static void  *ma_realloc(void *p, size_t s)   { return realloc(p, s); }

3.4 fast_memory_adapter — 大内存优化(可选)

struct _awk_fast_memory_adapter_t {
    void  (*mem_free)  (void *ptr);
    void* (*mem_malloc)(size_t size, int type);  // type=0 瓦片缓存 / type=1 瓦片绘制
};

适用于宿主有专用大内存池(如 PSRAM)的眼镜平台。若不需要,留 NULL,SDK 会回退到普通 memory_adapter。

3.5 network_adapter — 网络

struct _awk_network_adapter_t {
    uint64_t (*send)   (awk_http_request_t *request, awk_http_response_callback_t *callback);
    void     (*cancel) (uint64_t request_id);
};

必填(错误码 -600 / -601)。

关键约定

  • send 必须返回唯一 request_id(自增即可),用于 cancel
  • HTTP 请求体可以在异步线程发起,但 callback 必须切回主流程线程调用
  • request 由 SDK 维护生命周期,adapter 不要释放

响应回调

struct _awk_http_response_callback_t {
    void (*on_receive_header)(awk_http_response_callback_t*, const awk_http_response_t*);
    void (*on_receive_body)  (awk_http_response_callback_t*, const awk_http_response_t*);
    void (*on_fail)          (awk_http_response_callback_t*, const awk_http_response_t*, int32_t error);
    void (*on_success)       (awk_http_response_callback_t*, const awk_http_response_t*);
    void (*on_canceled)      (awk_http_response_callback_t*, const awk_http_response_t*);
};
  • on_receive_header 最多回调 1 次
  • on_receive_body 可分多次回调(流式)
  • 终态三选一:on_success / on_fail / on_canceled

最小示例骨架

static uint64_t s_req_seq = 0;

static uint64_t net_send(awk_http_request_t *req, awk_http_response_callback_t *cb) {
    uint64_t id = ++s_req_seq;
    // 投递到工作队列,异步执行 HTTP
    enqueue_http_task(id, req, cb);
    return id;
}
static void net_cancel(uint64_t id) {
    cancel_http_task(id);
}

3.6 system_adapter — 系统

struct _awk_system_adapter_t {
    uint64_t (*get_system_time)(void);                   // 单位 ms
    int      (*log_printf)     (const char *fmt, ...);
};

必填(错误码 -500 / -501)。

static uint64_t sa_time(void) {
    struct timespec ts; clock_gettime(CLOCK_REALTIME, &ts);
    return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
static int sa_log(const char *fmt, ...) {
    va_list ap; va_start(ap, fmt);
    int r = vprintf(fmt, ap);
    va_end(ap);
    return r;
}

注意:get_system_time 必须返回真实墙钟时间(用于 license 校验、tile 时效)。如果 RTOS 没有硬件 RTC,需要在联网后用 NTP 同步。

3.7 thread_adapter — 线程

typedef struct _awk_thread_adapter_t {
    uint64_t (*get_thread_id)(void);
} awk_thread_adapter_t;

必填(错误码 -701)。仅用于校验调用线程是否与 awk_init 时一致。

static uint64_t ta_tid(void) { return (uint64_t)pthread_self(); }

3.8 tile_file_adapter — 离线瓦片文件

typedef struct _awk_map_tile_file_adapter_t {
    bool (*on_tile_file)(const char *tile_file_key,
                         char *file_path, size_t *file_offset, size_t *file_size);
} awk_map_tile_file_adapter_t;

仅当 tile_style = GRID_AND_POI 或 ROAD_AND_POI 时必填(错误码 -800)。SDK 给一个瓦片 key,宿主返回对应的文件路径、偏移、长度。

3.9 custom_adapter — 定制接口(可选)

typedef struct _awk_map_custom_adapter_t {
    int  (*custom_sscanf)(const char *s, const char *format, ...);
    void (*custom_assert)(int expression);
} awk_map_custom_adapter_t;

某些不带 libc 的 RTOS 厂商需要外部实现 sscanf 和 assert。普通平台留 NULL。

四、地图 API 参考

4.1 生命周期与渲染

API

说明

int32_t awk_map_create_view(awk_map_view_param_t param)

创建地图实例,返回 map_id (>0 成功)

int32_t awk_map_destroy_view(uint32_t map_id)

销毁实例

int32_t awk_map_pause_render(uint32_t map_id)

暂停某实例渲染

int32_t awk_map_resume_render(uint32_t map_id)

恢复某实例渲染

int32_t awk_map_do_render(void)

主动触发一次渲染(驱动绘制)

int32_t awk_map_set_render_callback(awk_map_render_callback_t cb)

设置渲染过程回调(开始/结束、tile/poi 下载等)

渲染回调结构(awk_map_render_callback_t)部分关键回调:

bool (*on_tile_begin_draw)     (uint32_t map_id, uint32_t tx, uint32_t ty, uint32_t zoom);
void (*on_tile_end_draw)       (uint32_t map_id, uint32_t tx, uint32_t ty, uint32_t zoom, int32_t status);
bool (*on_tile_begin_download) (int32_t type, uint32_t tx, uint32_t ty, uint32_t zoom);
void (*on_tile_end_download)   (int32_t type, uint32_t tx, uint32_t ty, uint32_t zoom, awk_map_tile_response_status_t status);
bool (*on_poi_begin_draw)      (uint32_t map_id, uint32_t tx, uint32_t ty, uint32_t zoom);
void (*on_poi_end_draw)        (uint32_t map_id, uint32_t tx, uint32_t ty, uint32_t zoom, int32_t status);
bool (*on_point_begin_draw)    (uint32_t map_id, int32_t guid);
void (*on_point_end_draw)      (uint32_t map_id, int32_t guid, int32_t status);
// 还有 line / polygon / img_bin 等系列

on_*_begin_* 返回 false 表示放弃绘制/下载该项。

4.2 视图与坐标

API

说明

int32_t awk_map_set_center(uint32_t map_id, awk_map_coord2d_t coord)

设置中心点经纬度

int32_t awk_map_set_level(uint32_t map_id, float level)

设置缩放级别(3 ~ 20)

float awk_map_get_level(uint32_t map_id)

获取当前级别

int32_t awk_map_set_view_port(uint32_t map_id, awk_map_view_port_t port)

设置视口尺寸

int32_t awk_map_set_map_view_rect(uint32_t map_id, awk_rect_area_t rect)

设置展示区域

int32_t awk_map_set_map_view_anchor(uint32_t map_id, awk_map_view_anchor_t anchor)

设置锚点(0~1)

int32_t awk_map_set_roll_angle(uint32_t map_id, float angle)

设置旋转角(部分 tile_style 不支持)

int32_t awk_map_get_posture(uint32_t map_id, awk_map_posture_t *out)

获取姿态(中心、级别、锚点、旋转)

int32_t awk_map_set_visible_bounds(uint32_t map_id, awk_navi_point_bounds_t bounds, awk_edge_insets_t insets)

设置可见区域

int32_t awk_map_get_map_bounds(uint32_t map_id, awk_map_base_overlay_t *overlay, awk_map_coord2d_t *ne, awk_map_coord2d_t *sw, float *level)

获取覆盖物或全局外接矩形

int32_t awk_map_lonlat_to_xy(uint32_t map_id, awk_map_coord2d_t lonlat, int32_t *x, int32_t *y)

经纬度 → 屏幕坐标

int32_t awk_map_xy_to_lonlat(uint32_t map_id, int32_t x, int32_t y, awk_map_coord2d_t *lonlat)

屏幕坐标 → 经纬度

double awk_map_calc_points_distance(double lon1, double lat1, double lon2, double lat2)

两点距离(米)

void awk_map_wgs84_to_mgs(double lng_wgs, double lat_wgs, double *lng, double *lat)

WGS84 → GCJ02

4.3 交互(手势)

API

说明

int32_t awk_map_touch_begin(uint32_t map_id, int32_t x, int32_t y)

拖动开始

int32_t awk_map_touch_update(uint32_t map_id, int32_t x, int32_t y)

拖动中

int32_t awk_map_touch_end(uint32_t map_id, int32_t x, int32_t y)

拖动结束

awk_map_point_overlay_t** awk_map_click_points(uint32_t map_id, int32_t x, int32_t y, int32_t *count)

单击命中点覆盖物(按 priority 倒序)

int32_t awk_map_release_overlays(awk_map_base_overlay_t **arr, int32_t n)

释放上面接口返回的数组

4.4 覆盖物

纹理(点 icon)

int32_t  awk_map_add_texture   (const awk_map_texture_data_t *data);     // 返回 texture_id
int32_t  awk_map_update_texture(uint32_t texture_id, const awk_map_texture_data_t *data);
int32_t  awk_map_remove_texture(uint32_t texture_id);

点/线/面/轨迹(共用接口)

int32_t awk_map_init_point_overlay  (awk_map_point_overlay_t *o);
int32_t awk_map_init_line_overlay   (awk_map_polyline_overlay_t *o);
int32_t awk_map_init_polygon_overlay(awk_map_polygon_overlay_t *o);

int32_t awk_map_add_overlay   (uint32_t map_id, awk_map_base_overlay_t *o);
int32_t awk_map_update_overlay(uint32_t map_id, awk_map_base_overlay_t *o);
int32_t awk_map_remove_overlay(uint32_t map_id, uint32_t overlay_id);
const awk_map_base_overlay_t* awk_map_find_overlay(uint32_t map_id, uint32_t overlay_id);
const awk_map_base_overlay_t* awk_map_get_overlay (uint32_t map_id, uint32_t index);
uint32_t awk_map_get_overlay_count(uint32_t map_id);

核心结构

typedef struct _awk_map_base_overlay_t {
    awk_map_overlay_type geometry_type;   // POINT / LINE / POLYGON / TRACK_NAVI
    int32_t  group_id;
    int32_t  map_id;
    int32_t  priority;
    bool     visible;
    bool     is_focus;
    float    min_level;                   // 可显示的最小级别
    float    max_level;                   // 可显示的最大级别
    int32_t  guid;                        // 由调用方分配
} awk_map_base_overlay_t;

点覆盖物有 normal_marker / focus_marker,每个包含 icon_texture / name_texture / bubble_texture。 线覆盖物支持虚线、鱼骨箭头、走过路线 (pre_index) 等。

4.5 瓦片预加载与缓存

API

说明

int32_t awk_map_request_tiles(awk_rect_area_t rect, awk_map_coord2d_t center, float level, int32_t priority)

预加载某区域瓦片

int32_t awk_map_cancel_request_tiles(int32_t req_id)

取消预加载

int32_t awk_clear_disk_cache(void)

清磁盘缓存

int32_t awk_clear_memory_cache(awk_memory_cache_type_t type)

清内存缓存(TILE / POI 位掩码)

awk_tile_style_t awk_tile_style_with_path(char *dir_path)

检测目录下离线瓦片类型(GRID/VECTOR)

4.6 离线数据下载(仅手表,需 OFFLINE feature)

int32_t awk_map_start_download_offline_data(const char *adcode, uint32_t level, awk_map_download_callback_t *cb);
int32_t awk_map_stop_download_offline_data(void);

int32_t awk_map_start_download_region_range(awk_map_coord2d_t center, awk_map_range_t range,
                                            uint8_t expect_level, awk_map_download_callback_t *cb);
int32_t awk_map_stop_download_region_range(void);

int32_t awk_map_list_download_offline_regions(const char *adcode, uint32_t level,
                                              awk_map_offline_gdb_query_result_t *out);
int32_t awk_map_delete_download_offline_region(const char *adcode, uint32_t level);

int32_t awk_map_list_download_region_range(awk_map_coord2d_t loc, awk_map_range_t range,
                                           uint8_t expect_level, awk_map_offline_gdb_query_result_t *out);
int32_t awk_map_delete_download_region_range(awk_map_coord2d_t loc, awk_map_range_t range, uint8_t expect_level);

int32_t awk_map_sync_download_offline_region(void);
int32_t awk_map_list_region_levels(awk_map_coord2d_t loc, uint8_t *expect_levels, int32_t n,
                                   awk_map_offline_gdb_query_result_t *out);

// 沿路下载
int32_t awk_map_download_polyline_region(const char *key, awk_map_coord2d_t *pts, uint32_t n,
                                         uint8_t *expand_levels, uint8_t expand_levels_n,
                                         awk_map_tile_download_callback_t *cb);

// 获取瓦片请求(高级用法,外部自管下载)
awk_http_request_t* awk_map_download_get_request(const char *tile_file_key);
int32_t awk_map_sync_tile_file(char **keys, uint32_t n);

下载回调

struct _awk_map_download_callback_t {
    void (*on_started) (awk_map_download_callback_t *cb);
    void (*on_progress)(awk_map_download_callback_t *cb, float progress);
    void (*on_finish)  (awk_map_download_callback_t *cb);
    void (*on_stop)    (awk_map_download_callback_t *cb);
    void (*on_error)   (awk_map_download_callback_t *cb, int32_t code, const char *msg);
};

下载不支持并发,需顺序执行。

4.7 轨迹导航 / 循迹(仅手表,需 TRACK_NAVI feature)

awk_map_track_info_t* awk_map_track_navi_parse_gpx(const char *gpx, size_t len);
void                  awk_map_track_navi_parse_track_info_free(awk_map_track_info_t *info);

int32_t awk_map_init_track_navi_overlay  (awk_map_track_navi_overlay_t *o);
int32_t awk_map_track_navi_add_overlay   (uint32_t map_id, awk_map_track_navi_overlay_t *o);
int32_t awk_map_track_navi_remove_overlay(uint32_t map_id, uint32_t overlay_id);

void   awk_map_track_navi_update_real_point(uint32_t map_id, awk_map_coord2d_t pt, float bear,
                                            awk_map_track_navi_overlay_t *o);
double awk_map_track_navi_get_distance     (uint32_t map_id, awk_map_coord2d_t pt,
                                            awk_map_track_point_type ptype,
                                            awk_map_track_navi_overlay_t *o);

轨迹覆盖物 awk_map_track_navi_overlay_t 包含规划线、实走线、偏航线、转向点图标和事件监听 (on_track_pass_point / on_trajector_yaw / on_navi_event)。

五、导航 API 参考

导航功能依赖 NAVI feature。手表和眼镜默认都启用。

导航构建在地图层之上:必须先 awk_init 并 awk_map_create_view 拿到 map_id,再 awk_init_navi 启动导航服务。

5.1 生命周期

int32_t awk_init_navi      (awk_navi_config_t *config);      // 启动导航数据通路
int32_t awk_uninit_navi    (void);
int32_t awk_init_navi_view (uint32_t map_id, awk_navi_view_config_t *vc);  // 启动导航 UI
int32_t awk_uninit_navi_view(void);
  • 调用 awk_init_navi 后,仅有数据回调;若需要 SDK 内部画导航 UI(车标、路线高亮等),再调 awk_init_navi_view
  • 导航期间外部不要直接操作地图(如旋转、缩放),与内部冲突
  • awk_navi_get_map_id() 返回当前导航绑定的 map_id

5.2 数据输入

导航数据由宿主以 protobuf 格式喂入:

int32_t awk_navi_data(const uint8_t *data, size_t len);
// 返回 0 成功;负值为数据类型相关错误(详见头文件)
// -10000 外层包装异常;-10001 反初始化后调用

5.3 视图控制

API

说明

int32_t awk_navi_should_autorotate_car(bool b)

是否允许内部自动旋转车标(默认 false)

int32_t awk_navi_set_car_angle(float angle)

手动设置车标角度(需先关闭自动)

int32_t awk_navi_set_tracking_mode(awk_navi_tracking_mode_type m)

北朝上 / 车头朝上 / 路线朝上

int32_t awk_navi_set_show_mode(awk_navi_show_mode_type m)

NONE / 锁车 / 全览

int32_t awk_navi_set_locked_overlay_type(awk_navi_locked_overlay_type t)

锁车状态下顶部显示地图还是速度

int32_t awk_navi_show_ui_elements(bool b)

是否显示界面元素(默认 false)

int32_t awk_navi_set_map_level(uint32_t map_id, float level)

导航过程中调整地图级别

bool awk_navi_is_navigating(void)

是否正在导航

5.4 回调监听

int32_t awk_navi_add_data_callback   (awk_navi_data_callback_t *cb);
int32_t awk_navi_remove_data_callback(awk_navi_data_callback_t *cb);
int32_t awk_navi_add_event_callback   (awk_navi_event_callback_t *cb);
int32_t awk_navi_remove_event_callback(awk_navi_event_callback_t *cb);

数据回调(awk_navi_data_callback_t) 关键字段:

void (*update_navi_route_group)(...);   // 路线更新
void (*update_navi_info)       (...);   // 行中导航信息(剩余距离/时间/下一动作)
void (*update_navi_location)   (...);   // 自车位置
void (*update_turn_info)       (...);   // 当前路口转向图标
void (*update_next_turn_info)  (...);   // 下下路口转向
void (*show_rear_appr_vehicle) (...);   // 后方来车提醒(显示)
void (*hide_rear_appr_vehicle) (...);   // 后方来车提醒(隐藏)
void (*show_traffic_signal)    (...);   // 红绿灯倒计时(显示)
void (*hide_traffic_signal)    (...);
void (*show_lane_info)         (...);   // 车道线
void (*hide_lane_info)         (...);
void (*show_traffic_light_num) (..., int32_t num, ...);

事件回调(awk_navi_event_callback_t) 关键字段:

void (*update_navi_calc_success)(...);  // 算路成功
void (*update_navi_calc_failed) (...);  // 算路失败
void (*did_start_navi)          (...);  // 开始导航
void (*play_navi_sound_string)  (...);  // 播报
void (*arrived_way_point)       (...);  // 到达途经点
void (*update_tracking_mode)    (...);  // 跟随模式变更
void (*update_show_mode)        (...);  // 显示模式变更
void (*update_is_navigation)    (...);  // 是否在导航
void (*on_reset)                (...);
void (*update_highlight_route)  (...);  // 高亮路线变更
void (*stop_navi)               (...);  // 停止导航
void (*on_arrived_destination)  (...);  // 到达终点
void (*show_map)                (..., uint32_t map_id, bool show);  // 显隐地图

5.5 枚举与类型

typedef enum {
    AWK_NAVI_TRACKING_MODE_MAP_NORTH,   // 0 正北朝上
    AWK_NAVI_TRACKING_MODE_CAR_NORTH,   // 1 车头朝上
    AWK_NAVI_TRACKING_MODE_ROUTE_NORTH  // 2 路线朝上
} awk_navi_tracking_mode_type;

typedef enum {
    AWK_NAVI_SHOW_MODE_NONE,
    AWK_NAVI_SHOW_MODE_CAR_POSITION_LOCKED,
    AWK_NAVI_SHOW_MODE_OVERVIEW,
} awk_navi_show_mode_type;

typedef enum {
    AWK_NAVI_LOCKED_OVERLAY_NONE,
    AWK_NAVI_LOCKED_OVERLAY_MAP,
    AWK_NAVI_LOCKED_OVERLAY_SPEED
} awk_navi_locked_overlay_type;

更详细的导航事件/回调字段(awk_navi_route_group_t / awk_navi_info_t / awk_navi_location_t 等结构),见 include/navi/awk_navi_defines.h。

六、Demo / Harness 验证

SDK 本体是 C 语言静态库,最终部署在 RTOS 设备上。真机调试链路慢、可观测性弱,因此推荐的工作流是:先在 PC 端宿主上用同一份 SDK 把流程跑通,再换 adapter 部署到 RTOS 真机

仓库提供两类验证手段:

  • 上层 Demo:用任意一种能跑 C 的宿主(iOS App / Mac CLI / Linux / Android 等)实现一套 adapter,把 SDK 静态库链入,跑通主流程
  • 事件流 Harness:基于日志关键字做断言,可在 Demo 宿主或 RTOS 真机上跑,用于自动化回归

两者都不是最终交付形态,但能在厂商对接真机前把 SDK 行为收敛。

6.1 上层 Demo(以 iOS 工程为参考)

定位:宿主仅作为验证容器,目的不是发布 iOS 应用。SDK 是同一份 C 库,宿主可以是任意能跑 C 的环境(iOS / Mac / Linux / Android / 厂商 PC 工具),各家按需自建即可。

仓库自带的 iOS 参考工程(test/WatchSDKDemo/WatchSDKDemo.xcodeproj)用 CoreGraphics / NSURLSession / POSIX 文件接口实现了一套完整 adapter,可直接在 iOS 模拟器上看到地图绘制结果,便于快速对照。

运行 iOS 参考工程

# 用 Xcode 打开
open test/WatchSDKDemo/WatchSDKDemo.xcodeproj

# 或命令行编译
xcodebuild build \
  -project test/WatchSDKDemo/WatchSDKDemo.xcodeproj \
  -scheme WatchSDKDemo \
  -configuration Debug \
  -destination 'generic/platform=iOS Simulator'

判断成功的关键信号(任何宿主都通用):

  1. awk_init 返回 0
  2. awk_map_create_view 返回 > 0 的 map_id
  3. render_adapter.begin_drawing 持续被调用
  4. on_tile_begin_download → on_tile_end_download 链路成功(在线模式)
  5. 屏幕(或 framebuffer 抓帧)显示出地图瓦片

厂商对接建议:先用熟悉的 PC 宿主实现一遍 adapter(甚至 Mac 上写个命令行程序也行),把上面 5 个信号跑通;然后再把 adapter 移植到 RTOS 真机,只需替换平台相关的实现,业务逻辑无需变动。

6.2 Harness 事件流验证

位置:script/harness/run_requirement_harness.sh

适用于 RTOS 真机或 iOS 参考工程上的自动化回归。Harness 基于事件流(日志关键字)做断言,能验证:

  • SDK 初始化是否成功
  • 网络请求路径与 payload
  • 缓存文件生成情况
  • DAU 上报链路是否打通

基本用法

# 默认用例
./script/harness/run_requirement_harness.sh

# 指定 case
./script/harness/run_requirement_harness.sh <case_name>

需要在环境中预设:

export WATCH_SDK_DEMO_DIR=/path/to/WatchSDKDemo
export DEMO_PROJECT_DIR=$WATCH_SDK_DEMO_DIR/AMapWatch
export SIMULATOR_UDID=<your-booted-ios-simulator-udid>
export LOG_PREFIX="[RTOS_DAU]"           # 或对应业务前缀

关键事件日志前缀

前缀

模块

[RTOS_DAU]

DAU 上报

[RTOS_INIT]

初始化链路

[RTOS_TILE]

瓦片下载/绘制

[RTOS_NAVI]

导航数据/事件

详细原理参见 doc/requirement_development_harness.md

七、错误码速查

7.1 awk_init 返回码

范围

含义

0

成功

-1

已初始化,不能重复

-100

context 为空

-101

key 为空

-102

device_id 为空

-103

root_dir 为空

-200 ~ -208

render_adapter 函数指针缺失

-300 ~ -316

file_adapter 函数指针缺失

-400 ~ -403

memory_adapter 函数指针缺失

-500 ~ -501

system_adapter 函数指针缺失

-600 ~ -601

network_adapter 函数指针缺失

-701

thread_adapter.get_thread_id 缺失

-800

tile_file_adapter.on_tile_file 缺失(POI 模式必填)

-900

POI 功能被禁用但 tile_style 需要 POI

-901

SVG 功能被禁用但 tile_style 需要 SVG

-902

TILE 功能被禁用但 tile_style 需要 TILE

具体到字段,参考 src/awk.c::awk_check_context() / awk_check_feature()。

7.2 通用错误码

含义

-1

未初始化

-3

线程不一致(与 awk_init 不在同一线程)

7.3 地图常见错误码

含义

-2

找不到对应 map_id 实例 / license 校验失败 / 参数为 NULL

-4

参数非法(如 level 越界)

7.4 设备激活错误码

含义

30046

license 数量超过限制

30047

license 已存在

30048

license 已被禁用

30049

license 超过有效期

八、常见问题

Q1:awk_init 返回 -900 / -901 / -902 怎么办?

tile_style 与编译时启用的 feature 不匹配。例如眼镜默认未启用 SVG,但 tile_style 设成 AWK_MAP_TILE_STYLE_VECTOR 就会返回 -901。改用支持的 tile_style,或与 SDK 提供方确认平台 feature 集合。

Q2:awk_init 返回 -200 系列怎么办?

render_adapter 中某个函数指针为 NULL。对照 §7.1 表格定位具体哪一个,补上实现即可。

Q3:调用任意 API 返回 -3?

调用线程与 awk_init 时不一致。SDK 是单线程模型,所有 API(包括网络回调注入数据)必须切回主流程线程。

Q4:多实例(多张地图同屏)注意事项?

  • 每个 awk_map_create_view 返回独立 map_id,可同时存在多个
  • 退出页面/不再使用时必须调用 awk_map_destroy_view 释放
  • 渲染回调 awk_map_render_callback_t 是全局的,需在回调内部通过 map_id 区分实例

Q5:内存/磁盘缓存大小如何选?

RTOS 设备普遍紧内存,建议根据可用 PSRAM / 闪存按需调整:

  • 内存缓存:受 PSRAM 大小约束;开 tile_clip_load=true 可显著降低瓦片缓冲占用
  • 磁盘缓存:受闪存大小约束;默认 200 MB 通常需要按设备闪存余量下调
  • 像素格式:彩屏选 ARGB_8888;紧显存选 RGB_565 / BGR_565;单色屏选 GREY

Q6:多进程共用 root_dir 会有问题吗?

会。SDK 内部没有跨进程文件锁,多个进程同时写 tile_cache.index 会损坏索引。 多进程场景下,请每个进程使用独立的 root_dir。 offline_map_dir 因为下载完成后只读,可以安全共享。

Q7:网络请求回调能在异步线程吗?

send 可以在异步线程内部发起 HTTP,但 awk_http_response_callback_t 的回调必须切回主流程线程,否则 SDK 内部线程检查会失败。

Q8:导航开了,但 SDK 不画 UI 怎么办?

只调用 awk_init_navi 不会画 UI,只回调数据。需要 SDK 内部绘制时必须再调用 awk_init_navi_view(map_id, vc)。 同时检查 awk_navi_show_ui_elements(true) 是否打开。

九、延伸阅读

权威头文件(凡本文档与头文件冲突,以头文件为准):

  • include/awk.h
  • include/awk_adapter.h
  • include/awk_version.h
  • include/map/awk_map.h
  • include/map/awk_map_defines.h
  • include/navi/awk_navi.h
  • include/navi/awk_navi_defines.h
本页目录
返回顶部 示例中心 常见问题 智能客服 公众号
二维码