Vue+OpenLayers学习系列(一)OpenLayers 总体介绍+切换地图底图

一、OpenLayers 数据组织

OpenLayers 的地图数据通过图层(Layer)进行组织渲染,然后通过数据源(Source)设置具体的地图数据来源。

Layer 可看作渲染地图的层容器,具体的数据需要通过 Source 设置。

Source 和 Layer 是一对一的关系。每一个 Layer 里面需要一个 Source,然后把 Layer 添加到 Map 上,就可以显示出来了。

地图数据根据数据源(Source)可分为 Image、Tile、Vector 三大类型的数据源类,对应设置到地图图层(Layer)的 Image、Tile、Vector 三大类的图层中。其中,矢量图层 Vector 通过样式(Style)来设置矢量要素渲染的方式和外观。

在数据源中:

  • Tile 类为瓦片抽象基类,其子类作为各类瓦片数据的数据源。
  • Vector 类为矢量数据源基类,为矢量图层提供具体的数据来源,包括直接组织或读取的矢量数据(Features)、远程数据源的矢量数据(即通过 url 设置数据源路径)等。若是 url 设置的矢量数据源,则通过解析器 Format(即 ol.format.Feature 的子类)来解析各类矢量数据,如 XML、Text、JSON、GML、KML、GPS、WFS、WKT、GeoJSON 等地图数据。
  • Image 类为单一图像基类,其子类为画布(canvas)元素、服务器图片、单个静态图片、WMS 单一图像等的数据源。它与 Tile 类的区别在于,Image 类对应的是一整张大图片,而不像瓦片那样很多张小图片,从而无需切片,也可以加载一些地图,适用于一些小场景地图。

从复杂度来分析,Image 类和 Vector 类都不复杂,其数据格式和来源方式都简单。而 Tile 类则不一样,由于一些历史问题,多个服务提供商,多种标准等诸多原因,导致要支持世界上大多数的瓦片数据,就需要针对这些差异(这些差异主要是瓦片坐标系不同、分辨率不同等)提供不同的 Tile 数据源支持。

(1)我们先来看一下 OpenLayers 现在支持的 Source 具体有哪些:

preview

上图中的类是按照继承关系,从左到右展开的,左边的为父类,右边的为子类。在使用时,一般来说,都是直接使用叶子节点上的类,基本就可以完成需求。父类需要自己进一步扩展或者处理才能有效使用。

首先了解最为复杂的 ol.source.Tile,其叶子节点类有很多,大致可以分为几类:

  • 在线服务的 Source,包括 ol.source.BingMaps(微软提供的 Bing 在线地图数据)、ol.source.Stamen(Stamen提供的在线地图数据)。没有自己的地图服务器情况下,可直接使用它们,加载地图底图。
  • 支持协议标准的 Source,包括 ol.source.TileArcGISRest、ol.source.TileWMS、ol.source.WMTS、ol.source.UTFGrid、ol.source.TileJSON。如果要使用它们,首先得学习对应的协议,之后必须找到支持这些协议的服务器来提供数据源,这些服务器可以是底图服务商提供的,也可以是自己搭建的服务器,关键是得支持这些协议。
  • ol.source.XYZ,这个需要单独提一下,因为是可以直接使用的,而且现在很多地图服务(在线的,或者自己搭建的服务器)都支持 xyz 方式的请求。国内在线的地图服务,如高德、天地图等,都可以通过这种方式加载,本地离线瓦片地图也可以,用途广泛,且简单易学。

ol.source.Image虽然有几种不同的子类,但大多比较简单,因为不牵涉到过多的协议和服务提供商。而 ol.source.Vector 就更加简单了,但有时候其唯一的子类 ol.source.Cluster(聚合要素时使用)在处理大量的要素时,我们可能需要使用。

(2)现在介绍 Source 的搭档 Layer。OpenLayers 现有的 Layer 类图大致如下:

preview

为了便于了解和使用,图中标注了每一个 Layer 对应的 Source。通过上图可以看到 Layer 相对于 Source 而言,真是太简单了。

其中 ol.layer.Group 是一个用于将多个图层存储在一起的集合类。

二、OpenLayers 实现底图切换

