0
点赞
收藏
分享

微信扫一扫

openlayers二次简单封装 线性、点

技术只适用于干活 2021-09-21 阅读 52
随笔开源

从自己的角度,简单的二次封装了一下openlayer,在这里提供一下我的思路!
1.添加一个底图对象 map
2.向底图对象上添加线层或者点层 line-map与 point-map

效果图


前端组件引用

<div style="height:500px">
    <map :baseMap="baseMap" @handleDownEvent="handleDownEvent" ref="map">
        <template slot="yl-map-layers">
            <line-map :lineData="lineData" :fun="lineFun"></line-map>
            <point-map :pointData="pointData" :fun="pointFun"></point-map>
        </template>
        <template slot="map-overlay" slot-scope="scope">
            {{scope.content}}
        </template>
    </map>
</div>

<script>
//  注意:
//    1.传入地图地图需引用 :
//      import TileLayer from "ol/layer/Tile";
//      import XYZ from "ol/source/XYZ";

//todo:1.其它地图交互事件暴露

import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";

export default {
  name: "yl-map-sam",
  data() {
    return {
        pointFun:(e)=>{
            return {
                src:null,
                scale:null
            }
        },//点样式
        lineFun:(e)=>{
            return {
                color:null,
                width:null
            }
        },//线样式
        lineData:[
            {
                data:[
                    [[104,30],[106,28]],//路段1
                    [[108,22],[105,33]],//路段2
                ],
                info:'路线1'
            }
        ],//线性数据结构
        pointData:[
            {lng:104,lat:30,info:'点1'},//点1
            {lng:108,lat:24,info:'点2'}//点2
        ],//点数据结构
        baseMap:new TileLayer({
          source: new XYZ({
            projection: "EPSG:3857",
            url:
              "https://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}"
          }),
          name: "底图"
        })
    }
  },
  methods:{
      //地图元素点击事件
      handleDownEvent(feature){
        //点击后将对应元素移动至地图中间
        this.fitView(feature);
      },

    //注意:closeOverlay()、refMapData()、fitView()使用:  给地图添加ref
    
    //关闭弹框
    closeOverlay(){
        this.$refs.map.close();
    },
    //刷新地图叠加层数据
    refMapData(){
        this.$bus.$emit(this.$refs.map.mapId + "ready", {});
    },
    //移动焦点位置   传入值features:Array
    fitView(feature){
        this.$refs.map.fitViewfeatures([feature]);
    }
  }
}
</script>

线性层 map

<template>
  <div class="wapper">
    <div :id="mapId" :ref="mapId" style="height:100%;width:100%;">
      <slot name="yl-map-layers"></slot>
      <div id="popup" class="ol-popup" v-show="content!=null">
        <span class="popup-close" @click="close">
          <i class="el-icon-close" />
        </span>
        <div id="popup-content">
          <slot name="yl-map-overlay" :content="content"></slot>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import { Cluster, OSM, Vector as VectorSource } from "ol/source";
import Feature from "ol/Feature";
import VectorLayer from "ol/layer/Vector";
import Icon from "ol/style/Icon";
import GeoJSON from "ol/format/GeoJSON";
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from "ol/style";
import * as olSize from "ol/size";

import request from "@/utils/request";

//弹框
import Overlay from "ol/Overlay";

//自定义事件方法
import {
  defaults as defaultInteractions,
  Pointer as PointerInteraction,
} from "ol/interaction";

export default {
  name: "yl-map",
  props: {
    baseMap: {
      type: Object,
      default: function () {
        return new TileLayer({
          source: new XYZ({
            projection: "EPSG:3857",
            url:
              "https://mt1.google.cn/vt/lyrs=y@113&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}&s=",
          }),
          name: "底图",
        });
      },
    },
  },
  data() {
    return {
      timeout: null,
      content: null, //内容
      mapId: null, //地图id
      map: null, //地图
      view: null,
      overlay: null, //弹框
    };
  },
  methods: {
    close() {
      //弹窗关闭方法(防止外部调用此方法——所以先要判断是否为空)
      this.overlay ? this.overlay.setPosition(undefined) : "";
    },
  },
  created() {
    console.info("map-created");
    this.mapId = "map" + new Date().getTime();
  },
  mounted() {
    console.info("地图组件挂载,id:" + this.mapId);
    let view = new View({
      center: [104.06, 30.67],
      projection: "EPSG:4326",
      zoom: 8,
      minZoom: 6,
      maxZoom: 20,
    });
    this.view = view;
    const map = new Map({
      target: this.$refs[this.mapId],
      layers: [this.baseMap],
      view: view,
    });
    this.map = map;
    this.$bus.$emit(this.mapId + "ready", {});
  },
};
</script>

