I. Functional analysis

The measurement function of map is a common function in geographic information system. It mainly measures the distance, area, or length of line elements, perimeter and area of surface elements on the map.

This article will introduce the first leaflet-measurement-path plug-in based on leaflet.js to realize map measurement. The reason for using this plug-in is that it is simple and easy to use. If you have read the previous articles or mastered the graphic loading and drawing in leaflet, this plug-in can quickly realize the map measurement function.

1) Leaflet-measure – PATH plug-in

The introduction of the plug-in is as follows. The details are leaflet-measure-path and the official example.

A plugin to show measurements on paths (polylines, polygons and circles currently supported).

A plugin to realistically measure results on a path (currently supports lines, planes and circles).

The measurement method realized by this plug-in is to expand the measurement data acquisition and display of polyline, Polygon and Circle graph classes in Leaflet. js. One is simple and easy to use, but the disadvantage is that the length information labeling of online elements sometimes appears unreasonable.

2) Measurement function analysis

Based on my understanding of this function, I divide the common measurement functions into the following measurements.

(1) Known graph measurement

Lines, surfaces and other elements already exist on the map, and its length and area need to be obtained. The effect of this function is to load the graph directly onto the map and display the measurement information of the graph. As in the official example:

(2) Dynamic measurement

Dynamic measurement is actually the measurement function we often see, here is mainly for the above measurement method to make a difference. Display measurement information in real time during user drawing. This function needs to be based on the drawing function, refer to the previous article: VUE-CLI and Leaflet (6) : Line drawing, Vue CLI and Leaflet (7) surface drawing

Two, code implementation

Before implementing the functions, you must be familiar with the usage of leaflet-measure- PATH plug-in. Also all the code was added based on the directory structure built in the first article, see vue-CLI and Leaflet (1) : Show a map

1) Introduction of plug-ins

The introduction of leaflet-measure-path plug-in is very simple. Beginners may encounter problems in referencing the plug-in in vuE-CLI. Here’s how it’s introduced.

// src\utils\map.js
import $L from "leaflet";
import "leaflet/dist/leaflet.css";

/ / note:
// Be sure to reference this plug-in after the successful introduction of leaflet.js
import "leaflet-measure-path";
import "leaflet-measure-path/leaflet-measure-path.css";

Copy the code

2) Known graph measurement

Firstly, the simple measurement information display of known graph is introduced. After the successful introduction of the plug-in, polyline, polygon and circle elements in leaflet.js have been supported by the leaflet-measure-path plug-in. The way to display graphic measurement information is to turn on the properties of measurement information display when creating elements.

I created a new measurestatic. vue on the project’s views directory line.

// src\views\MeasureStatic.vue

<template>
  <div class="map-container">
    <div id="map-container"></div>
  </div>
</template>

