I. Functional analysis

It is a common function to add markers or graphs in WebGIS, such as graphic linkage of query results, locating marker points and point map query, etc. The addition of graphics is the basis of all graphics display, drawing, editing and other functions.

Two, code implementation

1) Add marker

The construction of marker object in Leaflet is relatively simple, and the main construction parameters can be seen in THE API document provided by the official website:

Among them, the most important intermediate parameter is icon, which is the key parameter to display the results, iconUrl

Icon Supported image formats, including.jpg.png. GIF

In my project, I need to add two construction methods of Icon and Maker respectively in map.js:

// src/utils/map.js

const createIcon = options => {
  return $L.icon(options); }; /** * pass [x, 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;
};

Copy the code

Then add functionality to our page that uses the above method, and here I add a new component to place the sample functionality entry.

// 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>

Copy the code
// 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. The map. CreateMakerByXY (enclosing 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>

Copy the code

By default, the method of adding marker can pass no parameters, and the Leaflet will load its default marker style. However, if we call the add marker method we just wrote, we will not see the marker displayed in the map view, and some path error will appear in the console. In fact, the default picture path of icon in Leaflet is wrong. The Leaflet failed to load the default marker

The solution is as follows: add SRC /utils/map.js

// src/utils/map.js

import "leaflet/dist/leaflet.css";
import $L from "leaflet"; // Fix the problem that default Leaflet maker cannot display 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; .Copy the code

Effect after solution

To customize the Maker style, first create a different icon and modify map. vue to add addMarker method

// src/views/Map.vue

......

addMaker() {
      this.$utils. The map. CreateMakerByXY (enclosing 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}); }...Copy the code

In fact, we talk a lot about adding points, lines, and surfaces to maps. If you have used the ArcGIS API for Javascript, the Graphic class includes points, lines and faces, and the style class is responsible for rendering. The midpoint element of leaflet corresponds to Marker

2) Add Polyline

In Leaflet, the construction line element and surface element is the key to make clear the first parameter in its construction parameters. The first parameter, which determines the shape and position of the element, is a coordinate array. This coordinate array can also contain multiple elements to form composite multiline elements or composite polygons.

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]

]

The style parameters are placed in the second parameter options. For detailed parameters such as line color, width, transparency, please refer to the official website.

Add methods to create line elements in map.js

// SRC /utils/map.js /** * create line element ** @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;
};

Copy the code

Here I am adding data to map.vue to hold the coordinate array for creating the line

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

Here I store the method to create the line element in map.vue’s method

// 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 ); }}...Copy the code

3) Add Polygon

Polygon is created in much the same way as Polyline is created, including the way coordinate strings are organized.

// 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);
  returnpolygon; }; .Copy the code

Here is an example of the graphics shown in the article:

// src/views/map.vue

data() {
    return{ singlePolygon: [51.50203767899114, -0.13977527618408206], [51.505777518488806, -0.13072013854980472], [51.505109712517786, [51.50388092395907, -0.12921810150146487], [51.50345351147583, -0.12921810150146487], 51.50302609498369, -0.12947559356689456], 51.502545246638114, -0.12973308563232425, [51.50219796412198, [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.48426924964768, -0.07638931274414064], [51.486941636341456, -0.07604598999023438], [51.485552014806856, [51.48426924964768, -0.0830841064453125], [51.48320025111633, -0.08754730224609376], [51.4826657424533, -0.089437739257814], [51.481489801341986, -0.09441375732421875], [51.481489801341986, [[51.49869827721546, -0.05613327026367188], [51.498377681772325, -0.05922317504882813], 51.49506473014368, -0.05802154541015626], [51.49132401147376, -0.05407333374023438], [51.49143089340988, [51.492072179764314, -0.05046844482421876], [51.49292721420453, -0.04978179931640626], [51.49388910878061, -0.04840850830078125], [51.49506473014368, -0.05149841308593751], [51.49602657961649, [51.49709527744871, -0.05373001098632813], [51.498484547170605, -0.05647659301757813], [51.49762961696847, -0.06025314331054688], [51.49762961696847, 51.49762961696847, 0.06025314331054688]]]}; }Copy the code

It should be mentioned here that the method of adding lines and faces is tied directly to the working component.

// 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>

Copy the code

3) the summary

The simple functionality of adding dot, line and surface functions is not complicated to implement, and if it is transferred from the ArcGIS API for Javascript, it may be uncomfortable at first. The examples shown here will be posted on gitHub later. If there are omissions or mistakes, please give us more advice.




directory

Vue-cli and Leaflet: Start using the Leaflet in VUe-CLI

(2) VUE-CLI and Leaflet: basic map operations (zoom in, zoom out, translation, positioning, etc.)

Vue-cli and Leaflet: Add marker, polyline, polygon

Vue-cli and Leaflet: Add tooltips and popup

Vue-cli and Leaflet: point drawing

Vue-cli and Leaflet: line drawing

(7) VuE-CLI and Leaflet: surface painting system

Vue-cli and Leaflet: Load Esri ArcGIS Map Service

(9) VUE-CLI and Leaflet: layer control implementation of basic functions

(10) VUE-CLI and Leaflet: AGS attribute query and point map query

Vue-cli and Leaflet: point aggregation leaflet. markerCluster

Please refer to my GitHub for the source code. Since the article is written at the same time as coding, the source code in GitHub may be a little confused, you can find the corresponding code according to the function. Later will be sorted out and improved.