开发 RTOS 地图SDK 开发指南 专业导航 循迹导航

循迹导航 最后更新时间: 2025年06月05日

使用循迹导航功能,和添加覆盖物的前置流程是一致的,需要先初始化、激活设备、创建地图等必要的操作。

循迹导航数据生成及绘制

awk_map_track_info_t *track_info = NULL;
awk_map_track_navi_overlay_t trackNaviOverlay;
std::map<uint32_t, std::vector<uint32_t>> _textures;

//解析文件并生成数据
char file_path[256] = ''; //此处使用您存储数据的真实地址
size_t file_size = 0;
FILE *file = fopen(file_path, "rb+");
if (file) {
    fseek(file, 0, SEEK_END);
    file_size = ftell(file);
    fseek(file, 0, SEEK_SET);

    char *file_buffer = (char*)malloc(file_size);
    fread(file_buffer, file_size, 1, file);

    track_info = awk_map_track_navi_parse_gpx(file_buffer, file_size);

    fclose(file);
    free(file_buffer);
}

//请注意,【下面设置的数据均为模拟数据,请根据实际情况设置】

if (track_info) {
    // 生成测试途经点
    size_t pass_point_size = track_info->point_size / 50;
    track_info->via_point_index_size = pass_point_size;
    track_info->via_point_indexes = (int32_t*)malloc(sizeof(int32_t) * pass_point_size);
    int32_t index = 0;
    for (int32_t i = 50; i < track_info->point_size - 1; i+=50) {
        track_info->via_point_indexes[index] = i;
        ++index;
    }

    // 生成测试转向点
    size_t turn_point_size = track_info->point_size / 130;
    track_info->turn_point_size = turn_point_size;
    track_info->turn_points = (awk_map_track_turn_point_info_t*)malloc(sizeof(awk_map_track_turn_point_info_t) * track_info->turn_point_size);
    index = 0;
    for (int32_t i = 130; i < track_info->point_size - 1; i+= 130) {
        awk_map_track_turn_point_info_t turn_point_info;
        memset(&turn_point_info, 0, sizeof(awk_map_track_turn_point_info_t));
        turn_point_info.index = i;
        turn_point_info.bear = 100.0F;
        turn_point_info.turn_location_message = "转向位置信息";
        turn_point_info.turn_message = "转向信息";

        track_info->turn_points[index] = turn_point_info;
        ++index;
    }
}

// 添加图标点
awk_map_point_overlay_t pointOverlay;
awk_map_init_point_overlay(&pointOverlay);

pointOverlay.position.lon = 0.0;
pointOverlay.position.lat = 0.0;
pointOverlay.normal_marker.icon_texture.scale = 0.8f;
pointOverlay.normal_marker.icon_texture.anchor_x = 0.5f;
pointOverlay.normal_marker.icon_texture.anchor_y = 0.5f;
pointOverlay.focus_marker.icon_texture.scale = 0.8f;
pointOverlay.focus_marker.icon_texture.anchor_x = 0.5f;
pointOverlay.focus_marker.icon_texture.anchor_y = 0.5f;

awk_map_texture_data_t texture_data;
memset(&texture_data, 0, sizeof(awk_map_texture_data_t));
//请根据自身开发环境获取普通状态下的纹理信息,并赋值给texture_data
loadTexture("WatchEngine.bundle/car.png", &texture_data);
int32_t texture_id = awk_map_add_texture(&texture_data);
_textures[(uint32_t)mapId].emplace_back(texture_id);
pointOverlay.normal_marker.icon_texture.texture_id = texture_id;

if(texture_data.buffer) {
    free(texture_data.buffer);
    texture_data.buffer = NULL;
    texture_data.buffer_size = 0;
}

memset(&texture_data, 0, sizeof(awk_map_texture_data_t));
//请根据自身开发环境获取焦点状态下的纹理信息,并赋值给texture_data
loadTexture("WatchEngine.bundle/car.png", &texture_data);
texture_id = awk_map_add_texture(&texture_data);
_textures[(uint32_t)mapId].emplace_back(texture_id);
pointOverlay.focus_marker.icon_texture.texture_id = texture_id;

awk_map_add_overlay((uint32_t)mapId, (awk_map_base_overlay_t *)&pointOverlay);

if(texture_data.buffer) {
    free(texture_data.buffer);
    texture_data.buffer = NULL;
    texture_data.buffer_size = 0;
}

// 添加覆盖物
memset(&trackNaviOverlay, 0, sizeof(awk_map_track_navi_overlay_t));
awk_map_init_track_navi_overlay(&trackNaviOverlay);

//自定义点图标覆盖物id
trackNaviOverlay.custom_point_point_overlay_id = pointOverlay.base_overlay.guid;

