2022-11-10-视频地图开发文档

写在前面的话

  • 本文档仅供参考,相关描述不一定准确
  • 仅描述已发布的SDK应该如何使用
  • 不涉及正在开发中的内容
  • SDK在持续迭代中,相关描述可能有变化

介绍

本文档仅简单地记录了当前版本使用产品包进行无人机视频(离线视频)相关的开发流程。

其环境配置与基于filament渲染引擎的AR开发环境一致。

环境配置

依赖配置

由于Android不同版本的gradle,配置有所差异。
此处推荐的gradle配置如下

  • Android Gradle Plugin Version -> 4.1.2
  • Gradle Version -> 6.5

本地依赖

必需的so库

使用libimb2d.so 或libimb.so,
仅当需要使用到com.supermap.realspace.jar时,必须使用libimb.so。

JAR配置

常使用到的jar如下:

  • com.supermap.data.jar(必需)
  • com.supermap.ar.jar(必需)
  • com.supermap.ai.jar(在使用到AI功能以及地图叠加视频帧时需要添加)
  • com.supermap.mapping.jar(地图模块,根据需要添加)
  • com.supermap.realspace.jar(三维模块,根据需要添加)
渲染引擎

此外,为确保com.supermap.ar模块正常运行,需额外引入sceneform-sm.aar
引入sceneform-sm有两种方式。

第一种方式

根据不同的sceneform版本,直接在模块的build.gradle文件的dependencies中添加以下内容
sceneform-sm_v1.19.8.aar配置如下:

    //注意:当前版本的sceneform-sm,需在filament 1.9.25版本上运行
    implementation files('lib\\sceneform-sm_v1.19.8.aar')
    //ARCORE
    api 'com.google.android.filament:filament-android:1.9.25'
    api 'com.google.android.filament:gltfio-android:1.9.25'
    api 'com.google.android.filament:filament-utils-android:1.9.25'
    implementation 'com.google.ar:core:1.25.0'
    implementation 'com.huawei.hms:arenginesdk:3.0.0.11'

scenefrom-sm-11.0.0.aar配置如下:

    //注意:当前版本的sceneform-sm,需在filament 1.12.0版本上运行
    implementation files('lib\\sceneform-sm-11.0.0.aar')
    依赖谷歌filament渲染引擎
    def filament_version = '1.12.0'
    api "com.google.android.filament:filament-android:$filament_version"
    api "com.google.android.filament:gltfio-android:$filament_version"
    api "com.google.android.filament:filament-utils-android:$filament_version"
    //支持ARCore的手机(如小米、onePlus等安卓设备)
    api "com.google.ar:core:1.25.0"
    //支持AREngine的设备(华为系列手机)注:此项需要确保在项目的build.gradle引用了华为repo
    api 'com.huawei.hms:arenginesdk:3.7.0.3'
第二种方式

先在项目工程的build.gradle文件中的repositories中添加在线maven配置
地址为以下二选一:
官方地址:
https://raw.githubusercontent.com/SupermapIMobile/repo/main

内部开发人员地址(注意:url地址可能变动,若地址无效,请咨询相关人员)
https://repo.eqgis.cn

buildscript {
    repositories {
        google()
        jcenter()
        // 配置Maven地址。
        maven {
            url "https://raw.githubusercontent.com/SupermapIMobile/repo/main"
            //url "https://repo.eqgis.cn"
        }
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        // 配置Maven地址。
        maven {
            url "https://raw.githubusercontent.com/SupermapIMobile/repo/main"
            //url "https://repo.eqgis.cn"
        }
    }
} 

再在模块的build.gradle文件

    //仅添加对应版本的sceneform-sm依赖即可
    implementation 'com.supermap:sceneform-sm:11.0.0'

注意事项

AREngine的引入

若项目中有使用到AREngine,即依赖了“com.huawei.hms:arenginesdk:x.x.x”,则需要在项目的build.gradle添加华为的repo配置。也可参考 AREgine开发文档 开发准备部分。

buildscript {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url "https://developer.huawei.com/repo/" }
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        // 配置HMS Core SDK的Maven仓地址。
        maven {url "https://developer.huawei.com/repo/" }
    }
} 
不同版本的Gradle

