zoukankan      html  css  js  c++  java
  • Vue+Openlayers实现绘制线段并测量距离显示

    场景

    Vue+Openlayer使用Draw实现交互式绘制线段:

    https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/121287934

    在上面已经实现交互式绘制线段基础上,怎样实现测量距离。

    注:

    博客:
    https://blog.csdn.net/badao_liumang_qizhi
    关注公众号
    霸道的程序猿
    获取编程相关电子书、教程推送与免费下载。

    实现

    1、页面上添加按钮与map

    <template>
      <div>
        <div>
          <el-button type="primary" @click="beginCalDistance">开始测距</el-button>
          <el-button type="primary" @click="cancleCalDistance">取消测距</el-button>
        </div>
        <div id="app">
          <div id="map" class="map"></div>
        </div>
      </div>
    </template>

    2、引入相关依赖

    //导入基本模块
    import "ol/ol.css";
    import Map from "ol/Map";
    import View from "ol/View";
    import { Fill, Style, Stroke } from "ol/style";
    //导入相关模块
    import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
    import { TileWMS, Vector as VectorSource } from "ol/source";
    import { Select, Draw } from "ol/interaction";
    import { getLength } from "ol/sphere";
    import { LineString } from "ol/geom";
    import Overlay from "ol/Overlay";

    3、声明变量

    export default {
      name: "olMapImageWMSDrawLineAndCalDistance",
      data() {
        return {
          map: null, // map地图
          layer: null, //地图图层
          lineLayer: null, //线图层
          draw: null,
          lineSource: null,
          coordinate: [],
          measureTooltipElement: null,
          measureTooltip: null,
          sketch: null,
          geom: null,
        };
      },

    4、在页面初始化之后调用初始化地图的方法

        //初始化地图
        initMap() {
          //地图图层
          this.layer = new TileLayer({
            source: new TileWMS({
              //不能设置为0,否则地图不展示。
              ratio: 1,
              url: "http://localhost:8000/geoserver/nyc/wms",
              params: {
                LAYERS: "nyc:nyc_roads",
                STYLES: "",
                VERSION: "1.1.1",
                tiled: true,
              },
              serverType: "geoserver",
            }),
          });
    
          //线的图层
          this.lineSource = new VectorSource({ wrapX: false });
          this.lineLayer = new VectorLayer({
            source: this.lineSource,
          });
    
          this.map = new Map({
            //地图容器ID
            target: "map",
            //引入地图
            layers: [this.layer, this.lineLayer],
            view: new View({
              //地图中心点
              center: [987777.93778, 213834.81024],
              zoom: 14,
              minZoom: 6, // 地图缩放最小级别
              maxZoom: 19,
            }),
          });
        },

    5、开始测试按钮的点击事件中

        //开始测距
        beginCalDistance() {
          //调用绘图工具并传递类型为线,其他类型有Point,LineString,Polygon,Circle
          this.onAddInteraction("LineString");
          //创建一个新的测距提示
          this.createMeasureTooltip();
        },

    调用绘图功能并传递类型为线以及给地图添加交互onAddInteraction方法

      // 绘图工具
        onAddInteraction(type) {
          let self = this;
          //勾绘矢量图形的类
          this.draw = new Draw({
            //source代表勾绘的要素属于的数据集
            source: self.lineSource,
            //type 表示勾绘的要素包含的 geometry 类型
            type: type,
          });
    
          //绘制开始时触发的事件
          this.draw.on("drawstart", function (evt) {
            self.sketch = evt.feature;
            //提示框的坐标
            var tooltipCoord = evt.coordinate;
            //定义一个事件监听,监听几何要素的change事件
            var listener = self.sketch.getGeometry().on("change", function (evt) {
              //获取绘制的几何对象
              self.geom = evt.target;
              //定义一个输出对象,用于记录长度
              var output;
              //判断交互类型是否为线
              if (self.geom instanceof LineString) {
                //输出多线段的长度
                output = self.formatLength(self.geom);
                //获取多线段的最后一个点的坐标
                tooltipCoord = self.geom.getLastCoordinate();
              }
              //设置测量提示框的内标签为最终输出结果
              self.measureTooltipElement.innerHTML = output;
              self.measureTooltipElement.className =
                "ol-tooltip ol-tooltip-static draw_km";
              //设置测量提示框的位置坐标
              self.measureTooltip.setPosition(tooltipCoord);
            });
          });
    
          //绘制结束时触发的事件
          this.draw.on("drawend", function (e) {
            //输出坐标信息
            const geometry = e.feature.getGeometry();
            let pointArr = geometry.getCoordinates();
            self.coordinate.push(pointArr);
            console.log("self.coordinate=" + self.coordinate);
            //移除交互
            self.removeDraw();
          });
    
          //添加交互
          self.map.addInteraction(this.draw);
        },

    创建测距提示的方法createMeasureTooltip

        //创建一个新的测距提示
        createMeasureTooltip() {
          let self = this;
          //如果已经存在帮助提示框则移除
          if (self.measureTooltipElement) {
            self.measureTooltipElement.parentNode.removeChild(
              self.measureTooltipElement
            );
          }
          //创建帮助提示要素的div
          self.measureTooltipElement = document.createElement("div");
          //设置帮助提示要素的样式
          self.measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
          //创建一个帮助提示的覆盖标注
          self.measureTooltip = new Overlay({
            element: self.measureTooltipElement,
            offset: [0, -15],
            positioning: "bottom-center",
          });
          //将帮助提示的覆盖标注添加到地图中
          self.map.addOverlay(self.measureTooltip);
        },

    其中又用到测量距离的方法formatLength

        // 测量距离
        formatLength(line) {
          //计算平面距离
          var length = getLength(line);
          //定义输出变量
          var output;
          //如果长度大于1000,则使用km单位,否则使用m单位
          if (length > 1000) {
            output = Math.round((length / 1000) * 100) / 100 + " " + "km";
          } else {
            output = Math.round(length * 100) / 100 + " " + "m";
          }
          return output;
        },

    6、取消测距方法的点击事件

        // 取消测距
        cancleCalDistance() {
          let self = this;
          this.map.removeInteraction(this.draw);
          this.lineSource.clear();
          let layerArr = this.map.getOverlays();
          var deleteOverlayArr = [];
          layerArr.forEach((item) => {
            if (
              item.values_.element.className ===
              "ol-tooltip ol-tooltip-static draw_km"
            ) {
              deleteOverlayArr.push(item);
            }
          });
          deleteOverlayArr.forEach((item) => {
            self.map.removeOverlay(item);
          });
        },

    7、完整示例代码

    <template>
      <div>
        <div>
          <el-button type="primary" @click="beginCalDistance">开始测距</el-button>
          <el-button type="primary" @click="cancleCalDistance">取消测距</el-button>
        </div>
        <div id="app">
          <div id="map" class="map"></div>
        </div>
      </div>
    </template>
    
    <script>
    //导入基本模块
    import "ol/ol.css";
    import Map from "ol/Map";
    import View from "ol/View";
    import { Fill, Style, Stroke } from "ol/style";
    //导入相关模块
    import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer";
    import { TileWMS, Vector as VectorSource } from "ol/source";
    import { Select, Draw } from "ol/interaction";
    import { getLength } from "ol/sphere";
    import { LineString } from "ol/geom";
    import Overlay from "ol/Overlay";
    
    export default {
      name: "olMapImageWMSDrawLineAndCalDistance",
      data() {
        return {
          map: null, // map地图
          layer: null, //地图图层
          lineLayer: null, //线图层
          draw: null,
          lineSource: null,
          coordinate: [],
          measureTooltipElement: null,
          measureTooltip: null,
          sketch: null,
          geom: null,
        };
      },
      mounted() {
        this.initMap();
      },
      methods: {
    
        //开始测距
        beginCalDistance() {
          //调用绘图工具并传递类型为线,其他类型有Point,LineString,Polygon,Circle
          this.onAddInteraction("LineString");
          //创建一个新的测距提示
          this.createMeasureTooltip();
        },
    
        // 取消测距
        cancleCalDistance() {
          let self = this;
          this.map.removeInteraction(this.draw);
          this.lineSource.clear();
          let layerArr = this.map.getOverlays();
          var deleteOverlayArr = [];
          layerArr.forEach((item) => {
            if (
              item.values_.element.className ===
              "ol-tooltip ol-tooltip-static draw_km"
            ) {
              deleteOverlayArr.push(item);
            }
          });
          deleteOverlayArr.forEach((item) => {
            self.map.removeOverlay(item);
          });
        },
        // 绘图工具
        onAddInteraction(type) {
          let self = this;
          //勾绘矢量图形的类
          this.draw = new Draw({
            //source代表勾绘的要素属于的数据集
            source: self.lineSource,
            //type 表示勾绘的要素包含的 geometry 类型
            type: type,
          });
    
          //绘制开始时触发的事件
          this.draw.on("drawstart", function (evt) {
            self.sketch = evt.feature;
            //提示框的坐标
            var tooltipCoord = evt.coordinate;
            //定义一个事件监听,监听几何要素的change事件
            var listener = self.sketch.getGeometry().on("change", function (evt) {
              //获取绘制的几何对象
              self.geom = evt.target;
              //定义一个输出对象,用于记录长度
              var output;
              //判断交互类型是否为线
              if (self.geom instanceof LineString) {
                //输出多线段的长度
                output = self.formatLength(self.geom);
                //获取多线段的最后一个点的坐标
                tooltipCoord = self.geom.getLastCoordinate();
              }
              //设置测量提示框的内标签为最终输出结果
              self.measureTooltipElement.innerHTML = output;
              self.measureTooltipElement.className =
                "ol-tooltip ol-tooltip-static draw_km";
              //设置测量提示框的位置坐标
              self.measureTooltip.setPosition(tooltipCoord);
            });
          });
    
          //绘制结束时触发的事件
          this.draw.on("drawend", function (e) {
            //输出坐标信息
            const geometry = e.feature.getGeometry();
            let pointArr = geometry.getCoordinates();
            self.coordinate.push(pointArr);
            console.log("self.coordinate=" + self.coordinate);
            //移除交互
            self.removeDraw();
          });
    
          //添加交互
          self.map.addInteraction(this.draw);
        },
    
        //删除交互
        removeDraw() {
          this.map.removeInteraction(this.draw);
        },
    
        //创建一个新的测距提示
        createMeasureTooltip() {
          let self = this;
          //如果已经存在帮助提示框则移除
          if (self.measureTooltipElement) {
            self.measureTooltipElement.parentNode.removeChild(
              self.measureTooltipElement
            );
          }
          //创建帮助提示要素的div
          self.measureTooltipElement = document.createElement("div");
          //设置帮助提示要素的样式
          self.measureTooltipElement.className = "ol-tooltip ol-tooltip-measure";
          //创建一个帮助提示的覆盖标注
          self.measureTooltip = new Overlay({
            element: self.measureTooltipElement,
            offset: [0, -15],
            positioning: "bottom-center",
          });
          //将帮助提示的覆盖标注添加到地图中
          self.map.addOverlay(self.measureTooltip);
        },
    
        //初始化地图
        initMap() {
          //地图图层
          this.layer = new TileLayer({
            source: new TileWMS({
              //不能设置为0,否则地图不展示。
              ratio: 1,
              url: "http://localhost:8000/geoserver/nyc/wms",
              params: {
                LAYERS: "nyc:nyc_roads",
                STYLES: "",
                VERSION: "1.1.1",
                tiled: true,
              },
              serverType: "geoserver",
            }),
          });
    
          //线的图层
          this.lineSource = new VectorSource({ wrapX: false });
          this.lineLayer = new VectorLayer({
            source: this.lineSource,
          });
    
          this.map = new Map({
            //地图容器ID
            target: "map",
            //引入地图
            layers: [this.layer, this.lineLayer],
            view: new View({
              //地图中心点
              center: [987777.93778, 213834.81024],
              zoom: 14,
              minZoom: 6, // 地图缩放最小级别
              maxZoom: 19,
            }),
          });
        },
       
        // 测量距离
        formatLength(line) {
          //计算平面距离
          var length = getLength(line);
          //定义输出变量
          var output;
          //如果长度大于1000,则使用km单位,否则使用m单位
          if (length > 1000) {
            output = Math.round((length / 1000) * 100) / 100 + " " + "km";
          } else {
            output = Math.round(length * 100) / 100 + " " + "m";
          }
          return output;
        },
      },
    };
    </script>
    
    <style scoped>
    .map {
       100%;
      height: 800px;
    }
    </style>
  • 相关阅读:
    SSM-Spring-02:Spring的DI初步加俩个实例
    python自动华 (五)
    python自动华 (三)
    python自动华 (四)
    python自动华 (二)
    python自动华 (一)
    java 下拉控件 转自 http://www.cnblogs.com/lhb25/p/form-enhanced-with-javascript-three.html
    java 正则《转载》
    jQuery 操作一览表
    JAVA多线程和并发基础面试问答
  • 原文地址:https://www.cnblogs.com/badaoliumangqizhi/p/15748161.html
Copyright © 2011-2022 走看看