vue使用openlayers实现流动线

本文介绍了如何在Vue3项目中结合TypeScript和OpenLayers库,实现动态绘制不同类型(如多边形、线段等)的流动线,并对单点进行标记。展示了从接口获取GeoJSON数据并动态设置样式的过程。

需求:使用vue3+openlayers绘制流动线,效果如下
请添加图片描述
主要代码:语法为vue3+ts+openlayers

<template>
  <div class="MapContainer" ref="mapContainer"></div>
  <!-- 弹窗 -->
  <div ref="pointDom" class="popup-content"></div>
</template>
<script setup lang="ts">
import { onMounted, ref } from "vue";
import "ol/ol.css";
import initMap from "@/utils/map/InitMap";
import { Feature, Map, Overlay } from "ol";
import {
  MultiPolygon,
  Polygon,
  MultiLineString,
  LineString,
  Point,
Geometry,
} from "ol/geom";
import { Style, Fill, Stroke, Circle, Icon } from "ol/style";
import VectorLayer from "ol/layer/Vector";
import { Vector as VectorSource } from "ol/source";
import { featuresJson } from "@/utils/mock/lineMock";

const mapContainer = ref();
let myMap: Map;
let json = featuresJson;
function getGeojson() {
  console.log("aaaaaaa", json);
  const featuresJson = json.data.features;
  const source = new VectorSource();
  // 设置图层
  const routeLayer = new VectorLayer({
    source,
  });
  featuresJson.forEach((g) => {
    let lineData:any = g.geometry;
    let routeFeature: Feature<Geometry>;
    if (lineData.type === "MultiPolygon") {
      routeFeature = new Feature({
        geometry: new MultiPolygon(lineData.coordinates),
      });
      routeFeature.setStyle(
        new Style({
          fill: new Fill({
            color: "rgba(127,255,170)", //填充颜色
          }),
          stroke: new Stroke({
            width: 2, //边界宽度
            color: [35, 160, 72, 1], //边界颜色
          }),
        })
      );
    } else if (lineData.type === "Polygon") {
      routeFeature = new Feature({
        geometry: new Polygon(lineData.coordinates),
      });
      routeFeature.setStyle(
        new Style({
          fill: new Fill({
            color: "rgba(35, 160, 72, 1)", //填充颜色
          }),
          stroke: new Stroke({
            width: 2, //边界宽度
            color: [35, 160, 72, 1], //边界颜色
          }),
        })
      );
    // 多条线段
    } else if (lineData.type === "MultiLineString") {
      // console.log("线====", lineData, lineData.coordinates);
      routeFeature = new Feature({
        geometry: new MultiLineString(lineData.coordinates),
      });
      let offset = 0;
      setInterval(() => {
          offset -= 1;
          routeFeature.setStyle(LineStyleFunction(offset))
      }, 200)
    } else if (lineData.type === "LineString") {
      routeFeature = new Feature({
        geometry: new LineString(lineData.coordinates),
      });
      routeFeature.setStyle(
        new Style({
          fill: new Fill({
            color: "rgba(35, 160, 72, 1)", //填充颜色
          }),
          stroke: new Stroke({
            width: 2, //边界宽度
            color: [35, 160, 72, 1], //边界颜色
          }),
        })
      );
    } else if (lineData.type == "Point") {
      const point = new Point(lineData.coordinates);
      const fill = new Fill({
        color: "green",
      });
      const stroke = new Stroke({
        color: "green",
        width: 25,
      });
      const styles = [
        new Style({
          image: new Circle({
            fill: fill,
            stroke: stroke,
            radius: 5,
          }),
          fill: fill,
          stroke: stroke,
        }),
      ];

      // 创建矢量对象
      routeFeature = new Feature({
        geometry: point,
        // style: styles
      });
      routeFeature.setStyle(
        new Style({
          image: new Icon({
            anchor: [0.5, 0.5],
            crossOrigin: "anonymous",
            src: "https://openlayers.org/en/v4.6.5/examples/data/icon.png",
            scale: 1,
          }),
        })
      );
      // 创建矢量源
    } else {
      console.log("不是");
    }
    source.addFeature(routeFeature);
  });

  // 添加图层
  myMap.addLayer(routeLayer);
  const view = myMap.getView();
  view.setZoom(11);
  view.animate({
    center: [114.0549, 34.7473],
    duration: 1,
  });
}
const LineStyleFunction = (offset: number) => {
  let styles = [
                new Style({
                  fill: new Fill({
                    color: "rgba(35, 160, 72, 1)", //填充颜色
                  }),
                  stroke: new Stroke({
                    width: 2, //边界宽度
                    color: [35, 160, 72, 1], //边界颜色
                  }),
                }),
                tmLineStyle(offset),
              ]
              return styles
}
const tmLineStyle = (offset: number) => {
  return new Style({
    stroke: new Stroke({
      color: "#ffffff",
      width: 2,
      lineDash: [2, 7],
      lineDashOffset: offset,
    }),
    fill: new Fill({
      color: [57, 156, 238, 0.5],
    }),
  });
};
onMounted(() => {
  myMap = new initMap(mapContainer.value).map;
  getGeojson();
});
</script>
<style lang="scss">
.MapContainer {
  width: 100vw;
  height: 100vh;
}

.popup-content {
  background-color: #fff;
  border: 1px solid #000;
  padding: 12px 8px;
  border-radius: 8px;
  position: relative;
}
</style>

注意:featuresJson为接口数据主要格式如下
在这里插入图片描述

在这里插入图片描述

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值