三维管线

数据制作

移动端加载的三维数据,是三维缓存,使用SuperMap iDesktopX或SuperMap iDesktop(以下简称“iDesktopX”或“iDesktop”),制作数据并生成缓存。本文使用的软件和版本如下表:

名称 版本
SuperMap iDesktopX v11.1,即11i(2023)

(1)加载数据(可选)

若原始管线数据不是超图格式,请按照此步骤导入数据,将数据转化为超图格式(工作空间smwu,数据源udb,udbx)。若已是前述数据格式,请忽略此步骤。

运行iDesktopX,右键单击“工作空间管理器”中的“数据源”,选择【新建文件型数据源…】,保存类型选择“SuperMap UDB文件(*.udb)”或“SuperMap UDBX文件(*.udbx)”。

右键单击新创建的数据源,选择【导入数据集…】,在“数据导入”对话框中,点击【添加】按钮,选择数据导入。

右键单击导入的数据,选择【添加到新场景】—【添加到新平面场景】,若导入多个数据并添加到同一场景,其它数据选择“添加到当前场景”,添加完成后,保存场景,保存工作空间。若“添加到新平面场景”为灰,则执行步骤二,进行坐标系转换。

图:加载管线数据

(2)坐标系转换(可选)

这里的三维管线,要求为“平面坐标系”,若数据不满足坐标系要求,需先转换坐标系。若已是“平面坐标系”请忽略此步骤。

选择管线数据所在的数据源或者需要添加到三维场景中的数据集(这里设置数据源中的全部数据集,即选择数据源,设置某个或某几个数据集,则选择数据集并逐个设置),单击右键,选择“属性”。打开“属性”窗口。

在右侧的“属性”窗口中,选择“坐标系”选项卡,点击【投影转换…】按钮,打开“数据集投影转换”对话框。点击【重新设定坐标系...】,选择“WGS_1984_Web_Mercator”,点击“确定”按钮,进行投影转换。

图:投影转换

(3)风格设置、场景保存(可选)

若有制作完成并保存的三维平面场景请忽略此步骤,否则,按下述操作,保存新的三维平面场景。

在“工作空间管理器”中,右键单击“场景”,在右键菜单中选择【添加到新场景】—【添加到新平面场景】。

将第一步转换后的数据集拖到平面场景中,如下图所示。

在“图层管理器”中,选择一个图层,选择界面上方的“风格设置”选择卡,设置线符号、颜色、线宽等(这里以线图层举例,点图层、面图层同理),设置“高度模式”为“绝度高度”,并设置“底部高程”。依次设置各图层。

设置完成后,在场景窗口单击右键,选择【保存场景】,输入场景名称,完成保存。

图:设置场景风格

(4)生成缓存

场景保存完成后,在“工作空间管理器”中的“场景”分支下,可以找到已保存的三维平面场景。选择该场景,单击右键,在右键菜单中选择【生成场景瓦片…】。

图:生成场景瓦片

若弹出的以下对话框中,选择【确定】,先关闭缓存。

图:关闭场景

在“生成场景缓瓦片”对话框中,选择生成缓存的数据集,设置缓存名称和路径。纹理压缩格式,设置为Webp。S3M版本,可以选择1.0、2.0、或3.0.点击“确定”按钮,生成缓存。缓存数据生成在“缓存路径”对应的目录中。

图:生成场景瓦片

功能实现

(1)必备类库

进行三维管线功能开发必需的类库为com.suerpamp.realspace.jar、com.supermap.data.jar、com.supermap.mapping.jar,必需的so库为libarcore_sdk_c.so、libarcore_sdk_jni.so、libimb.so。

(2)功能开发

在布局文件 activity_main.xml 中添加场景控件,代码如下:

<com.supermap.realspace.SceneControl
    android:id = "@+id/SceneControl"
    android:layout_width="match_parent"
    android:layout_height = "match_parent">
</com.supermap.realspace.SceneControl>

加载三维管线主要代码如下:

//打开工作空间
Workspace workspace = new Workspace();
WorkspaceConnectionInfo info = new WorkspaceConnectionInfo();
info.setServer(sdcard+"/SampleData/CBD_android/CBD_android.sxwu");
info.setType(WorkspaceType.SXWU);
workspace.open(info);
//场景显示控件与工作空间相关联
SceneControl sceneControl = (SceneControl)findViewById(R.id.SceneControl);
Scene scene = sceneControl.getScene();
scene.setWorkspace(workspace);
//打开场景
String sceneName = workspace.getScenes().get(0);
scene.open(sceneName);
三维管线查询主要代码如下:
Feature3D feature = null;
Layer3DOSGBFile layer3d = null;
if (layer.getType() == Layer3DType.OSGBFILE) {
  layer3d = (Layer3DOSGBFile) layer;
} else if (layer.getType() == Layer3DType.VECTORFILE) {
  feature = selection.toFeature3D();
}
int count = fieldInfos.getCount();
if (count > 0) {
  Object[] str = layer3d.getAllFieldValueOfLastSelectedObject();
  if (str == null) {
    return;
  }
  for (int j = 0; j < count; j++) {
    String name = fieldInfos.get(j).getName();
    String strValue;
    Object value;
    if (feature == null) {
      value = str[j];
    } else {
      value = feature.getFieldValue(name);
    }
    if (value.equals("NULL")) {
      strValue = "";
    } else {
      strValue = value.toString();
    }
    queryInfoBubble.additem(name + ":", strValue);
}