//添加起点
memset(&texture_data, 0, sizeof(awk_map_texture_data_t));
//请根据自身开发环境获取起点的纹理信息,将id赋值给start_marker.icon_texture.texture_id
loadTexture("WatchEngine.bundle/pin_start.png", &texture_data);
texture_id = awk_map_add_texture(&texture_data);
_textures[(uint32_t)mapId].emplace_back(texture_id);

trackNaviOverlay.start_marker.icon_texture.texture_id = texture_id;

//添加终点
if(texture_data.buffer) {
    free(texture_data.buffer);
    texture_data.buffer = NULL;
    texture_data.buffer_size = 0;
}

memset(&texture_data, 0, sizeof(awk_map_texture_data_t));
//请根据自身开发环境获取终点的纹理信息,将id赋值给end_marker.icon_texture.texture_id
loadTexture("WatchEngine.bundle/end_start.png", &texture_data);
texture_id = awk_map_add_texture(&texture_data);
_textures[(uint32_t)mapId].emplace_back(texture_id);

trackNaviOverlay.end_marker.icon_texture.texture_id = texture_id;
trackNaviOverlay.end_marker.icon_texture.anchor_x = 0.5;
trackNaviOverlay.end_marker.icon_texture.anchor_y = 0.5;
trackNaviOverlay.end_marker.icon_texture.scale = 0.8;

if(texture_data.buffer) {
    free(texture_data.buffer);
}

//途经点Icon数量
trackNaviOverlay.navi_options.pass_point_icon_size = 3;
trackNaviOverlay.navi_options.pass_point_icon = (awk_map_point_overlay_marker_t*)malloc(sizeof(awk_map_point_overlay_marker_t) * trackNaviOverlay.navi_options.pass_point_icon_size);
for (int i=0; i<trackNaviOverlay.navi_options.pass_point_icon_size; i++) {
    //请根据自身开发环境获取途径点纹理,并赋值给texture_data
    memset(&texture_data, 0, sizeof(awk_map_texture_data_t));
    NSString *texture_name = [NSString stringWithFormat:@"WatchEngine.bundle/pass_%d.png", i+1];
    loadTexture([texture_name UTF8String], &texture_data);
    int32_t pass_texture_id = awk_map_add_texture(&texture_data);
    _textures[(uint32_t)mapId].emplace_back(texture_id);
    if(texture_data.buffer) {
        free(texture_data.buffer);
    }

    //途经点图标参数设置
    awk_map_point_overlay_marker_t pass_point_icon;
    pass_point_icon.icon_texture.texture_id = pass_texture_id;
    pass_point_icon.icon_texture.scale = 0.8f;
    pass_point_icon.icon_texture.anchor_x = 0.5f;
    pass_point_icon.icon_texture.anchor_y = 0.5f;
    trackNaviOverlay.navi_options.pass_point_icon[i] = pass_point_icon;
}

//转向点Icon数量
trackNaviOverlay.navi_options.turn_point_icon_size = 3;
trackNaviOverlay.navi_options.turn_point_icon = (awk_map_point_overlay_marker_t*)malloc(sizeof(awk_map_point_overlay_marker_t) * trackNaviOverlay.navi_options.turn_point_icon_size);
for (int i=0; i<trackNaviOverlay.navi_options.turn_point_icon_size; i++) {
    //请根据自身开发环境获取纹理,并赋值给texture_data
    memset(&texture_data, 0, sizeof(awk_map_texture_data_t));
    NSString *texture_name = [NSString stringWithFormat:@"WatchEngine.bundle/turn_%d.png", i+1];
    loadTexture([texture_name UTF8String], &texture_data);
    int32_t pass_texture_id = awk_map_add_texture(&texture_data);
    _textures[(uint32_t)mapId].emplace_back(texture_id);
    if(texture_data.buffer) {
        free(texture_data.buffer);
    }

    //转向点图标参数设置
    awk_map_point_overlay_marker_t turn_point_icon;
    turn_point_icon.icon_texture.texture_id = pass_texture_id;
    turn_point_icon.icon_texture.scale = 0.8f;
    turn_point_icon.icon_texture.anchor_x = 0.5f;
    turn_point_icon.icon_texture.anchor_y = 0.5f;
    trackNaviOverlay.navi_options.turn_point_icon[i] = turn_point_icon;
}

//轨迹信息
trackNaviOverlay.track_info = track_info;

//设置循迹导航覆盖物优先级的起始值,内部基于此值会设置具体覆盖物的优先级,为了避免不明确的覆盖问题,开发者设置的其他覆盖物的优先级应该在此区间外:[trackNaviOverlay.base_overlay.priority trackNaviOverlay.base_overlay.priority+20]
trackNaviOverlay.base_overlay.priority = 10000;