<template>
  <div>
    <div id="map" ref="rootmap">
    </div>
    <button @click="change_img()">切换影像底图</button>
    <button @click="change_vec()">切换街道底图</button>
    <button @click="change_ter()">切换地形底图</button>
    <button @click="change_google()">切换谷歌卫星地图</button>
    <button @click="change_google_tile()">切换谷歌路网地图</button>
  </div>
</template>

<script>
  import "ol/ol.css";
  import { Map, View } from "ol";
  import {VectorTile as VectorLayerTile,Tile} from 'ol/layer'
  import {Style,Fill,Stroke} from 'ol/style';
  import {VectorTile as VectorSourceTile,OSM,WMTS,XYZ} from 'ol/source'
  import {fromLonLat} from 'ol/proj'
  import {defaults} from 'ol/control'

  export default {
    name: 'OlChangeMap',
    data() {
      return {
        map: null,
        img: null,
        map_cva: null,
        map_vec: null,
        map_ter: null,
        map_cta: null,
        map_google: null,
        map_google_Tile: null
      };
    },
    mounted() {  
      this.img = new Tile({
        source: new XYZ({  //天地图
          url: 'http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=你的token'
        }),
        visible: true
      });
      this.map_cva= new Tile({
        source: new XYZ({
          url: "http://t3.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=你的token"
        }),
        visible: false
      });
      this.map_vec =new Tile({
        source: new XYZ({
          url: "http://t4.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=你的token"
        }),
        visible: false
      });
      this.map_ter = new Tile({
        source: new XYZ({
          url:  "http://t4.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}&tk=你的token"
        }),
        visible: false
      });
      this.map_cta =new Tile({
        source: new XYZ({
          url: "http://t4.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=你的token"
        }),
        visible: false
      });
      this.map_google =new Tile({
        source: new XYZ({
          url: "http://www.google.cn/maps/vt?lyrs=s@189&gl=cn&x={x}&y={y}&z={z}"
        }),
        visible: false
      });
      this.map_google_Tile =new Tile({
        source: new XYZ({
          url: "http://www.google.cn/maps/vt?lyrs=r@189&gl=cn&x={x}&y={y}&z={z}"
        }),
        visible: false
      });
      this.map = new Map({
        target: 'map',
        layers: [
            this.img,this.map_cva,this.map_vec,
            this.map_ter,this.map_cta,this.map_google,this.map_google_Tile
        ],
        controls: defaults({
          attributionOptions: {
            collapsible: false
          }
        }),
        view: new View({
          center: fromLonLat([116.24, 39.55]),//将坐标从经度,纬度转换为不同的投影,默认为'EPSG:3857'。
          zoom: 6
        })
      })
    },
    methods:{
      change_img(){
        this.img.setVisible(true);
        this.map_cva.setVisible(false);
        this.map_vec.setVisible(false);
        this.map_ter.setVisible(false);
        this.map_cta.setVisible(false);
        this.map_google.setVisible(false);
        this.map_google_Tile.setVisible(false);
      },
      change_vec(){
        this.img.setVisible(false);
        this.map_cva.setVisible(true);
        this.map_vec.setVisible(false);
        this.map_ter.setVisible(false);
        this.map_cta.setVisible(false);
        this.map_google.setVisible(false);
        this.map_google_Tile.setVisible(false);
      },
      change_ter(){
        this.img.setVisible(false);
        this.map_cva.setVisible(false);
        this.map_vec.setVisible(false);
        this.map_ter.setVisible(true);
        this.map_cta.setVisible(false);
        this.map_google.setVisible(false);
        this.map_google_Tile.setVisible(false);
      },
      change_google(){
        this.img.setVisible(false);
        this.map_cva.setVisible(false);
        this.map_vec.setVisible(false);
        this.map_ter.setVisible(false);
        this.map_cta.setVisible(false);
        this.map_google.setVisible(true);
        this.map_google_Tile.setVisible(false);
      },
      change_google_tile(){
        this.img.setVisible(false);
        this.map_cva.setVisible(false);
        this.map_vec.setVisible(false);
        this.map_ter.setVisible(false);
        this.map_cta.setVisible(false);
        this.map_google.setVisible(false);
        this.map_google_Tile.setVisible(true);
      }
    }
  };
</script>

<style>
  #map{
    height:800px;
    width: 1400px;
  }
  /*隐藏ol的一些自带元素*/
  .ol-attribution,.ol-zoom { display: none;}

</style>

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值