不同版本的Gradle配置在配置Maven仓库时,有一定差异。Gradle 7.0版本后,需参考Android官方对于Gradle版本与Gradle插件的配套关系,把Gradle插件版本也升级到7.0及以上。

7.0版本

第一步,打开Android Studio项目级“build.gradle”文件,添加Maven代码库。
在“buildscript > repositories”中配置Maven仓地址。

buildscript {
    repositories {
        google()
        jcenter()
        maven {url "https://..." }
    }
}

第二步,打开项目级“settings.gradle”文件,配置Maven仓地址。

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        repositories {
            google()
            jcenter()
            maven {url "https://..." }
        }
    }
}
7.1以上版本

第一步,打开Android Studio项目级“build.gradle”文件,添加Maven代码库。
在“buildscript > repositories”中配置Maven仓地址。

buildscript {
    repositories {
        google()
        jcenter()
        maven {url "https://..." }
    }
}

第二步,打开项目级“settings.gradle”文件,配置Maven仓地址。

pluginManagement {
    repositories {
        repositories {
            google()
            jcenter()
            maven {url "https://..." }
        }
    }
}

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        repositories {
            google()
            jcenter()
            maven {url "https://..." }
        }
    }
}

视频加载

视图控件

使用UAVVideoEffectView控件,UAVVideoEffectView是无人机视频场景视图,它与AREffectView(AR场景视图)一样,都是EffectView的子类。

UAVVideoEffectView的所有方法如下:

@startuml
class UAVVideoEffectView {
+ void updateCurrentCameraParameter(UAVRecordParameter)
+ ArrayList<UAVRecordParameter> getUavRecordParameters()
+ void setUavRecordParameters(ArrayList<UAVRecordParameter>)
+ void start()
+ void pause()
+ void stop()
+ void updateFrame(int,UAVRecordParameter)
+ UAVRecordParameter updateFrame(int)
+ UAVRecordParameter getCurrentUAVRecordParameter()
+ void updateFrame(UAVRecordParameter)
+ UAVActionControl getUAVActionControl()
+ void setDatasetVector(DatasetVector)
+ void setDatasetVector(DatasetVector,String)
}

ICommonControl <|.. UAVVideoEffectView
EffectView <|-- UAVVideoEffectView
RelativeLayout <|-- EffectView
@enduml

视频数据集

视频数据集是类型为VIDEO的DatasetVector,里面包含了相机姿态和视频路径。

视频数据集的获取

目前视频数据集的获取(生成方式)有两种。

  1. 在PC端使用iDesktopX,通过以下步骤获取。

    ​ 新建数据集->选择视频格式->选择视频路径->导入相机参数(或通过配准添加相机参数)。

    ​ 注意:需确保相机参数记录数大于2,且建议视频和数据集放在相同路径。

  2. 通过使用UAVSurvey App,录制姿态视频生成视频数据集。

打开视频数据集

当相机姿态不为NULL和视频路径有相应视频时,可通过以下方式直接在UAV场景中打开。

try {
    uavVideoEffectView.setDatasetVector(/*视频数据集*/mVideoDatasetVector);
} catch (Exception e) {
    Toast.makeText(this, "视频数据集设置失败!", Toast.LENGTH_SHORT).show();
}

此外,当前版本支持通过图层组管理的方式添加视频数据集。

uavVideoEffectView.getUAVLayers().add(mVideoDatasetVector);

CSV+MP4

文件说明

当前版本,为确保视频场景能正常打开且和地图叠加准确,需确保CSV文件至少包括以下参数。

csv文件:

  1. 时刻值(时间戳),单位:us
  2. 相机的经度(通常采用无人机的经度)
  3. 相机的纬度(通常采用无人机的纬度)
  4. 相机相对起飞位置的高度(通常采用无人机的相对高度)
  5. 相机的偏航角(注意区分无人机的偏航角)
  6. 相机的俯仰角(注意区分无人机的俯仰角)
  7. 相机的翻滚角(主语区分无人机的翻滚角)
  8. 相机的垂直视场角、水平视场角或35mm等效焦距(忽略相机畸变时,三者取一即可)

mp4文件:

