基于SuperMap iMobile9.1.1环境的App开发总结:
最近由于公司项目需求,需要做一个三维平台的移动端App,超图在这方面API相对于ArcGIS比较成熟一点,所以才有超图的iMobile进行开发,项目磕磕绊绊,一个人历时差不多两个月终于结束了。这两个月从不了解iMobile到开发出满足具体业务需求的可用App,可谓一路艰辛,超图公司的技术支持人员,估计这会儿都看见我的提问得烦透了,哈,闲下来项目总结一下,以备自己不时之需,同时也分享出来,支持一下有三维移动端开发需求的朋友。
超图官网:https://www.supermap.com/cn/
许可申请、软件下载都可在官网找到;
工程配置:
下载官网示例SampleCode,直接改包名,项目名称,拿过来使用即可;
一、基础功能模块:主要包括图层树、测距、测面、指北针、放大、缩小、主页等功能;
1、图层树:supermap加载三维场景有两种方式,iserver发布的在线三维场景,以及idesktop直接处理的工作空间(离线工作空间)
<com.supermap.realspace.SceneControl
android:id="@+id/scene_control"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.supermap.realspace.SceneControl>
在线场景加载:
(1)、直接通过打开scene场景方式加载:
这种方式的iserverURL是到服务的/realspace这里结尾,后面sceneName是场景名称,在iserver预览的时候可以看到。
boolean open = sceneControl.getScene().open(iserverURL, sceneName);
(2)、通过加载图层的方式加载:
String layerUrl = "http://192.168.5.229:8090/iserver/services/xxxx/rest/realspace/datas/xxxx";
Layer3D add = scene.getLayers().add(layerUrl, Layer3DType.OSGBFILE, "b13@udb13", true);
public Layer3D add(String iserverURL, Layer3DType layerType, String layerName, boolean addToHead) {} //这是方法参数
离线工作空间加载:
//本地源地址
String url = Environment.getExternalStorageDirectory().getAbsolutePath();
String ZMLMF = url + "/xxx/SampleData/珠峰/珠峰.sxwu";xxx
SupMapUtil.openLocalWP(getActivity(), mainActivity.getSceneControl(), null, WorkspaceType.SXWU, ZMLMF, "珠峰");
public static boolean openLocalWP(Context context, SceneControl sceneControl, Workspace m_workspace, WorkspaceType workspaceTypetemp, String workspacePath, String sceneName){
WorkspaceConnectionInfo info = new WorkspaceConnectionInfo();
// 新建一个工作空间对象
if (m_workspace == null) {
m_workspace = new Workspace();
}
// 根据工作空间类型,设置服务路径和类型信息。
info.setServer(workspacePath);
info.setType(workspaceTypetemp);
// 场景关联工作空间
if (m_workspace.open(info)) {
Scene m_scene = sceneControl.getScene();
m_scene.setWorkspace(m_workspace);
}
// 打开场景
boolean successed = sceneControl.getScene().open(sceneName);
if (successed) {
Toast.makeText(context, "打开场景成功", Toast.LENGTH_LONG).show();
}
return false;
}
2、三维测量(测距、测面)
点击按钮开始测量:
// 关闭所有情况下的分析
public void closeAnalysis() {
sceneControl.setAction(Action3D.PANSELECT3D);
sceneControl.removeTrackingListener(mTracking3dListener);
tvInfo.setText("");
}
sceneControl.addTrackingListener(mTracking3dListener);
AnalysisTypeArea = 1;
sceneControl.setAction(Action3D.MEASUREAREA3D);
Tracking3DListener点击事件跟踪类,
/**
* 用于分析时候监听交互
*
* @author:Supermap
* @注释 :三维场景窗口的跟踪图层中交互绘制事件的监听器。
*/
private Tracking3DListener mTracking3dListener = new Tracking3DListener() {
@Override
public void tracking(Tracking3DEvent event) {
initAnalySis(sceneControl, event);
}
};
public void initAnalySis(SceneControl sceneControl, Tracking3DEvent event) {
if (sightline != null && sceneControl.getAction() == CREATEPOINT3D) {
Point3D p3D = new Point3D(event.getX(), event.getY(), event.getZ());
if (sightline.getvViewerPosition().getX() == 0) {
sightline.setViewerPosition(p3D);
sightline.build();
// add point
Point3D point3d = new Point3D(event.getX(), event.getY(), event.getZ());
GeoPoint3D geoPoint3D = new GeoPoint3D(point3d);
GeoStyle3D geoStyle3D = new GeoStyle3D();
geoStyle3D.setMarkerScale(2);
geoStyle3D.setMarkerColor(new Color(255, 0, 0));
geoStyle3D.setLineWidth(3);
geoStyle3D.setLineColor(new Color(255, 0, 0));
geoPoint3D.setStyle3D(geoStyle3D);
sceneControl.getScene().getTrackingLayer().add(geoPoint3D, "point");
} else {
sightline.addTargetPoint(p3D);
// add point
Point3D point3d = new Point3D(event.getX(), event.getY(), event.getZ());
GeoPoint3D geoPoint3D = new GeoPoint3D(point3d);
GeoStyle3D geoStyle3D = new GeoStyle3D();
geoStyle3D.setMarkerColor(new Color(255, 0, 0));
geoStyle3D.setLineWidth(2);
geoStyle3D.setLineColor(new Color(255, 0, 0));
geoPoint3D.setStyle3D(geoStyle3D);
sceneControl.getScene().getTrackingLayer().add(geoPoint3D, "point");
}
} else if (sceneControl.getAction() == Action3D.MEASUREDISTANCE3D) {
measureDistance(event);
} else if (sceneControl.getAction() == Action3D.MEASUREAREA3D) {
measureSurearea(event);
}
}
得到结果,然后测距或者测面:
// 测量距离
private void measureDistance(Tracking3DEvent event) {
// 加点
// 更新总距离长度
double totalLength = event.getTotalLength();
double totalcurrentlength = event.getCurrentLength();
double x = event.getX();
Log.v("enbir", "totalLength=" + totalLength + ";" + "totalcurrentlength=" + totalcurrentlength);
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putDouble("length", totalLength);
msg.setData(bundle);
totalLengthHandler.sendMessage(msg);
}
// 测量面积
private void measureSurearea(Tracking3DEvent event) {
// 加点
// 更新测量面积
double TotalArea = event.getTotalArea();
double totalcurrentlength = event.getCurrentLength();
Message msg = new Message();
Bundle bundle = new Bundle();
bundle.putDouble("Area", TotalArea);
msg.setData(bundle);
totalLengthHandler.sendMessage(msg);
Log.v("enbir", "TotalArea=" + TotalArea + ";" + "totalcurrentlength=" + totalcurrentlength);
}
最后控制开启测距或者测面:
// 开启距离测量分析
public void startMeasureAnalysis() {
sceneControl.setAction(Action3D.MEASUREDISTANCE3D);
}
// 开启测量面积分析
public void startSurearea() {
sceneControl.setAction(Action3D.MEASUREAREA3D);
}
3、指北针
Camera camera = sceneControl.getScene().getCamera();
camera.setHeading(0);
sceneControl.getScene().setCamera(camera);
sceneControl.getScene().refresh();
4、放大缩小
//放大
sceneControl.getScene().zoom(0.5);
sceneControl.getScene().refresh();
//缩小
sceneControl.getScene().zoom(-1);
sceneControl.getScene().refresh();
5、主页
sceneControl.getScene().viewEntire();
sceneControl.getScene().refresh();
好鸟~要下班鸟~
未完待续~
Life is like a pendulum,shaking between pain and boredom,it's power is desire.