赞
踩
为了方便测试本人用的是parcel打包工具创建的一个小项目,项目结构如图
arcgisJS文档查看点这里
const map = new Map({
basemap: 'topo-vector',
});
const view = new SceneView({
container: 'viewDiv', // 包含视图的容器
map: map,
// camera: {
// position: [104.06340647710485, 30.659828202233566, 1000],
// tilt: 45,
// },
center: [105, 29],
zoom: 3,
});
外部渲染器,需要必备的3个函数:setup render dispose
创建外部渲染器对象
首先创建threejs的渲染器,并联系arcgis上下文gl
this.renderer = new THREE.WebGLRenderer({
context:context.gl,
premultipliedAlpha:false
})
this.renderer.setPixelRatio(window.devicePixelRatio);
this.renderer.setViewport(this.view.width, this.view.height);
// 防止Three.js清除ArcGIS JS API提供的缓冲区。
this.renderer.autoClearDepth = false; // 定义renderer是否清除深度缓存
this.renderer.autoClearStencil = false; // 定义renderer是否清除模板缓存
this.renderer.autoClearColor = false; // 定义renderer是否清除颜色缓存
this.scene = new THREE.Scene(); // 场景
this.camera = new THREE.PerspectiveCamera(); // 相机
this.ambient = new THREE.AmbientLight(0xffffff, 0.5); // 环境光
this.scene.add(this.ambient); // 把环境光添加到场景中
this.sun = new THREE.DirectionalLight(0xffffff, 0.5); // 平行光(模拟太阳光)
this.scene.add(this.sun); // 把太阳光添加到场景中
// 添加坐标轴辅助工具
const axesHelper = new THREE.AxesHelper(10000000);
this.scene.add(axesHelper);
以上将ThreeJS必要的场景、相机、渲染器已经成功创建,现在我们来创建3D模型。创建一个立方体,这里设置的宽高与深度很大,方便观看效果。
const geometry = new THREE.BoxGeometry( 100000, 100000, 100000 );
现在是重点的坐标转换,目前存在的问题是这个模型的位置如何去对应arcgis场景的坐标位置。目前参考两种方法:
let transform = new THREE.Matrix4(); // 变换矩阵 let transformation = new Array(16); let vector3List = []; // 顶点数组 // 转换顶点坐标 points.forEach((point) => { // 将经纬度坐标转换为xy值\ let pointXY = webMercatorUtils.lngLatToXY(经度, 维度); // 先转换高度为0的点 transform.fromArray( externalRenderers.renderCoordinateTransformAt( this.view, [pointXY[0], pointXY[1], 0], // 坐标在地面上的点[x值, y值, 高度值] this.view.spatialReference, transformation ) ); vector3List.push( new THREE.Vector3( transform.elements[12], transform.elements[13], transform.elements[14] ) ); })
此生成的vector3List 就是物体在arcgis场景中相对于three坐标,对应的位置。
还有一种是arcgis api自带将外部空间坐标渲染到内部空间坐标的方法
const entryPos = [105, 29, 550000]; // 输入位置 [经度, 纬度, 高程]
const renderPos = new Array(3); // 渲染位置
externalRenderers.toRenderCoordinates(
view,
entryPos,
0,
SpatialReference.WGS84,
renderPos,
0,
1
);
console.log("转换后坐标",renderPos)
可以查看官方文档查阅,现在已经得到物体位置坐标,可以进行下一步将物体添加到场景中。
const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
this.obj = new THREE.Mesh( geometry, material );
this.obj.position.set(...renderPos)
this.scene.add( this.obj );
这里用来渲染物体的动态效果
// 获取ArcGIS场景中的大小 const cam = context.camera; this.camera.position.set(cam.eye[0], cam.eye[1], cam.eye[2]); this.camera.up.set(cam.up[0], cam.up[1], cam.up[2]); this.camera.lookAt( new THREE.Vector3(cam.center[0], cam.center[1], cam.center[2]) ); // 投影矩阵可以直接复制 this.camera.projectionMatrix.fromArray(cam.projectionMatrix); // this.obj.position.x += 1 this.renderer.state.reset(); context.bindRenderTarget() this.renderer.render(this.scene, this.camera); externalRenderers.requestRender(this.view); // cleanup context.resetWebGLState();
最后别忘了外部渲染器添加
externalRenderers.add(view, myRenderer);
运行代码已经能够看到立方体了
参考
参考博主https://blog.csdn.net/qq_37155408/article/details/105295877?spm=1001.2014.3001.5506。他是渲染了一个外部模型。我这里渲染的是three自带的模型,对应初学者包括我自己,非常的友好。能够更加快速的理解渲染流程同时看到自己学习效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。