蜂鸟视图室内地图 Android SDK

定位导航 Fengmap Andriod SDK 结合定位技术,可实现导航的功能。SDK提供导航工具类,使导航开发变得很简单,开发者可根据本章节结合实际定位系统,实现定位导航功能。

初始化导航对象

在onMapInitSuccess回调后,初始化导航类对象,在FMNaviOption对象中可以设置导航相关配置属性。示例代码如下:

@Override
public void onMapInitSuccess(String path) {
    // 创建模拟导航对象
    mNavigation = new FMSimulateNavigation(mFMMap)
    // 创建真实导航对象
    // mNavigation = new FMActualNavigation(mFMMap);

    // 设置导航文字语种,目前支持中文英文两种("zh","en")
    // mNavigation.setNaviLanguage(this, "en");

    // 设置是否启用走过导航线变化,默认开启
    // mNavigation. setNaviAcrossChange(true);

    // 创建导航配置对象
    mNaviOption = new FMNaviOption();

    // 设置跟随模式,默认跟随
    mNaviOption.setFollowPosition(true);

    // 设置跟随角度(第一人视角),默认跟随
    mNaviOption.setFollowAngle(true);

    // 点移距离视图中心点超过最大距离5米,就会触发移动动画;若设为0,则实时居中
    mNaviOption.setNeedMoveToCenterMaxDistance(NAVI_MOVE_CENTER_MAX_DISTANCE);

    // 设置导航开始时的缩放级别,true: 导航结束时恢复开始前的缩放级别,false:保持现状
    mNaviOption.setZoomLevel(NAVI_ZOOM_LEVEL, false);

    // 设置配置
    mNavigation.setNaviOption(mNaviOption);
}
添加起终点

导航开始前需要设置起终点,起终点两部分构成:坐标信息(FMGeoCoord)和标注物信息(FMPointOption)。FMGeoCoord设置坐标和楼层ID,FMPointOption配置标注物属性,比如:图片,尺寸,高度等。示例如下:

/** 设置起点*/
// 设置坐标信息
mNavigation.setStartPoint(startPt);
// 配置标注物属性对象
Bitmap startBmp = BitmapFactory.decodeResource(getResources(), R.drawable.start);
mStartOption.setBitmap(startBmp);
// 设置标注物属性对象
mNavigation.setStartOption(mStartOption);

/** 设置终点*/
mNavigation.setEndPoint(endPt);

Bitmap endBmp = BitmapFactory.decodeResource(getResources(), R.drawable.end);
mEndOption.setBitmap(endBmp);

mNavigation.setEndOption(mEndOption);
绘制导航线

由起点到终点坐标进行导航分析,并绘制导航线。

通过FMLineOption来配置导航线属性,比如:线的宽度、颜色、类型等,使用 FMNavigation# setLineOption方法来设置。

通过FMNaviLineOption来配置走过的导航线属性,比如:线的宽度、颜色、类型等,使用 FMNavigation# setLineOption方法来设置。默认与FMLineOption样式一致,除颜色为灰色。

路径规划和绘制导线的参考代码如下:

// 路径规划
int ret = mNavigation.analyseRoute(FMNaviAnalyser.FMNaviModule.MODULE_SHORTEST);
// 路径规划成功,绘制导航线
if (ret == FMNaviAnalyser.FMRouteCalcuResult.ROUTE_SUCCESS) {
    mNavigation.drawNaviLine();
}else{
    FMLog.le("路径规划失败", FMNaviAnalyser.FMRouteCalcuResult.getErrorMsg(ret));
}
设置导航监听

在真实导航中,接收一次定位位置需要调用FMActualNavigation.locate来触发该回调,返回该位置相应的导航信息FMNavigationInfo,导航信息中包含了此时的剩余距离,路段描述,真实位置点的偏离距离,约束过的位置,位置点方向等。开发者使用这些信息,来展示行进过程中的提示信息,还可以根据偏移距离完成路径重新规划的功能。与真实导航不同的是,模拟导航没有locate方法,只要在开始模拟前设置了导航监听,模拟过程中就会不断触发该回调,直至导航结束。

设置导航监听对象,示例代码如下:

// 设置导航监听对象
mNavigation.setOnNavigationListener(new OnFMNavigationListener() {
    // 导航过程中跨层回调
    @Override
    public void onCrossGroupId(int lastGroupId, int currGroupId) {
    }

    // 行走回调
    @Override
    public void onWalking(FMNavigationInfo navigationInfo) {
        // 路段描述
        String naviText = info.getNaviText();
       // 原始路段数据
        FMNaviDescriptionData naviData = info.getDescData();

        // 剩余距离
        double surplusDist = navigationInfo.getSurplusDistance();
        // 偏离距离
        double offsetDist = info.getOffsetDistance();

        // 路径约束过后点
        FMGeoCoord contraintedPos = navigationInfo.getPosition();
        // 真实的定位点
        FMGeoCoord realPos = navigationInfo.getRealPosition();
        // 方向
        float angle = navigationInfo.getAngle();
        // 更新定位标注物
        // …
    }

    @Override
    public void onComplete() {
        // 导航完成
    }
});
添加定位标注物

定位标注物用于展示导航过程中的位置与方向,添加方法如下:

int groupId = mFMMap.getFocusGroupId();       //当前焦点层楼层id
//创建定位图层
FMLocationLayer locationLayer = mFMMap.getFMLayerProxy().getFMLocationLayer();
mFMMap.addLayer(locationLayer);

FMLocationMarker locationMarker = new FMLocationMarker(groupId, mapCoord);
//设置定位点图片
locationMarker.setActiveImageFromAssets("active.png");
//设置定位图片宽高
locationMarker.setMarkerWidth(30);
locationMarker.setMarkerHeight(30);
locationMarker.setAngle(angle);
locationLayer.addMarker(locationMarker);
导航对象的生命周期

导航对象的生命周期是:开始(模拟导航为:simulate,真实导航为: start),暂停,恢复,停止。当导航对象调用了clear方法后,则代表清除了此次导航的所有数据。当导航对象调用了release方法,则底层会释放对象,对象变为不可用,只能重新创建。

/**导航开始*/
// 模拟导航对象
FMSimulateNavigation simulateNavigation = (FMSimulateNavigation) mNavigation;
// 3米每秒
simulateNavigation.simulate(3.0f);

// 真实导航对象
final FMActualNavigation actualNavigation = (FMActualNavigation) mNavigation;
actualNavigation.start();

/** 暂停导航*/
mNavigation.pause();

/** 恢复导航*/
mNavigation.resume();

/** 停止导航*/
mNavigation.stop();

/** 清除导航数据*/
mNavigation.clear();

/** 释放底层导航对象*/
mNavigation.release();
真实导航对象接入定位

真实导航对象与模拟导航对象不同之处是需要接入真实定位位置。一般接入的定位系统,会提供一个实时获取当前位置的接口,假如是一个位置回调onLocate(int groupId, double x, double y, float angle),该回调出的数据分别是:楼层id,x坐标,y坐标,方向角度。

/**位置回调*/
@Override
public void onLocate(int groupId, double x, double y, float angle) {
    // 坐标转换
FMGeoCoord coord = transform(groupId, x, y);

    // 里面会做路径约束, 约束后的数据通过导航监听回调返回
    actualNavigation.locate(coord, angle);
}