当前位置:   article > 正文

ArcGIS API for JavaScript+three.js实现视频GIS||增强虚拟环境技术_arcgis for js three.js

arcgis for js three.js

概念

将真实场景融入到虚拟场景中的技术称为增强虚拟环境,主要研究视频与虚拟场景的关系。

视频融合技术是虚拟现实技术的一个分支,也可以说是虚拟现实的一个发展阶段。

视频融合技术指将一个或多个由视频采集设备采集的关于某场景或模型的图像序列视频与一个与之相关的虚拟场景加以融合,以生成一个新的关于此场景的虚拟场景或模型。

本文实现监控视频数据导入到倾斜摄影模型中,摄像头获取的实时视频流直接在三维场景中叠加。

目前Web端的三维GIS视频融合技术,可以Cesium、Googel earth等三维平台实现,

作者除了在esri比赛官网上看到可以实现这种效果,但在没有找到任何的技术思路。

esri2019年三维组比赛形式举例:http://contest.geoscene.cn/html/jingsaifenzu/sanweijianmoyushejizu/

步骤

首先ArcGIS API for JavaScript中支持第三方3D引擎(Three.js),由 Three.js创建外部渲染模型,

利用HTML5中video的特性,以动态纹理的方式实时动态的显示监控视频,

然后将外部渲染模型以ExternalRenderers接口导入到三维场景中。

此时视频的特征点有虚拟场景的特征点存在些许的差距,需要用户手动微调,从而获得最佳视角下的最好视觉效果。

ExternalRenderersAPI参考:https://developers.arcgis.com/javascript/latest/api-reference/esri-views-3d-externalRenderers.html

一个很重要的demo:https://developers.arcgis.com/javascript/latest/sample-code/scene-external-renderer-threejs/

 

效果

 

 

代码

