# LearnWebGIS
**Repository Path**: mrwhitebare/learn-web-gis
## Basic Information
- **Project Name**: LearnWebGIS
- **Description**: 学习OpenLayers5并记录相关知识......
- **Primary Language**: HTML
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: https://gitee.com/mrwhitebare/learn-web-gis
- **GVP Project**: No
## Statistics
- **Stars**: 6
- **Forks**: 2
- **Created**: 2020-11-12
- **Last Updated**: 2025-08-18
## Categories & Tags
**Categories**: Uncategorized
**Tags**: openlayer, Aspnet
## README
# LearnWebGIS
#### 介绍
  《WebGIS之OpenLayers全面解析》第二版的学习过程,记录知识与源码;:email:
## 1.了解:v:
  **地理信息系统**(Geographic Inforamation System,**GIS**)是一种特定的十分重要的空间信息系统,它是在计算机软硬件系统的支持下,以采集、存储、管理、检索、分析和描述空间物体的定位分布及与之相关的属性数据,并以回答用户的问题为主要任务的计算机系统。
  **WebGIS**(网络地理信息系统)是指基于网络平台,客户端应用软件采用网络协议,运行在网络上的地理信息系统,即将**GIS**所提供的功能通过网络展现给用户。
## 2.WebGIS开发基础:eyes:
### 2.1 Web开发基础理论
#### 2.1.1 B/S架构
  **B/S**(Browser/Server,浏览器/服务器)架构,其基本结构一般包括Web服务器、Web页面、Web浏览器和HTTP协议等部分。

  Web应用的经典多层架构为表现层、业务逻辑层、数据访问层、数据源。

#### 2.1.2 客户端技术
  Web前端开发技术包括网页开发技术、客户端交互技术等。**HTML  CSS JavaScript**
#### 2.1.3 服务器端技术
  Web服务器端开发技术分为两大派系:**.NET**与**Java**。前者是微软提供的框架,可以使用ASP.NET进行动态网页开发,后台使用C#语言实现;后者基于Java进行Web应用开发,主要采用JavaEE平台体系,使用JSP进行动态网页开发,后台使用Java语言实现。
**Java**
  Java平台由Java虚拟机和Java应用编程接口构成。在硬件或操作系统中安装一个Java平台之后,即可与逆行Java平台程序。Java平台主要分为三个体系,即**JavaSE(Java 2 Platform Standard Edition,Java平台标准版)**、**JavaME(Java 2 Platform Micro Editin,Java平台微型版)**、**JavaEE (Java 2 Platform Enterprise,Java平台企业版)**。
  **JavaEE**使用多层次分布式应用模型,应用逻辑按功能划分为组件,各个应用组件根据他们所在层分布在不同机器上。
  `-`客户端:运行在客户计算机上的组件;
  `-`Web层与业务逻辑层:运行在JavaEE服务器上的组件;
  `-`企业信息系统层(EIS)层:运行在EIS服务器上的软件系统,比如数据库。

#### 2.1.4 数据库技术
  数据是网络世界的基础,数据库为Web应用与资源共享提供了一个有力的工具。
  现有的关系型数据库几乎都采用结构化查询语言(Structured Query Language,SQL)标准。SQL是专门为数据库而建立的操作命令集,包括数据定义、数据操纵、数据控制等,是一个功能齐全的数据库语言。
### 2.2 WebGIS开发的GIS背景知识
#### 2.2.1 基础几何图形
  地图可视化是GIS的基础内容,而几何图形则是地图表达的基本元素。几何图形对应二维空间中的点、线、面。
`1.点`:oncoming_police_car:
  点是几何图形中最基本的单元,是空间中只有位置、没有大小的图形。在一个平面上,通常用坐标(x,y)来表示一个点,其中x表示水平位置,y表示竖直位置。
`2.线`:rainbow:
  线是显示空间中线状地物(如道路、河流、航线、电力线)的抽象。当需要记录一条线时,实际仅仅记录线上的一些节点用以描述整条线。**节点**即线的端点与转折点。
`3.多边形`:bullettrain_front:
  多边形是现实世界中面状地物(如农田、湖泊、行政区等)的抽象。多边形是由平面上三个及三个以上的节点连接而成的封闭图形,可以通过有序描述多边形边界的节点来描述一个简单多边形。
#### 2.2.2 GIS地图学基础
:one: :heavy_check_mark:坐标系:
  坐标系是用于定义要素实际位置的坐标框架,包括坐标原点$(O)$、长半轴$(a)$、短半轴$(b)$、扁率$(f)$。
  坐标系可以分为地理坐标系(Geography Coordinate System)和投影坐标系(Projected Coordinate System)
  地理坐标系是直接建立在椭球体上的,用经度和纬度表达地理对象位置;投影坐标系是建立在平面上的。
:two: :white_check_mark:投影转换
  球面上一点的位置取决于它的经度与纬度,在投影时先将一些经线和纬线的交点展绘在平面上,在将相同经度的点连成经线,相同纬度的点连成纬线,构成经纬网。

球面上任意一点是用地理坐标$(\lambda,\varphi)$表示的,而平面上点的位置使用平面直角坐标系$(x,y)$或者极坐标$(\rho,\theta)$表示的,所以将地球表面上的点转化到平面上,必须采用一定的法则来确定地理坐标与平面直角坐标之间的关系。
:three: :o:比例尺
  比例尺等于图上距离除以实际距离。
  **地图**是按照一定的数学法则,将地球表面上的空间信息,经概况综合,以可视化、数字或触摸的符号形式,缩小表达在一定载体上的图形模型,用以传输、模拟和认知客观世界的时空信息。
## 3.OpenLayers开发基础 :100:
### 3.1 OpenLayers简介
  **OpenLayers**是一个模块化、高性能、功能丰富的WebGIS客户端的JavaScript包,用于显示地图及空间数据,并与之进行交互,具有灵活的扩展机制。