为无人机拍摄的视频,需确保视频无拉伸,无黑边。

文件读取

当CSV文件可用且合规时,通过以下方法读取CSV文件,得到无人机参数集。

UAVCsvReader uavCsvReader = new UAVCsvReader(getApplicationContext(), new UAVCsvReader.OnReadUpdateListener() {
    @Override
    public void onUpdate(UAVRecordParameter currentPara, String[] value) {
        //value[i]分别对应csv文件对应列
        currentPara.setUnixTimeStamp(Long.parseLong(value[1]));
        currentPara.setSensorLongitude(Double.parseDouble(value[2]));
        currentPara.setSensorLatitude(Double.parseDouble(value[3]));
        currentPara.setPlatformHeight(Float.parseFloat(value[4]));
        currentPara.setYaw(Float.parseFloat(value[5]));
        currentPara.setPitch(Float.parseFloat(value[6]));
        currentPara.setRoll(Float.parseFloat(value[7]));
        currentPara.setVerticalFOV(Float.parseFloat(value[8]));
        currentPara.setHorizontalFOV(Float.parseFloat(value[9]));
    }
});
ArrayList<UAVRecordParameter> uavRecordParameters = 
    uavCsvReader.readFileFromSdCard(SDCARD + "/SuperMap/UavDemo/record.csv");
uavVideoEffectView.setUavRecordParameters(uavRecordParameters);

当MP4文件可用时,通过以下方法将MP4加入场景。

uavVideoEffectView.setDataSource(SDCARD + "/SuperMap/UavDemo/record.mp4");

常用工具

在加载数据前,需先了解以下工具类,以便于场景坐标与地理坐标之间的转换和屏幕坐标与场景坐标的转换。

地理坐标转换

可通过ConvertTool工具类实现地理坐标与场景坐标的互相转换。示例如下:

Point3D point3D = ConvertTool.convertToArPosition(arView, new Location(106.126814, 30.350063, 0));

Location location = ConvertTool.convertToLocation(arView, new Point3D(0, 25, 0));

屏幕坐标转换

在手机屏幕上的坐标(x,y)可表示一条射线,若这条射线与场景中的参考水平面(通常,选用高度值为0的水平面)存在交点的话,那么可以获取场景中该交点的位置(x,y,z)。

在UAVVideoEffectView中,通过点击、触摸等方式,可以获取到MotionEvent(event)对象,通过event.getX()/getY()获取屏幕坐标后,可通过以下方法求取场景中对应的位置。

//设置参考水平面高度
uavVideoEffectView.setBasePlaneHeight(/*基准水平面高度值*/0.0f);

//根据(x,y)求取射线对象
Ray ray = ScreenPointTool.screenPointToRay(uavVideoEffectView, x,y);
//求取场景中的坐标,若射线与参考水平面无交点,则为null
Point3D resultPoint = PresetUtils.correctHitPoint(uavVideoEffectView.getCameraPosition(),
                PointConvertTool.convertToPoint3D(ray.getPoint(1)), 
                uavVideoEffectView.getBasePlanePoints());

此外,也可通过以下方法将场景中的坐标转换为屏幕坐标。

int[] p = ScreenPointTool.convertToScreenPoint(arView, new Point3D(0, 25, 0));
Log.i(TAG, "x = "+ p[0] + ", y = " + p[1]);

坐标对象转换

在开发过程中,会经常使用到Vector3、Point3D对象,这两个对象可通过以下方法互相转换。

Point3D point3D = PointConvertTool.convertToPoint3D(new Vector3(1, 0, 1));
Vector3 vector3 = PointConvertTool.convertToVector3(new Point3D(0, 0, 1));

数据加载

当前版本,无人机场景支持以下数据载入场景。

SCI地图缓存

支持直接在UAV场景中加载满足以下条件的地图缓存。

前提条件

当前版本,需确保sci缓存在通过iDesktopX切图时,满足以下条件。

  1. 所切的地图确保坐标系为WGS_1984/Web_Mercator(EPSG Code 3857)

  2. 剖分方式为“全球剖分”或“本地剖分”

  3. 存储类型为“原始”

  4. 当前支持的图片类型为 PNG、WEBP、JPG,在需要背景透明时,需要勾选背景透明,且不能使用JPG。

  5. 块大小建议”1024x1024“,此处块大小越大,在UAV场景中显示的范围越大。

