Vue-CLI and Leaflet (3): 添加 marker, polyline, polygon

1、功能分析

​ WebGIS 中添加標記或者圖形是很常見的功能,如查詢結果的圖文聯動,定位標記點,點圖查詢等都以此功能展開。而添加graphics是一切圖形顯示,繪製,編輯等功能的基礎。javascript

2、代碼實現

1)添加 marker

​ Leaflet 中 marker 對象構造較爲簡單,可在官網提供的 API 文檔中能夠看到的主要構造參數:css

marker

​ 其中最主要的較爲中中的參數爲 icon 是顯示結果的關鍵參數,iconUrlhtml

icon

icon支持的圖片格式,支持經常使用的 .jpg .png .gifvue

在個人項目中須要在 map.js 分別添加 icon 和 maker 的兩個構方法:java

// src/utils/map.js

const createIcon = options => {
  return $L.icon(options);
};

/**
 * 經過 [x, y] 座標添加 Maker
 *
 * @param {Object} map
 * @param {Object} latLng
 * @param {Object} options
 * 
 */
const createMakerByXY = (map, coordinate, options = {}) => {
  let marker = $L.marker($L.latLng(coordinate[1], coordinate[0s]), options);
  marker.addTo(map);
  return marker;
};

複製代碼

而後再咱們的頁面添加使用上述方法的功能,這裏我添加一個新的組件,放置示例功能入口。git

// src/componets/MapTools.vue

<template>
  <div class="map-tools">
    <ul>
      <li @click="$emit('marker')">Maker</li>
      <li @click="$emit('polyline')">Polyline</li>
      <li @click="$emit('polygon')">Polygon</li>
    </ul>
  </div>
</template>

<script>
export default {
  name: "mapNavigation"
};
</script>
<style lang="less">
.map-tools {
  position: absolute;
  right: 15px;
  top: 15px;
  z-index: 999;

  height: 36px;
  box-shadow: 0px 0px 50px 2px rgba(0, 0, 0, 0.35);
  background-color: #fff;
  ul {
    display: flex;
    padding: 0;
    margin: 0;
    list-style: none;

    li {
      padding: 0 15px;
      height: 36px;
      font-size: 13px;
      line-height: 36px;
      cursor: pointer;
    }

    li:hover {
      background-color: rgb(212, 224, 246);
    }
  }
}
</style>

複製代碼
// src/views/Map.vue

<template>
  <div class="map-container">
    <div id="map-container"></div>
    <NavigationCtrl @zoomIn="zoomIn" @zoomOut="zoomOut" @resetMap="resetMap"></NavigationCtrl>

    <MapTools @marker="addMarker" @polyline="addPolyline" @polygon="addPolygon"></MapTools>
  </div>
</template>

<script>
// @ is an alias to /src
import NavigationCtrl from "@/components/NavigationCtrl.vue";
import MapTools from "@/components/MapTools.vue";

export default {
  name: "mapView",
  components: { NavigationCtrl, MapTools },
  data() {
    return {
      map: null,
      OSMUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
    };
  },
  mounted() {
    this.map = this.$utils.map.createMap("map-container", {
      zoomControl: false
    });
    this.$utils.map.createTileLayer(this.map, this.OSMUrl, {});
    this.map.setView([51.505, -0.09], 13);
  },
  methods: {
    zoomIn() {
      this.map.zoomIn();
    },
    zoomOut() {
      this.map.zoomOut();
    },
    resetMap() {
      this.map.flyTo([51.505, -0.09], 13);
    },
    addMarker() {
      this.$utils.map.createMakerByXY(this.map, [51.505, -0.09]);
    },
    addPolyline() {},
    addPolygon() {}
  }
};
</script>
<style lang="less">
.map-container {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
}
#map-container {
  width: 100%;
  height: 100%;
}
</style>

複製代碼

UI

這裏添加 marker 方法默認是能夠不傳入任何參數,Leaflet 會加載其默認的 marker 樣式。可是若是咱們若是直接調用剛剛寫的 添加 marker 的方法,看不到地圖視圖中有Marker顯示,在控制檯中會出現某一個路徑錯誤。實際上是Leaflet 默認的 icon 的圖片路徑不對。卻是 Leaflet 加載默認marker失敗github

error

解決方法以下,添加到 src/utils/map.js數組

// src/utils/map.js

import "leaflet/dist/leaflet.css";
import $L from "leaflet";