## 4.OpenLayers入门 :no_pedestrians: :id:
### 4.1 实现地图显示功能
**(1)** 新建一个空白的Web网站并将OpenLayers5开发库与样式文件复制到Web网站的某一目录下;
**(2)** 在新建的Web网站中创建一个HTML网页,在网页的`
`标签中引入`ol.js`与`ol.css`。
**(3)** 在HTML网页的``中新建一个``层作为地图容器,设置其ID为map,并通过CSS设置地图容器的样式。
```html
//head中引入
```
Ⅰ.  **ol.Map**:地图容器类,OpenLayers5的核心部件,用于显示地图,可以加载各种类型的图层,地图控件(如比例尺、缩放、鹰眼等),以及与地图交互的功能控件等。通过实例化地图容器对象加载显示地图,主要是target、layers、view参数的设置。
Ⅱ.  **ol.layer.Tile** :瓦片图层类,主要用于加载瓦片图层(根据显示级别对各级地图切片后的地图),实例化瓦片图层对象,绑定其数据源(source)以加载瓦片图层。
Ⅲ.  **ol.source.XYZ**:使用了定义在`url`模板中方的一套`XYZ`格式的`url`地址的瓦片数据类,默认情况下,遵循Google网格。自定义网格,则在`url`模板中使用`{x},{y},{z}`占位符。
Ⅳ.  **ol.View**:地图视图类,主要控制地图与人的交互,如进行缩放、调节分辨率、控制地图旋转。
```js
//通过Map.AddLayer()加载图层
//天地图影像地图
var  TiandiMap_img = new ol.layer.Tile({
     title: '天地图影像图层',
    source: new ol.source.XYZ({
           url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=申请key",
           crossOrigins: "anonymous",
           wrapX:false
            })
});
//天地图影像地图注记
var TiandiMap_cia = new ol.layer.Tile({
    title: '天地图影像地图注记',
    source: new ol.source.XYZ({
           url: 'http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=申请key',
           crossOrigins: "anonymous",
           wrapX: false
            })
});
//加载图层
map.addLayer(TiandiMap_img);
map.addLayer(TiandiMap_cia);
```
### 4.2 加载常用控件
#### 4.2.1 导航控件
  导航条的主要功能是实现地图按级缩放,拖动导航条上的滑块可以实现缩放操作,向上可以拖动可放大地图,向下拖动可以缩小地图。

#### 4.2.2 基本操作控件
  地图基本操作是指用户与地图的简单交互,主要包括地图放大、缩小、移动、复位和更新。
```html
    地图基本操作功能
    
    
    
    
    
    
        
        
        
        
    
    
    
```
#### 4.2.3 图层控件:two_hearts:
  实际应用中,将地图容器中加载的图层以列表形式显示,便于查看与操作。
**功能实现**
:one: 首先创建Map对象分别加载天地图矢量图层,矢量图层标注、天地图影像图层、影像图层标注;
:two: 其次,新建一个方法loadLayersControl(map,id) 在其中获取每个图层的Name、可见属性、序号,然后动态添加为li元素,li元素由`Checkbox`和`label`组成;最后给每个`Checkbox` 添加事件,给`label`赋值。
```html
    加载图层控件(自定义)
    
    
    
    
    
```
#### 4.2.4 比例尺控件 :cupid:
  地图比例尺用于表示图上距离比实际距离缩小(或者放大)的程度,表示地图图形的缩小程度,又称为缩尺。比例尺控件:**ol.control.ScaleLine**
```html
```
#### 4.2.5 鹰眼控件 :sparkling_heart:
  地图鹰眼可以称为鸟瞰图或者缩略图。在地图中,通过鹰眼可以知道地图的当前位置;也可以在鹰眼上点击、拖动或者移动到想要查看的位置。鹰眼的可视范围可以是地图全局,鹰眼中心框的可视范围就是主图的可视范围,主图的地理信息要比鹰眼控件详细,鹰眼可视范围更加广阔。鹰眼控件:**ol.control.OverviewMap**

 ```html
    加载鹰眼控件
    
    
    
    
    
 ```
#### 4.2.6 图层探查控件 :broken_heart:
  当有多个图层叠加显示时,上层图层会遮盖下层图层。图层探查控件可以方便地查看下层图层数据,可用于辅助功能操作或分析。图层探查原理是在客户端上裁剪上层图层,将上层图层裁剪一部分,让下层图层数据变得可见。
**Demo设计思路**
Ⅰ. 为地图视图添加鼠标的mousemove和mouseout事件监听,通过调用Map类中的getEventPixel方法获取当前鼠标焦点坐标点;
Ⅱ . 图层画布剪裁:为矢量图层(上层图层)添加**precompose**事件监听 ,在影像图层渲染前进行裁剪,就是以鼠标焦点为圆心,以radius为半径,在图层画布设置一个圆,通过clip()裁剪图层画布,将画布裁剪为一个圆的形状;同时,为影像图层(下层图层)添加**postcompose**事件监听,在矢量图层渲染后还原图层画布的背景,即通过restore()还原。
Ⅲ . 裁剪圆半径的设置:为**document**添加**keydown**事件监听,通过**Ctrl+Z**控制缩小;通过**Ctrl+L**控制放大圆。
```html
    图层探查控件
    
    
    
    
    
    
```
**Ctrl+Z控制缩小;通过Ctrl+L控制放大**