注意:切图后需检查切图结果的文件夹对应的层级是否与切图所选择的层级一致。

加载步骤

当数据合规时,通过以下步骤实现SCI缓存的加载。

  1. 在布局中添加SceneMapControl控件,宽度高度设置多少无影响。
    <com.supermap.ar.areffect.uav.map.SceneMapControl
        android:id="@+id/scene_map"
        android:layout_width="1dp"
        android:layout_height="1dp"/>
  1. 绑定UAVVideoEffectView控件。
  2. 设置工作空间。(仅打开SCI缓存,可跳过此步)
  3. 打开指定的地图。(仅打开SCI缓存,可跳过此步)
  4. 设置SCI缓存路径。(指向xxx.sci)
  5. 启用缓存
    步骤2-6示例代码如下:
sceneMapControl = findViewById(R.id.scene_map);
//绑定场景视图
sceneMapControl.bindEffectView(uavVideoEffectView,/*瓦片数量的算术平方根*/5);
//获取地图对象,并打开指定地图
Map map = sceneMapControl.getMap();
map.setWorkspace(DatasetVectorReader.mWorkSpace);
map.open("thMap");
sceneMapControl.setCacheFolderPath(SDCARD+"/000MapCache/map3/map3.sci");
sceneMapControl.setUseCache(true);
sceneMapControl.setRefreshListener(new SceneMapRefreshListener() {
    @Override
    public void onRefresh(RefreshStatus refreshStatus) {
        Log.i(TAG, "onRefresh: " + refreshStatus.toString());
    }
});

7.通过调用refresh方法刷新地图。此外,为了地图瓦片能动态更新显示范围,可参考如下代码。

uavVideoEffectView.addOnUpdateListener(new EffectView.OnUpdateListener() {
    @Override
    public void onUpdate() {
        UAVRecordParameter currentUAVRecordParameter = 
            uavVideoEffectView.getCurrentUAVRecordParameter();
        if (currentUAVRecordParameter != null){
            sceneMapControl
                .refresh(uav.getSensorLongitude(),uav.getSensorLatitude(),/*Zoom*/18);
        }
    }
});

几何图形

Shape

可通过以下方法绘制点、线、面等基础的几何图形。

AREffectElement parentNode = new AREffectElement(this).setParentNode(arView);

//设置样式
ShapeStyle shapeStyle = new ShapeStyle();
shapeStyle.setColor(0.5f,0.5f,0,0.8f);
shapeStyle.setRadius(0.05f);

//创建shape
Shape shape = new Shape(BaseShape.MatType.OPAQUE);
//绑定父节点
shape.setParentNode(parentNode);
//在(0,1,0)位置绘制半径为0.2m的球体
shape.drawSphere(new Vector(0,1,0),0.2f);
//绘制线,半径为shapeStyle中的radius = 0.05f
shape.drawLine(new Point3D(0,0,0),new Point3D(0,1,0));
//绘制多边形
shape.drawHorizontalPolygon(/*在同一水平面,首尾相连的点集*/pointList);

ARGeometry

ARGeometry继承至Shape,同时与SupeMap iMobile的Geometry对象相关联。方便了在UAV场景直接渲染Supemap的Geometry对象。

ARGeometry的直接子类:

  • 点(使用GeoPoint作为参数):ARGeoPoint
  • 线(使用GeoLine作为参数):ARGeoLine、ARGeoDoottedLine
  • 面(使用GeoRegion作为参数):ARGeoRegion 、ARGeoHorizontalRegion、ARGeoVerticalRegion
  • 体(使用GeoRegion作为参数):ARGeoPrism

参考代码如下。

ARGeoPoint arGeoPoint = new ARGeoPoint(BaseShape.MatType.OPAQUE);
arGeoPoint.drawPoint(new GeoPoint(103.001123,30.0641));

GLTF模型

模型加载

当前使用sceneform作为渲染引擎的版本,仅支持加载gltf2.0格式的三维模型。

通过使用ARGltfElement类将模型作为AR元素加载到场景中。可参考如下代码。

