動態

詳情 返回 返回

vue+leaflet示例:結合turf.js實現圖斑分割(附源碼下載) - 動態 詳情

demo源碼運行環境以及配置

  • 運行環境:依賴Node安裝環境,demo本地Node版本:14.19.1。
  • 運行工具:vscode或者其他工具。
  • 配置方式:下載demo源碼,vscode打開,然後順序執行以下命令:
    (1)下載demo環境依賴包命令:npm i
    (2)啓動demo命令:npm run dev
    (3)打包demo命令: npm run build:release

示例效果

本篇實現的思路:turf.js中提供了一中多邊形的裁剪方法是使用多邊形去裁剪多邊形,但是如果實際工作中需要使用到線去裁剪多邊形卻無法滿足。

  • 核心源碼
<template>
  <div id="map"></div>
  <div id="msg">先在地圖上點擊要裁剪的多邊形</div>
  <div id="reset" @click="resetClip">重置</div>
  <div class="titleContainer center">
    <span>vue+leaflet示例:結合turf.js實現圖斑分割</span>
  </div>
</template>

<script setup>
import { onMounted, reactive, ref } from "vue";
import "./clipSpotMap";
import L from "leaflet";
import "./leaflet.draw.css";
import "./leaflet.draw";
// import config from "../config";
import { useRouter } from "vue-router";
const router = useRouter();
let map = null;
let editLayer = null;
let drawView = null;
let polygonLayer = null;
let clipResultLayer = null;
let clipLineLayer = null;
const colorList = ["#00FF66", "#66CCFF", "#6600FF", "#FF9933", "#FF3333"];
onMounted(() => {
  initMap();
});
const initMap = () => {
  // 創建地圖對象
  map = L.map("map", { attributionControl: false }).setView(
    [39.91036, 116.403704],
    10
  );
  const basemap = L.tileLayer(
    "http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
    {
      attribution: "",
    }
  ).addTo(map);
  // 創建標繪圖層
  drawView = new L.geoJSON(null, {}).addTo(map);
  clipResultLayer = new L.geoJSON(null, {}).addTo(map);
  // 創建多邊形圖層及添加測試geojson數據
  polygonLayer = L.geoJSON(null, {
    style: function (feature) {
      return { color: "#fff" };
    },
  }).addTo(map);
  polygonLayer.addData({
    type: "Feature",
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [116.2535, 40.009898],
          [116.25144, 39.971495],
          [116.324225, 39.990436],
          [116.296072, 40.032509],
          [116.2535, 40.009898],
        ],
      ],
    },
  });
  polygonLayer.addData({
    type: "Feature",
    geometry: {
      type: "Polygon",
      coordinates: [
        [
          [116.490393, 39.88435],
          [116.596823, 39.895413],
          [116.626349, 39.784167],
          [116.409369, 39.775197],
          [116.490393, 39.88435],
        ],
        [
          [116.502285, 39.870091],
          [116.516018, 39.800887],
          [116.599789, 39.795744],
          [116.567001, 39.870486],
          [116.502285, 39.870091],
        ],
      ],
    },
  });
  polygonLayer.addData({
    type: "Feature",
    geometry: {
      type: "MultiPolygon",
      coordinates: [
        [
          [
            [116.361303, 39.926488],
            [116.454001, 39.935439],
            [116.437521, 39.874338],
            [116.359243, 39.876973],
            [116.361303, 39.926488],
          ],
        ],
        [
          [
            [116.49353, 40.058103],
            [116.665192, 40.06441],
            [116.677551, 39.930801],
            [116.512756, 39.947648],
            [116.49353, 40.058103],
          ],
        ],
      ],
    },
  });
  // 添加Leaflet.Draw標繪功能
  clipLineLayer = new L.Draw.Polyline(map);
  clipLineLayer.setOptions({
    showLength: false,
    shapeOptions: {
      stroke: true,
      color: "#3388ff",
      weight: 1,
      opacity: 0.7,
      dashArray: "5,5",
    },
  });
  L.drawLocal.draw.handlers.polyline.tooltip = {
    start: "點擊地圖開始裁剪",
    cont: "點擊地圖開始裁剪",
    end: "雙擊地圖或點擊最後一個點完成裁剪",
  };
  //地圖或圖層事件綁定
  polygonLayer.on("click", function (evt) {
    if (drawView) {
      drawView.clearLayers();
    }
    editLayer = evt.layer;
    polygonLayer.setStyle({ color: "#fff" });
    editLayer.setStyle({ color: "#ecf53e" });
    clipLineLayer.enable();
    document.getElementById("msg").innerText = "繪製切割線";
  });
  ……
</script>

<style scoped>
#map {
  width: 100vw;
  height: 100vh;
}
.titleContainer {
  position: absolute;
  top: 0;
  background: rgba(0, 0, 0, 0.45);
  height: 50px;
  width: 100vw;
  z-index: 999;
  font-size: 14px;
  color: #fff;
  font-size: 28px;
}
.center {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
#msg {
  width: 200px;
  padding: 20px;
  background: #ffffff;
  position: absolute;
  bottom: 10px;
  left: 10px;
  font-size: 15px;
  z-index: 9999;
}
#reset {
  width: 100px;
  height: 40px;
  background-color: #3aa2eb;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
  color: #fff;
  position: absolute;
  bottom: 10px;
  left: 300px;
  z-index: 9999;
  -webkit-transition: all 600ms ease;
  -moz-transition: all 600ms ease;
  -ms-transition: all 600ms ease;
  -o-transition: all 600ms ease;
  transition: all 600ms ease;
}
#reset:hover {
  background-color: #1b85cf;
}
#github {
  width: 50px;
  height: 50px;
  text-align: center;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 50%;
  margin-left: -25px;
  border-radius: 0 0 5px 5px;
  z-index: 9999;
  background-color: #fff;
}
.github-icon {
  margin-top: 8px;
}
.leaflet-marker-pane .leaflet-editing-icon {
  margin-left: -6px !important;
  margin-top: -6px !important;
  width: 12px !important;
  height: 12px !important;
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.5);
  border-radius: 50px;
}
</style>

下載源碼:GIS之家的學習交流圈

Add a new 評論

Some HTML is okay.