WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置

目录

    • 前言
    • 1、Openlayers自带的地图控件介绍与展示
    • 2、Openlayers-Extension提供的地图控件介绍与展示
    • 3、地图控件位置调整
    • 4、下一步计划
    • 5、相关源码

相关Web GIS实战信息:
上一篇博客:WebGIS实战:Vue+Openlayers实现网络地图的加载与切换
下一篇博客:

前言

在上一节《WebGIS实战:Openlayers实现网络地图的加载与切换》中,我们已经用到了一个地图控件了——图层切换控件(由Openlayers-Extension实现),这一节将讲述我们可能还会用到什么控件,而且由于这些控件位置都是固定在地图的某一位置,有时不满足我们的布局需求,这就需要我们知道怎么调整这些控件的位置了

项目源码
注意: 上一节中,我们创建了一个controls.js文件来统一管理我们的地图控件,本节还是基于此,将新添加的控件都放在controls.js中。对于需要用到的控件直接在地图初始化时添加到controls属性中,如下代码所示

BaseMap.vue

import {controls} from "@c/js/controls";//导入控件管理文件

let mMap = new Map({
      //挂载目标元素
      target: 'map',
      //显示的地图
      layers: [baseLayerGroup, vectorLayer],
      //表层图层
      overlays: [],
      //在此设置地图控件
      controls: [controls.zoom, controls.overview, controls.switcher, controls.fullScreen, controls.attr],
      //开启交互时加载瓦片
      loadTilesWhileInteracting: true,
      //地图显示中心
      view: view
    });

controls.js

import {defaults} from 'ol/control'
export const controls = {
  //定义控件格式
  控件命名: new 控件名称({
    //控件属性
    
  }),

  // 默认控件()
  default: defaults() // 没有new
};

1、Openlayers自带的地图控件介绍与展示

注意:括号中的英文名称链接到控件的API文档。由于每个控件比较零散,所以把代码全部放在最后面的controls.js文件中,读者请根据注释对应

  • 地图基本信息控件(Attribution):显示地图资源的版权信息
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第1张图片

  • 地图全屏显示控件(FullScreen):在浏览器中全屏显示地图,按esc退出全屏
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第2张图片

  • 鼠标位置控件(MousePosition):实时显示鼠标当前的坐标
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第3张图片
    对于位置覆盖的控件,可以查看第三小节了解如何调整位置

  • 地图鹰眼拖拽控件(OverviewMap):用户拖拽鹰眼图中的小矩形,主图显示对应的区域
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第4张图片

  • 地图比例尺控件(ScaleLine):显示当前的地图比例尺
    在这里插入图片描述

  • 地图缩放按钮控件(Zoom):点击+/-,实现放大和缩小显示等级
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第5张图片

  • 地图缩放拉条控件(ZoomSlider):通过拉动条位置,实现实现放大和缩小显示等级
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第6张图片

  • 地图指定范围跳转控件(ZoomToExtent)不常用:移动到指定范围的位置
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第7张图片

2、Openlayers-Extension提供的地图控件介绍与展示

  • 图层切换控件(LayerSwitch):用于控制图层显示与否,可以拖拽图层移动到顶层
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第8张图片

  • WMS加载控件(WMSCapabilities):在线搜索与加载wms地图数据
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第9张图片

  • 地图鹰眼点击控件(Overview):点击鹰眼图上的位置,然后主图平移到对应的位置
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第10张图片

  • 地球鹰眼转动控件(Globle):移动主图后在地球鹰眼图同时定位显示
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第11张图片

  • 地图书签标记控件(GeoBookMark):为当前的界面添加界面,点击书签名字自动切换到对应界面
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第12张图片
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第13张图片

  • 屏幕滑动对比控件(Swipe):中间的控件可以拉动,类似帘子效果,有水平模式与垂直模式

  • 地图工具栏控件(ControlBar):将相关性比较高控件整合为一个工具栏
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第14张图片

  • 地图界面打印控件(Print)):将当前的地图页面进行下载,省去用其他工具截图,而且更加清晰。需要依赖file-saver库。
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第15张图片

  • 地图中心控件(Target):显示地图的中心

  • 图例控件(Legend):用于显示图层的图例信息
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第16张图片

3、地图控件位置调整

