openlayer+vue实现监听绘制(实时导出绘制要素,回调函数之外操作绘制对象)

更新:

        睡觉果然有用,睡了觉又想到更好的思路,这里就不用Promise了,代码看着不简洁,直接用EventBus在内部将需要的数据派发出来,然后在业务组件里面进行启动绘制和提交请求的解耦,这样一下子做到了需求拆解,逻辑变得简单,而且丰富了UI跟高大上了有木有,哎,有木有?

前言:

        大伙好,我又带来干货啦,今天在做交互时有个问题困扰了我许久,先说应用场景:

用户对影像进行绘制区域栅格统计查询,统计出栅格的区间占比,最后根据数据生成带图例的饼状图,像这样:

        在组件化开发的时代,讲究功能组件化、组件功能单一化,展示组件逻辑要完全和地图组件分离开,不能出现展示组件中引入ol库的low代码。大家用过ol的都清楚,ol的Draw绘制监听是回调,例如:

 draw.on("drawend", (DrawEvent) => {
        DrawEvent.feature.getGeometry().flatCoordinates);//绘制坐标串
      });

        那么这种回调我们是没办法控制的,在这里就特别容易出现功能耦合(部分绘制无关的逻辑必须写在回调),破坏了功能单一性。接下来说说我的思路和看法,如果有更好思路的可以讨论一下,我也希望写出更好的逻辑。

一、功能解耦,组件化分离

1.这里地图组件职责是统管所有和地图相关的操作,我这边列举一些:

 只包含一些地图、图层、绘制、地位等等地理操作

2.非地图,也叫业务功能,这里以栅格统计展示图表组件为例

这里面只写栅格统计的逻辑

二、组件通信

        有vue开发经验的朋友都知道这个通信是必不可少的,但我这里要提一点的是,在WebGIS开发过程中,异步操作占80%,这里如果你是使用EventBus进行组件对象的传递的话,注意使用位置,一是EventBus.$emit派发要放在初始化后面,EventBus.$on接收要放在beforeMount

三、Promise监听事件中的回调,resolve出结果

      return new Promise((resolve) => {
        let drawEvent = draw.on(
          "drawend",
          (DrawEvent) => {
            // 拿到extent拼接成左上右下查询格式
            let cord = DrawEvent.feature.getGeometry().extent_;
            let bounds = {
              leftBottom: {
                x: cord[0],
                y: cord[1],
              },
              rightTop: {
                x: cord[2],
                y: cord[3],
              },
            };
            resolve(bounds);
          }
        );
        console.log(drawEvent);
      });

在函数中用Promise进行包裹,再resolve出你需要操作的参数,我这边是操作边界bound

四、巧用监听属性去使得绘制实时反馈到业务组件

        前三步都比较顺通,相信也是许多朋友走过的流程,但是如果这是你需要点击绘制按钮,需要每次绘制区域都刷新结果,那基本没戏,因为本次调用以及结束,绘制信息以及死在map组件的函数襁褓里面喽!

        这里就可以先在业务组件中把刚刚的resolve里面的值用async/await先取到,然后保存到当前组件的data中,最后在watch中监听数据,这里直接对函数进行调用,就可以做到实时导出draw.on()回调里面的数据啦。

  watch:{
    RecQueryBounds:{
      handler(newValue, oldValue) {
        this.RecQuery()
    },
    // 矩形统计
    async RecQuery() {
      // 取点 左下 右上 走extent就行
      // 也支持多边界查询
      this.RecQueryBounds = await this.MapCom.DrawGeometry();
     console.log(this.RecQueryBounds);
      // 拿到数据去更新
     await this.RasterQueryApi(this.RecQueryBounds);
      this.RasterStatistics();
    },

结尾:

        来的都是朋友,上述的分有错误还希望各位朋友指出,有更好的思路也可以教一下我,最后有疑问可以留言或者私信讨论,今天的分析就到这里啦,睡大觉去。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以使用Vue.js和OpenLayers库来实现绘制折线并计算折线距离。下面是一个基本的实现示例: 首先,确保你已经安装了Vue.js和OpenLayers依赖: ```bash npm install vue openlayers ``` 然后,在你的Vue组件中,引入OpenLayers和样式表: ```javascript import 'ol/ol.css'; import { Map, View } from 'ol'; import { Tile as TileLayer, Vector as VectorLayer } from 'ol/layer'; import { OSM, Vector as VectorSource } from 'ol/source'; import { Draw, Modify } from 'ol/interaction'; import { createBox } from 'ol/interaction/Draw'; export default { mounted() { // 创建地图 const map = new Map({ target: 'map', layers: [ new TileLayer({ source: new OSM() }) ], view: new View({ center: [0, 0], zoom: 2 }) }); // 创建绘制交互 const source = new VectorSource(); const vector = new VectorLayer({ source: source }); map.addLayer(vector); const draw = new Draw({ source: source, type: 'LineString' }); map.addInteraction(draw); // 创建修改交互 const modify = new Modify({ source: source }); map.addInteraction(modify); // 计算折线距离 draw.on('drawend', (event) => { const feature = event.feature; const geometry = feature.getGeometry(); const coordinates = geometry.getCoordinates(); let distance = 0; for (let i = 1; i < coordinates.length; i++) { const coord1 = coordinates[i]; const coord2 = coordinates[i - 1]; distance += getDistance(coord1, coord2); } console.log('折线距离:', distance); }); // 计算两点之间的距离 function getDistance(coord1, coord2) { const dx = coord2[0] - coord1[0]; const dy = coord2[1] - coord1[1]; return Math.sqrt(dx * dx + dy * dy); } } } ``` 在上面的代码中,我们创建了一个地图实例,并添加了一个基本的OSM图层。然后,我们创建了一个矢量图层和一个绘制交互,允许用户绘制线段。在绘制结束时,我们计算折线的距离,并输出到控制台。 注意,我们使用了`ol/ol.css`样式表来确保地图正确显示。你可以根据自己的需求进行样式调整。 最后,在你的Vue模板中,添加一个具有指定ID的容器元素: ```html <template> <div> <div id="map"></div> </div> </template> ``` 这样,当你在浏览器中运行该Vue组件时,你将能够在地图上绘制折线,并计算折线的距离。 希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值