☰
高德地图与Three.js融合:数字农场3D可视化大屏开发实践
2026/10/3 3:46:14 网站建设 项目流程

1. 为什么选择“高德地图+Three.js”:这场2D底图与3D渲染的搭配是怎么确定的

1.1 数字农场的可视化需求,到底在展示什么

先聊点实在的。接到“数字农场3D可视化大屏”这个需求时,很多人的第一反应是“不就是做个3D场景嘛,拉个模型放进去就行了”。但真正跑一遍业务调研你会发现,客户真正要的其实是一个带地理语义的实时农情驾驶舱——不是单纯为了“好看”,而是要把农场的真实位置、田块边界、温室内外环境、农机作业轨迹、人员位置等信息,放到一张能看懂、能定位、能回溯的地图上。

你想想看,一片几千亩的农场,如果只给你一个“假想三维沙盘”,左上角写着“A区大棚当前温度28.5℃”,领导问一句“A区大棚在哪儿?离东门多远?旁边那块地在种什么?”——这种沙盘根本答不上来。因为它的空间坐标是“作者自己编的”,和真实世界的经纬度、道路、河流、地块边界毫无对应关系。所以核心矛盾其实是:大屏要展示的真实世界位置与3D场景的“虚拟空间”必须建立映射,而高德地图,恰好是这层映射最好的承载基础。

1.2 高德地图与Three.js的结合点在哪里

高德地图擅长的,是全国范围的路网、卫星图、POI、行政区划、逆地理编码这些“宏观地理信息”。Three.js擅长的,是在WebGL里构建逼真的局部三维场景——能有光照、阴影、半透明材质、粒子、动画。两者天然互补。

这个项目的思路说白了就一句话:以高德地图为“画布底座”,将Three.js渲染的3D农场场景作为一层透明的“增强现实面板”覆盖在上方,通过经纬度坐标把两者锚定在一起。

地图拖拽缩放时,Three.js的相机和场景跟着移动;地图停止时,3D模型准确地叠在地图瓦片对应的位置。用户在视觉上看到的是一个整体——底图是高清卫星影像,上面立着半透明的温室大棚、颜色分层的农田地块、正在移动的农机模型,以及一系列浮在空中的数据标签。这种体验,比把整个区块做成纯3D、或者纯用2D地图加图标,在信息密度和视觉冲击力上都要高一个档次。

1.3 技术选型对比:为什么不选Cesium、Mapbox GL、纯Three.js

接下来说说选型过程。这套方案看似顺理成章,但真要动手前,我建议你把主流方案都过一遍。下表是我在定这个架构前做的横向对比:

方案优势劣势适配场景
Cesium原生支持全球地形、3D Tiles、大场景性能优秀学习曲线陡峭;做“局部精致小场景”反而笨重;Cesium默认坐标、瓦片服务在国内调用的适配成本较高城市级、地形级、跨区域大场景数字孪生
Mapbox GL样式编辑灵活,3D建筑支持不错,生态成熟在国内使用需要自行处理瓦片服务可达性和坐标系转换;个性化底图和审图合规工作麻烦有海外部署需求或强样式定制的项目
纯Three.js自建底图场景表现力最强,完全可控路网、POI、行政边界等基础地理数据要自己维护,地图交互(缩放、平移、旋转)全部手写,工作量爆炸不依赖真实地理位置的演示沙盘
高德地图+Three.js国内地理数据开箱即用;JS API成熟稳定;局部场景用Three.js实现,复杂度可控;用户可以基于熟悉的2D地图交互习惯操作地图底图与3D场景需要手动同步坐标系;全局大场景性能不如Cesium园区/农场/工厂/工地等局部园区级可视化大屏

这里必须强调一个判断标准:如果你的项目是“几百平方公里的多区域宏观态势”,不用犹豫选Cesium;如果是“一个园区、一个农场、一个厂区,要展示厘米级细节和业务数据”,高德+Three.js的综合成本最低。我见过不少人拿着Cesium做园区级项目,光是把建筑模型转成3D Tiles、处理地形、调相机就折腾了两周,最后出来的效果还不如Three.js一个下午搭的场景精致。选型不是追潮流,而是要对齐项目范围和交付周期。

2. 开工前必须先解决坐标系:经纬度到Three.js世界的换算思路

2.1 用农场中心点把地球“摊平”

这块是整个项目最容易被低估、也最影响成败的地方。三个字:坐标系。