// 解決 leaflet 默認 maker 沒法顯示的問題
import icon from "leaflet/dist/images/marker-icon.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";
let DefaultIcon = $L.icon({
  iconUrl: icon,
  shadowUrl: iconShadow
});
$L.Marker.prototype.options.icon = DefaultIcon;

......

複製代碼

解決後效果bash

addMarker

自定義 maker 樣式,則先建立不一樣的icon,修改一下 Map.vue 中添加addMarker方法less

// src/views/Map.vue

......

addMaker() {
      this.$utils.map.createMakerByXY(this.map, [-0.09, 51.505]);

      let gifIcon = this.$utils.map.createIcon({
        iconUrl: require("./../assets/images/sample.gif"),
        iconSize: [32, 32]
      });
      this.$utils.map.createMakerByXY(this.map, [-0.095, 51.505], {
        icon: gifIcon
      });

      let pnOrJpgIcon = this.$utils.map.createIcon({
        iconUrl: require("./../assets/images/tree.png"),
        iconSize: [52, 42]
      });
      this.$utils.map.createMakerByXY(this.map, [-0.09, 51.490], {
        icon: pngJpgIcon
      });
    }
    
......

複製代碼

addMarker

事實上咱們在地圖功能上常常說到的添加點、線、面。若是你使用過 ArcGIS API for Javascript ,裏面 Graphic 類包括了點,線,面三個要素,有專門負責負責渲染的樣式類。而 leaflet 中點要素對應是 Marker

2)添加 Polyline

​ Leaflet 中構造線要素,面要素中關鍵的是弄清楚的其構造參數中的第一個參數。第一個參數,決定了要素的形狀位置,是一個座標數組。這個座標數組是也能夠包含多個要素組成複合多線要素或是複合多邊形。

MultiPolyline shape SinglePolyline shape
[
[[45.51, -122.68],
[37.77, -122.43],
[34.04, -118.2]],
[[40.78, -73.91],
[41.83, -87.62],
[32.76, -96.72]]
]
[
[45.51, -122.68],
[37.77, -122.43],
[34.04, -118.2]
]

負責樣式的參數都在放在第二個參數 options 中。詳細參數 如 線條顏色,寬度,透明度等 請參考官網

map.js 中添加建立線要素的方法

// src/utils/map.js

/**
 * 建立線要素
 *
 * @param {Object} map
 * @param {Array} linePath
 * @param {Object} lineOpts
 */

const createPolyline = (map, linePath, lineOpts) => {
  let polyline = $L.polyline(linePath, lineOpts);
  polyline.addTo(map);
  return polyline;
};

複製代碼

我這裏在 map.vue 在添加 data 存放建立線的座標數組

// src/views/map.vue
data() {
    return {
      singleLine: [
        [51.517288954651875, -0.16685485839843753],
        [51.51194758264939, -0.1474571228027344],
        [51.51878442657495, -0.13320922851562503],
        [51.530426064343594, -0.1419639587402344],
        [51.53640593191922, -0.11209487915039064]
      ],
      miltipleLine: [
        [
          [51.49282033577651, -0.11432647705078126],
          [51.48010001366223, -0.10265350341796876],
          [51.48084836613703, -0.08222579956054689],
          [51.49591970845512, -0.08239746093750001]
        ],
        [
          [51.47614423230301, -0.08909225463867188],
          [51.47571655971428, -0.05973815917968751],
          [51.4829864484029, -0.03398895263671876],
          [51.49025517833079, -0.008239746093750002],
          [51.477641054786694, 0.008583068847656252],
          [51.487796767005534, 0.021800994873046875]
        ]
      ]
    };
  }
複製代碼

我這裏在 map.vuemethod 存放建立線要素的方法

// src/views/map.vue

......

methods: {
 addPolyline() {
      let singleLineStyle = {
        stroke: true,
        color: "#de0000",
        weight: 3,
        opacity: 1
      };

      this.$utils.map.createPolyline(
        this.map,
        this.singleLine,
        singleLineStyle
      );

      let multipleLineStyle = {
        stroke: true,
        color: "#0085fb",
        weight: 4,
        opacity: 1
      };
      this.$utils.map.createPolyline(
        this.map,
        this.miltipleLine,
        multipleLineStyle
      );
    }
  }

......

複製代碼

polyline

3)添加 Polygon

Polygon 的建立和Polyline的建立方法幾乎是同樣的,包括座標串的組織方式也基本同樣。

// src/utils/map.js

......

/** * 建立面要素 * * @param {Object} map * @param {Array} areaPath * @param {Object} areaOpts */

