vue3+arcgisAPI4案例:智慧林业资源监测分析平台(附源码下载)

发布于:2025-06-22 ⋅ 阅读:(14) ⋅ 点赞:(0)

基于vue3+arcgisapi4的智慧林业资源监测分析平台简单案例,覆盖功能点包括图层管理,生态环境监测点,防火路径选线以及智能问答等,适合学习arcgisapi4与前端框架结合开发3D可视化项目。

demo源码运行环境以及配置

运行环境:依赖Node安装环境,demo本地Node版本:推荐v18+。 运行工具:vscode或者其他工具。
配置方式:下载demo源码,vscode打开,然后顺序执行以下命令:
(1)下载demo环境依赖包命令:npm install
(2)启动demo命令:npm run dev
(3)打包demo命令: npm run build

技术栈

Vue 3.3.9
Vite 5.0.4
@arcgis/core 4.29.3

示例效果
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
核心源码

const initMap = () => {
  esriConfig.assetsPath = "./assets";
  esriConfig.fontsUrl = "./static.arcgis.com/fonts";
  // esriConfig.apiKey = 'AAPKca495ea263b64e44b61eaaecdbddebfcwEQjC8k8-6XGMrrXyCie6xzybboRl4REq-TwDQTm8Wz-8sL6REARz1wcm14Kq9ny';
  // 初始化创建地图对象
  map = new Map({
    basemap: basemapBlue_ArcGIS, // 默认显示arcgis在线影像图
    ground: "world-elevation"
  });
  // 初始化创建视图view对象
  view = new SceneView({
    container: "viewDiv",
    map: map,
    // center: config.mapInitParams.center,
    // zoom: config.mapInitParams.zoom
    camera: {
      position: {
        x: config.mapInitParams.center[0], // 经度
        y: config.mapInitParams.center[1],   // 纬度
        z: 2000      // 高度(米)
      },
      tilt: 75
    }
  });
  const labelPolygonClass = new LabelClass({
    labelExpressionInfo: { expression: "$feature.名称_name" },
    symbol: {
      type: "text",
      color: "#fff",
      font: {
        size: 10,
        weight: "normal",
      },
      haloColor: [0, 0, 0, 255],
      haloSize: 1,
    },
    minScale: 288895,         // 最小比例尺(最大缩放级别)
    // maxScale: 577790,    // 最大比例尺(最小缩放级别,
    // labelPlacement: "center-right"
  });
  // 老山林场图层
  LSLCLayer = new FeatureLayer({
    id: 'LSLCLayer',
    url: "https://www.geosceneonline.cn/server/rest/services/Hosted/老山林场/FeatureServer/0",
    renderer: {
      type: "simple",
      symbol: {
        type: "simple-fill",
        color: [51, 51, 204, 0],
        style: "solid",
        outline: {
          color: "red",
          width: 2
        }
      }
    },
    featureReduction: {
      type: "selection"
    },
    labelingInfo: [labelPolygonClass]
  });
  map.add(LSLCLayer);
  const labelClass = new LabelClass({
    labelExpressionInfo: { expression: "$feature.NAME" },
    symbol: {
      type: "text",
      color: "#fff",
      font: {
        size: 10,
        weight: "normal",
      },
      haloColor: [0, 0, 0, 255],
      haloSize: 1,
    },
    minScale: 288895,         // 最小比例尺(最大缩放级别)
    // maxScale: 577790,    // 最大比例尺(最小缩放级别,
    // labelPlacement: "center-right"
  });
  // 创建水系图层
  SXLayer = new FeatureLayer({
    id: 'SXLayer',
    url: "https://www.geosceneonline.cn/server/rest/services/Hosted/水系water/FeatureServer/0",
    renderer: {
      type: "simple",
      symbol: {
        type: "simple-line",
        color: "#1890ff",
        width: "4px",
        style: "solid"
      }
    },
    featureReduction: {
      type: "selection"
    },
    labelingInfo: [labelClass]
  });
  map.add(SXLayer);
  // 创建公路图层
  GLLayer = new FeatureLayer({
    id: 'GLLayer',
    url: "https://www.geosceneonline.cn/server/rest/services/Hosted/公路road/FeatureServer/0",
    renderer: {
      type: "simple",
      symbol: {
        type: "simple-line",
        color: "yellow",
        width: "4px",
        style: "solid"
      }
    },
    featureReduction: {
      type: "selection"
    },
    labelingInfo: [labelClass]
  });
  map.add(GLLayer);
  // 创建居民地地名图层
  JMDDMLayer = new FeatureLayer({
    id: 'JMDDMLayer',
    url: "https://www.geosceneonline.cn/server/rest/services/Hosted/居民地地名/FeatureServer/0",
    renderer: {
      type: "simple",
      symbol: {
        type: "simple-marker",
        size: 8,
        color: "#edd317",
        outline: {
          width: 0.5,
          color: "white"
        }
      }
    },
    featureReduction: {
      type: "selection"
    },
    labelingInfo: [labelClass]
  });
  map.add(JMDDMLayer);
  // 创建生态资源监测点图层
  const labelSTClass = new LabelClass({
    labelExpressionInfo: { expression: "$feature.name" },
    symbol: {
      type: "label-3d",
      symbolLayers: [
        {
          type: "text",
          material: {
            color: "white"
          },
          halo: {
            size: 1,
            color: [50, 50, 50]
          },
          size: 10
        }
      ]
    }
  });
  const verticalOffset = {
    screenLength: 40,
    maxWorldLength: 200,
    minWorldLength: 35
  };
  // create a new blob from geojson featurecollection
  const blob = new Blob([JSON.stringify(STGeojsonData.value)], {
    type: "application/json"
  });
  // URL reference to the blob
  const url = URL.createObjectURL(blob);
  monitorPointLayer = new GeoJSONLayer({
    id: 'monitorPointLayer',
    // url: "./public/data/monitorPoints.geojson",
    url: url,
    labelingInfo: [labelSTClass],
    featureReduction: {
      type: "selection"
    },
    outFields: ["*"],
    elevationInfo: {
      mode: "relative-to-scene"
    },
    renderer: {
      type: 'unique-value',
      field: 'temperature',
      defaultSymbol: {
        type: "point-3d",
        symbolLayers: [
          {
            type: "icon",
            resource: {
              href: ParkIMG
              // href: "https://developers.arcgis.com/javascript/latest/sample-code/visualization-point-styles/live/Park.png"
            },
            size: 20,
            outline: {
              color: "white",
              size: 2
            }
          }
        ],
        verticalOffset: verticalOffset,
        callout: {
          type: "line",
          color: "white",
          size: 2,
          border: {
            color: "#40C2B4"
          }
        }
      },
      // uniqueValueInfos: [
      //   {
      //     value: 35,
      //     symbol: {
      //       type: "simple-fill",
      //       color: '#00c460',
      //       style: "solid",
      //       outline: {
      //         color: '#dcdcdc',
      //         width: 1,
      //         style: "solid"
      //       }
      //     },
      //   }
      // ]
    },
  });
  map.add(monitorPointLayer);
  // 创建图形图层用于放置3D模型
  graphicsLayer3D = new GraphicsLayer({
    id: 'graphicsLayer3D',
    elevationInfo: { mode: 'on-the-ground' } // on-the-ground relative-to-ground absolute-height relative-to-scene
  });
  map.add(graphicsLayer3D);
  pathLineGraphicsLayer = new GraphicsLayer({
    id: 'pathLineGraphicsLayer',
    // elevationInfo: { mode: 'on-the-ground' }
  });
  map.add(pathLineGraphicsLayer);
  // 创建一个图形图层用于添加点图标
  pointGraphicsLayer = new GraphicsLayer({
    id: 'pointGraphicsLayer',
    // elevationInfo: { mode: 'on-the-ground' }
  });
  map.add(pointGraphicsLayer);
  // 去除logo
  view.ui.remove(["attribution", "navigation-toggle", "compass", "zoom"]);
  const popup = {
    alignment: "top-center",
    // collapseEnabled: false, // 移除title点击折叠功能
    visibleElements: {
      actionBar: false,
      collapseButton: false,
      closeButton: false,
      heading: false
    },
    dockOptions: {
      buttonEnabled: false, // 隐藏固定标签页
    }
  };
  view.popup = popup;
  // 监听视图view初始化加载完成执行
  view.when(function () {
    removeElementById('loader-wrapper');
    // 初始化创建地图默认视图控件
    // const homeWidget = new Home({
    //   view: view
    // });
    // 初始化创建地图切换控件
    basemapGallery = new BasemapToggle({
      view: view,
      nextBasemap: basemapVec_tianditu
    });
    // 控制地图控件位置
    view.ui.add([
      {
        component: basemapGallery,
        position: "bottom-right",
        index: 0
      }
    ]);
    // 视图地图监听点击事件
    view.on("immediate-click", (event) => {
      view.closePopup();
      const mapPoint = event.mapPoint;
      console.log('mapPoint:', mapPoint);
      // 判断是否执行路线规划选择点
      if (addPointType.value === 1 || addPointType.value === 2) {
        addPointGraphic(mapPoint, addPointType.value === 1 ? starPointSymbol : endPointSymbol);
        const position = `${mapPoint.longitude.toFixed(6)},${mapPoint.latitude.toFixed(6)}`;
        addPointType.value === 1 ? startPoint.value = position : endPoint.value = position;
        addPointType.value = 0;
      }
      view.popupEnabled = false;
      const opts = {
        include: monitorPointLayer
      };
      view.hitTest(event, opts).then(function (response) {
        // console.log('response:', response);
        const graphicHits = response.results?.filter(
          (hitResult) => hitResult.type === "graphic" && hitResult.layer.id.includes("monitorPointLayer")
        );
        if (graphicHits?.length > 0) {
          graphicHits.forEach((graphicHit) => {
            console.log(graphicHit.graphic.attributes);
            const attributes = graphicHit.graphic.attributes;
            typhoonInfo.value = attributes;
            // 弹窗显示生态资源监测点信息
            view.openPopup({
              title: '',
              location: mapPoint,
              content: typhoonPopup.value
            });
          });
        }
      });
    });
    // 加载GLB模型
    loadGlbModel(graphicsLayer3D);
  });
}
// 添加点图标到地图
const addPointGraphic = (mapPoint, pointSymbol) => {
  // 清除之前的点图标
  // pointGraphicsLayer.removeAll();
  // 移除所有id为特定值的图形
  const graphicsToRemove = pointGraphicsLayer.graphics.filter(g => g.attributes && g.attributes.id === addPointType.value);
  pointGraphicsLayer.removeMany(graphicsToRemove);
  // 创建点图形
  const pointGraphic = new Graphic({
    geometry: mapPoint,
    symbol: pointSymbol,
    attributes: {
      id: addPointType.value
    }
  });
  // 将点图形添加到图层
  pointGraphicsLayer.add(pointGraphic);
  // console.log("添加了新的点图标,坐标:", mapPoint.longitude, mapPoint.latitude);
};
// 路线规划
const fireRoute = async () => {
  if (validatenull(startPoint.value)) {
    ElMessage.warning('请选择起点');
    return;
  }
  if (validatenull(endPoint.value)) {
    ElMessage.warning('请选择终点');
    return;
  }
  // 坐标转换
  const url = `${coordinateConvertURL}&locations=${startPoint.value}|${endPoint.value}`;
  const response = await axios.get(url);
  console.log('response:', response);
  const data = response.data;
  if (data.status === '0') {
    ElMessage.error('坐标转换失败');
    return;
  }
  const locations = data.locations;
  // 路线规划
  const drUrl = `${drivingURL}&origin=${locations.split(';')[0]}&destination=${locations.split(';')[1]}`;
  const drResponse = await axios.get(drUrl);
  console.log('drResponse:', drResponse);
  const resultdata = drResponse.data;
  if (resultdata.status === '0') {
    ElMessage.error('路线规划失败');
    instructionList.value = [];
    drtip.value = '搜索不到路径规划相关信息';
    return;
  }
  analyzeResponseA(resultdata);
}
const parseCoordinates = (data) =>
  data.split(';').map(point => point.split(',').map(Number));
const analyzeResponseA = (data) => {
  const steps = data.route.paths[0].steps;
  totalDistance.value = data.route.paths[0].distance;
  totalTime.value = data.route.paths[0].duration;
  let allPath = [];
  instructionList.value = [];
  for (let i = 0; i < steps.length; i++) {
    const path = steps[i].polyline;
    const coordinates = parseCoordinates(path);
    const wgs84coordinates = convertGCJ02ToWGS84(coordinates);
    console.log('coordinates:',wgs84coordinates);
    // allPath = [...coordinates];
    allPath.push(wgs84coordinates);
    console.log('allPath:',allPath);
    instructionList.value.push(
      {
        instruction: steps[i].instruction
      }
    );
  }
  pathLineGraphicsLayer.removeAll();
  const polyline = {
    type: "polyline",
    paths: allPath
  };
  const polylineGraphic = new Graphic({
    geometry: polyline,
    symbol: pathLineSymbol
  });
  pathLineGraphicsLayer.add(polylineGraphic);
}

网站公告

今日签到

点亮在社区的每一天
去签到