vue+openlayers5学习总结(六)改装成vue的一些功能

博客围绕OpenLayers展开,介绍了测量功能的源代码,阐述清除测量痕迹的方法,需先清除map内部的线,再用source.clear()清除线和面,用map.getOverlays().clear()批量删除div标注,还提及非vue环境下parcel编译的图层控制,包含html和js代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.测量功能

源代码

<template>
  <div>
    <!-- <div id="map" ref="rootmap" class="map"></div> -->
    <div id="fullscreen" class="fullscreen">
      <div id="map" ref="rootmap" class="map"></div>
      <div class="sidepanel">
        <span class="sidepanel-title">Side Panel</span>
      </div>
    </div>
    <form class="form-inline">
      <select v-model="selected">
        <option v-for="option in options" v-bind:value="option.value">{{ option.text }}</option>
      </select>
      <span>Selected: {{ selected }}</span>
    </form>
  </div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import mapconfig from "../config/mapconfig";
import mapfunction from "../methods/mapfunction";
import {
  defaults as defaultControls,
  FullScreen,
  ScaleLine,
  MousePosition,
  ZoomToExtent
} from "ol/control.js";
//import TileLayer from "ol/layer/Tile";
//import TileArcGISRest from "ol/source/TileArcGISRest";
import OSM from "ol/source/OSM";
//用于获取鼠标坐标
import mousePosition from "ol/control/MousePosition.js";
import { createStringXY } from "ol/coordinate.js";

//获取map四个角坐标
import { toLonLat } from "ol/proj.js";
import { getBottomLeft, getTopRight } from "ol/extent.js";
//拖动gpx,geojson,igc,kml,topojson到地图中
import { GPX, GeoJSON, IGC, KML, TopoJSON } from "ol/format.js";
import {
  defaults as defaultInteractions,
  DragAndDrop
} from "ol/interaction.js";
import { Vector as VectorLayer, Tile as TileLayer } from "ol/layer.js";
import { BingMaps, Vector as VectorSource } from "ol/source.js";
//绘画
import { Draw, Modify, Snap } from "ol/interaction.js";
import { Circle as CircleStyle, Fill, Stroke, Style } from "ol/style.js";
//测量
import { unByKey } from "ol/Observable.js";
import Overlay from "ol/Overlay.js";
import { getArea, getLength } from "ol/sphere.js";
import { LineString, Polygon } from "ol/geom.js";
export default {
  data() {
    return {
      view: null,
      map: null,
      dragAndDropInteraction: null,
      chengdu: [11584612, 3588584],
      draw: null,
      // snap: null,
      mysource: null,
      selected: "请选择",
      options: [
        { text: "length", value: "length" },
        { text: "area", value: "area" },
        { text: "None", value: "None" }
      ],
      sketch: null,
      measureTooltipElement: null,
      measureTooltip: null
    };
  },
  mounted() {
    //selected= { text: 'Point', value: 'Point'  };
    let self = this;

    //console.log("chengdu" + this.chengdu);
    var mapcontainer = this.$refs.rootmap;
    var mapxyposition = this.$refs.xyposition;
    //拖动gpx,geojson,igc,kml,topojson到地图中
    var raster = new TileLayer({
      source: new OSM()
    });
    var source = new VectorSource();
    var vector = new VectorLayer({
      source: source,
      style: new Style({
        fill: new Fill({
          color: "rgba(255, 255, 255, 0.2)"
        }),
        stroke: new Stroke({
          color: "#ffcc33",
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: "#ffcc33"
          })
        })
      })
    });

    //初始化地图
    let myview = new View({
      center: [-11000000, 4600000],
      zoom: 15
    });
    this.view = myview;
    //绘图
    self.mysource = new VectorSource({ wrapX: false });
    var vector = new VectorLayer({
      source: self.mysource,
      style: new Style({
        fill: new Fill({
          color: "rgba(255, 255, 255, 0.2)"
        }),
        stroke: new Stroke({
          color: "#ffcc33",
          width: 2
        }),
        image: new CircleStyle({
          radius: 7,
          fill: new Fill({
            color: "#ffcc33"
          })
        })
      })
    });
    this.map = new Map({
      target: mapcontainer,
      //地图图层
      //layers: mapconfig.testmap(),
      layers: [
        new TileLayer({
          source: new OSM(),
          minResolution: 1,
          maxResolution: 500
        }),
        vector
      ],

      loadTilesWhileAnimating: true,
      //地图视图
      view: myview
    });
    this.addInteraction("area");
  },
  watch: {
    selected: function() {
      this.map.removeInteraction(this.draw);
      console.log(this.selected);
      if (this.selected != "None") {
        this.addInteraction(this.selected);
      } 
    }
  },
  methods: {
    addInteraction(typevalue) {
      var type = typevalue == "area" ? "Polygon" : "LineString";
      let self = this;
      self.draw = new Draw({
        source: self.mysource,
        type: type,
        style: new Style({
          fill: new Fill({
            color: "rgba(255, 255, 255, 0.2)"
          }),
          stroke: new Stroke({
            color: "rgba(0, 0, 0, 0.5)",
            lineDash: [10, 10],
            width: 2
          }),
          image: new CircleStyle({
            radius: 5,
            stroke: new Stroke({
              color: "rgba(0, 0, 0, 0.7)"
            }),
            fill: new Fill({
              color: "rgba(255, 255, 255, 0.2)"
            })
          })
        })
      });
      self.map.addInteraction(self.draw);
      self.createMeasureTooltip();
      //self.createHelpTooltip();
      var listener;
      self.draw.on(
        "drawstart",
        function(evt) {
          // set sketch
          self.sketch = evt.feature;
          /** @type {module:ol/coordinate~Coordinate|undefined} */
          var tooltipCoord = evt.coordinate;
          listener = self.sketch.getGeometry().on("change", function(evt) {
            var geom = evt.target;
            var output;
            if (geom instanceof Polygon) {
              output = self.formatArea(geom);
              tooltipCoord = geom.getInteriorPoint().getCoordinates();
            } else if (geom instanceof LineString) {
              output = self.formatLength(geom);
              tooltipCoord = geom.getLastCoordinate();
            }
            self.measureTooltipElement.innerHTML = output;
            self.measureTooltip.setPosition(tooltipCoord);
          });
        },
        this
      );
      self.draw.on(
        "drawend",
        function() {
          self.measureTooltipElement.className = "tooltip tooltip-static";
          //self.measureTooltipElement.Style="color:red"
          self.measureTooltip.setOffset([0, -7]);
          // unset sketch
          self.sketch = null;
          // unset tooltip so that a new one can be created
          self.measureTooltipElement = null;
          self.createMeasureTooltip();
          //unByKey(listener);
        },
        this
      );
    },
    createMeasureTooltip() {
      if (this.measureTooltipElement) {
        this.measureTooltipElement.parentNode.removeChild(
          this.measureTooltipElement
        );
      }
      this.measureTooltipElement = document.createElement("div");
      this.measureTooltipElement.className = "tooltip tooltip-measure";
      this.measureTooltip = new Overlay({
        element: this.measureTooltipElement,
        offset: [0, -15],
        positioning: "bottom-center"
      });
      this.map.addOverlay(this.measureTooltip);
    },
    formatLength(line) {
      var length = getLength(line);
      var output;
      if (length > 100) {
        output = Math.round((length / 1000) * 100) / 100 + " " + "km";
      } else {
        output = Math.round(length * 100) / 100 + " " + "m";
      }
      return output;
    },
    formatArea(polygon) {
      var area = getArea(polygon);
      var output;
      if (area > 10000) {
        output =
          Math.round((area / 1000000) * 100) / 100 + " " + "km<sup>2</sup>";
      } else {
        output = Math.round(area * 100) / 100 + " " + "m<sup>2</sup>";
      }
      return output;
    },
    removemeasure(){

    }


  }
};
</script>