高德地图给你的是经纬度,比如某条田埂的顶点是[116.397428, 39.90923]。但Three.js的世界是一个以原点为中心、用X/Y/Z直角坐标系描述的立方体空间。你需要一套方法,把WGS-84思想模型下的经纬度,映射到Three.js的平面世界坐标。

最常用的做法是“局部切平面法”——取农场的中心点作为坐标原点,其他所有经纬度都换算成相对中心的偏移量。可以理解成:地球表面在你农场这一小块区域足够“平”,你把它当作一个平面直角坐标系来用。误差在几公里范围内几乎可以忽略(农业园区的面积一般都符合这个假设)。

换算公式的思路是:经度差 × 地球在该纬度的每度距离 ≈ X偏移(米),纬度差 × 每度纬度距离 ≈ Y偏移(米);然后为了视觉习惯,把Y轴作为“北”方向(Three.js默认Z轴朝向你,X轴向右,Y轴向上,所以通常我会让Z轴表示北)。换算成代码后,几乎所有3D对象都能通过这个函数快速定位。

2.2 核心换算代码与场景比例

我在这套项目里封装了一个核心工具函数,所有模型摆放都用它:

// 以农场中心为原点,附上一个场景比例因子,后面调相机视野时有用 const FARM_CENTER = [116.397428, 39.90923]; const SCALE = 1; // 1个Three.js单位 = 1米,方便真实尺寸建模 function lngLatToScene(lnglat) { const R = 6378137; // 地球半径,WGS-84椭球体长半轴近似值 const latRad = (FARM_CENTER[1] * Math.PI) / 180; const meterPerLng = (Math.PI * R * Math.cos(latRad)) / 180; const meterPerLat = (Math.PI * R) / 180; const dx = (lnglat[0] - FARM_CENTER[0]) * meterPerLng; const dy = (lnglat[1] - FARM_CENTER[1]) * meterPerLat; return new THREE.Vector3(dx, 0, dy); }

这样做的核心价值在于,所有3D模型的真实尺寸可以直接用“米”来定义。比如大棚宽12米、长60米、肩高3.5米,建模时参数直接写12、60、3.5,完全不用缩放换算。场景相对真实世界没有形变,后续做相机同步、农机轨迹、热力图范围计算都省心。

2.3 别忘了高德坐标和GPS坐标不是一回事

这里必须敲黑板:高德地图用的是GCJ-02坐标,也就是俗称的“火星坐标系”,它是基于WGS-84做了偏移处理的。如果你手里的农机GPS轨迹、土壤采样点数据是WGS-84原始坐标,直接拿lngLatToScene换算进场景,会发现所有模型整体漂移了——轻则几十米,重则几百米,在卫星影像底图上一眼就能看出“田块和边界对不上”。

解决办法有两个方向。第一,所有业务数据进来之前统一转成GCJ-02再做展示,高德JS API自身就带AMap.convertFrom转换方法,但注意批量转换有配额和延迟,不适合高频实时调用。第二,后端在数据入库时就把坐标统一成项目的“展示坐标系”,前端不需要再做额外转换。我的建议是选第二种,因为坐标统一是数据治理问题,不应该下沉到前端每帧去处理。

3. 搭建大屏骨架:让Three.js渲染器正常叠加到高德地图上

3.1 页面布局与大屏结构

大屏的布局通常走经典三栏:顶部标题栏,左侧一列数据面板(环境监测、设备状态),右侧一列数据面板(种植任务、告警信息),中间是核心场景区。因为我这次是用高德地图做底图,中间区域天然是一个地图容器,右侧面板做成半透明浮层盖在上面,方便看底下的3D场景。

推荐一个稳妥的大屏栅格思路:中间地图容器占宽度的60%~70%,不要撑满,两侧面板各留15%~20%,面板背景用深色半透明渐变。这样“地图+3D”作为视觉重心,但业务数据又不会被遮挡。

3.2 初始化高德地图实例

高德JS API 2.0的初始化代码比较简洁,需要在index.html里引一个script,然后创建地图实例:

<script src="https://webapi.amap.com/maps?v=2.0&key=YOUR_KEY&plugin=AMap.Scale"></script>
const map = new AMap.Map('mapContainer', { center: [116.397428, 39.90923], zoom: 16, pitch: 0, // 先不做地图自身3D倾斜,避免和Three.js的相机冲突 rotation: 0, viewMode: '2D', mapStyle: 'amap://styles/light', // 农业主题用浅色底图比较干净,也可以用卫星底图 showBuildingBlock: false, // 关掉自带建筑,后面和Three.js叠加风格才统一 });

这里有几个细节值得注意。一是showBuildingBlock一定要关,否则地图自带的灰白色建筑块会从Three.js画布下方穿透上来混乱视觉。二是初始pitch设为0,因为地图自带的3D倾斜本质是改变瓦片投影,再叠Three.js场景会让两个相机参数纠缠不清,不如让地图始终保持俯视,所有立体表现交给Three.js。

3.3 把Three.js“贴”进地图容器,并管好事件

创建Three.js渲染器时,最关键的一行是alpha: true,这能让canvas背景透明,露出下面的高德瓦片:

const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true }); renderer.setSize(mapContainer.clientWidth, mapContainer.clientHeight); renderer.setPixelRatio(window.devicePixelRatio); // 大屏一般为1或2,按实际屏算 mapContainer.appendChild(renderer.domElement);

接下来,如果你什么都不做,Three.js画布会铺在地图上方,但它只是一张静态透明纸,地图怎么拖怎么放大,它都纹丝不动。所以要建立同步逻辑:高德地图每次移动、缩放、旋转,都要触发Three.js相机的重新定位。

核心思路是:

