vue+openlayer实现地图框选、多选

48 篇文章 53 订阅

一,地图框选 

 效果图

添加交互时要按住Ctrl键,再拖动鼠标

 在线预览:WebGIS之家WebGIS之家,openlayers示例源码,cesium示例源码,openlayers在线调试预览,cesium在线调试预览,webgis,数字地球,数字孪生icon-default.png?t=N7T8https://www.webgishome.com/preview?id=90&example_name=dragBox_feature&title=dragBox%E6%A1%86%E9%80%89%E8%A6%81%E7%B4%A0

实现代码: 

<template>
  <div id="map">
    <el-button @click="addLayer()">添加图层</el-button>
    <el-button @click="removeLayer()">移除图层</el-button>
    <el-button @click="addInteraction()">添加交互</el-button>
    <el-button @click="removeInteraction()">移除交互</el-button>
  </div>
</template>
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector.js";
import { OSM, Vector as VectorSource } from "ol/source";
import { defaults as defaultControls } from "ol/control";
import ZoomSlider from "ol/control/ZoomSlider";
import GeoJSON from "ol/format/GeoJSON";
import Select from "ol/interaction/Select";
import DragBox from "ol/interaction/DragBox";
import { platformModifierKeyOnly } from "ol/events/condition";

export default {
  name: "",
  data() {
    return {
      map: null,
      select: {},
      dragBox: {},
      vectorSource: {},
      vectorLayer: {},

      selectedFeatures: [],
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    addLayer() {
      this.vectorLayer = new VectorLayer({
        source: this.vectorSource,
        zIndex: 2,
      });

      this.map.addLayer(this.vectorLayer);
    },
    removeLayer() {
      this.map.removeLayer(this.vectorLayer);
    },
    addInteraction() {
      this.select = new Select();
      this.selectedFeatures = this.select.getFeatures();

      this.dragBox = new DragBox({ condition: platformModifierKeyOnly });
      this.map.addInteraction(this.select);
      this.map.addInteraction(this.dragBox);

      this.dragBox.on("boxend", () => {
        let extent = this.dragBox.getGeometry().getExtent();
        this.vectorSource.forEachFeatureIntersectingExtent(
          extent,
          (feature) => {
            this.selectedFeatures.push(feature);
          }
        );
      });
      this.dragBox.on("boxstart", () => {
        this.selectedFeatures.clear();
      });
    },
    removeInteraction() {
      this.selectedFeatures.clear();
      this.map.removeInteraction(this.select);
      this.map.removeInteraction(this.dragBox);
    },

    // 初始化地图
    initMap() {
      let view = new View({
        projection: "EPSG:4326",
        center: [115, 39],
        zoom: 4,
      });
      let layer = new TileLayer({
        source: new OSM(),
        visible: true,
        zIndex: 1,
        name: "OSM",
      });
      let vectorSource = new VectorSource({
        url: "sichuan.json",
        format: new GeoJSON(),
      });

      this.vectorSource = vectorSource;

      this.map = new Map({
        layers: [layer],
        target: "map",
        view: view,
        controls: defaultControls().extend([new ZoomSlider()]),
      });
    },
  },
};
</script>
<style scoped>
#map {
  height: 100vh;
  width: 100vw;
}
</style>

记得在public文件夹中放一个sichuan.json的文件 

千万要注意this的指向,在用箭头函数时,里面的this指向的是外层的vue实例 

二,多选

控制多选:设置select对象的属性:

        condition: click, //单击选择。点击空白处,会取消选择
        toggleCondition: click,//点击空白处,不会取消选择

将示例1的代码更改如下即可:

   import { click } from "ol/events/condition";

   addInteraction() {
      this.select = new Select({ condition: click, toggleCondition: click });
      this.selectedFeatures = this.select.getFeatures();
      this.map.addInteraction(this.select);
    }
    removeInteraction() {
      this.selectedFeatures.clear();
      this.map.removeInteraction(this.select);
    },

所有代码如下所示:

<template>
  <div id="map">
    <el-button @click="addLayer()">添加图层</el-button>
    <el-button @click="removeLayer()">移除图层</el-button>
    <el-button @click="addInteraction()">添加交互</el-button>
    <el-button @click="removeInteraction()">移除交互</el-button>
  </div>
</template>
<script>
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector.js";
import { OSM, Vector as VectorSource } from "ol/source";
import { defaults as defaultControls } from "ol/control";
import ZoomSlider from "ol/control/ZoomSlider";
import GeoJSON from "ol/format/GeoJSON";
import Select from "ol/interaction/Select";

import { click } from "ol/events/condition";

export default {
  name: "",
  data() {
    return {
      map: null,
      select: {},
      dragBox: {},
      vectorSource: {},
      vectorLayer: {},

      selectedFeatures: [],
    };
  },
  mounted() {
    this.initMap();
  },
  methods: {
    addLayer() {
      this.vectorLayer = new VectorLayer({
        source: this.vectorSource,
        zIndex: 2,
      });

      this.map.addLayer(this.vectorLayer);
    },
    removeLayer() {
      this.map.removeLayer(this.vectorLayer);
    },
    addInteraction() {
      this.select = new Select({ condition: click, toggleCondition: click });
      this.selectedFeatures = this.select.getFeatures();
      this.map.addInteraction(this.select);
    },
    removeInteraction() {
      this.selectedFeatures.clear();
      this.map.removeInteraction(this.select);
    },

    // 初始化地图
    initMap() {
      let view = new View({
        projection: "EPSG:4326",
        center: [115, 39],
        zoom: 4,
      });
      let layer = new TileLayer({
        source: new OSM(),
        visible: true,
        zIndex: 1,
        name: "OSM",
      });
      let vectorSource = new VectorSource({
        url: "sichuan.json",
        format: new GeoJSON(),
      });

      this.vectorSource = vectorSource;

      this.map = new Map({
        layers: [layer],
        target: "map",
        view: view,
        controls: defaultControls().extend([new ZoomSlider()]),
      });
    },
  },
};
</script>
<style scoped>
#map {
  height: 100vh;
  width: 100vw;
}
</style>

效果图:

 

参考:

Box Selection

openlayers map的(包括拉框选择)初始化 openlayers版本6.11 - 简书

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值