<style map>

.fullscreen:-moz-full-screen {
  height: 100%;
}
.fullscreen:-webkit-full-screen {
  height: 100%;
}
.fullscreen:-ms-fullscreen {
  height: 100%;
}

.fullscreen:fullscreen {
  height: 100%;
}

.fullscreen {
  margin-bottom: 10px;
  width: 100%;
  height: 600px;
}

.ol-rotate {
  top: 3em;
}
.sidepanel {
  background: rgb(52, 63, 61);
  width: 20%;
  height: 100%;
  float: right;
}
.map {
  width: 80%;
  height: 100%;
  float: right;
}

.sidepanel-title {
  width: 100%;
  font-size: 1em;
  color: #ffffff;
  display: block;
  text-align: center;
}
.tooltip {
  position: relative;
  background: rgba(0, 0, 0, 0.5);
  border-radius: 4px;
  color: white;
  padding: 4px 8px;
  opacity: 0.7;
  white-space: nowrap;
}
.tooltip-measure {
  opacity: 1;
  font-weight: bold;
}
.tooltip-static {
  background-color: #ffcc33;
  color: black;
  border: 1px solid white;
}
.tooltip-measure:before,
.tooltip-static:before {
  border-top: 6px solid rgba(0, 0, 0, 0.5);
  border-right: 6px solid transparent;
  border-left: 6px solid transparent;
  content: "";
  position: absolute;
  bottom: -6px;
  margin-left: -7px;
  left: 50%;
}
.tooltip-static:before {
  border-top-color: #ffcc33;
}
</style>

2.清除测量

本文实例中绘画测量后的痕迹,需要先清除map内部的线,再清除div标注
清除线和面的方法为source.clear();
div利用 map.getOverlays().clear(); 批量删除

3.图层控制(非vue)parcel编译