//创建父节点,建议将一类gltf模型,绑定在同一个父节点,便于通过控制父节点的显隐,整体控制所有gltf的显隐
AREffectElement parentNode = new AREffectElement(this).setParentNode(uavVideoEffectView);
ARGltfElement gltfElement = new ARGltfElement(/*context*/this);
gltfElement.setParentNode(parentNode);
//设置位置,UAV场景为相对初始位置(视频第一帧参数的高度为0的位置作为场景的原点)
//采用ENU坐标系(东-北-天)
gltfElement.setPosition(new Point3D(0,25,0));
gltfElement.loadModel(R.raw.building);

资源引入

在res目录下,添加raw或supermap文件夹,将模型拷贝至该文件夹中。

例如,将building.glb拷贝至res/raw/目录下。通过以下方式载入。

gltfElement.loadModel(R.raw.building);

此外,也可直接通过文件路径载入gltf模型。示例如下:

gltfElement.loadModel(SDCARD + "/SuperMap/Demo/building.glb");

或是

gltfElement.loadModel("https://xxx.xx/SuperMap/Demo/building.glb");

图片与文字

在UAV场景中加载图片、文字的方式与加载GLTF模型类似。通过使用ARViewElement实现将Android的layout布局加载进场景。示例如下:

AREffectElement parentNode = new AREffectElement(this).setParentNode(uavVideoEffectView);

//图片加载可使用ImageView
TextView textView = new TextView(this);
textView.setText(R.string.hello_world);
        
ARViewElement viewElement = new ARViewElement(/*context*/this);
viewElement.setParentNode(parentNode);
viewElement.setPosition(new Point3D(0,25,0));
viewElement.loadModel(textView);

视频与网页

在UAV场景中加载视频使用ARVideoElement与ARVideoElement2,加载网页使用ARWebElement,这些类的使用方法与ARGltfElement一致,需先将视频资源放入res/raw目录下或通过url地址的方式载入。

ARVideoElement2与已过时的ARVideoElement相比,前者可修改视频的对齐位置以及视频的中心点。

ARWebElement的父类是ARViewElement,它是通过渲染安卓WebView组件来实现渲染网页的,因此我们也可以通过ARViewElement自定义渲染网页的样式。

矢量数据集

对于SupeMap的点数据集、线数据集、面数据集,在UAV场景中可通过间接的方式进行加载。此外,也可通过图层管理的方式直接加载。

点数据集

通常,为了实现在UAV场景中加载标注。可通过以下几步实现。

  1. 制作点数据集时,额外添加一些属性字段(如,图片资源路径,标注文字,属性内容等)。
  2. 读取数据集的属性内容。示例如下:
Recordset recordset = datasetVector.getRecordset(false, CursorType.STATIC);
recordset.moveFirst();
while (!recordset.isEOF()){
    //根据属性信息创建layout布局,记为view
    //...
    Geometry geometry = recordset.getGeometry();
    Point2D innerPoint = geometry.getInnerPoint();
    //注意:此处为地理坐标,使用的是地理坐标转场景坐标的方法
    Point3D scenePosition = ConvertTool.convertToArPosition(uavVideoEffectView, new Location(innerPoint.getX(), innerPoint.getY(), 0));
    ARViewElement viewElement = new ARViewElement(this);
    viewElement.setParentNode(parentNode);
    viewElement.loadModel(view);
    viewElement.setPosition(scenePosition);
    recordset.moveNext();
}

我们可通过recordset的属性值自定义创建View,同时结合坐标转换方法,实现多种样式的标注显示。

线数据集

与点数据集的使用方式类似,在读取到数据集的信息后,通过坐标转换,实现地理数据在场景中显示。

需要注意的是,不仅可以使用ARViewElement之类AR元素,也可以使用Shape、ARGeometry等对象,实现线数据到场景内容的转化。

面数据集

使用方法与点、线数据集类似。但是需要额外注意以下内容:

  • 在使用ARGeoRegion 、ARGeoHorizontalRegion、ARGeoVerticalRegion、ARGeoPrism时,都需要给面对象设置高度信息。

图层管理

当前版本,UAV场景具有统一的图层组,方便管理场景中的各个图层。

