开发一个前后端分离的webgis城市共享单车投放管理系统(6)完结

146 阅读2分钟

文章同步更新于我的个人博客:松果猿的博客,欢迎访问获取更多技术分享。

同时,您也可以关注我的微信公众号:松果猿的代码工坊,获取最新文章推送和编程技巧。

前言

这应该算是这个项目的完结篇了,其实这个项目特别蠢,我应该有一个明确的规划,但都是走一步看一步,踩了许多坑,毕竟我也是初学者,比如说不知道Mybatis无法处理Geometry数据格式,前后端wkt、wkb、geojson格式互转瞎搞一通,然后tmd搞到后面我都不知道是什么了,代码胡乱改一通。

本人的这次改动有点多,如果真的有人跟着我这个项目来系统学习的话(大概率没人看),那你真的是太nb了哈哈哈哈,直接去我的github仓库下载源码来学习吧。

演示视频放在B站了:webgis课程作业:Vue3+Springboot共享单车系统

前端

添加@/hooks/useBikeGeom.js

import { ref } from "vue";
import { Point } from "ol/geom";
import axios from "axios";
import { useMapStore } from "@/stores/mapStore.js";
import bikeIcon from "@/assets/img/bike.png";
import { Vector as VectorLayer } from "ol/layer";
import { Vector as VectorSource } from "ol/source";
import { Feature } from "ol";
import { Icon, Style } from "ol/style";
import { Heatmap as HeatmapLayer } from "ol/layer";
import { fromLonLat } from "ol/proj";

export function useBikeGeom() {
  const bikeGeom = ref([]);

  const bikeGeomLayer = ref(null);
  const mapStore = useMapStore();
  const map = mapStore.map;
  const bikeGeomSource = ref(null);
  const bikeGeomFeature = ref([]);

  const fetchBikeGeom = async () => {
    try {
      const res = await axios.get(`${import.meta.env.VITE_API_URL}/bikes`);
      console.log("API返回数据:", res.data.data);

      bikeGeom.value = res.data.data.map((item) => {
        // 将字符串解析为 JSON 对象
        const locationObj = JSON.parse(item.location);
        const coordinates = locationObj.coordinates;
        const transformedCoords = fromLonLat(coordinates);
        return new Point(transformedCoords);
      });

      console.log("转换后的坐标点:", bikeGeom.value);
    } catch (error) {
      console.error("获取单车数据失败:", error);
      throw error;
    }
  };

  const loadBikeGeom = async () => {
    await fetchBikeGeom();
    console.log(bikeGeom.value);
    bikeGeomFeature.value = bikeGeom.value.map((item) => {
      return new Feature({
        geometry: item,
      });
    });

    bikeGeomSource.value = new VectorSource({
      features: bikeGeomFeature.value,
    });

    bikeGeomLayer.value = new VectorLayer({
      source: bikeGeomSource.value,
      style: new Style({
        image: new Icon({
          src: bikeIcon,
          scale: 0.05,
        }),
      }),
    });
  };

  const addBikeGeomLayer = async () => {
    await loadBikeGeom();
    mapStore.map.addLayer(bikeGeomLayer.value);
  };

  const toggleBikeHeatMap = async () => {
      await loadBikeGeom();
      if (bikeGeomLayer.value) {
        mapStore.map.removeLayer(bikeGeomLayer.value);
      }
      bikeGeomLayer.value = new HeatmapLayer({
        source: bikeGeomSource.value,
        blur: 10,
        radius: 20,
      });
      mapStore.map.addLayer(bikeGeomLayer.value);
  };

  return {
    toggleBikeHeatMap,
    addBikeGeomLayer,
  };
}

Header.vue中添加点击事件:

后端

后端魔改的比较多,就不赘述了

效果:

项目地址:github.com/songguo1/Sh…