以上介绍了那么多控件,总有一些控件会重叠在一起,如果此时我们都需要这些控件的话,就需要调整控件的位置(上图的OverviewMap 与 Legend 控件就重叠在一起了)。下面以调整Legend控件到右边为例,介绍如何通过CSS文件调整控件的位置。

  • 在src/assets下新建一个文件夹scss并创建一个scss文件
    在这里插入图片描述

  • 针对控件编写CSS样式
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第17张图片

  • 引入到BaseMap.vue文件中
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第18张图片

  • 通过className引入自定义的类样式,调整放置位置。注意:需要在控件原样式之前添加我们自己定义的样式
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第19张图片

  • 调整结果
    WebGIS实战:Vue+Openlayers实现地图控件的加载与控件自定义位置_第20张图片

4、下一步计划

至此,关于Openlayers中常用的地图控件的使用方法与自定义位置就介绍完了。

目前,我们使用的还是网络上发布的通用地图,那如果我们要加载自己发布的地图/专题地图呢?这要怎么操作,下一节将介绍如何加载Mapserver/GeoServer发布的地图数据

5、相关源码

目前相关文件已经上传至GitHub中,请需要的同学自行clone学习。
controls.js

/**
 * 地图控件
 * 方便使用
 */
import {
  OverviewMap,
  ZoomSlider,
  Zoom,
  ScaleLine,
  FullScreen,
  Attribution,
  MousePosition,
  ZoomToExtent, Rotate
} from 'ol/control';
import {defaults} from 'ol/control';
import Baselayers from "@c/js/baselayers";
import {createStringXY} from "ol/coordinate";
import Legend from 'ol-ext/control/Legend';
import LayerSwitcher from 'ol-ext/control/LayerSwitcher';
import WMSCapabilities from "ol-ext/control/WMSCapabilities";
import Overview from "ol-ext/control/Overview";
import GeoBookmark from "ol-ext/control/GeoBookmark";
import Swipe from "ol-ext/control/Swipe";
import Globe from "ol-ext/control/Globe";
import Bar from "ol-ext/control/Bar";
import Print from "ol-ext/control/Print";
import Compass from "ol-ext/control/Compass";
import Target from "ol-ext/control/Target";
import {Style, Fill, Text} from "ol/style";

/**
 * ol 自带控件
 */
export const controls = {
  // 鹰眼图
  overview: new OverviewMap({
    collapsed: true,
    layers: [
      //ol6版本需要开发者设置一个新的地图资源,而ol5版本直接显示主图的缩略图
      Baselayers.OSMLayer(true, true)//ol6需要设置图层,ol5不需要
    ]
  }),
  // 缩放滑块
  zoomSlider: new ZoomSlider({
    duration: 800
  }),
  // 缩放按钮
  // className: 'control-right'
  zoom: new Zoom({
    duration: 800,
  }),
  // 比例尺
  scale: new ScaleLine({
    className: 'scale-left ol-scale-line'
  }),
  // 旋转
  rotate: new Rotate({

  }),
  // 地图版权
  attr: new Attribution({
    //该控件自动绑定网络地图的相关信息,如果没有提供则不显示
    //默认信息是收起状态,点击后显示
    className: 'attr-right ol-attribution'
  }),
  // 鼠标位置
  mousePosition: new MousePosition({
    coordinateFormat: createStringXY(4),
    projection: 'EPSG:4326',
    undefinedHTML: ' '
  }),
  // 地图全屏
  fullScreen: new FullScreen({

  }),
  zoomToExtend: new ZoomToExtent({
    //不设置时显示全图
  }),
  // 地图图层切换
  switcher: new LayerSwitcher({
    show_progress: true,
    extent: true
  }),
  // wsm地图服务的查询与加载
  wmsCapabilities: new WMSCapabilities({
    srs: ['EPSG:4326'],
    cors: true
  }),
  // 平移到鹰眼图上的点击位置
  clickOverview: new Overview({
    collapsed: true,
    layers: [
      //ol6版本需要开发者设置一个新的地图资源,而ol5版本直接显示主图的缩略图
      Baselayers.OSMLayer(true, true)//ol6需要设置图层,ol5不需要
    ]
  }),
  // 地图位置书签
  geoBookmark: new GeoBookmark({

  }),
  // 地图对比控件
  swipe: new Swipe({
    orientation: 'vertical' //'vertical':水平对比;'horizontal':垂直对比
  }),
  // 地球鹰眼控件
  globalOverview: new Globe({
    layers: [Baselayers.BingMapLayer(Baselayers.BingMapLayerTypes.AerialWithLabels)],
    panAnimation: 'elastic',
    follow: true,
  }),
  // 工具栏控件
  controlBar: new Bar({

  }),
  // 打印控件
  print: new Print({
    imageType: 'image/png', //也可以是image/png
  }),
  // 指北针控件
  compass: new Compass({
    className: 'bottom',
    rotateVithView: true,
    src: 'http://viglino.github.io/ol-ext/examples/data/piratecontrol.png'
  }),
  // 地图中心控件
  center: new Target({
    style: new Style({
      text: new Text({
        text: '\uf140',
        font: '25px Fontawesome',
        fill: new Fill({color: 'red'})
      })
    }),
    composite: 'default'
  }),

  //图例
  legend: new Legend({
    className: 'legend-right ol-legend',
    title: 'Legend',
    size: [100, 210],
    collapsed: true,
  }),

  // 默认控件()
  default: defaults() // 没有new
};