没想到从一个大项目中剥夺出一个小功能还要花这么久。

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0">
  6. <meta name="description" content="">
  7. <meta name="author" content="ThemeBucket">
  8. <link rel="shortcut icon" href="#" type="image/png">
  9. <title>北斗园区</title>
  10. <link rel="stylesheet" href="api/arcgis_js_v414_api/arcgis_js_api/library/4.14/esri/themes/dark-blue/main.css" />
  11. <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
  12. <!--[if lt IE 9]>
  13. <script src="js/html5shiv.js"></script>
  14. <script src="js/respond.min.js"></script>
  15. <![endif]-->
  16. <style>
  17. html,
  18. body,
  19. #ViewDiv
  20. {
  21. padding: 0;
  22. margin: 0;
  23. height: 100%;
  24. width: 100%;
  25. }
  26. #video {
  27. position: absolute;
  28. width: 0;
  29. height: 0;
  30. }
  31. </style>
  32. </head>
  33. <video id="video" autoplay loop muted controls>VID</video>
  34. <body class="sticky-header">
  35. <div id="ViewDiv" ></div>>
  36. <!-- 引入three.js库 -->
  37. <script src="api/libs/threejs/three104.min.js"></script>
  38. <script src="api/libs/threejs/GPUParticleSystem.js"></script>
  39. <!-- 引入arcgis api库 -->
  40. <!--数据配置 end-->
  41. <!--js api start-->
  42. <!--<script src="api/arcgis_js_v416_api/arcgis_js_api/library/4.16/init.js"></script>
  43. <script src="js/scripts.js"></script>
  44. -->
  45. <!--common scripts for all pages-->
  46. <script src="api/arcgis_js_v414_api/arcgis_js_api/library/4.14/init.js"></script>
  47. </body>
  48. </html>
  49. var view;
  50. var scene, webscene;
  51. var dynamicCylinderLayer;
  52. var videoCurrent,videoFlag;
  53. <script type="text/javascript">
  54. require([
  55. "esri/WebScene",
  56. "esri/config",
  57. "esri/views/SceneView",
  58. "esri/layers/WebTileLayer",
  59. "esri/layers/KMLLayer",
  60. "esri/layers/BaseDynamicLayer",
  61. "esri/views/3d/externalRenderers",
  62. "esri/geometry/SpatialReference",
  63. "dojo/dom",
  64. "dojo/on",
  65. ], function (
  66. WebScene,
  67. esriConfig,
  68. SceneView,
  69. WebTileLayer,
  70. KMLLayer,
  71. BaseDynamicLayer,
  72. externalRenderers,
  73. SpatialReference,
  74. dom,
  75. on,
  76. ) {
  77. var x=0, y=0,z=0;
  78. // 创建一副空的三维场景
  79. // var scene = new WebScene({});
  80. esriConfig.portalUrl="https://trail.arcgisonline.cn/portal";
  81. scene = new WebScene({
  82. portalItem: { // 自动创建一个PortalItem()
  83. id: "c2ca6bd95b104890905f321d6db08174"
  84. } });
  85. webscene=scene;
  86. view = new SceneView({
  87. container: "ViewDiv",
  88. map: scene,
  89. //viewingMode: "global",
  90. camera: {
  91. position: [119.19470299543177, 36.69956091981171, 318.9954051710665 ],
  92. heading: 359.3912760953511,
  93. tilt: 48.94296290684675
  94. },
  95. environment: {
  96. atmosphere: {
  97. quality: "high"
  98. },
  99. lighting: {
  100. date: new Date(),
  101. directShadowsEnabled: true
  102. }
  103. },
  104. });
  105. // 开始定义一个自定义的外部渲染器Create our custom external renderer
  106. var myFirstExternalRenderer = {
  107. renderer: null, // three.js renderer
  108. camera: null, // three.js camera
  109. scene: null, // three.js scene
  110. ambient: null, // three.js ambient light source
  111. sun: null, // three.js sun light source
  112. /**
  113. * Setup function, called once by the ArcGIS JS API.
  114. 注册对象时被调用,只调用一次,用于初始化three.js创建的对象
  115. */
  116. setup: function (context) {
  117. this.renderer = new THREE.WebGLRenderer({
  118. context: context.gl,
  119. premultipliedAlpha: false //表示是否可以设置像素深度
  120. });
  121. this.renderer.setPixelRatio(window.devicePixelRatio); //设置设备像素比
  122. this.renderer.setViewport(0, 0, view.width, view.height);
  123. // prevent three.js from clearing the buffers provided by the ArcGIS JS API.
  124. this.renderer.autoClearDepth = false; //不清楚深度缓冲区
  125. this.renderer.autoClearStencil = false; //不清理模板缓冲区
  126. this.renderer.autoClearColor = false; //不清理颜色缓冲区
  127. var originalSetRenderTarget = this.renderer.setRenderTarget.bind(
  128. this.renderer
  129. );
  130. this.renderer.setRenderTarget = function (target) {
  131. originalSetRenderTarget(target);
  132. if (target == null) {
  133. context.bindRenderTarget();
  134. }
  135. };
  136. // 基础设置 end
  137. this.scene = new THREE.Scene();
  138. this.camera = new THREE.PerspectiveCamera(); //透视投影相机
  139. // setup scene lighting
  140. this.ambient = new THREE.AmbientLight(0xffffff, 0.5);
  141. this.scene.add(this.ambient);
  142. this.sun = new THREE.DirectionalLight(0xffffff, 0.5);
  143. this.scene.add(this.sun);
  144. var znum=4;
  145. zgeoData=new Array();
  146. for(var i=0;i<znum;i++){
  147. zgeoData[i]=new Array();}
  148. zgeoData[0][0]=119.194612; <!-- 2 -->
  149. zgeoData[0][1]=36.703352;
  150. zgeoData[0][2]=37.5;
  151. zgeoData[1][0]=119.194656; <!-- 3 -->
  152. zgeoData[1][1]=36.703288;
  153. zgeoData[1][2]=38;
  154. zgeoData[2][0]=119.194656; <!-- 4 -->
  155. zgeoData[2][1]=36.703288;
  156. zgeoData[2][2]=43.3;
  157. zgeoData[3][0]=119.194610; <!-- 1 -->
  158. zgeoData[3][1]=36.703349;
  159. zgeoData[3][2]=43.5;
  160. var zx=new Array();
  161. var zy=new Array();
  162. var zz=new Array();
  163. for(var i=0;i<znum;i++){
  164. var transform = new THREE.Matrix4(); //4*4构建矩阵
  165. transform.fromArray(externalRenderers.renderCoordinateTransformAt(view, zgeoData[i], SpatialReference.WGS84, new Array(16))); //fromArray方法将存储Matrix4(4x4矩阵)元素值的数组赋值给当前Matrix4(4x4矩阵)对象
  166. zx[i] = transform.elements[12];
  167. zy[i] = transform.elements[13];
  168. zz[i] = transform.elements[14];
  169. }
  170. var geometry = new THREE.Geometry();
  171. var p=new Array();
  172. for(var i=0;i<znum;i++){
  173. p[i]=new THREE.Vector3(zx[i],zy[i],zz[i]);
  174. }
  175. geometry.vertices.push(p[0],p[1],p[2],p[3]);
  176. var normal = new THREE.Vector3(0, 0, 1); //三角面法向量
  177. //利用顶点 0, 1, 2 创建一个面
  178. var face0 = new THREE.Face3( 0, 1, 2, normal); //三角面1
  179. var face1 = new THREE.Face3( 0, 2, 3, normal); //三角面2
  180. geometry.faces.push( face0,face1); //三角面12添加到几何体
  181. var t0=new THREE.Vector2(0,0);
  182. var t1=new THREE.Vector2(1,0);
  183. var t2=new THREE.Vector2(1,1);
  184. var t3=new THREE.Vector2(0,1);
  185. var uv1=[t0,t1,t2];
  186. var uv2=[t0,t2,t3];
  187. geometry.faceVertexUvs[0].push(uv1,uv2);
  188. var material = new THREE.MeshBasicMaterial({ color: 0xff0000, side: THREE.DoubleSide });
  189. //创建网格对象
  190. var meshObj = new THREE.Mesh(geometry, material);
  191. this.scene.add(meshObj);
  192. var video = document.getElementById('video');
  193. var texture = new THREE.VideoTexture(video);
  194. var texture33=new THREE.MeshBasicMaterial({ map: texture });
  195. // 重新为网格对象设置材质
  196. meshObj.material = texture33;
  197. // cleanup after ourselfs
  198. context.resetWebGLState();
  199. },
  200. render: function (context) {
  201. // update camera parameters
  202. ///
  203. var cam = context.camera;
  204. this.camera.position.set(cam.eye[0], cam.eye[1], cam.eye[2]);
  205. this.camera.up.set(cam.up[0], cam.up[1], cam.up[2]);
  206. this.camera.lookAt(
  207. new THREE.Vector3(cam.center[0], cam.center[1], cam.center[2])
  208. );
  209. // Projection matrix can be copied directly
  210. this.camera.projectionMatrix.fromArray(cam.projectionMatrix);
  211. // update lighting
  212. /
  213. // view.environment.lighting.date = Date.now();
  214. var l = context.sunLight;
  215. this.sun.position.set(
  216. l.direction[0],
  217. l.direction[1],
  218. l.direction[2]
  219. );
  220. this.sun.intensity = l.diffuse.intensity;
  221. this.sun.color = new THREE.Color(
  222. l.diffuse.color[0],
  223. l.diffuse.color[1],
  224. l.diffuse.color[2]
  225. );
  226. this.ambient.intensity = l.ambient.intensity;
  227. this.ambient.color = new THREE.Color(
  228. l.ambient.color[0],
  229. l.ambient.color[1],
  230. l.ambient.color[2]
  231. );
  232. // draw the scene
  233. /
  234. this.renderer.state.reset();
  235. this.renderer.render(this.scene, this.camera);
  236. // as we want to smoothly animate the ISS movement, immediately request a re-render
  237. externalRenderers.requestRender(view);
  238. // cleanup
  239. context.resetWebGLState();
  240. },
  241. };
  242. var videoSrc = "video/9hao.mp4";//新的视频播放地址
  243. var cam = view.camera.clone();
  244. document.getElementById("video").src=videoSrc ;
  245. document.getElementById("video").play();
  246. cam.heading= 73.967579887275, // face due east
  247. cam.tilt= 76.59737032861595, // looking from a bird's eye view
  248. cam.position = {
  249. latitude: 36.70328541718525,
  250. longitude: 119.194463268771,
  251. z: 43.54298318736255 // altitude in meters
  252. };
  253. view.goTo(cam);
  254. externalRenderers.add(view, myFirstExternalRenderer);
  255. videoFlag=true;
  256. });
  257. </script>

 

声明:zqk原创,转载请注明出处。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/861592
推荐阅读
相关标签
  

闽ICP备14008679号