3.1html

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>zsl</title>
    <style type="text/css">
        body,
        html,
        div,
        ul,
        li,
        iframe,
        p,
        img {
            border: none;
            padding: 0;
            margin: 0;
            font-size: 14px;
            font-family: "微软雅黑";
        }
        
        #map {
            width: 100%;
            height: 100%;
            position: absolute;
        }
        /* 图层控件层样式设置 */
        
        .layerControl {
            position: absolute;
            bottom: 5px;
            min-width: 200px;
            max-height: 200px;
            right: 0px;
            top: 5px;
            z-index: 2001;
            /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/
            color: #ffffff;
            background-color: #4c4e5a;
            border-width: 10px;
            /*边缘的宽度*/
            border-radius: 10px;
            /*圆角的大小 */
            border-color: #000 #000 #000 #000;
            /*边框颜色*/
        }
        
        .layerControl .title {
            font-weight: bold;
            font-size: 15px;
            margin: 10px;
        }
        
        .layerTree li {
            list-style: none;
            margin: 5px 10px;
        }
        /* 鼠标位置控件层样式设置 */
        
        #mouse-position {
            float: left;
            position: absolute;
            bottom: 5px;
            width: 200px;
            height: 20px;
            z-index: 2000;
            /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/
        }
    </style>
</head>

<body>
    <div id="map">
        <div id="mouse-position"></div>
        <div id="layerControl" class="layerControl">
            <div class="title"><label>图层列表</label></div>
            <ul id="layerTree" class="layerTree"></ul>
        </div>
    </div>

    <script src="./11layerc.js"></script>
</body>

</html>

2.2 js代码

import "ol/ol.css";
import { Map, View } from "ol";
import Overlay from "ol/Overlay.js";

import { Tile as TileLayer, Vector as VectorLayer } from "ol/layer.js";
import { OSM, BingMaps, Vector as VectorSource } from "ol/source.js";
import GeoJSON from "ol/format/GeoJSON.js";
import myshp from './data/geojson/countries.geojson'
var layer = new Array(); //map中的图层数组
var layerName = new Array(); //图层名称数组
var layerVisibility = new Array(); //图层可见属性数组

/**
 * 加载图层列表数据
 * @param {ol.Map} map 地图对象
 * @param {string} id 图层列表容器ID
 */

//实例化Map对象加载地图
var map = new Map({
    target: 'map', //地图容器div的ID
    //地图容器中加载的图层
    layers: [
        //加载瓦片图层数据
        new TileLayer({
            source: new OSM(),
            name: '世界地图(OSM瓦片)'
        }),
        new TileLayer({
            source: new BingMaps({
                imagerySet: 'Aerial',
                key: 'As1HiMj1PvLPlqc_gtM7AqZfBL8ZL3VrjaS3zIb22Uvb9WKhuJObROC-qUpa81U5'

            }),
            name: 'BingMaps',
        }),
        new VectorLayer({
            source: new VectorSource({
                url: myshp,

                format: new GeoJSON()
            }),
            name: '国界(Json格式矢量图)'
        }),
    ],
    //地图视图设置
    view: new View({
        center: [0, 0], //地图初始中心点
        zoom: 2 //地图初始显示级别
    })
});

function loadLayersControl(map, id) {
    var treeContent = document.getElementById(id); //图层目录容器

    var layers = map.getLayers(); //获取地图中所有图层
    for (var i = 0; i < layers.getLength(); i++) {
        //获取每个图层的名称、是否可见属性
        layer[i] = layers.item(i);
        layerName[i] = layer[i].get('name');
        layerVisibility[i] = layer[i].getVisible();

        //新增li元素,用来承载图层项
        var elementLi = document.createElement('li');
        treeContent.appendChild(elementLi); // 添加子节点
        //创建复选框元素
        var elementInput = document.createElement('input');
        elementInput.type = "checkbox";
        elementInput.name = "layers";
        elementLi.appendChild(elementInput);
        //创建label元素
        var elementLable = document.createElement('label');
        elementLable.className = "layer";
        //设置图层名称
        setInnerText(elementLable, layerName[i]);
        elementLi.appendChild(elementLable);

        //设置图层默认显示状态
        if (layerVisibility[i]) {
            elementInput.checked = true;
        }
        addChangeEvent(elementInput, layer[i]); //为checkbox添加变更事件                                         
    }
}
/**
 * 为checkbox元素绑定变更事件
 * @param {input} element checkbox元素
 * @param {ol.layer.Layer} layer 图层对象
 */
function addChangeEvent(element, layer) {
    element.onclick = function() {
        if (element.checked) {
            layer.setVisible(true); //显示图层
        } else {
            layer.setVisible(false); //不显示图层
        }
    };
}
/**
 * 动态设置元素文本内容(兼容)
 */
function setInnerText(element, text) {
    if (typeof element.textContent == "string") {
        element.textContent = text;
    } else {
        element.innerText = text;
    }
}
//加载图层列表数据
loadLayersControl(map, "layerTree");
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值