let syncTimer = null; map.on('mapmove', () => { clearTimeout(syncTimer); syncTimer = setTimeout(syncCameraFromMap, 16); // 节流到约60fps }); map.on('zoomchange', onZoomChange); map.on('moveend', syncCameraFromMap);

syncCameraFromMap做的事,是把地图中心经纬度换算成Three.js世界坐标,然后让透视相机的position落在这个坐标上方,目标点看向这个坐标:

function syncCameraFromMap() { const center = map.getCenter(); const sceneCenter = lngLatToScene([center.lng, center.lat]); const zoom = map.getZoom(); const fov = 45; // 根据缩放级别计算相机高度 const altitude = Math.pow(2, 18 - zoom) * 1.2; camera.position.set(sceneCenter.x, altitude, sceneCenter.z + altitude * 0.28); camera.lookAt(sceneCenter.x, 0, sceneCenter.z); camera.updateProjectionMatrix(); }

高度和缩放级别的关系,其实是按照“在屏幕上保持近似一致的地面范围”来调的。你不需要精确推导出WGS-84的米制比例尺,只要在几个常用zoom级别下(15、16、17、18)分别测一测,找到让3D模型和底图比例不别扭的系数即可。这个系数在每个项目中都要微调,因为显示器分辨率、画布宽度、fov都会影响结果。

3.4 手势事件与拾取事件的“分家”

由于Three.js画布是盖在高德地图上面的,会遇到一个典型问题:用户在地图上拖拽时,鼠标事件被canvas截获,地图拖不动了。最简单的处理是把Three.js画布的pointer-events设为none:

#mapContainer canvas { pointer-events: none; }

这样所有鼠标事件都穿透到高德地图,地图拖拽、缩放、双击放大都会正常响应。但代价是:你也没法用鼠标直接点击Three.js中的3D对象了。

想要“既能拖地图,又能点模型”,我的做法是做两套事件状态:默认状态让画布事件穿透,等用户点击时,先记录点击坐标,通过射线检测判断是否命中了Three.js场景里的对象;如果命中,临时把事件“吸住”一点,弹出交互面板,不命中则交给地图处理。实践中更简单的替代方案是:把“点击田块弹出详情”的事件绑定在高德的自定义覆盖物上,而不是Three.js网格上——高德Polygon本身是DOM/SVG层,天然响应点击,这样3D场景只负责视觉,业务交互回归地图,可以把复杂度降低一个量级。

4. 农场场景建模实战:农田地块、温室大棚、农机轨迹

4.1 农田地块:从多边形边界到挤压几何体

数字农场最核心的实体是农田地块。现实中,每一块田都有边界,可能来自测绘仪器、农机轨迹或者人工勾画,整理出来是一个多边形经纬度数组。在Three.js里,要做出一块“有厚度”的土地,最直接的办法是用THREE.Shape+ExtrudeGeometry:

const boundary = [ [116.397428, 39.90923], [116.399001, 39.909475], [116.399218, 39.908512], [116.397712, 39.908261] // ... ]; const shape = new THREE.Shape(); boundary.forEach((point, index) => { const scenePos = lngLatToScene(point); if (index === 0) shape.moveTo(scenePos.x, scenePos.z); else shape.lineTo(scenePos.x, scenePos.z); }); const extrudeSettings = { depth: 0.3, // 土地厚度,突出一点的立体感即可 bevelEnabled: false }; const geometry = new THREE.ExtrudeGeometry(shape, extrudeSettings); const material = new THREE.MeshStandardMaterial({ color: 0x6aad4e, // 根据作物生长状态切换 roughness: 0.9, metalness: 0.05, transparent: true, opacity: 0.92 }); const mesh = new THREE.Mesh(geometry, material); mesh.rotation.x = -Math.PI / 2; // ExtrudeGeometry默认是往Z轴挤出,转平 scene.add(mesh);

这里强调两个细节:第一,ExtrudeGeometry默认的挤出方向是Z轴,而我们的场景是平面世界,所以要旋转-90°;第二,田块的“生长状态变色”通过替换material.color实现,但要注意跨批次颜色各异时,每个地块单独创建材质,不要共用同一个材质实例,否则一个变了全部跟着变。

4.2 温室大棚:用半透明材质和InstancedMesh控制性能

温室大棚在视觉上很适合做文章。骨架做成半透明白色或绿色框架,棚膜用半透明材质,里面可以根据温度状态点亮灯光或者露出作物模型。

造型上不需要精细到每根钢管,取三个特征:长方体主体、弧形或人字形顶、若干立柱。一个简化的模型用BoxGeometry拼出来就行,关键是要让大棚“看得出是棚”而不是一个白色盒子。

农场大棚动辄几十上百个,如果一个大棚创建上百个Mesh节点,场景总顶点数会很快爆炸。这里强烈推荐用THREE.InstancedMesh做批量实例化渲染,把几百个大棚合并成一次draw call:

const instanceCount = greenhouseList.length; const instancedMesh = new THREE.InstancedMesh( greenhouseGeometry, greenhouseMaterial, instanceCount ); greenhouseList.forEach((item, index) => { const pos = lngLatToScene(item.coordinate); const matrix = new THREE.Matrix4(); const scale = new THREE.Vector3(item.width, item.height, item.length); const quaternion = new THREE.Quaternion(); // 按朝向设置,默认朝北 matrix.compose(pos, quaternion, scale); instancedMesh.setMatrixAt(index, matrix); }); instancedMesh.instanceMatrix.needsUpdate = true;

用InstancedMesh后,同类型模型的顶点数据只存一份,GPU把它当成一个整体批量绘制,性能提升非常明显。我以前单独建模300个大棚,每帧draw call接近600,帧率在20FPS徘徊;换成实例化后draw call降到几十,帧率直接拉满。

4.3 农机、树木和动态轨迹

农场里除了静态地块,还需要动态元素。农机、无人机、人员这几个角色建议直接用已经做好的glTF模型,在Three.js官方仓库或者市场里下载履带拖拉机、植保无人机模型,导入后放在经纬度转好的坐标上。模型加载用GLTFLoader:

const loader = new GLTFLoader(); loader.load('./models/tractor.glb', (gltf) => { const model = gltf.scene; model.scale.setScalar(1); const pos = lngLatToScene(tractorPos); model.position.set(pos.x, 0, pos.z); scene.add(model); });

动态轨迹则用THREE.Line画一条浅色导线,加一个LineDashedMaterial,再在动画循环里移动一个点光源或小方块表示农机当前位置,视觉上就是“一条线路 + 一个移动光点”,简洁但信息量足。

很多农业场景还需要做树木植被,网上搜“three.js 柳树”能搜到不少树木模型。但我的建议是:大屏的树木不需要每棵都做精细3D模型。把树做成THREE.Sprite(广告牌)贴图,永远正对相机,视觉效果在俯视角度下几乎看不出差别,但上百棵树的渲染开销可以忽略不计。如果你真的需要一棵动态柳枝摇曳的效果,再单独做一棵精模放在镜头必经之处当“门面”就行了,这是性价比最高的做法。

4.4 数据信息点:摄像头、气象站、土壤传感器

最后是散布在农场里的各种数据终端。摄像头用Cube拼个小盒子再画个圆面;气象站做成一根杆子加小圆球;土壤传感器直接用小立方体埋在地面附近。这些点位数量多但模型简单,同样用InstancedMesh或者Sprite完成。

每个数据点上浮一个信息标签,我建议不要用Three.js的CSS2DRenderer硬做,而是直接用高德的AMap.Marker,因为这类标签本质上也是“跟随经纬度定位”的。让高德Marker和Three.js场景走同样的坐标锚定逻辑,你就能享受高德自带的Marker动画、信息窗体、点击事件,并且不会出现Three.js遮挡DOM的问题。

5. 让大屏“动起来”:数据联动、颜色状态、面板交互

5.1 后台数据如何驱动场景变化

大屏项目如果没有真实数据驱动,做得再好看也就是个展示demo。数字农场的实时数据一般有两类来源:一类是传感器上报的IoT数据(温湿度、光照、土壤墒情、水肥状态),另一类是业务系统的结构化数据(生产任务、告警事件、农情记录)。

实践中,我会让前端轮询一个统一的/api/farm/overview接口,返回如下结构:

{ "greenhouse": [ { "id": "ws-001", "name": "1号温室", "lnglat": [116.397428, 39.90923], "temperature": 28.5, "humidity": 72, "light": 18000 } ], "field": [ { "id": "field-001", "boundary": [], "crop": "水稻", "growthStage": "拔节期", "health": "normal" } ] }

前端拿到数据后,做三件事:

  1. 根据growthStage或health字段更新对应地块网格的颜色和透明度;
  2. 更新大棚模型的发光状态或浮点数值;
  3. 更新两侧面板的DOM内容。

第2点最值得展开:大棚内部可以放一个点光源,温度在正常区间时,棚膜呈现淡淡的绿色;温度超过阈值时,大棚整体变成暖红色半透明,并且顶部的数据标签开始闪烁。这种“场景状态可视化”比任何图表都直观,用户一眼就能发现问题区域。

5.2 点击拾取与信息面板联动

我之前建议把点击交互放到高德自定义覆盖物上,这里具体演示如何做:

const fieldPolygon = new AMap.Polygon({ path: boundary, strokeColor: '#3da56b', strokeWeight: 2, fillColor: '#000000', fillOpacity: 0.1, extData: { fieldId: 'field-001' } }); map.add(fieldPolygon); fieldPolygon.on('click', (e) => { const fieldId = e.target.getExtData().fieldId; loadFieldDetail(fieldId); // 拉详情并更新右侧面板 });

这里有个视觉技巧:高德Polygon的fillColor设成完全透明的黑色,只是为了“接住点击事件”,实际填色完全交给Three.js的地块模型。这样Two.js只管视觉、高德只管交互,各司其职,既没有事件穿透问题,也不用在Three.js里做射线检测,代码量少了很多。

5.3 渲染循环和地图同步的收尾

场景中只要有动态元素(农机移动、点光源闪烁、流水动画),就要有requestAnimationFrame渲染循环:

function animate() { requestAnimationFrame(animate); // 移动农机:让模型的position沿着轨迹点插值 updateTractorPosition(); // 旋转环境中的风机、气象站风速计 updateRotatableObjects(); // 更新广告牌 spriteGroup.children.forEach(sprite => sprite.lookAt(camera.position)); renderer.render(scene, camera); } animate();

渲染循环和地图同步需要协调。我见过有人把renderer.render放进mapmove事件里每次刷新,结果地图高速拖拽时,Three.js场景一卡一卡的。正确做法是:Three.js始终保持独立渲染循环,地图移动只是更新相机参数,渲染循环里根据最新相机参数去渲染。两者解耦之后,流畅度会稳定很多。

6. 踩坑实录:高德地图+Three.js项目里的几个经典问题

6.1 场景里模型和地图底图对不上:排查跳进两层

这个坑几乎是所有用“地图+Three.js”组合的人都会踩。项目第一次联调时,我一圈大棚模型整体偏移到了地图的一个角上,底图上明明是大棚区域,模型却悬在旁边的路边。排查过程我把它分成两层:

第一层是坐标系一致性。检查业务数据到底用的是WGS-84还是GCJ-02。我们当时采到的地块边界是RTK测绘的WGS-84,而高德底图是GCJ-02,两者本身就有几十米偏移。解决后模型整体回到了农场范围内。

第二层是场景原点和容器尺寸。地图容器最左侧和最上侧的像素原点,跟Three.js渲染器的坐标原点是否对齐。如果你初始化Three.js的时候忘了把渲染器位置设成absolute top:0 left:0,或者容器有内边距,就会出现“缩放级别越深,偏移越大”的现象。排到后面发现是容器外层有个padding: 10px,把canvas整体挪了10像素,在zoom 18的时候这个10像素对应真实世界可能就一两米,在zoom 15的时候可能对应几十米——所以你才会看到模型随着缩放“漂移”得越来越离谱。

6.2 地图拖拽卡顿、画布挡住操作

这个前面已经铺垫过,最直接的诱因是Three.js canvas的pointer-events默认值挡住了高德地图的手势事件。解决方案就是CSS里写死pointer-events: none。

但如果你按这个改了之后,又遇到新的问题:地图能拖了,但3D场景里的浮空标签也点不到了。这是因为高德Marker是DOM元素,也被canvas盖在下面了。我当时的排查链路是:

  1. 确认canvas的pointer-events: none已生效;
  2. 用浏览器DevTools高亮元素,发现高德Marker的层级其实是正常的,但是父容器有个透明背景的浮层把整个中间区域覆盖了;
  3. 把浮层的pointer-events改为none,Marker立刻可点击。

这类“一层遮一层”的线索在叠加型可视化项目中特别多,排查时一定要养成用DevTools逐层看命中元素的习惯。

6.3 模型一多就降帧:从120FPS掉到20FPS的优化方案

最早我搭建田块和大棚时,是按“每个大棚一个独立Mesh、每个地块一个独立Geometry”的思路来的。500个Mesh叠加树木、设备、轨迹线之后,一帧的draw call冲到了800多,浏览器直接进入“卡顿中”状态。Debug的链路如下:

  1. 先用Three.js的renderer.info统计draw calls,确认瓶颈是CPU端的渲染命令过多,而不是GPU像素填充过重;
  2. 把所有同款式大棚改用InstancedMesh,瞬间减少了400多次draw calls;
  3. 把树木替换成Sprite广告牌,减少了几十棵精模树的渲染开销;
  4. 对地块的ExtrudeGeometry做顶点简化,去掉Bevel,减少顶点数;
  5. 远景模型做LOD简化——距离相机超过300米的对象,用一个低面体替代。

优化完后的数据:draw calls从800+降到不足100,帧率回到60FPS以上,GPU占用反而比以前更低了,因为半透明材质和复杂光照的draw calls才是大头。

6.4 高德自带建筑与Three.js场景风格割裂

高德地图默认会显示3D建筑,当你把地图倾斜起来时,那些灰白色的体块会在底图上冒出来,和Three.js里精心设计的绿色温室大棚格格不入。最初我以为是高德配置问题,一直找不到关闭入口,后来查文档才知道在初始化地图时有一个showBuildingBlock参数。

关掉之后,底图变成纯平面瓦片,Three.js的场景视觉风格才彻底统一。另外提醒一句,如果底图用的是高德卫星影像,注意试试不同缩放级别下影像的饱和度,很多场景下卫星图色彩太深会抢掉3D模型的视觉权重,可以通过高德的mapStyle或者给场景加一个极浅色半透明罩层来解决。

7. 写在最后:源码给你的不是“能跑”,而是一种可以复用的接入思路

这套项目做完以后,我复盘最大的收获并不是“我学会了Three.js”或者“我学会了高德API”,而是理解了地图系统与3D渲染引擎之间如何以坐标为核心互相配合。搞清楚了经纬度如何映射到场景坐标、相机如何随地图状态同步、事件穿透如何处理、实例化渲染如何优化性能,这套方法论可以复用到任何一个“园区级”可视化项目——工厂车间、港口码头、智慧校园、工业园区,逻辑几乎一样。

源码工程里包含的目录大概是:map.js处理高德地图初始化与同步,geo.js处理坐标换算,farm/目录下是地块、大棚、设备、农机四个子模块,data/目录放模拟的农情数据。你在参考时,不建议直接套用里面的固定建模样式,而应该把它当成一个“接入模板”,替换成自己的数据结构和模型资源。

最后再分享一个很实际的经验:大屏项目的验收标准,永远在“演示链路”是否顺畅。开发时就要经常站在决策者的位置上走一遍——打开大屏,看到农场全貌,点一个田块看生长期和墒情,切换到大棚看温湿度,模拟一个告警事件看是否会联动弹窗和闪烁。这条链路跑通了,项目就成功了大半。高德+Three.js的组合,能让你把这份“顺畅”建立在真实地理位置之上,这是纯3D沙盘完全给不了的底气。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询