使用Unity3d联合AS的开发方式,通过调用 SuperMap iMobile的路径分析功能,实现XR眼镜的室内导航。
XR眼镜:JIMO
移动手机:使用支持ARCore/AREngine移动手机(如华为、小米等)。
1、在官网申请试用许可。 2、将试用许可(两个license文件)拷贝至手机的根目录/SuperMap/license下
1、使用SuperMap iDesktopX制作路网数据(udb数据源以及swmu工作空间) 2、将制作完成的路网数据拷贝至手机的根目录/Supermap/arglasses/
1、开发平台选择Android
2、配置相应的SDK\NDK\JDK
3、导入master\01UnityAssets\下的unitypackage
(Demo.unitypackage为本导航示例的资源,SDK_Foundation.unitypackage为影创SDK)
AndroidStudio version > 3.6 gradle version > 5.6.1
说明:master\02AndroidStudioProj为本示例对应的AS工程,是通过Unity导出得到,
再在该AS工程上打包apk(此处涉及,AS与Unity的相互调用,具体实现见后续“关键代码”)。
libimb2d_v1021.so
com.supermap.data_v1021.jar
com.supermap.ar_v1021.jar
com.supermap.analyst_v1021.jar
gson-2.1.jar
说明:离线jar与so位于master\03离线依赖,so库和离线jar在SupMap下载。
1、创建unity项目,切换为Android平台
2、导入影创SDK(SDK_Foundation.unitypackage) Assets->Import Package->Custom Package
变更为:
3、若控制台报错,提示缺少'Newtonsoft',则打开对应脚本,根据提示导入 参考链接 4、打开scene
1、File->Build Settings->Player Settings
勾选使用自定义的gradle设置
2、在Assetes/Plugins/Android/目录下,找到baseProjectTemplate.gradle,
allprojects {
buildscript {
repositories {**ARTIFACTORYREPOSITORY**
google()
jcenter()
//添加的内容
maven{
url "https://repo.eqgis.cn"
}
maven {
url "https://developer.huawei.com/repo/"
}
...
}
3、在Assetes/Plugins/Android/目录下,找到mainTemplate.gradle,
...
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
//添加内容如下
api 'com.eqgis:sceneform-sm:1.19.10'
api 'com.eqgis:eqtool:1.2.2'
**DEPS**}
...
4、File->Build Settings 勾选Export Project,点击“Add Open Scenes”,再点击“Export”,选择导出路径后直接导出AS工程。
1、打开上一步骤导出的工程 2、将master\02AndroidStudioProj中的java、res、so拷贝至unityLibrary下
3、连接设备后,点击“run launcher”运行
在场景中点击面板上的名称,则在场景中生成对应的导航路径。
申请权限->加载离线许可->读取工作空间->载入数据
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.e(TAG, "onCreate: ");
//载入Unity场景
super.onCreate(savedInstanceState);
Utils.requestPermissions(this);
//加载SuperMap许可
Environment.setLicensePath(sdCard + "/SuperMap/license/");
Environment.initialization(this);
//加载工作空间
WorkspaceConnectionInfo info = new WorkspaceConnectionInfo();
info.setType(WorkspaceType.SMWU);
info.setServer(sdCard + "/SuperMap/arglasses/arglasses.smwu");
workspace = new Workspace();
boolean open = workspace.open(info);
if (!open){
Toast.makeText(this, "工作空间打开失败,\n请检查数据是否存在!", Toast.LENGTH_SHORT).show();
}
//初始化
Destination.getInstance().init(workspace);
}
编写pathAnalyst()方法,供Unity端调用。
static byte[] pathAnalyst(float startX,float startY,float endX,float endY){
//添加偏移量:
startX += offset[0];
startY += offset[1];
endX += offset[0];
endY += offset[1];
try {
if (pathAnalystHelper == null){
//传入指定数据源
pathAnalystHelper = new PathAnalystHelper(workspace.getDatasources().get(0));
}
}catch (Exception e){
Log.e("IKKYU_Destination", "pathAnalyst: ", e);
}
//根据起点、终点坐标生成路径
List<Point3D> pathLocationPs = createPath(startX, startY, endX, endY);
if (pathLocationPs == null)return null;
//坐标转换:地理坐标=>AR坐标=>Unity坐标
Vector3[] result = getVector3s(pathLocationPs);
String s = new Gson().toJson(result);
return s.getBytes(StandardCharsets.UTF_8);
}
路径分析。
SuperMap iMobile路径分析示例 搜索“路径分析”
SuperMap iMobile 交通网络分析结果类 搜索“TransportationAnalystResult”
/**
* 获取路径
* @param netDataName 交通网络数据集名称
* @param m_Points 第一个点为起点,最后一个点为终点
* @return 交通网络分析结果
*/
public TransportationAnalystResult getPath(String netDataName, Point2Ds m_Points){
if (m_analyst == null){
DatasetVector datasetLine = (DatasetVector) datasource.getDatasets().get(netDataName);
// 设置网络分析基本环境,这一步骤需要设置 分析权重、节点、弧段标识字段、容限
TransportationAnalystSetting setting = new TransportationAnalystSetting();
setting.setNetworkDataset(datasetLine);
setting.setEdgeIDField(m_edgeID);
setting.setNodeIDField(m_nodeID);
// setting.setEdgeNameField("roadName");
setting.setTolerance(2);
WeightFieldInfos weightFieldInfos = new WeightFieldInfos();
WeightFieldInfo weightFieldInfo = new WeightFieldInfo();
weightFieldInfo.setFTWeightField("smLength");
weightFieldInfo.setTFWeightField("smLength");
weightFieldInfo.setName("length");
weightFieldInfos.add(weightFieldInfo);
setting.setWeightFieldInfos(weightFieldInfos);
setting.setFNodeIDField("SmFNode");
setting.setTNodeIDField("SmTNode");
//构造交通网络分析对象,加载环境设置对象
m_analyst = new TransportationAnalyst();
m_analyst.setAnalystSetting(setting);
m_analyst.load();
}
//分析路径
TransportationAnalystParameter parameter = new TransportationAnalystParameter();
parameter.setWeightName("length");
/**
* 必须将交通网络分析参数设置(TransportationAnalystParameter)对象的 isPathGuidesReturn 方法设置为 true,才能从分析结果中获取到行驶导引集合。
* */
//设置最佳路径分析的返回对象
parameter.setPoints(m_Points);
parameter.setNodesReturn(true);
parameter.setEdgesReturn(true);
parameter.setPathGuidesReturn(true);//true
parameter.setRoutesReturn(true);
TransportationAnalystResult path;
try {
path = m_analyst.findPath(parameter, false);
}catch (Exception e){
Log.e("MapData", "getPath: ",e);
path = null;
}
return path;
}
将Destination.cs绑定至对应对象。通过调用CreatePath()创建路径。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Destination : MonoBehaviour
{
public Transform destination;//终点位置
public Transform currentPosition;//当前位置
public PathMonoBehaviour pathMonoBehaviour;//用于生成路径的组件
private AndroidJavaObject ajObject;
// Start is called before the first frame update
void Start()
{
if (Application.platform != RuntimePlatform.Android) return;
AndroidJavaClass androidJavaClass = new AndroidJavaClass("com.supermap.ar.path.Destination");
ajObject = androidJavaClass.CallStatic<AndroidJavaObject>("getInstance");
}
// Update is called once per frame
void Update()
{
}
public void CreatePath()
{
//获取当前位置
Vector3 currentP = currentPosition.position;
//目标位置为提前写入的固定值
Vector3 destinationP = destination.position;
if (Application.platform != RuntimePlatform.Android) return;
if(ajObject == null)
{
SuperMap.AR.Unity.IMB.ShowToast("the javaObject of Destination was null.");
return;
}
SuperMap.AR.Unity.IMB.ShowToast("创建路径");
//注意:unity的坐标系与supermap组件的Point3D的坐标系
byte[] resultBytes = ajObject.CallStatic<byte[]>("pathAnalyst", currentP.x, currentP.z, destinationP.x, destinationP.z);
//将字节组转为字符串
string jsonStr = System.Text.Encoding.UTF8.GetString(resultBytes);
pathMonoBehaviour.ClearPath();
pathMonoBehaviour.AddPath(jsonStr);
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。