高德地图配合three.js加载3d模型

注意点:three.j需要比较低的版本这边使用的是 0.117.1 并且高德的版本需要2.0

首先初始化一个地图

js 复制代码
// 初始化地图
  function initMap() {
    AMapLoader.load({
      key: 'b8929cd9524f38a88306fcbd0ee0d8de', //首次load必填
      version: '2.0',
      // 需要使用的的插件列表
      plugins: [
        'AMap.Geocoder', // 逆向地理解码插件
        'AMap.Marker', // 点标记插件
        'AMap.MapboxVectorTileLayer', // MVT多面体
        'AMap.3DTilesLayer', // MVT多面体
      ],
    })
      .then((_AMap) => {
        AMap = _AMap
        map = new AMap.Map('container', {
          viewMode: '3D', // 地图模式
          mapStyle: 'amap://styles/grey',
          pitch: 55,
          zoom: 18,
          center: mapCenter,
          // 只显示的特征
          // features: ['bg', 'road', 'building', 'point'],
          features: ['bg', 'road', 'point'],
          // layers: [
          //   // 高德默认标准图层
          //   new AMap.TileLayer.Satellite(),
          //   // 楼块图层
          //   new AMap.Buildings({
          //     zooms: [16, 18],
          //     zIndex: 10,
          //     heightFactor: 0, //2倍于默认高度,3D下有效
          //     wallColor: 'rgba(0, 0, 0,1)',
          //     roofColor: 'rgba(89, 142, 213,1)',
          //   }),
          // ],
        })
        initThree()
      })
      .catch((e) => {
        console.error(e)
      })
    // var roadNetLayer =  new AMap.TileLayer.RoadNet();
    // map.add( roadNetLayer);
  }

地图加载完之后加载three.js 调用initThree()

