研究ThreeJS也有段时间了,也能和公司业务相结合,但是涉及到地图层面的业务内容就有点菊紧,因为模型要和地图联动不知道如何实现,也就搁置下来。直到一个偶然的机会,发现百度地图的MapVGL可以实现各种炫酷3D效果,所以果断研究一波,先放一下百度自带的3D图层:
接下来需要我们跟着几个步骤来实现在指定位置放入我们自己的模型。
准备工作:
1 申请百度地图的ak,这个不难,可以自行百度。
2 copy一份官方的地图展示的代码,小白可以自己敲(我就是自己敲的)
3 我们需要运用ThreeJS来实现该功能,需要引入mapvgl.threelayers.min.js,我建议是吧这个文件保存在本地项目内,因为有些坑,要对这个文件进行小小的修改,下面会介绍到,如果有大佬看到这个坑有别的方法能解决,希望能私下交流下。
4 搞一个模型,转成json,导入的时候需要这个文件,可以用ThreeJS官方的Editor将obj转成json。(我用的obj格式的模型)
开始撸码:
var map = new BMapGL.Map("map_container"); // 创建Map实例
map.centerAndZoom(new BMapGL.Point(118.731134,32.011681), 19); // 初始化地图,设置中心点坐标和地图级别
map.enableScrollWheelZoom(true); //开启鼠标滚轮缩放
map.setHeading(20);
map.setTilt(70);
map.setMapStyleV2({ //这个根据个人喜好 不喜欢的 可以不加
styleId: '--------------------------------'
});
var THREE = mapvgl.THREE;
var view = new mapvgl.View({
map: map
});
var threeLayer = new mapvgl.ThreeLayer(); //创建一个threelayer
view.addLayer(threeLayer); //添加到view
var objectLoader = new THREE.ObjectLoader(); //读取模型
var group;
objectLoader.load("20200327/model.json",function (object) {
object.rotation.set(3.1415926 / 2,0,0);
object.scale.set(1.18,1.18,1.18);
for (var i = 0 ;i < object.children.length; i++){
object.children[i].material.color = new THREE.Color(1,0.796,0.429);
object.children[i].material.transparent = true;
object.children[i].material.opacity = 0.6;
for (var j = 0; j < object.children[i].material.length;j++){
object.children[i].material[j].color = new THREE.Color(1,0.796,0.429);
object.children[i].material[j].transparent = true;
object.children[i].material[j].opacity = 0.6;
}
group = object;
}
object.children[6].visible = false;
threeLayer.add(object,new BMapGL.Point(13217250,3742290)); //设置模型位置坐标
}
var light = new THREE.DirectionalLight('#ffffff',2); //添加灯光
light.position.set(100,100,100);
light.lookAt(0,0,0);
threeLayer.scene.add(light);
现在就可以运行浏览器,观察你的模型了,我这个用的南京奥体中心的模型和相关位置坐标,这个无所谓,可以根据喜好自己修改。
展示下我这边实现的效果:
说说这个里面的坑:
1 有同学会发现这个模型会根据鼠标缩放跟着一起缩放,我们找到mapvgl.threelayer.min.js,找到 key: "render", value: function 大概在26016行(因为我修改过这个代码),然后往下找到 this.updateCamera();,把这行代码注释掉就解决了模型缩放不正确问题,我来贴个图:
2 之前工程里面有ThreeJS的源码,用来导入obj模型,但是不成功,只能使用百度官方提供的THREE这个变量,看源码是针对ThreeJS又进行了封装,导致最原始的ThreeJS在这里并不适用。好在适用方法没有多大变化,看看源码还是能找到些眉目的。
3 还有这个坐标转换的问题一直没搞懂(毕竟菜鸡),官方也没有个具体文档来说明这个事情。就是3D世界的XYZ和现实世界的经纬度怎么转换的,我看FlyLineLayer的源码也是一头雾水,有大佬了解这个的话烦请指点♂下。
最后:
过段时间我来讲下怎么和加载的模型进行交互。顺便提下,希有相关行业经验的伙伴能多多交流。