openlayer生成GeoJSON坐标文件

需求

使用openlayer展示酒店房间平面图,需要覆盖房间的图层时需要获取到每个房间块的坐标,故需要一个工具将地图背景图片进行坐标收集并生成文件

思路

  1. 首先是获取坐标的方式,openlayer例子里有可以通过map的点击事件获取点击位置的坐标
  2. 其次明确openlayer添加layer所需的数据,我选择的是使用GeoJSON转换,故在写进文件之前要将GeoJSON转换成feature所需的数据都拼齐,最后转成json保存
  3. 保存文件,这里借用了FileSaver插件

实现及源码

使用的插件

ol和FileSaver

下载方式

如果是vue项目

npm install ol -D
npm install file-saver --save

如果是html

我是去git上下了FileSaver的源码
ol就是引用了外部链接

页面元素

<template>
  <div>
    <div id="map"></div><!--地图组件-->
    <input id="roomnumber"
           name="roomnumber"
           placeholder="请输入房间号"
           class="input-style">
    <div>
      <button @click="confirm"
              class="btn-style">确定</button>
      <button @click="render"
              class="btn-style">渲染</button>
      <button @click="exportFile"
              class="btn-style">导出文件</button>
    </div>
  </div>
</template>

主要就是地图展示和三个功能按钮以下分别说明(地图展示忽略,可在另一篇文章里看)
先定义几个全局变量

data () {
    return {
      map: {},//地图对象
      list: {//存放进文件的数据
        features: [],//对应多个图层
      },
      renderlist: {//渲染的对象
        type: 'FeatureCollection',
        crs: {
          type: 'name',
          properties: {
            name: 'EPSG:3857',
          },
        },
        features: [],
      },
      coordinates: [[]],//收集的坐标集合,根据openlayer里图层的集合的数据类型来定义的
      roomnumber: '',
    };
  }

存放进文件的数据和渲染数据分开是因为二者数据内容不一致,保存的数据不需要初始定义的部分类型数据。
map添加点击事件

this.map.on('click', (evt) => {
        this.coordinates[0].push(evt.coordinate);//收集坐标
      });

确定
就是用来将每个图层块区分开来,点击一次就代表一个图层块的坐标及相关数据获取完成了

confirm () {
      const id = Math.uuidFast();//获取uuid作为图层的唯一标识
      const value = {
        type: 'Feature',
        geometry: {
          type: 'Polygon',
          coordinates: this.coordinates,
        },
        id,
        properties: { modelId: document.getElementById('roomnumber').value, id, type: 'room' },
      };
      this.renderlist.features.push(value);
      this.list.features.push(value);
      console.log(value);
      this.coordinates = [[]];//要将坐标集合清空,以免多个图层的数据叠加
    },

渲染
这个功能也是方便收集完坐标之后能立刻看到根据收集的坐标画出的图层的效果

render () {
      const getStyles = (param) => {
        console.log(param);
        const style = new Style({
          stroke: new Stroke({
            color: '#2d9fd8',
            width: 0,
          }),
          fill: new Fill({
            color: '#2d9fd8',
            opacity: 0.8,
          }),
          text: new Text({ // 文本样式
            className: 'map-font',
            font: '14px Microsoft YaHei',
            fill: new Fill({
              color: 'black',
            }),
          }),
        });
        return style;
      };
      const styleFunction = (feature) => getStyles(feature.values_.modelId);//根据feature里的数据进行样式区分,这里由于只是看效果,所以没做渲染
      const vectorSource = new VectorSource({
        features: (new GeoJSON()).readFeatures(this.renderlist),//使用GeoJSON的readFeatures可将json数据转换成feature对象
      });
      console.log(this.map.getLayers());
      this.map.addLayer(new VectorLayer({
        source: vectorSource,
        style: styleFunction,
        title: '',
        type: 'room',
      }));
    },

导出

exportFile () {
      const content = JSON.stringify(this.list);
      const blob = new Blob([content], { type: 'text/plain;charset=utf-8' });
      FileSaver.saveAs(blob, 'A-10.roomlayer');//这个是默认名称,保存之后会有弹出框的,默认是下到C://user/dowload/,在弹出框里可更改路径和文件名称
 },

效果

在这里插入图片描述
深蓝色区块就是收集的坐标画出来的图层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值