//规划线覆盖物纹理信息
trackNaviOverlay.plan_polyline_options.plan_polyline_marker.use_dash = false;
trackNaviOverlay.plan_polyline_options.plan_polyline_marker.line_width = 5;
trackNaviOverlay.plan_polyline_options.plan_polyline_marker.line_color = 0xff0000ff;
trackNaviOverlay.plan_polyline_options.plan_polyline_marker.border_width = 2;
trackNaviOverlay.plan_polyline_options.plan_polyline_marker.border_color = 0xff0000ff;

//实际线覆盖物纹理信息
trackNaviOverlay.real_polyline_options.real_polyline_marker.use_dash = false;
trackNaviOverlay.real_polyline_options.real_polyline_marker.line_width = 5;
trackNaviOverlay.real_polyline_options.real_polyline_marker.line_color = 0xff00ff00;
trackNaviOverlay.real_polyline_options.real_polyline_marker.border_width = 2;
trackNaviOverlay.real_polyline_options.real_polyline_marker.border_color = 0xff00ff00;

//偏航参数设置
//偏航阈值
trackNaviOverlay.yaw_options.yaw_threshold = 200.0F;
//偏航线覆盖物纹理信息设置
trackNaviOverlay.yaw_options.yaw_polyline_marker.use_dash = true;
trackNaviOverlay.yaw_options.yaw_polyline_marker.line_width = 5;
trackNaviOverlay.yaw_options.yaw_polyline_marker.line_color = 0xffff0000;
trackNaviOverlay.yaw_options.yaw_polyline_marker.dash_offset = 0;
trackNaviOverlay.yaw_options.yaw_polyline_marker.dash_painted_length = 5;
trackNaviOverlay.yaw_options.yaw_polyline_marker.dash_unpainted_length = 10;

//轨迹导航参数设置
//轨迹纠偏阈值,小于阈值使用轨迹上的点
trackNaviOverlay.navi_options.point_correcttion_threshold = 20.0F;
//导航事件距离阈值,小于阈值触发,接近,到达都生效
trackNaviOverlay.navi_options.navi_event_distance_threshold = 3.0F;
//途经点接近通知阈值数量
trackNaviOverlay.navi_options.pass_point_around_threshold_size = 3;
//途经点接近通知阈值
trackNaviOverlay.navi_options.pass_point_around_threshold = (double*)malloc(sizeof(double) * trackNaviOverlay.navi_options.pass_point_around_threshold_size);
trackNaviOverlay.navi_options.pass_point_around_threshold[0] = 50.0F;
trackNaviOverlay.navi_options.pass_point_around_threshold[1] = 100.0F;
trackNaviOverlay.navi_options.pass_point_around_threshold[0] = 500.0F;
//转向点接近通知阈值数量
trackNaviOverlay.navi_options.turn_point_around_threshold_size = 1;
//转向点接近通知阈值
trackNaviOverlay.navi_options.turn_point_around_threshold = (double*)malloc(sizeof(double) * trackNaviOverlay.navi_options.turn_point_around_threshold_size);
trackNaviOverlay.navi_options.turn_point_around_threshold[0] = 50.0F;

//添加轨迹导航回调监听方法
trackNaviOverlay.listener.on_navi_event = onTrackNaviEvent;
trackNaviOverlay.listener.on_track_pass_point = onTrackPassPoint;
trackNaviOverlay.listener.on_trajector_yaw = onTrajectorYaw;
trackNaviOverlay.listener.on_trajector_yaw_end = onTrajectoryYawEnd;

//添加轨迹导航overlay
awk_map_track_navi_add_overlay((uint32_t)mapId, &trackNaviOverlay);

free(trackNaviOverlay.navi_options.pass_point_around_threshold);
free(trackNaviOverlay.navi_options.turn_point_around_threshold);
free(trackNaviOverlay.navi_options.pass_point_icon);
free(trackNaviOverlay.navi_options.turn_point_icon);

轨迹导航回调监听

//循迹导航走过点的回调
static void onTrackPassPoint(int32_t index, awk_map_coord2d_t point) {

}

//偏航回调
static void onTrajectorYaw(double distance) {

}

//轨迹导航偏航结束
static void onTrajectoryYawEnd() {

}

//导航事件回调
static void onTrackNaviEvent(awk_map_track_navi_event_info_t *event) {

}

更新用户实时位置信息

// 更新用户实时位置信息
awk_map_track_navi_update_real_point((uint32_t)mapId, point, bear, &trackNaviOverlay);

返回顶部 示例中心 常见问题 智能客服 公众号
二维码