BaseMap.vue

<template>
  <div>
    <div id="map">
    </div>
  </div>
</template>

<script>
  import Baselayers from "@c/js/baselayers";
  import {Map, View} from 'ol';
  import {addCoordinateTransforms, addProjection, fromLonLat} from 'ol/proj';
  import {controls} from "@c/js/controls";
  import Projection from "ol/proj/Projection";
  import {applyTransform} from "ol/extent";
  import projzh from "projzh";
  import saveAs from "file-saver";

export default {
  name: "base-map",
  mounted() {
    //添加百度地图的投影
    let extent = [-179.9, -90, 179.9, 90];
    let baiduMercator = new Projection({
      code: 'baidu',
      extent: applyTransform(extent, projzh.ll2bmerc),
      units: 'm'
    });
    addProjection(baiduMercator);
    addCoordinateTransforms('EPSG:4326', baiduMercator, projzh.ll2bmerc, projzh.bmerc2ll);
    addCoordinateTransforms('EPSG:3857', baiduMercator, projzh.smerc2bmerc, projzh.bmerc2smerc);

    let bingMap = Baselayers.BingMapLayer(Baselayers.BingMapLayerTypes.AerialWithLabels);
    let osm = Baselayers.OSMLayer(true, false);
    let bdMapLayer = Baselayers.BaiDuLayer('百度地图');
    let bdMapLayerCustom = Baselayers.BaiDuLayerCustom('自定义百度地图');
    let baseLayerGroup = Baselayers.BaseLayersGroup([bingMap, osm, bdMapLayer, bdMapLayerCustom]);
    let vectorLayer = Baselayers.VectorLayer();

    let centerPoint = fromLonLat([118.8, 32.0]);
    let view = new View({
      center: centerPoint,
      zoom: 11
    });
    
    //设置显示两个滑动地图
    controls.swipe.addLayer(bingMap);
    controls.swipe.addLayer(osm, true);

    // 组织控件工具栏
    controls.controlBar.addControl(controls.fullScreen);
    controls.controlBar.addControl(controls.wmsCapabilities);
    controls.controlBar.addControl(controls.zoomToExtend);
    controls.controlBar.addControl(controls.rotate);
    controls.controlBar.setPosition('right');

    // 监听点击事件,设置图片保存事件
    controls.print.on(['print', 'error'], (e) => {
      e.canvas.toBlob((blob => {
        saveAs(blob, 'map.' + e.imageType.replace('image/', ''))
      }), e.imageType);
    });

    new Map({
      //挂载元素
      target: 'map',
      //显示的地图
      layers: [baseLayerGroup, vectorLayer],
      //表层图层
      overlays: [],
      //在此设置地图控件
      controls: [controls.zoom, controls.clickOverview, controls.switcher, controls.controlBar, controls.print, controls.legend],
      //开启交互时加载瓦片
      loadTilesWhileInteracting: true,
      //地图显示中心
      view: view
    });
  }
}
</script>

// 注意不要加上scope属性
<style lang="scss">
//引入自定义的样式文件
 @import "../assets/scss/widgets.scss";
  #map {
    height: 100%;
    width: 100%;
    position: fixed;
  }
</style>

widgets.scss

// 定义变量
$widget-top: 5rem;
$widget-left: 1rem;
$widget-right: 1rem;
$widget-5right: 5rem;
// 缩放控件:右侧
// ol默认:ol-zoom
.control-right {
  bottom: 5.5rem;
  right: $widget-right;
}
.scale-left {
  left: $widget-left + 2rem;
}
.attr-right {
  right: $widget-right;
}
// 对于原生css文件已经使用的,可以使用initial!important强制初始化
.legend-right{
  left:initial!important;
  right:$widget-5right;
  z-index:1;
  max-height:90%;
  max-width:90%;
  overflow-x:hidden;
  overflow-y:auto
}

你可能感兴趣的:(Vue.js,Web,GIS,vue,css)