UAVLayers

获取方式

图层组在UAVVideoEffectView初始化时,自动创建。

我们可通过getUAVlayers()的方法直接获取得到。

UAVLayers uavLayers = uavVideoEffectView.getUAVLayers();

关键方法

图层组包含了以下方法:

@startuml
class UAVLayers {
+ UAVLayer add(DatasetVector)
+ int getCount()
+ UAVLayer get(int)
+ UAVLayer getCurrentEditLayer()
+ void removeAllLayer()
+ void removeLayer(String)
+ void removeLayer(int)
+ void removeLayer(UAVLayer)
+ boolean containName(String)
+ void refresh()
}
@enduml

可通过add(DatasetVector)将视频数据集添加进场景。

可通过add(DatasetVector)将点、线、面数据集渲染进场景。

注意当前版本支持的矢量数据集的PrjCoordSysType只能是PCS_EARTH_LONGITUDE_LATITUDE,后续将逐渐接入更多的PrjCoordSysType。

LayerStyle

关键方法

可通过LayerStyle控制点、线、面图层的样式。

@startuml
class LayerStyle {
+ float getMarkWidth()
+ void setMarkWidth(float)
+ float getLineWidth()
+ void setLineWidth(float)
+ int getMarkColor()
+ void setMarkColor(int)
+ int getLineColor()
+ void setLineColor(int)
+ int getPolygonColor()
+ void setPolygonColor(int)
+ int getAlpha()
+ void setAlpha(int)
}
@enduml

子类

LayerStyle有两个子类:DrawStyle、MeasureStyle。

@startuml
class DrawStyle {
}

class MeasureStyle {
+ float getTextSize()
+ void setTextSize(float)
+ int getTextColor()
+ void setTextColor(int)
+ int getTextBgColor()
+ void setTextBgColor(int)
+ UAVMeasureController.AreaType getAreaType()
+ void setAreaType(UAVMeasureController.AreaType)
+ UAVMeasureController.LengthType getLengthType()
+ void setLengthType(UAVMeasureController.LengthType)
+ String getDecimal()
+ void setDecimal(String)
}

LayerStyle <|-- DrawStyle
DrawStyle <|-- MeasureStyle
@enduml

UAVLayer

获取方式

图层组在添加矢量数据集(视频数据集时),返回值为UAVLayer。

UAVLayers uavLayers = uavVideoEffectView.getUAVLayers();
UAVLayer lineLayer = uavLayers.add(lineDatasetVector);

子类

UAVLayer有以下直接子类:

  • UAVVideoLayer
  • UAVPointLayer
  • UAVLineLayer
  • UAVRegionLayer

关键方法

UAVLayer包含了以下方法:

@startuml
abstract class UAVLayer {
+ void refresh()
+ boolean addGeometry(Geometry)
+ String getLayerName()
+ String getCaption()
+ void setCaption(String)
+ boolean isVisible()
+ void setVisible(boolean)
+ boolean isEditable()
+ void setEditable(boolean)
+ {abstract}void hitTest(Point3D)
+ {abstract}void highlightSelect(int)
+ void select(int)
+ void cancelSelect()
+ void deleteSelect()
+ UAVLayerType getLayerType()
+ int getCurrentSelectID()
+ boolean delete(int)
+ Recordset getRecordset(int)
+ DatasetVector getDatasetVector()
+ void restoreEditStatus()
+ void updateSelectGeometry(Geometry)
+ LayerStyle getLayerStyle()
+ void setLayerType(LayerStyle)
}
@enduml

可通过使用setEditable(boolean)来启用图层编辑。

手势控制

手势类型

当前版本支持上了以下多种动作类型(参考UAVAction.java)。

/**
 * 无人机手势操作类型
 */
