vue+leaflet示例:结合Leaflet-Geoman插件实现绘制以及动态配置样式(附源码下载)

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

示例效果


具体实现思路:利用Leaflet-Geoman插件绘制点线面,然后结合colorPick颜色带器拾取RGB颜色值,前端leaflet地图动态设置点线面不同样式Style。
Leaflet-Geoman插件

  • 核心源码
<template>
  <div id="map"></div>
  <div class="titleContainer center">
    <span>vue+leaflet示例:结合Leaflet-Geoman插件实现绘制以及动态配置样式</span>
  </div>
</template>

<script setup>
import { onMounted } from "vue";
import L from "leaflet";
import "@geoman-io/leaflet-geoman-free";
import "@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css";
let map = null;
let dashArray = [0, 0];
let weight = 3;
onMounted(() => {
  // 待加载的 JS 文件数组
  const files = ["./lib/colorPick.js"];
  loadScripts(files, function () {
    console.log("All scripts loaded");
    initMap();
  });
});
const loadScripts = (files, callback) => {
  if (files.length === 0) {
    callback();
    return;
  }
  const file = files.shift();
  const script = document.createElement("script");
  script.onload = function () {
    loadScripts(files, callback);
  };
  script.src = file;
  document.head.appendChild(script);
};
const initMap = () => {
  //多边形默认样式
  const geoJsonStyle_Polygon = {
    color: "#3388ff",
    weight: 3,
    opacity: 1,
    fillColor: "#3388ff",
    fillOpacity: 0.2,
    //dashArray:[5,5],
    fill: true,
    stroke: true,
  };
  window.colorPick = new DCI.Pick.colorPick(); //创建颜色器的对象 #3387FF
  colorPick.R2 = 51;
  colorPick.G2 = 135;
  colorPick.B2 = 255;
  colorPick.R = 51;
  colorPick.G = 135;
  colorPick.B = 255;

  map = L.map("map");
  L.tileLayer(
    "http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
  ).addTo(map);

  let geojsonLayers = L.featureGroup([]).addTo(map);
  //监听图层鼠标事件
  geojsonLayers.on("click", onClickGeojsonLayers);
  map.setView(L.latLng(37.550339, 104.114129), 4); //设置缩放级别及中心点
  //绘制工具draw
  //GitHub地址:https://github.com/geoman-io/leaflet-geoman
  const customTranslation = {
    tooltips: {
      finishLine: "单击任何存在的标记或者双击以完成",
      finishPoly: "单击第一个标记或者双击完成以完成",
    },
  };
  map.pm.setLang("customName", customTranslation, "zh");
  map.pm.addControls({
    position: "topleft",
    drawMarker: true,
    drawCircleMarker: false,
    drawCircle: true,
    drawPolyline: true,
    drawRectangle: true,
    drawPolygon: true,
    editMode: false,
    dragMode: false,
    cutPolygon: false,
    drawText: false,
    removalMode: true,
  });

  map.on("pm:create", (e) => {
    //console.log(e);
    switch (e.shape) {
      case "Rectangle":
      case "Polygon":
      case "Circle":
      case "Line":
        e.layer.options = { ...geoJsonStyle_Polygon, shape: e.shape };
        break;
    }
    geojsonLayers.addLayer(e.layer);
  });
};
/*
 * 清空绘制图形函数
 */
const clearGeojsonLayers = () => {
  if (geojsonLayers) {
    geojsonLayers.clearLayers();
  }
};
const onClickGeojsonLayers = (e) => {
  console.log("e", e);
  const layer = e.layer;
  const style2 = "solid";
  const mWidth = "3px";
  let html = ``;
  switch (layer.options.shape) {
    case "Rectangle":
    case "Polygon":
    case "Circle":
    case "Line":
      html =
        "<div style='width:225px; color: rgb(51, 51, 51); font-size:12px; word-wrap: break-word; '>" +
        "<div id='infowin' class='pointInfowin'>" +
        "<div id='pointInfoP' style='display: block; '>" +
        "<div class='style_line_polygon'>" +
        "<div class='line_shape'>" +
        "<span>线型</span>" +
        "<div class='line_shape_list'>" +
        "<div id='solid_line_shape'></div>" +
        "<div id='dashed_line_shape'></div>" +
        "</div>" +
        "</div>" +
        "<div class='line_thick'>" +
        "<span>线宽</span>" +
        "<div id='line_thick_list'>" +
        "<div id='thick_line_2'></div>" +
        "<div id='thick_line_3'></div>" +
        "<div id='thick_line_4'></div>" +
        "</div>" +
        "</div>" +
        "<div class='line_color_opacity'>" +
        "<div class='line_color'>" +
        "<span>线型颜色</span>" +
        "<div class='color_line_selector' id='inputcolor'></div>" +
        "<div id='colorpane' style='position:absolute;z-index:999;display:none;'></div>" +
        "</div>" +
        "<div class='line_opacity'>" +
        "<span>透明度</span>" +
        "<input id='lAlphaText' type='text' value='100' maxlength='3' id='borderOpacity' class='opacity_line_selector'>%</div>" +
        "<div class='clear'></div>" +
        "</div>" +
        "<div class='fill_color_opacity'>" +
        "<div class='fill_color'>" +
        "<span>填充颜色</span>" +
        "<div class='color_fill_selector'  id='inputcolor2'></div>" +
        "<div id='colorpane2' style='position:absolute;z-index:999;display:none;'></div>" +
        "</div>" +
        "<div class='fill_opacity'>" +
        "<span>透明度</span>" +
        "<input  id='mMAlphaText' type='text' value='20' maxlength='3' id='fillOpacity' class='opacity_fill_selector'>%</div>" +
        "</div>" +
        "<div class='fill_color_preview'>" +
        "<span>填充效果</span>" +
        "<div class='preview_fill_selector'>" +
        "<div id='fill_preview' style='border-top-color: rgb(" +
        colorPick.R2 +
        "," +
        colorPick.G2 +
        "," +
        colorPick.B2 +
        "); '></div>" +
        "</div>" +
        "</div>" +
        "<div class='line_color_preview' id='line_color_preview'>" +
        "<span>边框效果</span>" +
        "<div class='preview_line_selector'>" +
        "<div id='line_preview' style='border-top-style:" +
        style2 +
        "; border-top-width: " +
        mWidth +
        "; border-top-color: rgb(" +
        colorPick.R +
        "," +
        colorPick.G +
        "," +
        colorPick.B +
        "); '></div>" +
        "</div>" +
        "</div>" +
        "<button id='PolygonStyle' type='button'>确定</button>" +
        "</div></div></div></div></div>";
      break;
    default: //Marker
      html = `<div id="markerIMG">
				<img loading="lazy" src="./img/marker-icon.png" alt="" width="25" height="41">
				<img loading="lazy" src="./img/gpsRed.png" alt="" width="32" height="32">
				<img loading="lazy" src="./img/gpsYellow.png" alt="" width="32" height="32">
				<img loading="lazy" src="./img/gpsGreen.png" alt="" width="32" height="32">
		   </div>`;
  }
  const elements = html;
  layer.bindPopup(elements).openPopup(e.latlng);
  //动态修改线和面样式
  ……
</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;
}
</style>

下载源码:GIS之家的学习交流圈

posted @ 2025-03-25 20:55  GIS之家  阅读(35)  评论(0)    收藏  举报