<style lang="scss" scoped>
.wapper {
  position: relative;
  width: 100%;
  height: 100%;
  font-size: 80%;
  font-family: Source Han Sans CN;
  font-weight: 400;
}
.popup-close {
  position: absolute;
  right: 5px;
  top: 5px;
  cursor: pointer;
}
.ol-popup {
  background-color: #fff;
  padding: 10px;
  border-radius: 5px;
}
</style>

线性层 line-map

<template></template>   

<script>
/**
 * 线
 */

import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import XYZ from "ol/source/XYZ";
import VectorSource from "ol/source/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import VectorLayer from "ol/layer/Vector";
import Icon from "ol/style/Icon";
import GeoJSON from "ol/format/GeoJSON";
import { Circle as CircleStyle, Fill, Stroke, Style, Text } from "ol/style";
import * as olSize from "ol/size";

//线性
import LineString from "ol/geom/LineString";

import { getSessionMotif, getUserInfo } from "@/utils/auth";

import { localConvertArray } from "./../../../../../examples/utils/gps";

export default {
  name: "yl-line-map",
  props: {
    lineData: {
      type: Array,
      default: function () {
        return [];
      },
    },
    fun: {
      type: Function,
      default: function (data) {
        return (e) => {
          return {
            color: null,
            width: null,
          };
        };
      },
    },
  },
  watch: {
    lineData(val) {
      if (this.map == null) {
        this.map = this.$parent.map;
      }
      if (this.mapLayers.length > 0) {
        for (let i in this.mapLayers) {
          this.map.removeLayer(this.mapLayers[i]);
        }
        this.mapLayers = [];
      }
      this.addLineLayer();
    },
  },
  data() {
    return {
      mapLayers: [],
      map: null,
    };
  },
  methods: {
    setLineStyle(info) {
      if (this.fun(info).color && this.fun(info).width) {
        let lintStyle = new Style({
          stroke: new Stroke({
            //地图连线的样式
            color: this.fun(info).color,
            width: this.fun(info).width,
          }),
        });
        return lintStyle;
      } else {
        return null;
      }
    },
    addLineLayer() {
      let featureLines = [];
      if (this.lineData && this.lineData.length > 0) {
        for (let i in this.lineData) {
          if (this.lineData[i].data.length > 0) {
            for (let x in this.lineData[i].data) {
              if (this.lineData[i].data[x].length > 1) {
                // 设置  feature
                let featureLine = new Feature({
                  geometry: new LineString(
                    localConvertArray(this.lineData[i].data[x])
                  ),
                  _md_: this.lineData[i].info,
                });
                featureLine.setStyle(this.setLineStyle(this.lineData[i].info));
                featureLines.push(featureLine);
              }
            }
          }
        }
        if (featureLines.length > 0) {
          // 设置  线性数据源
          let LineSource = new VectorSource({
            features: featureLines,
          });
          // 设置  线性图层
          let LineLayer = new VectorLayer({
            source: LineSource,
            style: new Style({
              stroke: new Stroke({
                width: 6,
              }),
            }),
            type: "Line",
          });
          //添加  线性图层
          this.map.addLayer(LineLayer);
          this.mapLayers.push(LineLayer);
        }
      }
    },
  },
  beforeCreate() {},
  created() {
    this.$bus.$on(this.$parent.mapId + "ready", () => {
      if (this.map == null) {
        this.map = this.$parent.map;
      }
      if (this.mapLayers.length > 0) {
        for (let i in this.mapLayers) {
          this.map.removeLayer(this.mapLayers[i]);
        }
        this.mapLayers = [];
      }
      this.addLineLayer();
    });
  },
  beforeMount() {},
  mounted() {},
};
</script>

<style lang="scss" scoped>
</style>

todo:点层

举报

相关推荐

0 条评论