,,ԾㅂԾ,,**参考资料**
[**键盘按键keyCode大全js页面快捷键**](https://www.cnblogs.com/qiushuiblog/p/7086901.html)
[**JS监听组合按键**](https://www.cnblogs.com/xiaoheimiaoer/p/4716191.html)
[**JQuery绑定事件4种方式**](https://www.cnblogs.com/shiyh/p/8891139.html)
#### 4.2.7 动画效果控件 :heartpulse:
  动画效果控件,可增强地图操作的动态效果。**ol5**的动画效果在**ol.View**中的**animate**方法设置,可以传递一个或者多个对象实现旋转、弹性移动,反弹等;
```html
    动画效果控件
    
    
    
    
    
        
        
        
        
        
    
    
    
```
#### 4.2.8 测量控件 :love_letter:
  测量功能包括距离(即长度)测量与面积测量。面积测量是指计算鼠标绘制范围的实际面积大小,距离测量则是值计算鼠标的线条实际长度。
```html
    加载测量控件
    
    
    
    
    
        
    
    
```
## 5.OpenLayers之多源数据展示 :earth_asia:
  大量的网络地图服务资源,**Google**地图、**OpenStreetMap**、**Bing**地图、**Yahoo**地图、百度地图、高德地图、天地图。自定义格式的**GIS**数据有**ESRI**、中地数码(**MapGIS**)、超图(**SuperMap**)。
### 5.1 数据加载原理 :earth_africa:
  GIS的目的是利用空间信息为人们的生产生活提供便利与服务,而地图就是空间信息的直接表现,是空间信息的载体,因此地图加载是一个**WebGIS**应用的基础。
#### 5.1.1 一般原理
Ⅰ. 瓦片地图——是指网格中多个类似瓦片的图片集,对矢量地图文档或影像数据进行预处理,采用高效的缓存机制形成的缓存图片集,可以在网页中快速加载。通过**AJAX**请求瓦片地图服务或数据,根据瓦片地图的级数,行列号分别获取对应的瓦片地图。将其按照请求的空间范围组织好,从而形成一副完整地图显示在网页中。
Ⅱ . 矢量地图——加载矢量地图可以直接读取矢量地图文件,即存储在磁盘中的GML、KML格式的矢量地图文件;另一种为调用矢量地图服务接口,即通过服务接口读取并加载矢量地图。通过**AJAX**请求矢量地图服务或数据,根据请求到矢量地图,在Web端生产矢量地图并显示在网页中。
#### 5.1.2 OpenLayers  5加载地图的原理 :earth_americas:
  **ol5**将图层(Layer)与数据源(Source)分离,图层作为渲染地图数据的地图容器,数据源是GIS数据的载体,图层要与数据源配置。
  图层与数据源均分为Image、Tile、Vector三大类型;
ⅰ. 瓦片地图:使用ol.layer.tile+ol.source.tile加载,ol.souece.tile子类可以封装瓦片地图数据源;
ⅱ . 矢量地图:使用ol.layer.Vector+ol.source.Vector方式加载。
### 5.2 基础地图数据
#### 5.2.1 基于ArcGIS Server REST的瓦片地图
```html
    加载ArcGIS瓦片数据
    
    
    
    
    
    
```
使用**ol.layer.Tile+ol.source.TileArcGISRest**实现**ArcGIS ServerREST** 瓦片地图服务的加载。
#### 5.2.2 基于ArcGIS Server REST的矢量地图服务接口
由于ArcGIS该服务停止,无法显示效果
```html
    加载ArcGIS REST Feature Service
    
    
    
    
    
    
```
#### 5.2.3 基于ArcGIS Online的瓦片地图服务接口
```html
    加载ArcGIS影像数据
    
    
    
    
    
    
```
### 5.3 开放数据 🌐
Ⅰ. **KML** ——基于**XML**的谷歌地球的文件格式;
Ⅱ . **GML**——地理标记语言,可以表示地理空间对象的空间数据和非空间数据;
Ⅲ . **GPX**——**GPX**交换格式是基于**XML**的通用**GPS**数据格式,可以用来描述点、轨迹、路程;可以保存位置、海拔和时间
Ⅳ . **GeoJSON**——**GeoJSON**是一种对各种空间数据结构进行编码的格式,基于**JSON**的地理空间信息数据交换格式。可以表示几何,特征或者特征几何,支持点、线、面、多点、多线、多面和几何集合。
#### 5.3.1 加载GeoJSON数据
> **安装完整IIS服务**
>
> Ⅰ. 打开程序和功能窗口,点击**启用或关闭Windows功能** 
>
> 
>
> 找到Internet Information Services
>
> **万维网服务——应用程序开发功能**
>
> 
>
> **万维网服务——安全性**
>
> 
>
> **万维网服务——常见HTTP功能**
>
> 
>
> **万维网服务——运行状况和诊断**
>
> 
>
> **万维网服务——性能功能**
>
> 
>
> **Web管理工具**
>
> 
>
> 
>
> **IIS支持json、geojson文件**
>
> 打开IIS管理,添加MIME类型
>
> 文件扩展名:.geojson
>
> MIME类型:application/geojson
>
> 
>
> 点击处理程序映射,添加脚本映射
>
> 
>
> **参考资料** [完整安装IIS服务 - googlegis - 博客园 ](https://www.cnblogs.com/googlegis/p/4127389.html)
>
> [IIS支持json、geojson文件 - googlegis - 博客园 ](https://www.cnblogs.com/googlegis/p/4127356.html)
 **GeoJSON数据网站推荐** [地图选择器 ](http://datav.aliyun.com/tools/atlas/#&lat=30.316551722910077&lng=106.68898666525287&zoom=3.5)
```html
    加载GeoJSON数据
    
    
    
    
    
    
        
        
         
    
    
    
```

#### 5.3.2 加载KML数据
**配置ASP.NET应用程序**
  使其可以访问**.geojson、.kml、.gpx**格式的数据
```xml
    
      
      
    
  
    
      
        
        
      
    
    
      
        
          
          
          
          
        
      
    
    
      
      
      
    
  
```
```js
//矢量数据图层
var vectorLayer;
//数据类型
var ajaxDataType;
//地图投影坐标系
var projection = ol.proj.get('EPSG:3857');
/**
        *矢量几何要素的样式
        */
var image = new ol.style.Circle({
    radius: 5,
    fill: null,
    stroke: new ol.style.Stroke({ color: 'red', width: 1 })
});
var styles = {
    'Point': [
        new ol.style.Style({
            //点样式
            image: image
        })
    ],
    'LineString': [
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                //线的边界样式
                color: 'green',
                width: 1
            })
        })
    ],
    'MultiLineString': [
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                //多线的边界样式
                color: 'green',
                width: 1
            })
        })
    ],
    'MultiPoint': [
        new ol.style.Style({
            //多点的点样式
            image: image
        })
    ],
    'MultiPolygon': [
        new ol.style.Style({
            //多区的边界样式
            stroke: new ol.style.Stroke({
                color: 'yellow',
                width: 1
            }),
            fill: new ol.style.Fill({
                //多区的填充样式
                color: 'rgba(255, 255, 0, 0.1)'
            })
        })
    ],
    'Polygon': [
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                //区的边界样式
                color: 'blue',
                lineDash: [4],
                width: 3
            }),
            fill: new ol.style.Fill({
                //区的填充样式
                color: 'rgba(0, 0, 255, 0.1)'
            })
        })
    ],
    'GeometryCollection': [
        new ol.style.Style({
            //集合要素的边界样式
            stroke: new ol.style.Stroke({
                color: 'magenta',
                width: 2
            }),
            fill: new ol.style.Fill({
                //集合要素的填充样式
                color: 'magenta'
            }),
            image: new ol.style.Circle({
                //集合要素的点样式
                radius: 10,
                fill: null,
                stroke: new ol.style.Stroke({
                    color: 'magenta'
                })
            })
        })
    ],
    'Circle': [
        new ol.style.Style({
            stroke: new ol.style.Stroke({
                //圆的边界样式
                color: 'red',
                width: 2
            }),
            fill: new ol.style.Fill({
                //圆的填充样式
                color: 'rgba(255,0,0,0.2)'
            })
        })
    ]
};
var styleFunction = function (feature, resolution) {
    //根据要素类型设置几何要素的样式
    return styles[feature.getGeometry().getType()];
};
//实例化Map对象加载地图
var map = new ol.Map({
    //地图容器div的ID
    target: 'mapCon',
    //地图容器中加载的图层
    layers: [
        //加载瓦片图层数据
        new ol.layer.Tile({
            title: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                attributions: "天地图的属性描述",
                wrapX: false
            }),
            preload: Infinity
        }),
        new ol.layer.Tile({
            title: "天地图矢量图层注记",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                attributions: "天地图的属性描述",
                wrapX: false
            }),
            preload: Infinity
        })
    ],
    //地图视图设置
    view: new ol.View({
        //设置地图投影坐标系
        projection: projection,
        //地图初始中心点
        center: [0, 0],
        //地图初始显示级别
        zoom: 2
    })
});
//d787e9cde2030ae9666878b58e09c194
$('#addKML').click(function () {
    if (vectorLayer != null || vectorLayer == "undefined") {
        map.removeLayer(vectorLayer);
    }
    //实例化矢量数据源,使用KML格式解析
    var vectorSource = new ol.source.Vector({
        url: '2012-02-10.kml',
        format: new ol.format.KML({
            extractStyles:false
        })
    });
    vectorLayer = new ol.layer.Vector({
        source: vectorSource,
        style: styleFunction
    });
    map.addLayer(vectorLayer);
    var view = map.getView();
    view.setCenter([876970.8463461736, 5859807.853963373]);
    //地图缩放
    view.setZoom(4);
});
```
#### 5.3.3 加载GPX数据
```js
$('#addGPX').click(function () {
if (vectorLayer != null || vectorLayer == "undefined") {
//移除已有矢量图层
map.removeLayer(vectorLayer);
}
//实例化矢量数据源,用GPX格式的类解析
var vectorSource = new ol.source.Vector({
url: '../data/fells_loop.gpx',
format: new ol.format.GPX()
});
vectorLayer = new ol.layer.Vector({
//矢量数据源
source: vectorSource,
//样式设置
style: styleFunction
});
//将矢量图层加载到地图中
map.addLayer(vectorLayer);
//获取地图视图
var view = map.getView();
//平移地图
view.setCenter([-7916041.528716288, 5228379.045749711]);
//地图缩放
view.setZoom(10);
});
```
### 5.4 公共地图数据
  公共地图数据是指网上的大量地图服务资源,提供免费开发的基础地图服务,一般均为瓦片地图形式。比如 谷歌地图、OpenStreetMap、Bing地图、百度地图、高德地图、天地图等。
#### 5.4.1 加载OpenStreetMap
```js
var map = new ol.Map({
    target: 'mapCon',
    layers: [
        new ol.layer.Tile({
            source: new ol.source.OSM()
        })
    ],
    view: new ol.View({
        center: [0, 0],
        zoom: 2
    })
});
```
#### 5.4.2 加载并显示Bing地图
**无法加载成功**
```js
var styles = [//图层样式
        'Road',
        'RoadOnDemand',
        'Aerial',
        'AerialWithLabels',
        'collinsBart',
        'ordnanceSurvey'
        ];
        //初始化bing地图
        var bingMapLayer = new ol.layer.Tile({
            visible: false,
            preload: Infinity,
            source: new ol.source.BingMaps({
                key: 'Au9w9yukrcuvxu7bwokloyxynr - Krlxffqcnlxdel - 0w1iwldtr - gun08zoavfbm',
                //图层样式
                imagerySet: 'aerial'
            })
        });
        var map = new ol.Map({
            layers: [bingMapLayer],         
            loadTilesWhileInteracting: true,
            target: 'mapCon',
            view: new ol.View({
                center: [-6655.5402445057125, 6709968.258934638],
                zoom: 13
            })
        });
```
#### 5.4.3 加载百度地图 :put_litter_in_its_place:
```js
//参考坐标系
var projection = ol.proj.get("EPSG:3857");
//分辨率
var resolutions = [];
for (let i = 0; i < 19; i++) {
    resolutions[i] = Math.pow(2, 18 - i);
}
var tilegrid = new ol.tilegrid.TileGrid({
    origin: [0, 0],
    resolutions:resolutions
})
//连接百度地图的瓦片请求地址
var baidu_source = new ol.source.TileImage({
    projection: projection,
    tileGrid: tilegrid,
    tileUrlFunction: function (tileCoord, pixellRatio, proj) {
        if (!tileCoord) {
            return "";
        }
        var z = tileCoord[0];
        var x = tileCoord[1];
        var y = tileCoord[2];
        if (x < 0) {
            x = "M" + (-x);
        }
        if (y < 0) {
            y = "M" + (-y);
        }
        console.log("http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" + x + "&y=" + y + "&z=" + z + "&styles=pl&udt=20151021&scaler=1&p=1");
        return "http://online3.map.bdimg.com/onlinelabel/?qt=tile&x=" +
            x + "&y=" + y + "&z=" + z + "&styles=pl&udt=20151021&scaler=1&p=1";
    }
});
//百度地图
var baidu_layer = new ol.layer.Tile({
    source: baidu_source
});
var map = new ol.Map({
    target: 'mapCon',
    layers: [baidu_layer],
    view: new ol.View({
        center: [0, 0],
        zoom:2
    })
});
```
#### 5.4.4 加载高德地图 🗺️
```javascript
var gaodeMapLayer = new ol.layer.Tile({
    title: "高德地图",
    source: new ol.source.XYZ({
        url: 'http://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}',
        wrapX: false
    })
});
var map = new ol.Map({
    target: 'mapCon',
    layers: [gaodeMapLayer],
    view: new ol.View({
        center: [12958752, 4848452],
        projection: 'EPSG:3857',
        zoom: 8,
        minzoom: 1
    })
});
```
#### 5.4.5 加载Google地图 :dragon:
```javascript
var map = new ol.Map({
    target: 'mapCon',
    layers: [new ol.layer.Tile({
        title: '谷歌地图',
        source: new ol.source.XYZ({
            url: 'http://mt2.google.cn/vt/lyrs=m@167000000&hl=zh-CN&gl=cn&x={x}&y={y}&z={z}',
            wrapX:false
        })
    })
            ],
    view: new ol.View({
        center: [0, 0],
        zoom:3
    })
});
```
### 5.5 矢量瓦片 :milky_way:
  **矢量瓦片**是指不仅可以提供完整的样式设计灵活性,还能够快速渲染海量数据的矢量地图,本质是矢量地图,等效于在网页上绘制的栅格图片。
```js
//使用严格模式
'use strict';
var key = 'pk.eyJ1Ijoid29ya2luZ2RvZyIsImEiOiJjamQyZmszenczMHRoMzRuczVzaGthbGhnIn0.HTkYTE-R82N3azqscSyHkA';
var map = new ol.Map({
    target: 'mapCon',
    layers: [new ol.layer.VectorTile({
        declutter: true,
        source: new ol.source.VectorTile({
            attributions: '© 
Mapbox ' +
            '© 
' +
            'OpenStreetMap contributors',
            format: new ol.format.MVT(),
            url: 'http://a.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' +
            '{z}/{x}/{y}.mvt?access_token=' + key
        }),
        style:createMapboxStreetsV6Style(ol.style.Style,
                                         ol.style.Fill,ol.style.Stroke,ol.style.Icon,ol.style.Text)
    })
            ],
    view: new ol.View({
        center: [0, 0],
        zoom:2
    })
});
```
### 5.6 多源数据叠加 :star:
  在地图应用中,通常会根据应用的需求来叠加各种类型的数据,并针对叠加的数据进行操作与功能分析。ol5支持多源异构数据在同一个地图容器中叠加显示,数据叠加也是ol5的地图表现的实现机制。
`CSS样式表`
```css
body,html,div,ul,li,iframe,p,img{
    border:none;
    padding:0;
    margin:0;
}
#mapCon{
    width:100%;
    height:100%;
    position:absolute;
}
#container{
    float:left;
    position:absolute;
    width:250px;
    height:280px;
    left:50px;
    background-color:#4c4e5a;
    z-index:2000;
    top:10px;
    /*支持IE*/
    filter:alpha(opacity=50);
    /*支持火狐*/
    -moz-opacity:0.5;
    opacity:0.5;
    border-width:10px;
    border-radius:10px;
    border-color:#000 #000 #000 #000;
}
#layerTree{
    float:left;
    position:absolute;
    width:250px;
    height:280px;
    padding:10px;
    font-size:14px;
    font-family:"微软雅黑";
    color:#ffffff;
    left:50px;
    z-index:2001;
}
#layerTree ul li{
    margin:10px 15px;
    cursor:pointer;
}
```
`HTML`
```html
//引用
```
`JavaScript`
```js
 var map = new ol.Map({
     target: 'mapCon',
     layers: [
         new ol.layer.Tile({
             source:new ol.source.OSM()
         })
     ],
     view: new ol.View({
         center: [-10997148, 4569099],
         zoom:3
     })
 });
//加载GeoJSON矢量数据
var vectorSource = new ol.source.Vector({
    url: "../data/geojson/countries.geojson",
    format:new ol.format.GeoJSON()
});
var vectorLayer = new ol.layer.Vector({
    source: vectorSource
});
map.addLayer(vectorLayer);
//加载ArcGIS瓦片数据图层
var arcGISSource = new ol.source.TileArcGISRest({
    url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' + 'Specialty/ESRI_StateCityHighway_USA/MapServer'
});
var arcGISLayer = new ol.layer.Tile({
    source: arcGISSource,
    extent: [-13884991, 2870341, -7455066, 6338219]
});
map.addLayer(arcGISLayer);
//绑定图层显示样式控件
function bindInputs(layerid, layer) {
    //是否可见控件 图层id+ +图层可见性
    var visibilityInput = $(layerid + ' input.visible');
    //绑定change事件
    visibilityInput.on('change', function () {
        //设置图层可见性
        layer.setVisible(this.checked);
    });
    //更新可见控件状态
    visibilityInput.prop("checked", layer.getVisible());
    //遍历其他显示样式属性,依次绑定change事件
    $.each(['opacity', 'hue', 'saturation', 'contrast', 'brightness'],
           function (i, v) {//为了表示层级关系 父元素与子元素之间留有空格
        var input = $(layerid + ' input.' + v);
        input.on('input change', function () {
            layer.set(v, parseFloat(this.value));
        });
        input.val(String(layer.get(v)));
    });
}    
map.getLayers().forEach(function (layer,i) {
    bindInputs('#layer' + i, layer);
});
//设置样式面板
$('#layerTree li > span').click(function () {
    //切换图层样式面板的可见状态(显示与隐藏)
    // $(this).siblings('fieldset').toggle();
    $('#layerTree li > span').siblings('fieldset').hide();
    $(this).next().show();
}).siblings('fieldset').hide();//默认隐藏各图层显示样式面板
$("fieldset:eq(0)").show();
```
### 5.7 网格信息显示
  瓦片地图是基于金字塔策略裁剪后的图片集,因此瓦片地图由级数、行列数对应的单张图片按照网格划分组织而成。
```js
var TiandituSource = new ol.source.XYZ({
    url: 'http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key',
    wrapX:false
});
var TiandituLayer = new ol.layer.Tile({
    source: TiandituSource
});
var map = new ol.Map({
    target: 'mapCon',
    layers: [TiandituLayer,
             new ol.layer.Tile({
                 source: new ol.source.TileDebug({
                     projection: 'EPSG:3857',
                     tileGrid:TiandituSource.getTileGrid()
                 })
             }),
             //加载矢量注记图层
             new ol.layer.Tile({
                 title: '天地图矢量注记图层',
                 source: new ol.source.XYZ({
                     url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                     attributions: "天地图的属性描述",
                     crossOrigin: "anonymous",
                     wrapX: false
                 })
             })
            ],
    view: new ol.View({
        center: [12900000, 4900000],
        zoom:8
    })
});
```
### 5.8 地图打印 
  **OpenLayers5**渲染地图有两种模式,**Canvas WebGL** 方式,可以基于地图渲染容器对象来实现导出地图。
```js
//实例化Map对象加载地图
var map = new ol.Map({
    //地图容器div的ID
    target: 'mapCon',
    //地图容器中加载的图层
    layers: [
        //加载瓦片图层数据
        new ol.layer.Tile({
            title: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                attributions: "天地图的属性描述",
                crossOrigin: "anonymous",
                wrapX: false
            }),
            preload: Infinity
        }),
        new ol.layer.Tile({
            title: "天地图矢量图层注记",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                attributions: "天地图的属性描述",
                crossOrigin: "anonymous",
                wrapX: false
            }),
            preload: Infinity
        })
    ],
    //地图视图设置
    view: new ol.View({
        //地图初始中心点
        center: [12950000, 4860000],
        //地图初始显示级别
        zoom: 8,
        //最小级别
        minZoom: 6,
        //最大级别
        maxZoom: 19
    })
});
//导出图片功能项
var exportPNGElement = $('#btn_download').get(0);
if ('download' in exportPNGElement) {
    $('#btn_download').click(function () {
        map.once('postcompose', function (event) {
            //地图渲染容器
            var canvas = event.context.canvas;
            //导出图片
            exportPNGElement.href = canvas.toDataURL('image/png');
        },false);
        map.renderSync();
    });
} else {
    alert("浏览器不支持此导出地图图片功能!");
}
```
## 6.OpenLayers之图形绘制 :see_no_evil:
  图形绘制功能,是在地图容器中绘制图形,包括点、线、圆、矩形与多边形等,可通过鼠标交互绘制,也可以直接添加绘制好的图形。
### 6.1 图形交互绘制原理
  **图形绘制**的基础是空间坐标,任何图形都是由空间坐标组成的。一般有两种图形绘制方式:一种是空间坐标已知,通常根据已知的空间坐标信息直接添加图形,实现图形绘制功能;另一种是通过鼠标获取空间坐标,通过鼠标在地图上的操作来获取所需的空间范围信息,并以此空间坐标为基础来绘制图形。
  **交互式图形绘制的原理**:先初始化一个矢量地图对象并添加至地图容器中,然后加载交互式图形绘制控件【在实例化时设置绘制类型,如点、线、规则多边形、任意多边形、以及图形对应的特征参数】,最后通过交互式图形绘制控件在地图上绘制相应的几何图形,也可以通过交互式编辑控件来修改已经绘制好的几何图形。
:one: **ol.interaction.Draw** 交互式图形绘制控件
:two: **ol.interaction.Modify** 交互式编辑控件
:three: **ol.interaction.Select** 选择要素控件
> **Tips:** :clipboard:
>
> **JavaScript 中 == 和 ===的区别**
>
> `==` 操作符会将两边的值进行强制类型转换再比较是否相等,而`===` 操作符不会进行类型转换。`==` 操作符只要求比较两个值是否相等,而`===`操作符不仅要求值相等,而且要求类型相同。`!=`和`!==`的区别也是同理。
>
> ```js
> 66=='66';
> //true
> 66==='666';
> //false
> ```
>
> **参考资料**:[**融合xx**](https://www.jianshu.com/p/6ac1397e944c)
### 6.2 几何图形绘制
  基本图形包括点、线、圆、矩形、多边形等。
```js
//绘制类型对象
var typeSelect = $("#type").get(0);
//绘制对象
var draw;
var map = new ol.Map({
    target: 'mapCon',
    loadTilesWhileInteracting: true,
    layers: [
        //加载瓦片图层数据
        new ol.layer.Tile({
            title: '天地图影像图层',
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=申请key",
                crossOrigin: "anonymous",
                wrapX: false
            })
        }),
        //加载矢量注记图层
        new ol.layer.Tile({
            title: '天地图影像注记图层',
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=申请key",
                attributions: "天地图的属性描述",
                crossOrigin: "anonymous",
                wrapX: false
            })
        })
    ],
    //地图视图设置
    view: new ol.View({
        center: [2406849, 5850795],//地图初始中心点
        zoom: 3,//地图初始显示级别
        minZoom:2
    }),
    controls: ol.control.defaults().extend([
        new ol.control.MousePosition()
    ])
});
//实例化一个矢量图层Vector作为绘制层
var source = new ol.source.Vector({ wrapX: false });
var vector = new ol.layer.Vector({
    source: source,
    style: new ol.style.Style({
        fill: new ol.style.Fill({
            color:'rgba(255,255,255,0.2)'
        }),
        stroke: new ol.style.Stroke({
            color: '#ff0000',
            width:2
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color:'#ff0000'
            })
        })
    })
});
//绘制层加载至地图容器
map.addLayer(vector);
//根据类型进行交互绘制图形
function addInteraction() {
    //绘制类型
    var value = typeSelect.value;
    if (value !== "None") {
        if (source == null) {
            source = new ol.source.Vector({ wrapX: false });
            vector.setSource(source);
        }
        var geometryFunction, maxPoints;
        if (value === 'Square') {
            value = 'Circle';
            //正方形
            geometryFunction = ol.interaction.Draw.createRegularPolygon(4);
        } else if (value === 'Box') {
            value = 'LineString';
            maxPoints = 2;
            geometryFunction = function (coordinates, geometry) {
                var start = coordinates[0];
                var end = coordinates[1];
                if (!geometry) {
                    //多边形
                    geometry = new ol.geom.Polygon([
                        [start, [start[0], end[1]], end, [start[0], end[1]], start]
                    ]);
                }
                geometry.setCoordinates([
                    [start, [start[0], end[1]], end, [end[0], start[1]], start]
                ]);
                return geometry;
            };
        }
        //实例化绘制对象并添加至地图容器中
        draw = new ol.interaction.Draw({
            source: source,
            type: value,
            //几何信息变更时调用函数
            geometryFunction: geometryFunction,
            //最大点数
            maxPoints: maxPoints
        });
        map.addInteraction(draw);
    }
    else {
        source = null;
        //清空绘制图形
        vector.setSource(source);
    }
}
$('#type').change(function (e) {
    //移除当前绘制图形样式
    map.removeInteraction(draw);
    addInteraction();
});    
addInteraction();
```
### 6.3 图形样式编辑
  几何图形,点、线、多边形都有对应的样式,如线型、线颜色、线宽、线透明度、填充颜色等。几何图形样式由**ol.style.Style**类设置
|  OpenLayers类   |        负责功能        |
| :-------------: | :--------------------: |
| ol.style.Circle |    设置点或圆的样式    |
| ol.style.Stroke |    设置边界线的样式    |
|  ol.style.Fill  | 设置区域图形的填充样式 |
|  ol.style.Text  |      设置文字样式      |
`JavaScript`
```javascript
var vectorPoints, vectorLines, vectorPolygons;
var pointFeature, lineFeature, polygonFeature;
var myDom;
function init() {
    //绘制的几何图形要素
    pointFeature = new ol.Feature({
        geometry: new ol.geom.Point([102.755087, 37.899853]),
        name: 'Point Feature'
    });
    lineFeature = new ol.Feature({
        geometry: new ol.geom.LineString([[102.755087, 37.899853], [102.636798, 37.918519]]),
        name: 'Line Feature'
    });
    polygonFeature = new ol.Feature({
        geometry: new ol.geom.Polygon([[[102.634224, 37.912114], [102.636794, 37.90847], [102.628026, 37.906918], [102.620965, 37.910961], [102.619959, 37.917864]]]),
        name: 'Polygon Feature'
    });
    let divlayerPoint = $('#layer0 input,#layer0 select');
    let divlayerPolyLine = $('#layer1 input,#layer1 select');
    let divlayerPolygon = $('#layer2 input,#layer2 select');
    //点、线、区样式对象
    myDom = {
        points: {
            align: divlayerPoint.get(5),
            baseline: divlayerPoint.get(6),
            rotation: divlayerPoint.get(7),
            font: divlayerPoint.get(8),
            weight: divlayerPoint.get(9),
            size: divlayerPoint.get(10),
            offsetX: divlayerPoint.get(11),
            offsetY: divlayerPoint.get(12),
            color: divlayerPoint.get(13),
            outlineColor: divlayerPoint.get(14),
            outlineWidth: divlayerPoint.get(15)
        },
        lines: {
            align: divlayerPolyLine.get(3),
            baseline: divlayerPolyLine.get(4),
            rotation: divlayerPolyLine.get(5),
            font: divlayerPolyLine.get(6),
            weight: divlayerPolyLine.get(7),
            size: divlayerPolyLine.get(8),
            offsetX: divlayerPolyLine.get(9),
            offsetY: divlayerPolyLine.get(10),
            color: divlayerPolyLine.get(11),
            outlineColor: divlayerPolyLine.get(12),
            outlineWidth: divlayerPolyLine.get(13)
        },
        polygons: {
            align: divlayerPolygon.get(4),
            baseline: divlayerPolygon.get(5),
            rotation: divlayerPolygon.get(6),
            font: divlayerPolygon.get(7),
            weight: divlayerPolygon.get(8),
            size: divlayerPolygon.get(9),
            offsetX: divlayerPolygon.get(10),
            offsetY: divlayerPolygon.get(11),
            color: divlayerPolygon.get(12),
            outlineColor: divlayerPolygon.get(13),
            outlineWidth: divlayerPolygon.get(14)
        }
    };
    //分别实例化点、线、区图层对象
    vectorPoints = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [pointFeature]
        }),
        style: createPointStyleFunction()
    });
    vectorLines = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [lineFeature]
        }),
        style: createLineStyleFunction()
    });
    vectorPolygons = new ol.layer.Vector({
        source: new ol.source.Vector({
            features: [polygonFeature]
        }),
        style: createPolygonStyleFunction()
    });
    //实例化Map对象加载地图,底图加载MapQuest地图,叠加图层为几何图形要素
    var map = new ol.Map({
        layers: [
            new ol.layer.Tile({
                title: "天地图矢量图层",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                    wrapX: false
                })
            }),
            new ol.layer.Tile({
                title: "天地图矢量图层注记",
                source: new ol.source.XYZ({
                    url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                    attributions: "天地图的属性描述",
                    wrapX: false
                }),
                preload: Infinity
            }),
            vectorPoints,
            vectorLines,
            vectorPolygons
        ],
        //地图容器div的ID
        target: 'mapCon',
        view: new ol.View({
            //地图初始中心点
            center: [102.675573, 37.913],
            projection: "EPSG:4326",
            minZoom: 2,
            zoom: 12
        })
    });
    //点、线、区的更新按钮处理函数
    $('#refresh-points').click(function () {
        vectorPoints.setStyle(createPointStyleFunction(pointFeature));
    });
    $('#refresh-lines').click(function () {
        vectorLines.setStyle(createLineStyleFunction(lineFeature));
    });
    $('#refresh-polygons').click(function () {
        vectorPolygons.setStyle(createPolygonStyleFunction(polygonFeature));
    });
}
var createTextStyle = function (feature, dom) {
    //读取当前面板设置的样式值
    //文本位置
    var align = dom.align.value;
    //基准线
    var baseline = dom.baseline.value;
    //字体大小
    var size = dom.size.value;
    //偏移量X
    var offsetX = parseInt(dom.offsetX.value, 10);
    //偏移量Y
    var offsetY = parseInt(dom.offsetY.value, 10);
    //字体粗细
    var weight = dom.weight.value;
    //角度
    var rotation = parseFloat(dom.rotation.value);
    //字体样式(粗细、大小、字体)
    var font = weight + ' ' + size + ' ' + dom.font.value;
    //字体颜色
    var fillColor = dom.color.value;
    //外框颜色
    var outlineColor = dom.outlineColor.value;
    //外框密度
    var outlineWidth = parseInt(dom.outlineWidth.value, 10);
    //返回实例化的文本样式对象
    return new ol.style.Text({
        //位置
        textAlign: align,
        //基准线
        textBaseline: baseline,
        //文字样式
        font: font,
        //文本内容
        text: feature.get('name'),
        //文本填充样式(即文字颜色)
        fill: new ol.style.Fill({ color: fillColor }),
        //文本外框样式(颜色与宽度)
        stroke: new ol.style.Stroke({ color: outlineColor, width: outlineWidth }),
        //偏移量X
        offsetX: offsetX,
        //偏移量Y
        offsetY: offsetY,
        //角度
        rotation: rotation
    });
};
//创建点要素样式
var createPointStyleFunction = function () {
    var radius = $('#points-size').get(0).value;
    var fillColor = $('#points-fill-color').get(0).value;
    var strokeColor = $('#points-stroke-color').get(0).value;
    var strokeWidth = $('#points-stroke-width').get(0).value;
    return function (feature, resolution) {
        var style = new ol.style.Style({
            image: new ol.style.Circle({
                radius: radius,
                fill: new ol.style.Fill({ color: fillColor }),
                stroke: new ol.style.Stroke({ color: strokeColor, width: strokeWidth })
            }),
            text: createTextStyle(feature, myDom.points)
        });
        return [style];
    };
};
//创建线要素
var createLineStyleFunction = function () {
    var strokeColor = $('#lines-stroke-color').get(0).value;
    var strokeWidth = $('#lines-stroke-width').get(0).value;
    return function (feature, resolution) {
        var style = new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: strokeColor,
                width: strokeWidth
            }),
            text: createTextStyle(feature, myDom.lines)
        });
        return [style];
    };
};
//创建多边形要素
var createPolygonStyleFunction = function () {
    var fillColor = $('#polygons-fill-color').get(0).value;
    var strokeColor = $('#polygons-stroke-color').get(0).value;
    var strokeWidth = $('#polygons-stroke-width').get(0).value;
    return function (feature, resolution) {
        var style = new ol.style.Style({
            stroke: new ol.style.Stroke({
                color: strokeColor,
                width: strokeWidth
            }),
            fill: new ol.style.Fill({
                color: fillColor
            }),
            text: createTextStyle(feature, myDom.polygons)
        });
        return [style];
    };
};
```
`HTML`
```html
```
### 6.4 图形交互编辑
  一个几何图形的要素包括几何、属性、图形等信息。修改图形的几何信息,通过鼠标交互方式实现。
```javascript
//实例化Map对象加载地图,默认底图加载MapQuest地图
var map = new ol.Map({
    layers: [
        new ol.layer.Tile({
            title: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        }),
        new ol.layer.Tile({
            title: "天地图矢量图层注记",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            }),
            preload: Infinity
        })
    ],
    target: 'mapCon',
    view: new ol.View({
        center: [114.2905, 30.5607],
        projection: "EPSG:4326",
        minZoom: 2,
        zoom: 12
    })
});
//绘制几何图形要素
var pointFeature = new ol.Feature(new ol.geom.Point([114.1947, 30.5255]));
var lineFeature = new ol.Feature(
    new ol.geom.LineString([[114.2218, 30.5695], [114.2829, 30.4912]]));
var polygonFeature = new ol.Feature(
    new ol.geom.Polygon([[[114.2757, 30.5822], [114.3526, 30.5879],
                          [114.3608, 30.5367], [114.3234, 30.5187], [114.2826, 30.5530]]]));
//实例化一个实例图层Vector作为绘制层
var source = new ol.source.Vector({
    features: [pointFeature, lineFeature, polygonFeature]
});
var vector = new ol.layer.Vector({
    source: source,
    style: new ol.style.Style({
        fill: new ol.style.Fill({
            color: 'rgba(255, 255, 255, 0.2)'
        }),
        stroke: new ol.style.Stroke({
            color: '#ff0000',
            width: 2
        }),
        image: new ol.style.Circle({
            radius: 7,
            fill: new ol.style.Fill({
                color: '#ff0000'
            })
        })
    })
});
map.addLayer(vector);
//定义修改几何图形功能控件
var Modify = {
    init: function () {
        //初始化交互选择控件
        this.select = new ol.interaction.Select();
        map.addInteraction(this.select);
        //初始化交互编辑控件
        this.modify = new ol.interaction.Modify({
            features: this.select.getFeatures()
        });
        map.addInteraction(this.modify);
        //设置几何图形处理
        this.setEvents();
    },
    setEvents: function () {
        var selectedFeatures = this.select.getFeatures();
        //添加选中要素变更事件
        this.select.on('change:active', function () {
            selectedFeatures.forEach(selectedFeatures.remove, selectedFeatures);
        });
    },
    setActive: function (active) {
        //激活选择要素控件
        this.select.setActive(active);
        //激活修改要素控件
        this.modify.setActive(active);
    }
};
//初始化几何图形修改控件
Modify.init();
//激活几何图形修改控件
Modify.setActive(true);
```
## 7. OpenLayers之OGC服务
  开放地理信息系统协会(**Open GIS Consortium**)致力于采用最新的技术和商业方式提高地理信息处理的互操作性(**Interopetability**)。
  **OGC**制定统一的规范,使得应用该规范的系统在Web中对数据进行统一且透明的访问。【**互操作性**、**开放性**、**可移植性**、**兼容性**】
|  规范  |                           规范说明                           |
| :----: | :----------------------------------------------------------: |
| `WMS`  | Web地图服务,利用具有地理空间位置信息的数据制作地图,返回的是图层级的地图影像。数据形式矢量栅格都有。WMS支持HTTP协议,所支持的操作是由URL决定的 |
| `WFS`  | Web要素服务,返回的是矢量级的GML编码,并提供对矢量的增加、修改、删除等事务操作,是对Web地图服务的进一步深入。WFS通过OGC Filter构造查询条件,支持基于空间几何关系的查询,基于属性域的查询,当然还包括基于空间关系和属性域的共同查询。 |
| `WCS`  |     Web影像服务,面向空间影像数据,将这些数据在网上发布      |
| `WMTS` | 瓦片地图Web服务,WMTS标准定义了一些操作,这些操作允许用户访问瓦片地图。WMTS可能是OGC首个支持RESTful访问的服务标准。WMTS提供了一种采用预定义图块方法发布数字地图服务的标准化解决方案。WMTS弥补了WMS不能提供分块地图的不足。 |
| `TMS`  | 切片地图服务(Tile Map Service), 定义了一些操作,这些操作允许用户按需访问切片地图,访问速度更快,还支持修改坐标系。 |
| `WPS`  | Web处理服务,用于解决空间信息互操作的空间分析等问题。Processing即ArcView中的GeoProcessing,诸如Union,Intersect等方法。WPS要做的就是暴露基于URL接口来实现客户端通过WebService对此类方法的调用、并返回数据。 |
| `CSW`  |           目录服务,支持地理空间数据集的发布和搜索           |
**上述介绍来自于** [常见OGC服务小结 - 程序员大本营 (pianshen.com)](https://www.pianshen.com/article/51281804843/)
### 7.1 OGC规范的加载原理
Ⅰ. **WMTS**: Web瓦片地图服务,WMTS的GetTile接口返回单张瓦片地图,其他调用方式与其他类型的瓦片地图相同.**ol.layer.Tile + ol.source.WMTS**
Ⅱ . **WMS**:  即Web地图服务,WMS的GetMap接口返回指定范围内的地图.**ol.layer.Image+ol.source.ImageWMS**  
**ol.layer.Tile+ol.source.TileWMS**
Ⅲ .  **WFS**: 即Web要素服务,WFS的GetFeature接口返回GML格式的矢量地图,
**ol.layer.Vector+ol.souce.Vctor** 的方式加载。
### 7.2 OGC规范数据显示
### 7.2.1 加载WMTS
```js
//WMTS图层数据
var wmtsLayer;
//通过范围计算分辨率数组
var projection = ol.proj.get('EPSG:4326');
var projectionExtent = projection.getExtent();
var size = ol.extent.getWidth(projectionExtent) / 256;
var resolutions = new Array(19);
var matrixIds = new Array(19);
for (let z = 0; z < 19; z++) {
    //生成WMTS分辨率和matrixIds数组
    resolutions[z] = size / Math.pow(2, z);
    matrixIds[z] = z;
}
//实例化WMTS服务图层对象
wmtsLayer = new ol.layer.Tile({
    opacity: 1,
    source: new ol.source.WMTS({
        // 数据源信息
        attributions: 'Tiles © 
天地图矢量注记',
        //WMTS服务基地址
        url: 'http://t0.tianditu.gov.cn/cva_c/wmts?LAYER=cva&tk=申请key',
        //投影坐标系设置矩阵
        matrixSet: 'c',
        //图片格式
        format: 'tiles',
        //数据的投影坐标系
        projection: projection,
        //瓦片网格对象
        tileGrid: new ol.tilegrid.WMTS({
            //原点
            origin: ol.extent.getTopLeft(projectionExtent),
            //分辨率数组
            resolutions: resolutions,
            //矩阵识别列表
            matrixIds:matrixIds
        }),
        style: 'default',
        wrapX:true
    })
});
//实例化Map对象加载地图,默认底图加载天地图
var map = new ol.Map({
    target: 'mapCon',
    layers: [
        new ol.layer.Tile({
            title: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        })
    ],        
    view: new ol.View({
        center: [0, 0],
        minZoom: 2,
        projection: "EPSG:4326",
        zoom: 3
    })
});
//通过复选框控制加载和移除WMTS服务图层数据
$("input[name='maps']")[0].onclick = function () {
    if ($("input[name='maps']")[0].checked) {
        map.addLayer(wmtsLayer);
    } else {
        map.removeLayer(wmtsLayer);
    }
};
```
### 7.2.2 加载WMS
```js
```
### 7.2.3 加载WFS
```js
```