Vue+openLayers开发时的常用代码

Vue+openLayers开发时的常用代码

  1. 加载天地图与arcgis server发布的切片服务
<template>
  <div id="map" ref="rootmap"></div>
</template>
<script>
import "ol/ol.css";
import { Map, View } from "ol";
import TileLayer from "ol/layer/Tile";
import {OSM} from 'ol/source';
import XYZ from "ol/source/XYZ";
import {fromLonLat} from 'ol/proj';

export default {
  data(){
    return {
      map:null
    };
  },
  mounted() {
    // const skpMapImg = "https://t{0-7}.tianditu.gov.cn/DataServer?T=img_c&x={x}&y={y}&l={z}&tk="; //天地图影像
    // const skpMapCia = "https://t{0-7}.tianditu.gov.cn/DataServer?T=cia_c&x={x}&y={y}&l={z}&tk="; //天地图影像注记
    const skpMapVec = "https://t{0-7}.tianditu.gov.cn/DataServer?T=vec_c&x={x}&y={y}&l={z}&tk="; //矢量天地图
    const skpMapCva = "https://t{0-7}.tianditu.gov.cn/DataServer?T=cva_c&x={x}&y={y}&l={z}&tk="; //矢量天地图注记
    const skpMapKey = "天地图密钥"; //天地图密钥
    //这里用window['mapObj']替代this.map,切断对map对象的双向监控,提高速度
    window['mapObj'] = new Map({
      target: "map",
      //地图控件
      controls: defaultControls({ zoom: false }).extend([]),//这里是去掉自带的缩放按钮
      layers: [
        new TileLayer({
          source: new XYZ({
            projection: "EPSG:4326",    //使用4326来加载4490坐标系
            //经纬度投影
            url: skpMapVec + skpMapKey
          })
        }),
        new TileLayer({
          source: new XYZ({
            projection: "EPSG:4326",    //使用4326来加载4490坐标系
            //经纬度投影
            url: skpMapCva + skpMapKey
          })
        }),
        new TileLayer({
          zIndex: 1,
          source: new XYZ({
            url:
              'https://sldtptgis.zjwater.com/arcgis/rest/services/basemap/' +
              'ZLSLVectorMap/MapServer/tile/{z}/{y}/{x}',
            projection: "EPSG:4326",    //使用4326来加载4490坐标系
          })
        },{ zoomOffset: 1 })
      ],
      view: new View({
        center: fromLonLat([120.527,27.817]),
        // projection: "EPSG:4326",    //mapview
        zoom: 11,
        maxZoom: 18,
        minZoom: 10,
      }),
    });
  },
};
</script>
  1. 请求arcgis服务后绘制要素
    简单的网络请求模块:(封装在了名为mapRequest.js的文件中)
import axiosfrom 'axios'

export default function mapAxios(option) {
  return new Promise((resolve,reject) => {
    // 1. 创建axios实例
    const instance = axios.create({
      baseURL: "http://112.112.112.112:8008/arcgis/rest/services/",
      timeout: 15000
    });

    // 2. 配置请求和响应拦截
    instance.interceptors.request.use(config => {
      // console.log('来到了request拦截success中');
			// 2.1 当发送网络请求时, 在页面中添加一个loading组件, 作为动画

      // 2.2 某些请求要求用户必须登录, 判断用户是否有token, 如果没有token跳转到login页面
      
			// 2.3 对请求的参数进行序列化(看服务器是否需要序列化)
      
      return config
    },err => {
      // console.log('来到了request拦截failure中');
      return err
    })

    instance.interceptors.response.use(response => {
      // console.log('来到了response拦截success中');
      return response.data
    },err => {
      // console.log('来到了response拦截failure中');
      // console.log(err);
      if (err && err.response) {
        switch (err.response.status) {
          case 400:
            err.message = '请求错误'
            break;
          case 401:
            err.message = '未授权的访问'
            break;
        }
      }
      return err
    })

    //2.传入对象进行网络请求
    instance(option).then(res => {
      // console.log(option)
      resolve(res)
    }).catch(err => {
      reject(err)
    })
  })
}

