又一套智慧农场代码,vue3和threejs写的真优雅!

预览截图

内容介绍



技术栈

高德地图API three.js vue3

代码解析

<script setup>
import { getMap, initMap } from '@/utils/mainMap2.js'
import { fetchMockData } from '@/utils/mock.js'
import GLlayer from '#/gl-layers/lib/index.mjs'
import * as THREE from 'three'
import CropLayer from '@/components/map/cropLayer.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import * as dat from 'dat.gui'

const {
  PolygonLayer,
  FlowlineLayer,
  BorderLayer,
  DrivingLayer,
  TilesLayer,
  LayerManager
} = GLlayer

// 高德可视化类
let loca

// 容器
const container = ref(null)

// 图层管理
const layerManger = new LayerManager()

// 是否检测到有人试图越界
let isInvadeMode = false
let invadeClock = null
// 入侵者标记
let invadeMarker


// 是否第一人称
let isFirstView = false

// 无人机动画混合器
let mixer

let directionalLight
let gui
var guiCtrl = {
  lightPositionX: 1000,
  lightPositionY: 1000,
  lightPositionZ: 1600,
  cameraNear: 0,
  caremaFar: 20000,
  cameraLeft: -5000,
  cameraRight: 5000,
  cameraTop: 5000,
  cameraBottom: -5000,
  mapSize: 1024, // 1024
  planeMaterialOpacity: 0.5,
  intetity: 2.5,
  mixerPlaySpeed: 5
};

const allLayers = [
  { id: 'borderLayer', name: '区域边界', visible: true },
  { id: 'farmLayer', name: '农田', visible: true },
  { id: 'poolLayer', name: '鱼塘', visible: true },
  { id: 'waterLayer', name: '水域', visible: true },
  { id: 'buildingLayer', name: '村居', visible: true },
  { id: 'dronLayer', name: '无人机', visible: true },
  { id: 'dronPathLayer', name: '无人机轨迹', visible: true },
  { id: 'cropLayer', name: '农产品识别', visible: true },
  { id: 'riskLayer', name: '灾害预测', visible: false },
  { id: 'producationLayer', name: '年产量预测', visible: false },
  { id: 'serverLayer', name: '服务点', visible: false },
]

const SETTING = {
  center: [113.532936, 22.738711],
  alone: false,
  topicMap: {
    product: {
      label: '生产', //作物识别、农田灾害预测、水质检测
      layers: ['farmLayer', 'poolLayer', 'waterLayer', 'buildingLayer', 'riskLayer', 'cropLayer']
    },
    security: {
      label: '安全', //入侵检测、无人机巡航
      layers: ['borderLayer', 'waterLayer', 'buildingLayer', 'dronLayer', 'dronPathLayer', 'serverLayer']
    },
    value: {
      label: '经济', //产值预测
      layers: ['farmLayer', 'poolLayer', 'cropLayer', 'producationLayer']
    }
  }
}

// 地图数据提示浮窗
var normalMarker

onMounted(async () => {
  await init()
  // await getPointsData()
  await initLayers()
  animateFn()
  // initGUI()
})

var wxLayer

