SuperMap iClient3D for Cesium视频投放

1 概述

把监控视频投放到三维实景中,可以将静态的三维数据实现动态的显示效果,可以极大方便一些区域的查看和监管,该文章记录该投放的实现过程,以供入门参考。

效果如下:

SuperMap iClient3D for Cesium视频投放_第1张图片

2 具体步骤:

2.1 软件安装

在进行视频投放之前,首先安装SuperMap iDesktopX和SuperMap iServer,在实践中使用的是11i版本。

SuperMap iClient3D for Cesium视频投放_第2张图片

2.2 三维场景制作:

打开SuperMap iDesktopX 11i

SuperMap iClient3D for Cesium视频投放_第3张图片

在左侧工作空间管理器中找到场景,并右键,选择新建球面场景,之后即可看到工作空间中出现了地球画面

SuperMap iClient3D for Cesium视频投放_第4张图片

SuperMap iClient3D for Cesium视频投放_第5张图片

在左下角图层管理器中,找到普通图层并右键,选择添加三维切片缓存数据·,如果有其他类型的三维数据可以选则其他选项,找到模型文件并加载(三维切片缓存数据的元文件后缀是scp),加载之后双击图层就可以定位到模型所在位置。

SuperMap iClient3D for Cesium视频投放_第6张图片

SuperMap iClient3D for Cesium视频投放_第7张图片

SuperMap iClient3D for Cesium视频投放_第8张图片

之后按Ctri+S把制作好的三维场景保存,保存路径里面不能含有中文,否则后面发布的服务可能加载不出。

SuperMap iClient3D for Cesium视频投放_第9张图片

2.3 三维服务发布:

三维场景制作完成之后,把场景发布到服务端,首先打开SuperMap iServer 11i

点击启动服务即可打开,大概要等2分钟左右,跟电脑配置有关。

SuperMap iClient3D for Cesium视频投放_第10张图片

如果第一次打开,需要访问http://localhost:8090/iserver/services/security/login,进行管理员注册,在此已经注册过了,记住自己的账户和密码。

SuperMap iClient3D for Cesium视频投放_第11张图片

回到SuperMap iDesktopX 11i,打开创建好的的场景,右键左侧工作空间管理器中的工作空间名称,选择发布工作空间,

SuperMap iClient3D for Cesium视频投放_第12张图片

输入自己的服务端账户密码

SuperMap iClient3D for Cesium视频投放_第13张图片

勾选三维服务之后点击发布

SuperMap iClient3D for Cesium视频投放_第14张图片

之后打开浏览器,登录自己的管理员账号,就可以在服务管理中找到发布的三维服务

SuperMap iClient3D for Cesium视频投放_第15张图片

点击进入并复制服务地址,如果想要查看模型数据或者预览,可以点击链接,然后探索里面的内容。至此三维场景发布完成,得到一个服务端链接。

SuperMap iClient3D for Cesium视频投放_第16张图片

2.4 Web端服务加载:

首先按照SuperMap iClient3D for Cesium官网教程配置环境,得到一个Html前端工程,官方教程在:SuperMap iClient3D for Cesium 开发指南

,官网教程内容很详细,还有API可以学习。

SuperMap iClient3D for Cesium视频投放_第17张图片

本开发使用的是VScode,其他开发工具一样,根据官网教程创建viewer之后,使用打开场景,下面的地址就是刚刚服务端的链接。效果如下:(注意在此过程中SuperMap iServer 11i需要保持打开状态)

var scene = viewer.scene;
var promise = scene.open("http://localhost:8090/iserver/services/3D-test/rest/realspace"); //url为在SuperMap iServer上发布的服务地址

SuperMap iClient3D for Cesium视频投放_第18张图片

2.5 视频投放

最后一步,在场景中加载视频。

实际上,如果使用Cesium直接进行视频投放,原理类似把视频作为纹理贴到一个矩形实体上面,但是SuperMap在Cesium的基础上,把该步骤封装成了一个类,也就是Cesium.ProjectionImage,所以使用起来非常方便。

关于ProjectionImage的详细介绍,可以查看官方文档3D WebGL API

SuperMap iClient3D for Cesium视频投放_第19张图片

在自己书写代码之前可以在官网http://support.supermap.com.cn:8090/webgl/examples/webgl/editor.html#projectionImage进行练习

SuperMap iClient3D for Cesium视频投放_第20张图片

下面书写的代码也是对官方源码的理解

首先在

    

然后创建ProjectionImage对象,并跟视频对象绑定起来

var videoElement = document.getElementById('trailer');
var projectionImage = new Cesium.ProjectionImage(scene);
projectionImage.setImage({
                    video: videoElement
                });

获取视频之后,需要的就是视频投放的观测点、方向、距离这些参数了。

观测点使用

projectionImage.viewPosition = [longitude, latitude, height];

视频的长和宽使用

projectionImage.horizontalFov = 20;
projectionImage.verticalFov = 10;

之后设置投射的方向和距离

projectionImage.setDistDirByPoint([longitude, latitude, height]);
projectionImage.distance = 200;

不出意外的话,根据上面的代码,视频就可以正常投射了。

SuperMap iClient3D for Cesium视频投放_第21张图片

完整的JavaScript代码如下:

$(document).ready(function(){
            var viewer = new Cesium.Viewer('cesiumContainer');
            var scene = viewer.scene;
            var promise = scene.open("http://localhost:8090/iserver/services/3D-3D_Try/rest/realspace");
            promise.then(function(layers){
                console.log(layers)
                var videoElement = document.getElementById('trailer');
                var projectionImage = new Cesium.ProjectionImage(scene);
                projectionImage.distance = 0.1;
                var wgsPosition = scene.camera.positionCartographic;
                var longitude = Cesium.Math.toDegrees(wgsPosition.longitude);
                var latitude = Cesium.Math.toDegrees(wgsPosition.latitude);
                var height = wgsPosition.height;
                projectionImage.viewPosition = [longitude, latitude, height];
                projectionImage.horizontalFov = 20;
                projectionImage.verticalFov = 10;
                projectionImage.setImage({
                    video: videoElement
                });

                //videoElement.play();
                projectionImage.removeAllClipRegion();
                projectionImage.build();
                var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
                handler.setInputAction(function (movement) {
                var last = scene.pickPosition(movement.position);
                console.log(1);
                //计算该点与视口位置点坐标的距离
                var distance = Cesium.Cartesian3.distance(scene.camera.position, last);
                if (distance > 0) {
                //将鼠标当前点坐标转化成经纬度
                var cartographic = Cesium.Cartographic.fromCartesian(last);
                var longitude = Cesium.Math.toDegrees(cartographic.longitude);
                var latitude = Cesium.Math.toDegrees(cartographic.latitude);
                var height = cartographic.height;
                //通过该点设置视频投放对象的距离及方向
                projectionImage.setDistDirByPoint([longitude, latitude, height]);
                projectionImage.distance = 200;
                var wgsPosition = scene.camera.positionCartographic;
                var longitude = Cesium.Math.toDegrees(wgsPosition.longitude);
                var latitude = Cesium.Math.toDegrees(wgsPosition.latitude);
                var height = wgsPosition.height;
                projectionImage.viewPosition = [longitude, latitude, height];
                }

                }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

            })

        })

3 总结

本文是对三维场景视频投放的一个简单尝试,代码和功能都是很简略(几乎没什么功能),但是教程是很详细的,对于初学者比较友好,如果想要较好的投射效果,还需要对视频投射的参数进行仔细的打磨。。

你可能感兴趣的:(实景融合,3d,javascript)