<script>
export default {
  name: "map-point".data() {
    return {
      map: null,
      OSMUrl: "http://tile.osm.org/{z}/{x}/{y}.png", overLayer: { polylines: [], polygons: [], measurements: [] }, existLine: [[51.49404942257001, -0.14136314392089847], [51.48640717153227, -0.12797355651855472], [51.48640717153227, 0.12797355651855472], [51.48464339321334, -0.10376930236816408], 51.486353724706795, -0.09801864624023438], [51.486353724706795, -0.09801864624023438], [51.486353724706795, 0.09801864624023438]], existLinePolygon: [[51.497175428776025, -0.11269569396972658], [51.48825104864774, -0.1149272918701172], [51.48825104864774, 51.48723558931616, -0.09758949279785158], [51.48723558931616, -0.09758949279785158], 51.49450364191158, -0.09282588958740236], 51.49450364191158, -0.09282588958740236], [51.499980636437265, [51.499980636437265, -0.10437011718750001], [51.499980636437265, -0.10437011718750001]]}; },mounted() {
    this.map = this.$utils.map.createMap("map-container"); This. Map. SetView ([51.505, 0.09], 14); this.$utils.map.createTileLayer(this.map, this.OSMUrl, {});
    let existLineOpts = {
      color: "rgba(255, 58, 0, 1)"Function: 0, function: 0, function: 0, function: 0, function: 0true// measurementOptions: {minDistance: 30 // Display minimum line length of 30m(default), less than this length is not displayed}}; this.$utils.map.createPolyline(this.map, this.existLine, existLineOpts);

    let existPolygonOpts = {
      color: "Rgba (0, 58, 255, 0.85)"// Whether the measurement information is displayed after opacity:true, // Measure information attributes: measurementOptions: {showOnHover:true// Start displaying measurement information when mouse moves over graph}}; this.$utils.map.createPolygon( this.map, this.existLinePolygon, existPolygonOpts ); }}; </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

In addition, the plug-in provides formatDistance, which uses annotation styles from defining measurement results.

3) Dynamic measurement

The key of dynamic measurement is graph rendering. The following implementation is based on the previous drawing function. If you are not familiar with the implementation of the drawing function, go to vuE-CLI and Leaflet (6) : Line drawing, Vue CLI and Leaflet (7) plane drawing

ShowMeasurements: true, measurementOptions: {… measurementOptions: {… measurementOptions: {… measurementOptions: {… } properties. To make the article too long, distance measurement is used as a code example below. See github for the full measurement function:

Added the measurement switch component.

// src\components\MapMeasureDistance.vue
<template>
  <div class="map-tool-measure">
    <ul>
      <li @click="$emit('polyline')"</li> < li@click ="$emit('showMeasurements')"</li> < li@click ="$emit('hideMeasurements')"</li> </ul> </div> </template> <script>export default {
  name: "map-measure-dsitance"
};
</script>
<style lang="less"> .map-tool-measure { 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

Added the distance measurement component

// src\views\MeasureDistance.vue

<template>
  <div class="map-container">
    <div id="map-container"></div>
    <MapMeasureDistance
      @polyline="measurePolyline"
      @showMeasurements="showMeasurements"
      @hideMeasurements="hideMeasurements"
    ></MapMeasureDistance>
  </div>
</template>

<script>
import MapMeasureDistance from "@/components/MapMeasureDistance.vue";

export default {
  name: "map-point",
  components: { MapMeasureDistance },
  data() {
    return {
      map: null,
      OSMUrl: "http://tile.osm.org/{z}/{x}/{y}.png",
      overLayer: {
        polylines: [],
        polygons: [],
        measurements: []
      },
      tempGp: {
        lineNode: [],
        lineNodeLen: 0,
        tempLine: null,
        tempNode: []
      }
    };
  },
  mounted() {
    this.map = this.$utils.map.createMap("map-container"); This. Map. SetView ([51.505, 0.09], 14); this.$utils.map.createTileLayer(this.map, this.OSMUrl, {});
  },
  methods: {
    drawOn() { this.clearTemps(); this.map.doubleClickZoom.disable(); // Remove the listener map event this.map.off("click");
      this.map.off("mousemove");
      this.map.off("dblclick");
    },
    drawOff() {// Remove the listener map click event this.map.off("click");
      this.map.off("mousemove");
      this.map.off("dblclick"); this.map.doubleClickZoom.enable(); // Undo the mouse pan style this.$utils.map.removerCoursorStyle(this.map);
    },
    clearTemps() {this.tempgp.linenode = []; this.tempGp.lineNodeLen = 0;if (this.tempGp.tempLine) this.tempGp.tempLine.remove();
      this.tempGp.tempNode.map(el => el.remove());
    },
    measurePolyline() {
      this.$utils.map.addCursorStyle(this.map, "crosshare-cursor");
      this.drawOn();

      let tempPolygonOpts = {
        color: "Rgba (255, 0, 0, 0.85)"// Add opacity information and turn on showMeasurements:true// Set measurementOptions as required: {minDistance: 500}};let finalPolygonOpts = {
        color: "Rgba (0, 255, 0, 0.85)"// Add opacity information attribute and turn on showMeasurements:true// Set measurementOptions as required: {minDistance: 500}}; this.map.on("click", evt => {
        this.tempGp.lineNode.push([evt.latlng.lat, evt.latlng.lng]);
        this.tempGp.tempNode.push(this.addNode(evt.latlng, this.map));
        this.tempGp.lineNodeLen = this.tempGp.lineNode.length;
      });

      this.map.on("mousemove", evt => {
        if (this.tempGp.lineNodeLen >= 1) {
          if (this.tempGp.tempLine) this.tempGp.tempLine.remove();
          this.tempGp.lineNode[this.tempGp.lineNodeLen] = [
            evt.latlng.lat,
            evt.latlng.lng
          ];

          this.tempGp.tempLine = this.$utils.map.createPolyline( this.map, this.tempGp.lineNode, tempPolygonOpts ); }}); this.map.on("dblclick", () = > {let polyline = this.$utils.map.createPolyline(
          this.map,
          this.tempGp.lineNode,
          finalPolygonOpts
        );
        this.overLayer.polylines.push(polyline);
        this.clearTemps();
      });
    },
    addNode(latlng, map) {
      let node = this.$utils.map.createIcon({
        iconUrl: require(". /.. /assets/images/node.png"),
        iconSize: [10, 10]
      });
      node = this.$utils.map.createMakerByLatlng(latlng, {
        icon: node
      });
      node.addTo(map);
      return node;
    },
    showMeasurements() {
      this.overLayer.polylines.map(el => el.showMeasurements());
    },
    hideMeasurements() { this.overLayer.polylines.map(el => el.hideMeasurements()); }}}; </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

In this way the dynamic measurement function is realized.

4) Control the display and hiding of measurement information

Leaflet – measure – path plugin provides showMeasurements, hideMeasurements method, which can realize measurement information display control. Use method:


// feature is a line, surface or circle graphic element that has been loaded in the map
MeasurementOptions is the measurementDisplay attribute used above
feature.showMeasurements(measurementOptions)
feature.hideMeasurements()

Copy the code

Examples are provided in dynamic measurement above, and the results are as follows:

Third, summary

The above is the introduction of measurement function. The leaflet-measure- Path plug-in is the most simple and easy to use graphicmeasurement plug-in based on leaflet.js in my opinion. The article example is relatively simple, mainly because there are no specific business requirements. However, I believe that I can achieve very rich and efficient functions by mastering the usage method of this measurement plug-in combined with the actual business requirements.

If there are any mistakes or omissions, please kindly advise.

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.