const createPolygon = (map, areaPath, areaOpts) => {
  let polygon = $L.polyline(areaPath, areaOpts);
  polygon.addTo(map);
  return polygon;
};

......

複製代碼

這裏貼出文章中的展現的圖形示例:

// src/views/map.vue

data() {
    return {
        singlePolygon: [
            [51.50203767899114, -0.13977527618408206],
            [51.505777518488806, -0.13072013854980472],
            [51.505109712517786, -0.1296043395996094],
            [51.50388092395907, -0.12921810150146487],
            [51.50345351147583, -0.12921810150146487],
            [51.50302609498369, -0.12947559356689456],
            [51.502545246638114, -0.12973308563232425],
            [51.50219796412198, -0.12990474700927737],
            [51.50177053585362, -0.12990474700927737],
            [51.5014232474337, -0.12999057769775393],
            [51.50043479667606, -0.13891696929931643],
            [51.50134310357634, -0.1399040222167969],
            [51.50195753621433, -0.13973236083984378],
            [51.50195753621433, -0.13973236083984378]
          ],
        miltiplePolygon: [
            [
              [51.481703611072156, -0.09407043457031251],
              [51.480313829908056, -0.09080886840820312],
              [51.481703611072156, -0.08531570434570314],
              [51.482131227525315, -0.07415771484375001],
              [51.48394855271953, -0.07415771484375001],
              [51.48426924964768, -0.07638931274414064],
              [51.486941636341456, -0.07604598999023438],
              [51.485552014806856, -0.07947921752929689],
              [51.48426924964768, -0.0830841064453125],
              [51.48320025111633, -0.08754730224609376],
              [51.4826657424533, -0.08943557739257814],
              [51.481489801341986, -0.09441375732421875],
              [51.481489801341986, -0.09441375732421875]
            ],
            [
              [51.49869827721546, -0.05613327026367188],
              [51.498377681772325, -0.05922317504882813],
              [51.49506473014368, -0.05802154541015626],
              [51.49132401147376, -0.05407333374023438],
              [51.49143089340988, -0.05184173583984376],
              [51.492072179764314, -0.05046844482421876],
              [51.49292721420453, -0.04978179931640626],
              [51.49388910878061, -0.04840850830078125],
              [51.49506473014368, -0.05149841308593751],
              [51.49602657961649, -0.05270004272460938],
              [51.49709527744871, -0.05373001098632813],
              [51.498484547170605, -0.05647659301757813],
              [51.49869827721546, -0.05699157714843751],
              [51.49762961696847, -0.06025314331054688],
              [51.49762961696847, -0.06025314331054688]
            ]
          ]
    };
  }

複製代碼

這裏須要提一下,添加線和麪的的方法是直接綁定在工做組件上的。

// src/views/map.vue

<template>
  <div class="map-container">
    <div id="map-container"></div>
    <NavigationCtrl @zoomIn="zoomIn" @zoomOut="zoomOut" @resetMap="resetMap"></NavigationCtrl>
    <MapTools @maker="addMaker" @polyline="addPolyline" @polygon="addPolygon"></MapTools>
  </div>
</template>

複製代碼

三)總結

​ 添加點、線、面功能的簡單功能實現並不複雜,若是是從 ArcGIS API for Javascript 轉過來的,可能開始會不適應。這裏的展現的例子後面會放在gitHub上。若有疏漏或是錯誤請各位多多指教。




目錄

(一) Vue-CLI and Leaflet:起步 - 在 Vue-CLI 中使用 Leaflet

(二) Vue-CLI and Leaflet:地圖基本操做(放大,縮小,平移,定位等)

(三) Vue-CLI and Leaflet: 添加 marker, polyline, polygon

(四) Vue-CLI and Leaflet: 添加 tooltips 和 popup

(五) Vue-CLI and Leaflet: 點 繪製

(六) Vue-CLI and Leaflet: 線 繪製

(七) Vue-CLI and Leaflet: 面 繪 制

(八) Vue-CLI and Leaflet :加載 Esri ArcGIS Map Service

(九) Vue-CLI and Leaflet: 圖層控制基本功能的實現

(十) Vue-CLI and Leaflet: AGS 屬性查詢與點圖查詢

(十一)Vue-CLI and Leaflet: 點聚合 Leaflet.markercluster

源碼請參看 個人GitHub,因爲文章是一邊coding,一邊寫的因此 Github 裏面的源碼可能有點亂,能夠根據功能來找對應的代碼。後面會陸續整理完善。

相關文章
相關標籤/搜索