public enum UAVAction {
    /**
     * 漫游手势(缩放平移)
     */
    PAN,
    /**
     * 绘制点
     */
    CREATE_POINT,
    /**
     * 绘制线
     */
    CREATE_LINE,
    DRAW_LINE,
    /**
     * 绘制水平面的多边形
     */
    CREATE_HORIZONTAL_POLYGON,
    DRAW_HORIZONTAL_POLYGON,
    /**
     * 量算距离
     */
    MEASURE_DISTANCE,
    /**
     * 量算面积
     */
    MEASURE_AREA,
    /**
     * 量算高度
     */
    MEASURE_HEIGHT,
    /**
     * 无操作
     */
    NONE,
    /**
     * 选择
     */
    SELECT,
    /**
     * 编辑节点
     */
    EDIT_NODE,
    /**
     * 增加节点
     */
    ADD_NODE,
    /**
     * 删除节点
     */
    DELETE_NODE,
}

UAVActionControl

在UAVVideoEffectView中,UAVActionControl带有3种类别手势控制器(PanGestureController、UAVDrawController、UAVMeasureController)。分别用于实现视图窗口缩放平移、量算距离高度和面积、以及用于数据采集。

部分方法使用示例如下,可作参考。

mUAVActionControl = mUAVVideoEffectView.getUAVActionControl();
mUAVActionControl.setAction(UAVAction.NONE);
mUAVVideoEffectView.getSceneView().addOnTouchListener(mUAVActionControl);

//...

//当需要平移缩放时
mUAVActionControl.setAction(UAVAction.PAN);

//当需要编辑时,先设置需要编辑的图层,再更改Action
mEditUAVLayer = mUAVVideoEffectView.getUAVLayers().getCurrentEditLayer();
mUAVActionControl.getDrawController().setUAVLayer(mEditUAVLayer);
if (UAVLayerType.LINE == mEditUAVLayer.getLayerType()){
    mUAVActionControl.setAction(UAVAction.ADD_NODE);//绘制线,添加节点
}

//当需要进行距离量算时
mUAVActionControl.getMeasureController().clearMeasureResult();//清除上次量算结果
mUAVActionControl.setAction(UAVAction.MEASURE_DISTANCE);//量算距离

//当需要视图(视频)全幅显示时
mUAVActionControl.getPanController().reset();

PanGestureController

这是View视图的漫游控制器,不仅仅可用于UAVVideoEffectView。其他View视图依旧有效。

使用示例如下:

PanGestureController panGestureController = new PanGestureController(view);
panGestureController.setEnabled(true);

//在view的onTouch事件中示例如下:
//    ...
	onTouch(View v, MotionEvent event) {
        panGestureController.updateTouchEvent(event);
        //....
        return true;//注意:此处需要返回true
    }
//...

UAVDrawController

这是针对UAVVideoEffectView实现的绘制控制器。其关键方法如下:

@startuml
class UAVDrawController {
+ void setOnPointUpdateListener(OnPointUpdateListener)
+ boolean addPoint(float,float)
+ void undo()
+ void redo()
+ UAVLayer getCurrentEditLayer()
+ void setUAVLayer(UAVLayer)
+ void submit()
+ void cancel()
+ void clearDrawResult()
+ UAVAction getUAVActionType()
+ void setUAVAction(UAVAction)
+ void cancelSelect()
+ void deleteSelect()
+ int getCurrentSelectID()
+ Recordset getRecordset()
}
interface UAVDrawController.OnPointUpdateListener {
}

UAVDrawController +.. UAVDrawController.OnPointUpdateListener
@enduml

可通过addPoint(float,float)、undo()、redo()、submit()等实现对场景中几何对象的编辑。

UAVMeasureController

这是针对UAVVideoEffectView实现的量算控制器。其关键方法如下:

@startuml
class UAVMeasureController {
+ boolean addPoint(float,float)
+ void clearMeasureResult()
+ UAVAction getUAVActionType()
+ void setUAVAction(UAVAction)
+ void setAlpha(int)
+ int getAlpha()
+ void setMeasureLineColor(int)
+ void setMeasurePolygonColor(int)
+ void refresh()
+ LengthType getLengthType()
+ void setLengthType(LengthType)
+ AreaType getAreaType()
+ void setAreaType(AreaType)
+ DecimalType getDecimalType()
+ void setDecimalType(DecimalType)
}
@enduml

可通过setUAVAction(UAVAction)开启UAV场景的量算功能。

posted @ 2024-05-30 17:31  EQ-雪梨蛋花汤  阅读(115)  评论(0)    收藏  举报