基於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.