二次封装的请求(封装在了名为loadMapserver.js的文件中)

import mapAxios from '../config/mapRequest'

export function queryMapserver(url,params) {
  return mapAxios({
    url,
    params
  })
}

组件中:

<template>
  <div id="map" ref="rootmap">
    <!-- 这里是气泡弹窗的dom -->
    <div id="popup" class="ol-popup">
      <a href="#" id="popup-closer" class="ol-popup-closer"></a>
      <div id="popup-content" class="popup-content"></div>
    </div>
    <!-- --------------- -->
  </div>
</template>
    
<script>
import "ol/ol.css"
import { Map, View, Feature, ol } from "ol"
import XYZ from 'ol/source/XYZ'
import { toStringHDMS } from "ol/coordinate"
import { fromLonLat, transform, toLonLat } from 'ol/proj'
import  { defaults as defaultControls } from 'ol/control'
import Overlay from 'ol/Overlay';
import Point from 'ol/geom/Point';
// import GeoJSON from 'ol/format/GeoJSON'
import { Polygon, MultiPolygon } from "ol/geom"
import {Fill, Stroke, Icon, Style} from 'ol/style'
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer'
import {TileArcGISRest,Vector as VectorSource} from 'ol/source'
//请求服务画面用
import { queryMapserver } from '@/api/loadMapserver'
export default {
  name:'MainMap',
  components: {
    
  },
  props: {
    
  },
  data() {
    return {
      // map: null,
      serviceLink: "http://112.112.112.112:8008/arcgis/rest/services/",
      pointLayer: null, //点位图层
      featuresArr: []	//点位要素数组
    };
  },
  mounted() {
    // const skpMapImg = "https://t{0-7}.tianditu.gov.cn/DataServer?T=img_c&x={x}&y={y}&l={z}&tk="; //天地图影像
    // const skpMapCia = "https://t{0-7}.tianditu.gov.cn/DataServer?T=cia_c&x={x}&y={y}&l={z}&tk="; //天地图影像注记
    const skpMapVec = "https://t{0-7}.tianditu.gov.cn/DataServer?T=vec_c&x={x}&y={y}&l={z}&tk="; //天地图影像
    const skpMapCva = "https://t{0-7}.tianditu.gov.cn/DataServer?T=cva_c&x={x}&y={y}&l={z}&tk="; //天地图影像注记
    const skpMapKey = "434967d31e3d3f9d396b2f4c4250b023"; //天地图密钥
    //这里用window['mapObj']替代this.map,切断对map对象的双向监控,提高速度
    window['mapObj'] = new Map({
      target: "map",
      //地图控件
      controls: defaultControls({ zoom: false }).extend([]),
      layers: [
        new TileLayer({
          source: new XYZ({
            projection: "EPSG:4326"
            //经纬度投影
            url: skpMapVec + skpMapKey
          })
        }),
        new TileLayer({
          source: new XYZ({
            projection: "EPSG:4326",
            //经纬度投影
            url: skpMapCva + skpMapKey
          })
        })
      ],
      view: new View({
        center: fromLonLat([121.000,27.000]),
        zoom: 11,
        maxZoom: 18,
        minZoom: 10,
      }),
    });

    //添加要素1
    this.searchMap("border","2",'rgb(0,101,240)',3,'rgba(0,101,240,0.2)',this.showBorder)
    //添加要素2
    this.searchMap("river","0",'blue',1,'blue',this.showRiver)
  },
  methods: {
    //这里是请求服务中子图层的全部要素的方法
    searchMap(name,layer,bcolor,bwidth,fillcolor,callback) {
        // console.log('searchMap');
      //name为服务名,layer为子图层id,bcolor,bwidth为所绘边界颜色与宽度,fillcolor为填充色
      //请求要素得到vectorSource
      let mapUrl = name + "/MapServer/" + layer +"/query"
      let param = {
        where: "1=1",
        outSR:4490,
        inSR:4490,
        maxAllowableOffset:0,
        returnGeometry:true,
        outFields:"*",
        spatialRel:"esriSpatialRelIntersects",
        f: "pjson",
      }
      let geojson = {}
      queryMapserver(mapUrl,param).then(res => {
        // console.log('queryMapserver');
        let response = res.features
        //将返回数据整饰成geojson
        geojson = {
          "type": "FeatureCollection",
          'crs': {
            'type': 'name',
            'properties': {
              'name': 'EPSG:4326',
            },
          },
          "features": []
        }
        for(var i=0;i<response.length;i++) {
          var row = response[i];
          geojson.features.push({
            "type": "Feature",
            "geometry": {
              "type": "MultiPolygon",  //MultiPolygon
              "coordinates": [row.geometry.rings]
            }
          })
        }
        // return geojson;
        // this.showlayer(geojson,true,bcolor,bwidth,fillcolor)
        callback(geojson,bcolor,bwidth,fillcolor)
      })
    },

    //根据自己发的服务来画简单的面  作为初始方法
    showBorder(geojson,bcolor,bwidth,fillcolor) {
      // console.log(geojson);
      //此处透明度靠fillcolor的颜色透明度来实现
      if (geojson.features.length == 0) return false
      let areaFeature = null
      //设置要素样式
      let styles = [
        new Style({
          stroke: new Stroke({
            color: bcolor,
            width: bwidth,
          }),
          fill: new Fill({
            color: fillcolor,
          }),
        })
      ];
      this.ruianLayer = new VectorLayer({
        className: "ruianLayer",
        zIndex: 2,
        source: new VectorSource({
          features: []
        }),
        style: styles,
      });
      for (let i = 0; i < geojson.features.length; i++) {
        areaFeature = new Feature({
          geometry: new MultiPolygon(
            geojson.features[i].geometry.coordinates
          ).transform("EPSG:4326", "EPSG:3857")
        });
        this.ruianLayer.getSource().addFeatures([areaFeature])
      }
      window['mapObj'].addLayer(this.ruianLayer)
    },
    
    //根据自己发的服务来画简单的面  作为初始方法
    showRiver(geojson,bcolor,bwidth,fillcolor) {
      //此处透明度靠fillcolor的颜色透明度来实现
      if (geojson.features.length == 0) return false
      let areaFeature = null
      //设置要素样式
      let styles = [
        new Style({
          stroke: new Stroke({
            color: bcolor,
            width: bwidth,
          }),
          fill: new Fill({
            color: fillcolor,
          }),
        })
      ];
      this.riverLayer = new VectorLayer({
        className: "riverLayer",
        zIndex: 30,
        source: new VectorSource({
          features: []
        }),
        style: styles,
      });
      for (let i = 0; i < geojson.features.length; i++) {
        areaFeature = new Feature({
          geometry: new MultiPolygon(
            geojson.features[i].geometry.coordinates
          ).transform("EPSG:4326", "EPSG:3857")
        });
        this.riverLayer.getSource().addFeatures([areaFeature])
      }
      window['mapObj'].addLayer(this.riverLayer)
    },

	//添加图层方法
    showLayer(data) {
      switch (data) {
        case 1://加载全部
          //每加入一个图层就要在这里写入添加的方法
          window['mapObj'].addLayer(this.riverLayer)
          break;
        case 2://加载河道
          //每加入一个图层就要在这里写入添加的方法
          window['mapObj'].addLayer(this.riverLayer)
          break;
      }
    },
	//删除图层方法
    removeAllLayer() {
      //每加入一个图层就要在这里写入移除的方法
      window['mapObj'].removeLayer(this.riverLayer)
    }
  },
};
</script>
<style lang="scss" scoped>
#map {
  height: 100%;
  width: 100%;
  margin: 0;
  position: relative;
}
/*隐藏ol的一些自带元素*/
.ol-attribution,
.ol-zoom {
  display: none;
}
</style>
  1. 添加图标点位,并在图标上添加点击气泡弹窗
	//加在上面的methods下
    showPoint(coordinates) {
      // 设置图层
      this.pointLayer = new VectorLayer({
        className: "pointLayer",
        zIndex: 40,
        source: new VectorSource()
      });

      // 添加图层
      window['mapObj'].addLayer(this.pointLayer)

      // 循环添加feature
      for (let i = 0; i < coordinates.length; i++) {
        // 创建feature,一个feature就是一个点坐标信息
        let feature = new Feature({
          name: "第一个点",
          geometry: new Point(
            fromLonLat([coordinates[i].x, coordinates[i].y])
          )
        });
        feature.setStyle(this.getIcon(coordinates[i].type));
        this.featuresArr.push(feature);
      } // for 结束
      // 批量添加feature
      this.pointLayer.getSource().addFeatures(this.featuresArr);

      const pointlayer = this.pointLayer;
      
      // 使用变量存储弹窗所需的 DOM 对象
      let container = document.getElementById("popup");
      let closer = document.getElementById("popup-closer");
      let content = document.getElementById("popup-content");

      // 创建一个弹窗 Overlay 对象
      this.overlay = new Overlay({
          element: container, //绑定 Overlay 对象和 DOM 对象的
          autoPan: true, // 定义弹出窗口在边缘点击时候可能不完整 设置自动平移效果
          autoPanAnimation: {
              duration: 250 //自动平移效果的动画时间 9毫秒
          }
      });
      // 将弹窗添加到 map 地图中
      window['mapObj'].addOverlay(this.overlay);
      let _that = this;
      /**
       * 添加单击响应函数来处理弹窗动作
       */
      window['mapObj'].on("click", function(evt,_that) {
        pointlayer.getFeatures(evt.pixel).then((res) => {
          let feature = res.length ? res[0] : undefined;

          if (feature) {
            let coordinates = feature.getGeometry().getCoordinates();
            _that.overlay.setPosition(coordinates); //把 overlay 显示到指定的 x,y坐标
            //这里获取到的feature是pointlayer图层点击位置的要素
            // console.log(coordinates);
	          $(element).popover({
	            placement: 'top',
	            html: true,
	            content: feature.get('name'),
	          });
	          $(element).popover('show');
          } else {
         	$(element).popover('dispose');
            // console.log("no");
          }
        });

        // "EPSG:3857", "EPSG:4326" 转换
        let coordinate = transform(
            evt.coordinate,
            "EPSG:3857",
            "EPSG:4326"
        );
        // 点击尺 (这里是尺(米),并不是经纬度);
        let hdms = toStringHDMS(toLonLat(evt.coordinate)); // 转换为经纬度显示
        content.innerHTML = `
        <p>你点击了这里:</p>
        <p>经纬度:<p><code> ${hdms}  </code> <p>
        <p>坐标:</p>X:${coordinate[0]} &nbsp;&nbsp; Y: ${coordinate[1]}`;
        _that.overlay.setPosition(evt.coordinate); //把 overlay 显示到指定的 x,y坐标
      });
      /**
       * 为弹窗添加一个响应关闭的函数
       */
      closer.onclick = function() {
          _that.overlay.setPosition(undefined);
          closer.blur();
          return false;
      };
    },
    getIcon(type) {
      let src = "";
      type == "bule"
        ? (src = require("@/assets/images/patrol-img.png"))
        : (src = require("@/assets/logo.png"));
      var styleIcon = new Style({
        // 设置图片效果
        image: new Icon({
            src: src,
            anchor: [1, 1],
            anchorXUnits: 'fraction',
            anchorYUnits: 'pixels',
            scale: 0.2, //这个属性设置图片的大小
        })
      });
      return styleIcon;
    },
    //之后定义
    let coordinates = [
      { x: "120.527", y: "27.817", type: "lv" },
      { x: "120.527", y: "27.817", type: "bule" },
      { x: "120.527", y: "27.817", type: "lv" },
      { x: "120.527", y: "27.817", type: "bule" },
      { x: "120.527", y: "27.817", type: "lv" }
    ];
    //然后执行
    showPoint(coordinates )即可
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值