高德地图配合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)
  }
相关推荐
@大迁世界3 分钟前
TypeScript 的本质并非类型,而是信任
开发语言·前端·javascript·typescript·ecmascript
GIS之路12 分钟前
GDAL 实现矢量裁剪
前端·python·信息可视化
是一个Bug15 分钟前
后端开发者视角的前端开发面试题清单(50道)
前端
Amumu1213817 分钟前
React面向组件编程
开发语言·前端·javascript
持续升级打怪中39 分钟前
Vue3 中虚拟滚动与分页加载的实现原理与实践
前端·性能优化
GIS之路42 分钟前
GDAL 实现矢量合并
前端
hxjhnct1 小时前
React useContext的缺陷
前端·react.js·前端框架
前端 贾公子1 小时前
从入门到实践:前端 Monorepo 工程化实战(4)
前端
菩提小狗1 小时前
Sqlmap双击运行脚本,双击直接打开。
前端·笔记·安全·web安全
前端工作日常1 小时前
我学习到的AG-UI的概念
前端