js 复制代码
// 初始化树
  function initThree() {
    // 初始化数据转换工具 (高德数据转换为three.js坐标数据)
    customCoords = map.customCoords
    // 数据使用转换工具进行转换,这个操作必须要提前执行(在获取镜头参数 函数之前执行),否则将会获得一个错误信息。
    //lngLatToCoord转坐标
    comLocation = customCoords.lngLatToCoord(mapCenter)
    lightLocation1 = customCoords.lngLatToCoord(lightCenter1)

    //灯光二
    lightLocation2 = customCoords.lngLatToCoord(klight2)
    // 创建webgl layer
    let glLayer = new AMap.GLCustomLayer({
      // 图层的层级 这里写的太大模型会消失
      zIndex: 10,
      // 初始化的操作,创建图层过程中执行一次。
      init: (gl) => {
        render = new THREE.WebGLRenderer({
          context: gl,
        })
        // 自动清空画布这里必须设置为 false,否则地图底图将无法显示
        render.autoClear = false

        initScene()
        initLight()
        initCamera()

        // 添加盒子 如果不延迟 或者延迟时间少了会保一个警告(Vertex buffer is not big enough for the draw call)
        setTimeout(() => {
          addBox() // 灯光盒
          // addDrone() // 无人机
          // addFineDrone()  // 无人机动态
          addModel()
          animate()
        }, 500)
      },
      render: () => {
        render.state.reset()
        const { near, far, fov, up, lookAt, position } = customCoords.getCameraParams()
        camera.near = near
        camera.far = far
        camera.fov = fov
        camera.position.set(...position)
        camera.up.set(...up)
        camera.lookAt(...lookAt)
        camera.updateProjectionMatrix()

        render.render(scene, camera)
      },
    })

    map.add(glLayer)
    animate()
  }
  
  // 初始化场景
  function initScene() {
    scene = new THREE.Scene()
  }
  
  // 初始化相机
  function initCamera() {
    camera = new THREE.PerspectiveCamera(
      60,
      mapRef.value.offsetWidth / mapRef.value.offsetHeight,
      100,
      1 << 30
    )
  }
  
  // 添加灯光1盒子
  function addBox() {
    let mat = new THREE.MeshBasicMaterial({
      color: 0xffffff,
      roughness: 0.5,
      metalness: 0.5,
    })
    let geo = new THREE.BoxBufferGeometry(10, 10, 10)
    let mesh = new THREE.Mesh(geo, mat)
    mesh.position.set(lightLocation1[0], lightLocation1[1], 20)
    scene.add(mesh)
  }
  
  
  // 添加模型
  function addModel() {
    loader.load('/model/huanglong3d/huanglongModel.gltf', function (gltf) {
      //GLTF在场景中的位置
      gltf.scene.position.set(comLocation[0], comLocation[1], 0)
      //缩放模型
      gltf.scene.scale.set(0.5, 0.5, 0.5)
      //旋转
      gltf.scene.rotation.x = 0.5 * Math.PI
      // gltf.scene.rotation.y = 1000;
      scene.add(gltf.scene)
      // models.start = gltf.scene
      gltf.scene.traverse(function (child) {
        if (child.isMesh) {
          //模型阴影
          // child.castshadow = true
          //调整金蜀度
          // child.material.metalness = 0.58
          //模型变亮 模型自发光
          // child.material.emissive = child.material.color
          // child.material.emissiveMap = child.material.map
          //模型变亮,或重新赋颜色
          // child.material.color.set(0x5186cc)
        }
      })
    })
  }

  // 动画
  function animate() {
    // 渲染时刷新地图
    map.render()
    // 自动刷新
    requestAnimationFrame(animate)
  }
  
  
  // 初始化光源
  function initLight() {
    // 创建环境光
    let light = new THREE.AmbientLight(0x03378f, 1)
    // let light = new THREE.AmbientLight(0xfc5531, 100)
    light.position.set(comLocation[0], comLocation[1], 25) //点光源位置
    light.position.set(0, 0, 0) //点光源位置
    //添加环境光
    scene.add(light)
    // 点光1
    let pointLight = new THREE.PointLight(0xffce66, 1)
    pointLight.position.set(lightLocation1[0], lightLocation1[1], 20)
    pointLight.distance = 420 // 设置光源距离

    // 点光2
    let pointLight2 = new THREE.PointLight(0xffce66, 1)
    pointLight2.position.set(lightLocation2[0], lightLocation2[1], 80)
    pointLight2.distance = 400 // 设置光源距离
    // pointLight.castShadow = true
    // pointLight.shadow.camera.near = 0.1
    // pointLight.shadow.camera.far = 25
    // 灯光朝向
    // pointLight.lookAt(new THREE.Vector3(0, 0, 0));

    const pointLightHelper = new THREE.PointLightHelper(pointLight16, 100) //添加 点光源的辅助线
    
    scene.add(pointLight)
    scene.add(pointLightHelper)
    scene.add(pointLight2)
  }
相关推荐
夜寒花碎6 分钟前
前端自动化测试一jest基础使用
前端·单元测试·jest
小徐_233310 分钟前
uni-app工程实战:基于vue-i18n和i18n-ally的国际化方案
前端·微信小程序·uni-app
前端小菜鸟一枚s14 分钟前
`ConstantPositionProperty` 的使用与应用
前端·javascript·cesium
JohnsonXin14 分钟前
怎么使用vue3实现一个优雅的不定高虚拟列表
前端·javascript·css·html5
17Knight16 分钟前
我的个性化 VSCode
前端
前端小菜鸟一枚s19 分钟前
`ConstantProperty` 的使用与应用
前端·javascript·cesium
狠狠的学习25 分钟前
antd表格行hover效果性能处理
前端·css
在下小航29 分钟前
前端本地大模型 window.ai 最新教程
前端·人工智能
一颗奇趣蛋30 分钟前
vue哪些情况称作“销毁组件”
前端·vue.js
Ody30 分钟前
循环滚动列表浅析
前端