// 初始化地图
async function init() {
  // 区域掩模
  // const borderData = await getBoundaryData()
  const map = await initMap({
    viewMode: '3D',
    dom: container.value,
    showBuildingBlock: false,
    center: SETTING.center,
    zoom: 15.5,
    pitch: 42.0,
    rotation: 4.9,
    mapStyle: 'amap://styles/light',
    skyColor: '#c8edff'
  })

  // 添加卫星地图
  const satelliteLayer = new AMap.TileLayer.Satellite();

  map.add([satelliteLayer]);
  // 给底图添加css滤镜
  // document.querySelector('.amap-layer').style = 'filter:brightness(0.5) saturate(0.3) grayscale(0.5);'
  map.on('zoomend', (e) => {
    console.log(map.getZoom())
  })
  map.on('click', (e) => {
    const { lng, lat } = e.lnglat
    console.log([lng, lat])

    // 设置图层中心
    // const layer = layerManger.findLayerById('buildingLayer')
    // layer.setCenter([lng, lat])

    // 显示点击坐标
    // const marker = new AMap.Marker({
    //   map: getMap(),
    //   position: [lng, lat],
    //   label: {
    //     content: `[${lng},${lat}]`,
    //     direction: 'top'
    //   }
    // })
    if (normalMarker) {
      map.remove(normalMarker)
    }
  })

  loca = new Loca.Container({
    map,
  });

  normalMarker = new AMap.Marker({
    offset: [70, -15],
    zooms: [1, 22]
  });

  document.addEventListener('keydown', function (event) {
    var keyCode = event.keyCode;
    // 判断是否按下了数字键1、2、3
    if (keyCode === 49) { 
      switchTopic('product')
    } else if (keyCode === 50) {
      switchTopic('security')
    } else if (keyCode === 51) {
      switchTopic('value')
    }
  });
}

window.getMapView = function () {
  const center = mainMap.getCenter()
  const zoom = mainMap.getZoom()
  const pitch = mainMap.getPitch()
  const rotation = mainMap.getRotation()

  const res = {
    center,
    zoom,
    pitch,
    rotation
  }
  console.log(res)
  return res
}
window.setMapView = function ({ center, zoom, pitch, rotation }) {
  mainMap.setCenter(center)
  mainMap.setZoom(zoom)
  mainMap.setPitch(pitch)
  mainMap.setRotation(rotation)
}

async function initLayers() {
  // initWxLayer()
  await initBorderLayer()
  await initFarmLayer()
  await initPoolLayer()
  await initWaterLayer()
  await initBuildingLayer()
  await initDroneLayer()
  await initCropLayer()
  await initRiskLayer()
  await initProducationLayer()
  await initServePOILayer()
}
function initWxLayer() {
  const map = getMap()
  var wms = new AMap.TileLayer({
    // tileUrl: 'http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x=[x]&y=[y]&z=[z]',//google X
    tileUrl: 'https://gwxc.shipxy.com/tile.g?z=[z]&x=[x]&y=[y]', //shipInfo
    // tileUrl: 'https://mt1.google.com/vt/lyrs=h&x=[x]&y=[y]&z=[z]', //google 84 
    // tileUrl: 'http://gac-geo.googlecnapps.cn/maps/vt?lyrs=s&gl=CN&x={x}&y={y}&z={z}', //google cgj02 X
    zooms: [4, 22]
  });

  wms.setMap(map);

  wxLayer = wms
}

async function initServePOILayer() {
  const map = getMap()
  const data = await fetchMockData('serverpoi.geojson')

  const geo = new Loca.GeoJSONSource({ data });

  var labelsLayer = new Loca.LabelsLayer({
    zooms: [10, 20],
  })
  labelsLayer.setSource(geo);
  labelsLayer.setStyle({
    icon: {
      type: 'image',
      image: `./static/icons/server_poi.png`,
      size: [48, 75],
      anchor: 'center',
    },
    text: {
      // 每项配置都可使用回调函数来动态配置
      content: (index, feat) => {
        return feat.properties.name;
      },
      style: {
        fontSize: 12,
        fontWeight: 'normal',
        fillColor: '#5CDE8E',
        strokeColor: '#000',
        strokeWidth: 2,
      },
      direction: 'bottom',
    },
    extData: (index, feat) => {
      return feat.properties;
    }
  });
  loca.add(labelsLayer)

运行

npm install npm run dev

点赞(1) 打赏

立即下载

温馨提示! 此资源需支付 ¥30.00 后下载
购买成功后,如无法下载请联系微信: code2985

评论列表 共有 0 条评论

暂无评论

微信小程序

微信扫一扫体验

立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部