2 Star 4 Fork 1

MrWhitebare / LearnWebGIS

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
贡献代码
同步代码
取消
提示: 由于 Git 不支持空文件夾,创建文件夹后会生成空的 .keep 文件
Loading...
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协议等部分。

B/S架构

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

Web应用的多层架构

2.1.2 客户端技术

  Web前端开发技术包括网页开发技术、客户端交互技术等。HTML CSS JavaScript

2.1.3 服务器端技术

  Web服务器端开发技术分为两大派系:.NETJava。前者是微软提供的框架,可以使用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服务器上的软件系统,比如数据库。

JavaEE分层应用模型

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网页,在网页的<head>标签中引入ol.jsol.css

(3) 在HTML网页的<body>中新建一个<div>层作为地图容器,设置其ID为map,并通过CSS设置地图容器的样式。

//head中引入
<link href="../css/ol.css" rel="stylesheet" />
<script src="../libs/OL5/ol.js" type="text/javascript"></script>
<style type="text/css">
	#map{
            width:100%;
            height:100%;
            position:absolute;
        }
</style>
<div id="map"></div>
<script type="text/javascript">
    'use strict';
    var map = new ol.Map({
        target: 'map',
        loadTilesWhileInteracting: true,
            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",
                        crossOrigin: "anonymous",
                        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: "天地图的属性描述",
                        crossOrigin: "anonymous",
                        wrapX:false
                    })
                })
            ],
            //地图视图设置
            view: new ol.View({
                center: [0, 0],//地图初始中心点
                zoom:3//地图初始显示级别
            })
        })
</script>

Ⅰ. ol.Map:地图容器类,OpenLayers5的核心部件,用于显示地图,可以加载各种类型的图层,地图控件(如比例尺、缩放、鹰眼等),以及与地图交互的功能控件等。通过实例化地图容器对象加载显示地图,主要是target、layers、view参数的设置。

Ⅱ. ol.layer.Tile :瓦片图层类,主要用于加载瓦片图层(根据显示级别对各级地图切片后的地图),实例化瓦片图层对象,绑定其数据源(source)以加载瓦片图层。

Ⅲ. ol.source.XYZ:使用了定义在url模板中方的一套XYZ格式的url地址的瓦片数据类,默认情况下,遵循Google网格。自定义网格,则在url模板中使用{x},{y},{z}占位符。

Ⅳ. ol.View:地图视图类,主要控制地图与人的交互,如进行缩放、调节分辨率、控制地图旋转。

//通过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 基本操作控件

  地图基本操作是指用户与地图的简单交互,主要包括地图放大、缩小、移动、复位和更新。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>地图基本操作功能</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
    <link href="../css/style.css" rel="stylesheet" />
    <style type="text/css">
        #mapCon {
            width: 100%;
            height: 90%;
            position: absolute;
        }

        #menu {
            float: left;
            position: absolute;
            bottom: 10px;
            z-index: 2000;
        }

        .tooltip-inner {
            white-space: nowrap;
        }
    </style>
</head>
<body>
    <div class="ToolLib">
        <input type="button" class="ButtonLib" id="zoom-out" value="单击缩小" />
        <input type="button" class="ButtonLib" id="zoom-in" value="单击放大" />
        <input type="button" class="ButtonLib" id="panto" value="平移到【中国】" />
        <input type="button" class="ButtonLib" id="restore" value="复位" />
    </div>
    <div id="mapCon" title="地图显示" style="padding:5px"></div>
    <script type="text/javascript">
        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
                    })
                }),
                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
                    })
                })
            ],
            //地图视图设置
            view: new ol.View({
                center: [0, 0],
                zoom: 2,
                minZoom: 1,//缩小最小级别
                maxZoom: 12,//缩小最大级别
                rotation:Math.PI/6
            })
        });
        //地图视图的初始参数
        var view = map.getView();
        var zoom = view.getZoom();
        var center = view.getCenter();
        var rotation = view.getRotation();
        //单击缩小 按照id查询使用# class查询使用 .
        $('#zoom-out').click(() =>{
            var view = map.getView();
            var zoom = view.getZoom();//获取当前缩放级数
            view.setZoom(zoom - 1);
        });
        //单击放大
        $('#zoom-in').click(()=>{
            var view=map.getView();
            var zoom=view.getZoom();
            view.setZoom(zoom+1);
        });
        //平移功能 (平移至中国地图部分)
        $('#panto').click(()=>{
            var view=map.getView();
            var where=ol.proj.fromLonLat([105,35]);//平移地图
            view.setCenter(where);
            view.setZoom(5);
        });
        //复位功能
        $('#restore').click(()=>{
            view.setCenter(center);//初始中心点
        view.setRotation(rotation);//初始旋转角度
        view.setZoom(zoom);//初始缩放级数
        });
        //为内置的缩放控件与旋转控件添加tooltip提示信息
        $('.ol-zoom-in, .ol-zoom-out').css(" placement: 'right'");
        //tooltip在左侧显示
        $('.ol-rotate-reset, .ol-attribution button[title]').css("placement: 'left'");
    </script>
</body>
</html>

4.2.3 图层控件:two_hearts:

  实际应用中,将地图容器中加载的图层以列表形式显示,便于查看与操作。

功能实现

:one: 首先创建Map对象分别加载天地图矢量图层,矢量​图层标注、天地图影像图层、影像图层标注;

:two: 其次,新建一个方法loadLayersControl(map,id) 在其中获取每个图层的​Name、可见属性、序号,然后动态添加为li元素,li元素由Checkboxlabel组成;最后给每个Checkbox 添加事件,给label赋值。​

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>加载图层控件(自定义)</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <style type="text/css">
        body,html,div,ul,li,iframe,p,img{
            border:none;
            padding:0;
            margin:0;
            font-size:14px;
            font-family:"微软雅黑";
        }
        #mapCon{
            width:100%;
            height:95%;
            position:absolute;
        }
        /* 图层控件样式设置*/
        .layerControl{
            position:absolute;
            bottom:5px;
            min-width:200px;
            max-height:200px;
            right:0px;
            top:5px;
            /* 在地图容器中的层,要设置z-index的值让其显示在地图上层*/
            z-index:2001;
            color:#ffffff;
            background-color:#4c4e5a;
            /*边缘的宽度*/
            border-width:10px;
            /*圆角大小*/
            border-radius:10px;
            /*边框颜色*/
            border-color:#000 #000 #000 #000;
        }
        .layerControl.title{
            font-weight:bold;
            font-size:15px;
            margin:10px;
        }
        .layerTree li{
            list-style:none;
            margin:5px 10px;
        }
        /* 鼠标位置控制层样式设置 */
        #mouse-position{
            float:left;
            position:absolute;
            bottom:5px;
            width:330px;
            height:20px;
            /*在地图容器中的层,要设置z-index的值让其显示在地图上层*/
            z-index:2000;
        }
    </style>
</head>
<body>
    <div id="mapCon">
        <div id="mouse-position"></div>
        <div id="layerControl" class="layerControl">
            <div class="title"><label>图层列表</label></div>
            <ul id="layerTree" class="layerTree"></ul>
        </div>
    </div>
    <script type="text/javascript">
        //map中图层数组
        var layer = new Array();
        //图层名称数组
        var layerName = new Array();
        //图层可见属性数组
        var layerVisibility = new Array();
        /*
        *加载图层列表数据
        *@param {ol.Map} map 地图对象
        *@param {string} id 图层列表容器ID
        */
        function loadLayersControl(map, id) {
            //图层目录容器
            var treeContent = document.getElementById(id);
            //获取地图中所有图层
            var layers = map.getLayers();
            for (var i = 0; i < layers.getLength() ; i++) {
                //获取每一个图层的名称、是否可见属性
                layer[i] = layers.item(i);
                layerName[i] = layer[i].get('name');
                layerVisibility[i] = layer[i].getVisible();
                //新增li元素,用来承载图层项
                var elementLi = document.createElement('li');
                //添加子节点
                treeContent.appendChild(elementLi);
                //创建复选框
                var elementInput = document.createElement('input');
                elementInput.type = "checkbox";
                elementInput.name = "layers";
                elementLi.appendChild(elementInput);
                //创建label元素
                var elementLabel = document.createElement('label');
                elementLabel.className = "layer";
                //设置图层名称
                setInnerText(elementLabel, layerName[i]);
                elementLi.appendChild(elementLabel);
                if (layerVisibility[i]) {
                    elementInput.checked = true;
                }
                //为checkbox添加变更时间
                addChangeEvent(elementInput, layer[i]);
            }
        }
        //为checkbox元素绑定变更事件
        function addChangeEvent(element,layer) {
            element.onclick = function () {
                if (element.checked) {
                    layer.setVisible(true);
                }
                else {
                    layer.setVisible(false);
                }
            }
        }
        //动态设置元素文本内容
        function setInnerText(element, text) {
            if (typeof element.textContent == "string") {
                element.textContent = text;
            } else {
                element.innerText = text;
            }
        }
        var TiandiMap_vec = new ol.layer.Tile({
            name: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        var TiandiMap_cva = new ol.layer.Tile({
            name: "天地图矢量注记图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        var TiandiMap_img = new ol.layer.Tile({
            name: "天地图影像图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        var TiandiMap_cia = new ol.layer.Tile({
            name: "天地图影像注记图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        //实例化Map对象加载地图
        var map = new ol.Map({
            //地图容器div的ID
            target: 'mapCon',
            layers: [TiandiMap_vec, TiandiMap_cva, TiandiMap_img, TiandiMap_cia],
            view: new ol.View({
                center: [0, 0],
                zoom:2
            }),
            controls: ol.control.defaults().extend([
                new ol.control.MousePosition({
                        target:document.getElementById('mouse-position')
                    })
            ])
        });
        //加载图层列表数据
        loadLayersControl(map, "layerTree");
    </script>
</body>
</html>

4.2.4 比例尺控件 :cupid:

  地图比例尺用于表示图上距离比实际距离缩小(或者放大)的程度,表示地图图形的缩小程度,又称为缩尺。比例尺控件:ol.control.ScaleLine

<script type="text/javascript">
	var scaleLineControl = new ol.control.ScaleLine({
		//设置比例尺单位,degrees、imperial、us、nautical、metric(度量单位)
		units: "metric"
	});
	//实例化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({
			//地图初始中心点
			center: [0, 0],
			//地图初始显示级别
			zoom: 2
		}),
		//加载控件到地图容器中
		//加载比例尺控件
		controls: ol.control.defaults().extend([scaleLineControl])
	});
</script>

4.2.5 鹰眼控件 :sparkling_heart:

  地图鹰眼可以称为鸟瞰图或者缩略图。在地图中,通过鹰眼可以知道地图的当前位置;也可以在鹰眼上点击、拖动或者移动到想要查看的位置。鹰眼的可视范围可以是地图全局,鹰眼中心框的可视范围就是主图的可视范围,主图的地理信息要比鹰眼控件详细,鹰眼可视范围更加广阔。鹰眼控件:ol.control.OverviewMap

鹰眼视图

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
   <title>加载鹰眼控件</title>
   <link href="../css/ol.css" rel="stylesheet" />
   <script src="../libs/OL5/ol.js" type="text/javascript"></script>
   <style type="text/css">
       #mapCon{
           width:100%;
           height:95%;
           position:absolute;
       }
       /*自定义鹰眼样式*/
       .ol-custom-overviewmap, .ol-custom-overviewmap.ol-uncollapsible {
           bottom: auto;
           left: auto;
           right: 0; /*右侧显示*/
           top: 0; /*顶部显示*/
       }
       /*在鹰眼控件展开时控件外框样式*/
       .ol-custom-overviewmap:not(.ol-collapsed) {
            border: 1px solid black;
       }
       /*在鹰眼控件中地图容器样式*/
       .ol-custom-overviewmap .ol-overviewmap-map {
               border: none;
               width: 300px;
        }
       /*在鹰眼控件中显示当前窗口中主图区域的边框*/
        .ol-custom-overviewmap .ol-overviewmap-box {
             border: 2px solid red;
        }
       /*在鹰眼控件中展开时其按钮图标的样式*/
       .ol-custom-overviewmap:not(.ol-collapsed) button{
           bottom:auto;
           left:auto;
           right:1px;
           top:1px;
       }
   </style>
</head>
<body>
   <div id="mapCon"></div>
   <script type="text/javascript">
       var overviewMapControl = new ol.control.OverviewMap({
           className: 'ol-overviewmap ol-custom-overviewmap',
           //鹰眼中加载图层
           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',
                       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',
                       wrapX: false
                   })
               })
           ],
           collapseLabel: '\u00BB',//鹰眼控件展开时功能按钮的标识
           label: '\u00AB',//折叠时的标识
           collapsed: false,
       });
       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',
                       attributions: "天地图的属性描述",
                       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
                   })
               })
           ],
           view: new ol.View({
               center: [0, 0],
               zoom: 6
           }),
           controls: ol.control.defaults().extend([overviewMapControl])
       });
   </script>
</body>
</html>

4.2.6 图层探查控件 :broken_heart:

  当有多个图层叠加显示时,上层图层会遮盖下层图层。图层探查控件可以方便地查看下层图层数据,可用于辅助功能操作或分析。图层探查原理是在客户端上裁剪上层图层,将上层图层裁剪一部分,让下层图层数据变得可见。

Demo设计思路

Ⅰ. 为地图视图添加鼠标的mousemove和mouseout事件监听,通过调用Map类中的getEventPixel方法获取当前鼠标焦点坐标点;

Ⅱ . 图层画布剪裁:为矢量图层(上层图层)添加precompose事件监听 ,在影像图层渲染前进行裁剪,就是以鼠标焦点为圆心,以radius为半径,在图层画布设置一个圆,通过clip()裁剪图层画布,将画布裁剪为一个圆的形状;同时,为影像图层(下层图层)添加postcompose事件监听,在矢量图层渲染后还原图层画布的背景,即通过restore()还原。

Ⅲ . 裁剪圆半径的设置:为document添加keydown事件监听,通过Ctrl+Z控制缩小;通过Ctrl+L控制放大圆。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>图层探查控件</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
    <style type="text/css">
        #map {
            width: 100%;
            height: 100%;
            position: absolute;
        }
    </style>
</head>
<body>
    <div id="map" style="width:100%;height:95%;position:absolute;"></div>
    <script type="text/javascript">
        var TiandiMap_vec = new ol.layer.Tile({
            name: "天地图矢量图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        var TiandiMap_cva = new ol.layer.Tile({
            name: "天地图矢量注记图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=cva_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        var TiandiMap_img = new ol.layer.Tile({
            name: "天地图影像图层",
            source: new ol.source.XYZ({
                url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=申请key",
                wrapX: false
            })
        });
        //地图容器放置位置
        var container = $('#map');       
        var map = new ol.Map({
            layers: [TiandiMap_img,TiandiMap_cva, TiandiMap_vec],
            target: container.get(0),
            view: new ol.View({
                center: ol.proj.fromLonLat([-109, 46.5]),
                zoom:6
            })
        });
        //探查半径
        var radius = 75;
        //添加按下键盘事件监听,控制探查范围大小 
        //必须绑定至document
        $(document).bind('keydown',(event)=> {
            var keyCode=event.keyCode||event.which||event.charCode;
            var ctrlKey=event.ctrlKey||event.metaKey;        
            if (ctrlKey&&keyCode == 76) {//按键Ctrl+L
                radius = Math.min(radius + 5, 150);
                map.render();
                event.preventDefault();
            }//按键Ctrl+Z
            else if (ctrlKey&&keyCode == 90) {
                radius = Math.max(radius - 5, 25);
                map.render();
                event.preventDefault();              
            }
        });
      
        //实时得到鼠标焦点位置
        var mousePosition = null;
        container.bind('mousemove', function (event) {
            mousePosition = map.getEventPixel(event);
            map.render();//重新渲染
        });
        container.bind('mouseout', function () {
            mousePosition = null;
            map.render();
        });
        
        //渲染之前进行裁切
        TiandiMap_vec.on('precompose',(event)=> {
            var ctx = event.context;//矢量图层画布
            var pixelRatio = event.frameState.pixelRatio;
            ctx.save();
            ctx.beginPath();
            if (mousePosition) {
                //只显示一个以鼠标焦点为中心的画圈
                ctx.arc(mousePosition[0] * pixelRatio, mousePosition[1] * pixelRatio, radius * pixelRatio, 0, 2 * Math.PI);
                ctx.lineWidth = 5 * pixelRatio;//圆边框的宽
                ctx.strokeStyle = 'rgba(0,0,0,0.5)';
                ctx.stroke();
            }
            ctx.clip();//裁剪画布
        });
        //呈现上层图层后,恢复画布背景
        TiandiMap_vec.on('postcompose',(event)=>{
            var ctx = event.context;
            ctx.restore();
        });
    </script>
</body>
</html>

Ctrl+Z控制缩小;通过Ctrl+L控制放大

图层探查控件

,,ԾㅂԾ,,参考资料

键盘按键keyCode大全js页面快捷键

JS监听组合按键

JQuery绑定事件4种方式

4.2.7 动画效果控件 :heartpulse:

  动画效果控件,可增强地图操作的动态效果。ol5的动画效果在ol.View中的animate方法设置,可以传递一个或者多个对象实现旋转、弹性移动,反弹等;

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>动画效果控件</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
    <link href="../css/style.css" rel="stylesheet" />
</head>
<body>
    <div class="ToolLib">
        <button class="ButtonLib" id="spin">旋转定位到石家庄</button>
        <button class="ButtonLib" id="elastic">弹性定位到北京</button>
        <button class="ButtonLib" id="bounce">反弹定位到武威</button>
        <button class="ButtonLib" id="rotate">围绕兰州旋转</button>
        <button class="ButtonLib" id="fly">飞行定位到上海</button>
    </div>
    <div id="map"></div>
    <script type="text/javascript">
        var view = new ol.View({
            center: [12950000, 4860000],
            zoom: 11
        });
        var map = new ol.Map({
            target: "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
                    })
                })
            ],
            //加载图层时开启动画效果
            loadTilesWhileAnimating: true,
            view:view
        });
        //定位点
        var shijiazhuang = ol.proj.fromLonLat([114.527749,38.003699]);
        var beijing = ol.proj.fromLonLat([116.404053,39.915101]);
        var wuwei = ol.proj.fromLonLat([102.754993,37.900134]);
        var lanzhou = ol.proj.fromLonLat([103.82348,36.069792]);
        var shanghai = ol.proj.fromLonLat([121.506379, 31.245414]);
        //获取反弹值
        function bounce(t) {
            var s = 7.5625, p = 2.75, l;
            if (t < (1 / p)) {
                l = s * t * t;
            } else {
                if (t < (2 / p)) {
                    t -= (1.5 / p);
                    l = s * t * t + 0.75;
                } else {
                    if (t < (2.5 / p)) {
                        t -= (2.25 / p);
                        l = s * t * t + 0.9375;
                    } else {
                        t -= (2.625 / p);
                        l = s * t * t + 0.984375;
                    }
                }
            }
            console.log("反弹值为:" + l);
            return l;
        }
        //获取弹性伸缩值
        function elastic(t) {
            return Math.pow(2, -10 * t) * Math.sin((t - 0.075) * (2 * Math.PI) / 0.3) + 1;
        }
        //旋转定位
        $("#spin").click(()=>{
            var center=view.getCenter();
            view.animate(
            //第一个过程
            {
                center:[
                    center[0]+(shijiazhuang[0]-shijiazhuang[0])/2,
                    center[1]+(shijiazhuang[1]-shijiazhuang[1])/2
                ],
                rotation:Math.PI,//动画结束时的旋转角度
                easing:ol.easing.easeIn//控制动画速度
            },
            //第二个过程
            {
                center:shijiazhuang,
                rotation:2*Math.PI,
                easing:ol.easing.easeOut
            });
        });

        //弹性定位效果
        $('#elastic').click(()=>{
            view.animate({
                center:beijing,
                duration:2000,
                easing:elastic
            });
        });
        
        //反弹定位效果
        $('#bounce').click(()=>{  
            view.animate({
                center:wuwei,
                duration:2000,
                easing:bounce
            });
        });

        //自旋转定位效果
        $('#rotate').click(()=>{
            var rotation = view.getRotation();
            view.setCenter(lanzhou);
            view.animate( 
            {
                rotation: rotation + Math.PI,//第一次动画旋转角度
                anchor: lanzhou,//自旋的中心点,即武汉
                easing: ol.easing.easeIn////按每一帧动画控制的动画速度,即开始缓慢并逐渐加快速度
            },
            {
                rotation: rotation + 2 * Math.PI,//动画结束时的旋转角度,即360度回正
                anchor: lanzhou,// 旋转中心点
                easing: ol.easing.easeOut///按每一帧动画控制的动画速度,即开始快速并逐渐减速
            });
        });

        //飞行定位效果
        $('#fly').click(()=>{
            var duration=2000;
            var zoom=view.getZoom();
            var parts=2;
            var called=false;
            //动画完成回调函数
            function callback(complete){
                --parts;
                if(called){
                    return;
                }
                if(parts==0||!complete){
                    called=true;
                    done(complete);
                }
            }
            view.animate({
                center:shanghai,
                duration:duration
            },callback);
            view.animate({
                zoom:zoom-1,
                duration:duration/2
            },{
                zoom:zoom,
                duration:duration/2
            },callback);
        });
    </script>
</body>
</html>

4.2.8 测量控件 :love_letter:

  测量功能包括距离(即长度)测量与面积测量。面积测量是指计算鼠标绘制范围的实际面积大小,距离测量则是值计算鼠标的线条实际长度。

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>加载测量控件</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.1.min.js"></script>
    <style type="text/css">
        #mapCon{
            width:100%;
            height:95%;
            position:absolute;
        }
        #menu{
            float:left;
            position:absolute;
            bottom:10px;
            left:10px;
            z-index:2000;
        }
        .checkbox{
            left:20px;
        }
        /*提示框样式信息*/
        .tooltip{
            position:relative;
            background:rgb(178, 0, 255);
            border-radius:4px;
            color:white;
            padding:4px 8px;
            opacity:0.7;
            white-space:nowrap;
        }
        .tooltip-measure{
            opacity:1;
            font-weight:bold;
        }
        .tooltip-static{
            background-color:#ff0033;
            color:black;
            border:1px solid white;
        }
        .tooltip-measure:before, .tooltip-static:before {
            border-top: 6px solid rgba(128, 128, 128,0.5);
            border-right: 6px solid transparent;
            border-left: 6px solid transparent;
            content:"";
            position:absolute;
            bottom:-6px;
            margin-left:-7px;
            left:50%;
        }
        .tooltip-static:before{
            border-top-color:rgb(255, 106, 0);
        }
    </style>
</head>
<body>
    <div id="mapCon">
        <div id="menu">
            <label>几何类型[Geometry type]&emsp;</label>
            <select id="type">
                <option value="length">计算长度</option>
                <option value="area">计算面积</option>
            </select>
            <label class="checkbox"><input type="checkbox" id="geodesic" />使用球面距离量测[use geodesic measures]</label>
        </div>
    </div>
    <script type="text/javascript">
        var map = new ol.Map({
            target: 'mapCon', //地图容器div的ID
            //地图容器中加载的图层
            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=d787e9cde2030ae9666878b58e09c194",
                        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=d787e9cde2030ae9666878b58e09c194",
                        wrapX: false
                    }),
                    preload: Infinity
                })
            ],
            //地图视图设置
            view: new ol.View({
                center: [0, 0], //地图初始中心点
                zoom: 4 //地图初始显示级别
            })
        });
        //加载测量的绘制矢量层
        var source = new ol.source.Vector();//图层数据源
        var vector = new ol.layer.Vector({
            source: source,
            style: new ol.style.Style({
                //图层样式
                fill: new ol.style.Fill({
                    color: '#ffcc33',
                    width:2
                }),
                stroke: new ol.style.Stroke({
                    color: '#ffcc33',  //边框颜色
                    width: 2   // 边框宽度
                }),
                image: new ol.style.Circle({
                    radius: 7,
                    fill: new ol.style.Fill({
                        color:'#ffcc33'
                    })
                })
            })
        });
        map.addLayer(vector);

        //var wgs84Sphere = new ol.sphere(6378137);
        //当前绘制的要素
        var sketch;
        //帮助提示框对象
        var helpTooltipElement;
        //帮助提示框显示信息
        var helpTooltip;
        //测量工具提示框对象
        var measureTooltipElement;
        //测量工具中显示测量值
        var measureTooltip;
        //当用户正在绘制线时的提示文本信息
        var continueLineMsg = '继续点击绘制一条线';//Click to continue drawing the polyline
        //当用户正在绘制多边形时的提示文本
        var continuePolygonMsg = '继续点击绘制一个多边形';//Click to continue drawing the polygon

        //鼠标移动事件
        var pointerMoveHandler = function (event) {
            if (event.dragging) {
                return;
            }
            var helpMsg = '单击开始绘制';//Click to start drawing
            //根据几何类型显示不同提示
            if (sketch) {
                var geom = (sketch.getGeometry());
                if (geom instanceof ol.geom.Polygon) {
                    helpMsg = continuePolygonMsg;
                } else if (geom instanceof ol.geom.LineString) {
                    helpMsg = continueLineMsg;
                }
            }
            helpTooltipElement.innerHTML = helpMsg;
            helpTooltip.setPosition(event.coordinate);

            $(helpTooltipElement).removeClass('hidden');//移除帮助提示框的隐藏样式进行显示
        }
        map.on('pointermove', pointerMoveHandler);//地图容器绑定鼠标移动事件,动态显示帮助提示框内容

        //地图绑定鼠标移出事件,鼠标移出时为帮助提示框设置隐藏样式
        $(map.getViewport()).on('mouseout', function () {
            $(helpTooltipElement).addClass('hidden');
        });
        var geodesicCheckbox = document.getElementById('geodesic');//测地学方式对象
        var typeSelect = document.getElementById('type');//测量类型对象
        /*var geodesicCheckbox = $('#geodesic').get(0);
        var typeSelect = $('type').get(0);*/
        var draw;
        //加载交互绘制控件函数
        function addInteraction() {
            var type = (typeSelect.value == 'area' ? 'Polygon' : 'LineString');
            draw = new ol.interaction.Draw({
                source: source,//测量绘制层数据源
                type: (type),
                style: new ol.style.Style({
                    fill: new ol.style.Fill({
                        color: 'rgba(255,255,255,0.2)'
                    }),
                    stroke: new ol.style.Stroke({
                        color: 'rgba(0,0,0,0.5)',
                        lineDash: [10, 10],
                        width: 2
                    }),
                    image: new ol.style.Circle({
                        radius: 5,
                        stroke: new ol.style.Stroke({
                            color: 'rgba(0, 0, 0, 0.7)'
                        }),
                        fill: new ol.style.Fill({
                            color: 'rgba(255, 255, 255, 0.2)'
                        })
                    })
                })
            });
            map.addInteraction(draw);

            createMeasureTooltip(); //创建测量工具提示框
            createHelpTooltip(); //创建帮助提示框

            var listener;
            //绑定交互绘制工具开始绘制事件
            draw.on('drawstart',
                function (event) {
                    sketch = event.feature;//绘制的要素

                    var tooltipCoord = event.coordinate;//绘制坐标
                    //绑定change事件,根据绘制几何类型得到测量长度值或面积值,并将其设置到测量工具提示框中显示
                    listener = sketch.getGeometry().on('change', function (event) {
                        var geom = event.target;//绘制几何要素
                        var output;
                        if (geom instanceof ol.geom.Polygon) {
                            output = formatArea((geom));//面积值
                            tooltipCoord = geom.getInteriorPoint().getCoordinates();//坐标
                        } else if (geom instanceof ol.geom.LineString) {
                            output = formatLength((geom));//长度
                            tooltipCoord = geom.getLastCoordinate();
                        }
                        measureTooltipElement.innerHTML = output;//将测量值设置到测量工具提示框中显示
                        measureTooltip.setPosition(tooltipCoord);//设置测量工具提示框的显示位置
                    });
                }, this);
            //绑定交互绘制工具结束的事件
            draw.on('drawend', function (event) {
                measureTooltipElement.className = 'tooltip tooltip-static';//设置提示框样式
                measureTooltip.setOffset([0, -7]);
                sketch = null;//置空当前绘制的要素对象
                measureTooltipElement = null;//置空测量工具提示框对象
                createMeasureTooltip();//重新创建一个测试工具提示框显示结果
                ol.Observable.unByKey(listener);
            },this);
        }
        //创建一个新的帮助提示框
        function createHelpTooltip() {
            if (helpTooltipElement) {
                helpTooltipElement.parentNode.removeChild(helpTooltipElement);
            }
            helpTooltipElement = document.createElement('div');
            helpTooltipElement.className = 'tooltip hidden';
            helpTooltip = new ol.Overlay({
                element: helpTooltipElement,
                offset: [15, 0],
                positioning: 'center-left'
            });
            map.addOverlay(helpTooltip);
        }

        //创建一个新的测量工具提示框(tooltip)
        function createMeasureTooltip() {
            if (measureTooltipElement) {
                measureTooltipElement.parentNode.removeChild(measureTooltipElement);
            }
            measureTooltipElement = document.createElement('div');
            measureTooltipElement.className = 'tooltip tooltip-measure';
            measureTooltip = new ol.Overlay({
                element: measureTooltipElement,
                offset: [0, -15],
                positioning: 'bottom-center'
            });
            map.addOverlay(measureTooltip);
        }
        //用户切换选择测量类型
        typeSelect.onchange = function (e) {
            map.removeInteraction(draw);//移除绘制图形
            addInteraction();//添加绘图进行测量
        }

        //测量长度输出
        var formatLength = function (line) {
            var length;
            if (geodesicCheckbox.checked) {//使用测地学方法
                var sourceProj = map.getView().getProjection();//地图数据投影坐标系
                length = ol.sphere.getLength(line, { "projection": sourceProj, "radius": 6378137 });
            } else {
                length = Math.round(line.getLength() * 100) / 100;//数学方法
            }
            console.log(line + '线的长度' + length);
            var output;
            if (length > 100) {
                output = (Math.round(length / 1000 * 100) / 100) + "  " + 'km';
            } else {
                output = (Math.round(length * 100) / 100) + '' + 'm';
            }
            return output;
        }

        //测量面积输出
        var formatArea = function (polygon) {
            var area;
            if (geodesicCheckbox.checked) {//若使用测地学方法测量
                var sourceProj = map.getView().getProjection();//地图数据源投影坐标系
                var geom = /** @type {ol.geom.Polygon} */(polygon.clone().transform(sourceProj, 'EPSG:4326')); //将多边形要素坐标系投影为EPSG:4326
                area = Math.abs(ol.sphere.getArea(geom, { "projection": sourceProj, "radius": 6378137 })); //获取面积
            } else {
                area = polygon.getArea();//直接获取多边形的面积
            }
            console.log(polygon + '多边形的面积' + area);
            var output;
            if (area > 10000) {
                output = (Math.round(area / 1000000 * 100) / 100) + ' ' + 'km<sup>2</sup>'; //换算成KM单位
            } else {
                output = (Math.round(area * 100) / 100) + ' ' + 'm<sup>2</sup>';//m为单位
            }
            return output; //返回多边形的面积
        }
        addInteraction();//调用加载绘制交互控件方法,添加绘图进行测量
    </script>
</body>
</html>

5.OpenLayers之多源数据展示 :earth_asia:

  大量的网络地图服务资源,Google地图、OpenStreetMapBing地图、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的瓦片地图

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>加载ArcGIS瓦片数据</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
    <style type="text/css">
        #mapCon{
            width:100%;
            height:95%;
            position:absolute;
        }
        /*鼠标位置控件层样式设置*/
        #mouse-position{
            float:left;
            position:absolute;
            bottom:5px;
            width:200px;
            height:20px;
            z-index:2000;
        }
        /*鼠标位置样式信息*/
        .custom-mouse-position{
            color:rgb(255, 0, 110);
            font-size:16px;
            font-family:"微软雅黑";
        }
    </style>
</head>
<body>
    <div id="mapCon">
        <div id="mouse-position"></div>
    </div>
    <script type="text/javascript">
        var mousePositionControl = new ol.control.MousePosition({
            //坐标格式
            coordinateFormat: ol.coordinate.createStringXY(4),
            //地图投影坐标系
            projection: 'EPSG:4326',
            //坐标信息样式
            className: 'custom-mouse-position',
            //显示鼠标位置信息的目标容器
            target: $('#mouse-position').get(0),
            //为定义坐标的标记
            undefinedHTML:'&nbsp;'
        });
        var map = new ol.Map({
            target: 'mapCon',
            layers: [],
            view: new ol.View({
                center: [-10997148, 4569099],
                zoom:5
            }),
            controls: ol.control.defaults({
            }).extend([mousePositionControl])
        });
        var arcGISSource = new ol.source.TileArcGISRest({
            url: 'http://sampleserver1.arcgisonline.com/ArcGIS/rest/services/' + 'Specialty/ESRI_StateCityHighway_USA/MapServer'
        });
        var arcGISLayers = new ol.layer.Tile({
            source: arcGISSource,
            extent: [-13884991, 2870341, -7455066, 6338219]
        });
        //添加瓦片地图图层
        map.addLayer(arcGISLayers);
    </script>
</body>
</html>

使用ol.layer.Tile+ol.source.TileArcGISRest实现ArcGIS ServerREST 瓦片地图服务的加载。

5.2.2 基于ArcGIS Server REST的矢量地图服务接口

由于ArcGIS该服务停止,无法显示效果
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>加载ArcGIS REST Feature Service</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
    <style type="text/css">
        #mapCon {
            width: 100%;
            height: 95%;
            position: absolute;
        }
        /*鼠标位置控件层样式设置*/
        #mouse-position {
            float: left;
            position: absolute;
            bottom: 5px;
            width: 200px;
            height: 20px;
            z-index: 2000;
        }
        /*鼠标位置样式信息*/
        .custom-mouse-position {
            color: rgb(255, 0, 110);
            font-size: 16px;
            font-family: "微软雅黑";
        }
    </style>
</head>
<body>
    <div id="mapCon">
        <div id="mouse-position"></div>
    </div>
    <script type="text/javascript">
        var mousePositionControl = new ol.control.MousePosition({
            //坐标格式
            coordinateFormat: ol.coordinate.createStringXY(4),
            //地图投影坐标系
            projection: 'EPSG:4326',
            //坐标信息样式
            className: 'custom-mouse-position',
            //显示鼠标位置信息的目标容器
            target: $('#mouse-position').get(0),
            //为定义坐标的标记
            undefinedHTML: '&nbsp;'
        });
        var map = new ol.Map({
            target: 'mapCon',
            layers: [],
            view: new ol.View({
                center: [-121.1, 47.5],
                zoom: 2
            }),
            controls: ol.control.defaults({
            }).extend([mousePositionControl])
        });
        var serviceUrl = 'http://services.arcgis.com/rOo16HdIMeOBI4Mb/arcgis/rest/' + 'services/PDX_Pedestrian_Districts/FeatureServer/';
        var layer = '0';
        //ESRI的JSON数据格式解析类
        var esrijsonFormat = new ol.format.EsriJSON();

        var arcGISSource = new ol.source.Vector({
            loader: function (extent, resolution, projection) {
                var url=serviceUrl+layer+'/query/?f=json&' +
                    'returnGeometry=true&spatialRel=esriSpatialRelIntersects&geometry=' +
                    encodeURIComponent('{"xmin":'+extent[0]+',"ymin":'+
                    extent[1]+',"xmax":'+extent[2]+',"ymax":'+extent[3]+
                    ',"spatialReference":{"wkid":102100}}') +
                    '&geometryType=esriGeometryEnvelope&inSR=102100&outFields=*' +
                    '&outSR=102100';
                console.log('网址' + url);
                $.ajax({
                    url: url, dataType: 'jsonp', success: function (response) {
                        if (response.error) {
                            //alert(response.error.message + '\n' + response.error.details.join('\n'));
                            console.log(response.error.message + '\n' + response.error.details.join('\n'));
                        } else {
                            var features = esrijsonFormat.readFeatures(response, {
                                featureProjection:projection
                            });
                            if (features.length > 0) {
                                arcGISSource.addFeatures(features);
                            }
                        }
                    }
                });
            },
            strategy: ol.loadingstrategy.tile(ol.tilegrid.createXYZ({
                tileSize:512
            }))
        });
        arcGISLayers = new ol.layer.Vector({
            source:arcGISSource
        });
        map.addLayer(arcGISLayers);
    </script>
</body>
</html>

5.2.3 基于ArcGIS Online的瓦片地图服务接口

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>加载ArcGIS影像数据</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
    <style type="text/css">
        #mapCon {
            width: 100%;
            height: 95%;
            position: absolute;
        }
        /*鼠标位置控件层样式设置*/
        #mouse-position {
            float: left;
            position: absolute;
            bottom: 5px;
            width: 200px;
            height: 20px;
            z-index: 2000;
        }
        /*鼠标位置样式信息*/
        .custom-mouse-position {
            color: rgb(255, 0, 110);
            font-size: 16px;
            font-family: "微软雅黑";
        }
    </style>
</head>
<body>
    <div id="mapCon">
        <div id="mouse-position"></div>
    </div>
    <script type="text/javascript">
        var mousePositionControl = new ol.control.MousePosition({
            //坐标格式
            coordinateFormat: ol.coordinate.createStringXY(4),
            //地图投影坐标系
            projection: 'EPSG:4326',
            //坐标信息样式
            className: 'custom-mouse-position',
            //显示鼠标位置信息的目标容器
            target: $('#mouse-position').get(0),
            //为定义坐标的标记
            undefinedHTML: '&nbsp;'
        });
        var map = new ol.Map({
            target: 'mapCon',
            layers: [],
            view: new ol.View({
                center: [-121.1, 47.5],
                zoom: 2
            }),
            controls: ol.control.defaults({
            }).extend([mousePositionControl])
        });
        arcGISLayers = new ol.layer.Tile({
            source: new ol.source.XYZ({
                url: 'http://server.arcgisonline.com/ArcGIS/rest/services/' + 'World_Topo_Map/MapServer/tile/{z}/{y}/{x}'
            })
        });
        map.addLayer(arcGISLayers);
    </script>
</body>
</html>

5.3 开放数据 🌐

Ⅰ. KML ——基于XML的谷歌地球的文件格式;

Ⅱ . GML——地理标记语言,可以表示地理空间对象的空间数据和非空间数据;

Ⅲ . GPX——GPX交换格式是基于XML的通用GPS数据格式,可以用来描述点、轨迹、路程;可以保存位置、海拔和时间

Ⅳ . GeoJSON——GeoJSON是一种对各种空间数据结构进行编码的格式,基于JSON的地理空间信息数据交换格式。可以表示几何,特征或者特征几何,支持点、线、面、多点、多线、多面和几何集合。

5.3.1 加载GeoJSON数据

安装完整IIS服务

Ⅰ. 打开程序和功能窗口,点击启用或关闭Windows功能

启用关闭Windows

找到Internet Information Services

万维网服务——应用程序开发功能

应用程序开发

万维网服务——安全性

安全性

万维网服务——常见HTTP功能

常见http功能

万维网服务——运行状况和诊断

运行和诊断

万维网服务——性能功能

性能功能

Web管理工具

Web管理工具

IIS支持json、geojson文件

打开IIS管理,添加MIME类型

文件扩展名:.geojson

MIME类型:application/geojson

添加MIME类型

点击处理程序映射,添加脚本映射

添加MIME类型

参考资料 完整安装IIS服务 - googlegis - 博客园

IIS支持json、geojson文件 - googlegis - 博客园

GeoJSON数据网站推荐 地图选择器

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title>加载GeoJSON数据</title>
    <link href="../css/ol.css" rel="stylesheet" />
    <script src="../libs/OL5/ol.js" type="text/javascript"></script>
    <script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
    <link href="../css/style.css" rel="stylesheet" type="text/css"/>
    <style type="text/css">
        #mapCon{
            width:100%;
            height:95%;
            position:absolute;
        }
    </style>
</head>
<body>
    <div class="ToolLib">
        <input type="button" class="ButtonLib" id="addGansu" value="加载GEOJSON"/>
        <input type="button" class="ButtonLib" id="addHebei" value="加载河北Geojson"/>
        <input type="button" class="ButtonLib" id="addChina" value="加载全中国" /> 
    </div>
    <div id="mapCon"></div>
    <script type="text/javascript">
        //矢量数据图层
        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: [],
            //地图视图设置
            view: new ol.View({
                //设置地图投影坐标系
                projection: projection,
                //地图初始中心点
                center: [0, 0],
                //地图初始显示级别
                zoom: 2
            }),
            controls: [new ol.control.MousePosition()]
        });
        //矢量几何要素显示在地图中
        //加载甘肃
        $('#addGansu').click(function () {
            if (vectorLayer != null || vectorLayer == "undefined") {
                //移除已有矢量图层
                map.removeLayer(vectorLayer);
            }
            //实例化矢量数据源,使用GeoJSON解析
            var vectorSource = new ol.source.Vector({
                url: "https://geo.datav.aliyun.com/areas/bound/geojson?code=620000_full",
                format: new ol.format.GeoJSON()
            });
            vectorLayer = new ol.layer.Vector({
                source: vectorSource,
                style: styleFunction
            });
            map.addLayer(vectorLayer);
            var view = map.getView();
            view.setCenter([11408888.925807696, 4671423.50774935]);
            //地图缩放
            view.setZoom(6);
        });
        //加载河北
        $('#addHebei').click(function () {
            if (vectorLayer != null || vectorLayer == "undefined") {
                //移除已有矢量图层
                map.removeLayer(vectorLayer);
            }
            //实例化矢量数据源,使用GeoJSON解析
            var vectorSource = new ol.source.Vector({
                url: "https://geo.datav.aliyun.com/areas/bound/geojson?code=130000_full",
                format: new ol.format.GeoJSON()
            });
            vectorLayer = new ol.layer.Vector({
                source: vectorSource,
                style: styleFunction
            });
            map.addLayer(vectorLayer);
            var view = map.getView();
            view.setCenter([12907462.344348002,4785569.46678315]);
            //地图缩放
            view.setZoom(6);
        })
        //加载全中国
        $('#addChina').click(function () {
            if (vectorLayer != null || vectorLayer == "undefined") {
                //移除已有矢量图层
                map.removeLayer(vectorLayer);
            }
            //实例化矢量数据源,使用GeoJSON解析
            var vectorSource = new ol.source.Vector({
                url: "https://geo.datav.aliyun.com/areas/bound/geojson?code=100000_full",
                format: new ol.format.GeoJSON()
            });
            vectorLayer = new ol.layer.Vector({
                source: vectorSource,
                style: styleFunction
            });
            map.addLayer(vectorLayer);
            var view = map.getView();
            view.setCenter([11408888.925807696, 4671423.50774935]);
            //地图缩放
            view.setZoom(5);
        })
    </script>
</body>
</html>

效果图

5.3.2 加载KML数据

配置ASP.NET应用程序

  使其可以访问**.geojson、.kml、.gpx**格式的数据

<configuration>
    <system.web>
      <compilation debug="true" targetFramework="4.5" />
      <httpRuntime targetFramework="4.5" />
    </system.web>
  <system.webServer>
    <defaultDocument>
      <files>
        <clear />
        <add value="default.aspx" />
      </files>
    </defaultDocument>
    <security>
      <requestFiltering>
        <fileExtensions>
          <add fileExtension=".json" allowed="true" />
          <add fileExtension=".geojson" allowed="true" />
          <add fileExtension=".kml" allowed="true" />
          <add fileExtension=".gpx" allowed="true" />
        </fileExtensions>
      </requestFiltering>
    </security>
    <staticContent>
      <mimeMap fileExtension=".geojson" mimeType="text/geojson" />
      <mimeMap fileExtension=".kml" mimeType="application/vnd.google-earth.kml+xml" />
      <mimeMap fileExtension=".gpx" mimeType="application/gpx" />
    </staticContent>
  </system.webServer>
</configuration>
//矢量数据图层
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数据

$('#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

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地图

无法加载成功

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:

//参考坐标系
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 加载高德地图 🗺️

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:

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:

  矢量瓦片是指不仅可以提供完整的样式设计灵活性,还能够快速渲染海量数据的矢量地图,本质是矢量地图,等效于在网页上绘制的栅格图片。

//使用严格模式
'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: '© <a href="https://www.mapbox.com/map-feedback/">Mapbox</a> ' +
            '© <a href="https://www.openstreetmap.org/copyright">' +
            'OpenStreetMap contributors</a>',
            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样式表

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

//引用
<link href="../css/ol.css" rel="stylesheet" />
<script src="../libs/OL5/ol.js" type="text/javascript"></script>
<script src="http://libs.baidu.com/jquery/2.1.1/jquery.min.js"></script>
<div id="mapCon">
    <div id="container"></div>
    <div id="layerTree">
        <ul>
            <li>
                <span>OSM地图图层</span>
                <fieldset id="layer0">
                    <label class="checkbox" for="visible0">
                        <input id="visible0" class="visible" type="checkbox" />是否可见
                    </label><br />
                    <label>透明度</label>
                    <input class="opacity" type="range" min="0" max="1" step="0.01" /><br />
                    <label>色彩</label>
                    <input class="hue" type="range" min="-3.141592653589793" max="3.141592653589793" step="0.01" /><br />
                    <label>饱和度</label>
                    <input class="saturation" type="range" min="0" max="5" step="0.01" /><br />
                    <label>对比度</label>
                    <input class="contrast" type="range" min="0" max="2" step="0.01" /><br />
                    <label>亮度</label>
                    <input class="brightness" type="range" min="-1" max="1" step="0.01" />
                </fieldset>
            </li>
            <li>
                <span>GeoJSON格式的矢量地图图层</span>
                <fieldset id="layer1">
                    <label class="checkbox" for="visible1">
                        <input id="visible1" class="visible" type="checkbox" />是否可见
                    </label><br />
                    <label>透明度</label>
                    <input class="opacity" type="range" min="0" max="1" step="0.01" /><br />
                    <label>色彩</label>
                    <input class="hue" type="range" min="-3.141592653589793" max="3.141592653589793" step="0.01" /><br />
                    <label>饱和度</label>
                    <input class="saturation" type="range" min="0" max="5" step="0.01" /><br />
                    <label>对比度</label>
                    <input class="contrast" type="range" min="0" max="2" step="0.01" /><br />
                    <label>亮度</label>
                    <input class="brightness" type="range" min="-1" max="1" step="0.01" />
                </fieldset>
            </li>
            <li>
                <span>ArcGIS MapServer 瓦片地图数据</span>
                <fieldset id="layer2">
                    <label class="checkbox" for="visible2">
                        <input id="visible2" class="visible" type="checkbox" />是否可见
                    </label><br />
                    <label>透明度</label>
                    <input class="opacity" type="range" min="0" max="1" step="0.01" /><br />
                    <label>色彩</label>
                    <input class="hue" type="range" min="-3.141592653589793" max="3.141592653589793" step="0.01" /><br />
                    <label>饱和度</label>
                    <input class="saturation" type="range" min="0" max="5" step="0.01" /><br />
                    <label>对比度</label>
                    <input class="contrast" type="range" min="0" max="2" step="0.01" /><br />
                    <label>亮度</label>
                    <input class="brightness" type="range" min="-1" max="1" step="0.01" />
                </fieldset>
            </li>
        </ul>
    </div>
</div>

JavaScript

 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 网格信息显示

  瓦片地图是基于金字塔策略裁剪后的图片集,因此瓦片地图由级数、行列数对应的单张图片按照网格划分组织而成。

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 方式,可以基于地图渲染容器对象来实现导出地图。

//实例化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 中 == 和 ===的区别

== 操作符会将两边的值进行强制类型转换再比较是否相等,而=== 操作符不会进行类型转换。== 操作符只要求比较两个值是否相等,而===操作符不仅要求值相等,而且要求类型相同。!=!==的区别也是同理。

66=='66';
//true
66==='666';
//false

参考资料融合xx

6.2 几何图形绘制

  基本图形包括点、线、圆、矩形、多边形等。

//绘制类型对象
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

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

<div id="mapCon">
</div>
<div id="editGeomStyle" class="easyui-window" data-options="title:'要素样式',closed:false,maximizable:false,minimizable:false,closable:false,resizable:false,shadow:false"
     style="width: 310px; padding: 5px; left: 60px; top: 20px;">
    <div id="tt" class="easyui-tabs" data-options="headerWidth:26,tabPosition:'left',plain:true,border:true" style="width: 100%">
        <div title="点要素样式" data-options="iconCls:'icon-point'" style="padding: 10px;">
            <fieldset id="layer0">
                <input id="refresh-points" class="refreshBtn" type="button" value="更新" /><br />
                <!-- 图形样式设置 -->
                <label class="title">图形样式:</label><br />
                <label>点大小(radius):</label>
                <input type="text" value="10" id="points-size" /><br />
                <label>填充颜色(color):</label>
                <input type="color" value="#aa3300" id="points-fill-color" /><br />
                <label>边框样式(color):</label>
                <input type="color" value="red" id="points-stroke-color" /><br />
                <label>边框样式(width):</label>
                <input type="text" value="2" id="points-stroke-width" /><br />
                <!-- 文字样式设置 -->
                <label class="title">文字样式:</label><br />
                <label>位置(align): </label>
                <select id="points-text-align">
                    <option value="center" selected="selected">Center</option>
                    <option value="end">End</option>
                    <option value="left">Left</option>
                    <option value="right">Right</option>
                    <option value="start">Start</option>
                </select>
                <br />
                <label>基线(baseline): </label>
                <select id="points-text-baseline">
                    <option value="alphabetic">Alphabetic</option>
                    <option value="bottom">Bottom</option>
                    <option value="hanging">Hanging</option>
                    <option value="ideographic">Ideographic</option>
                    <option value="middle" selected="selected">Middle</option>
                    <option value="top">Top</option>
                </select>
                <br />
                <label>旋转角度(rotation): </label>
                <select id="points-text-rotation">
                    <option value="0"></option>
                    <option value="0.785398164">45°</option>
                    <option value="1.570796327">90°</option>
                </select>
                <br />
                <label>字体(font): </label>
                <select id="points-text-font">
                    <option value="Arial" selected="selected">Arial</option>
                    <option value="Courier New">Courier New</option>
                    <option value="Quattrocento Sans">Quattrocento</option>
                    <option value="Verdana">Verdana</option>
                </select>
                <br />
                <label>字体粗细(weight): </label>
                <select id="points-text-weight">
                    <option value="bold">Bold</option>
                    <option value="normal" selected="selected">Normal</option>
                </select>
                <br />
                <label>字体大小(size): </label>
                <input type="text" value="12px" id="points-text-size" />
                <br />
                <label>X偏移量(offset x):</label>
                <input type="text" value="0" id="points-text-offset-x" />
                <br />
                <label>Y偏移量(offset y):</label>
                <input type="text" value="0" id="points-text-offset-y" />
                <br />
                <label>字体颜色(color):</label>
                <input type="color" value="blue" id="points-text-color" />
                <br />
                <label title="Outline Color">文字外框颜色(O.Color):</label>
                <input type="color" value="#ffffff" id="points-text-outline-color" />
                <br />
                <label title="Outline Width">文字外框宽度(O.Width):</label>
                <input type="text" value="3" id="points-text-outline-width" />
            </fieldset>
        </div>
        <div title="线要素样式" data-options="iconCls:'icon-line'" style="padding: 10px;">
            <fieldset id="layer1">
                <input id="refresh-lines" class="refreshBtn" type="button" value="更新" /><br />
                <label class="title">图形样式:</label><br />
                <label>线颜色(color):</label>
                <input type="color" value="green" id="lines-stroke-color" /><br />
                <label>线宽(width):</label>
                <input type="text" value="2" id="lines-stroke-width" /><br />
                <!-- 文字样式设置 -->
                <label class="title">文字样式:</label><br />
                <label>位置(align): </label>
                <select id="lines-text-align">
                    <option value="center" selected="selected">Center</option>
                    <option value="end">End</option>
                    <option value="left">Left</option>
                    <option value="right">Right</option>
                    <option value="start">Start</option>
                </select>
                <br />
                <label>基线(baseline): </label>
                <select id="lines-text-baseline">
                    <option value="alphabetic">Alphabetic</option>
                    <option value="bottom">Bottom</option>
                    <option value="hanging">Hanging</option>
                    <option value="ideographic">Ideographic</option>
                    <option value="middle" selected="selected">Middle</option>
                    <option value="top">Top</option>
                </select>
                <br />
                <label>旋转角度(rotation): </label>
                <select id="lines-text-rotation">
                    <option value="0"></option>
                    <option value="0.785398164">45°</option>
                    <option value="1.570796327">90°</option>
                </select>
                <br />
                <label>字体(font): </label>
                <select id="lines-text-font">
                    <option value="Arial" selected="selected">Arial</option>
                    <option value="Courier New">Courier New</option>
                    <option value="Quattrocento Sans">Quattrocento</option>
                    <option value="Verdana">Verdana</option>
                </select>
                <br />
                <label>字体粗细(weight): </label>
                <select id="lines-text-weight">
                    <option value="bold">Bold</option>
                    <option value="normal" selected="selected">Normal</option>
                </select>
                <br />
                <label>字体大小(size): </label>
                <input type="text" value="12px" id="lines-text-size" />
                <br />
                <label>X偏移量(offset x):</label>
                <input type="text" value="0" id="lines-text-offset-x" />
                <br />
                <label>Y偏移量(offset y):</label>
                <input type="text" value="0" id="lines-text-offset-y" />
                <br />
                <label>字体颜色(color):</label>
                <input type="color" value="blue" id="lines-text-color" />
                <br />
                <label title="Outline Color">文字外框颜色(O.Color):</label>
                <input type="color" value="#ffffff" id="lines-text-outline-color" />
                <br />
                <label title="Outline Width">文字外框宽度(O.Width):</label>
                <input type="text" value="3" id="lines-text-outline-width" />
            </fieldset>
        </div>
        <div title="区要素样式" data-options="iconCls:'icon-polygon'" style="padding: 10px;">
            <fieldset id="layer2">
                <input id="refresh-polygons" class="refreshBtn" type="button" value="更新" /><br />
                <label class="title">图形样式:</label><br />
                <label>填充颜色(color):</label>
                <input type="color" value="rgba(255, 255, 255, 0.5)" id="polygons-fill-color" /><br />
                <label>边框颜色(color):</label>
                <input type="color" value="#000000" id="polygons-stroke-color" /><br />
                <label>边框宽度(width):</label>
                <input type="text" value="2" id="polygons-stroke-width" /><br />
                <!-- 文字样式设置 -->
                <label class="title">文字样式:</label><br />
                <label>位置(align): </label>
                <select id="polygons-text-align">
                    <option value="center" selected="selected">Center</option>
                    <option value="end">End</option>
                    <option value="left">Left</option>
                    <option value="right">Right</option>
                    <option value="start">Start</option>
                </select>
                <br />
                <label>基线(baseline): </label>
                <select id="polygons-text-baseline">
                    <option value="alphabetic">Alphabetic</option>
                    <option value="bottom">Bottom</option>
                    <option value="hanging">Hanging</option>
                    <option value="ideographic">Ideographic</option>
                    <option value="middle" selected="selected">Middle</option>
                    <option value="top">Top</option>
                </select>
                <br />
                <label>旋转角度(rotation): </label>
                <select id="polygons-text-rotation">
                    <option value="0"></option>
                    <option value="0.785398164">45°</option>
                    <option value="1.570796327">90°</option>
                </select>
                <br />
                <label>字体(font): </label>
                <select id="polygons-text-font">
                    <option value="Arial" selected="selected">Arial</option>
                    <option value="Courier New">Courier New</option>
                    <option value="Quattrocento Sans">Quattrocento</option>
                    <option value="Verdana">Verdana</option>
                </select>
                <br />
                <label>字体粗细(weight): </label>
                <select id="polygons-text-weight">
                    <option value="bold">Bold</option>
                    <option value="normal" selected="selected">Normal</option>
                </select>
                <br />
                <label>字体大小(size): </label>
                <input type="text" value="12px" id="polygons-text-size" />
                <br />
                <label>X偏移量(offset x):</label>
                <input type="text" value="0" id="polygons-text-offset-x" />
                <br />
                <label>Y偏移量(offset y):</label>
                <input type="text" value="0" id="polygons-text-offset-y" />
                <br />
                <label>字体颜色(color):</label>
                <input type="color" value="blue" id="polygons-text-color" />
                <br />
                <label title="Outline Color">文字外框颜色(O.Color):</label>
                <input type="color" value="#ffffff" id="polygons-text-outline-color" />
                <br />
                <label title="Outline Width">文字外框宽度(O.Width):</label>
                <input type="text" value="3" id="polygons-text-outline-width" />
            </fieldset>
        </div>
    </div>
</div>

6.4 图形交互编辑

  一个几何图形的要素包括几何、属性、图形等信息。修改图形的几何信息,通过鼠标交互方式实现。

//实例化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)

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

//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 &copy; <a href="http://t0.tianditu.cn/cva_c/wmts?LAYER=cva">天地图矢量注记</a>',
        //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

7.2.3 加载WFS

空文件

简介

学习OpenLayers5并记录相关知识...... 展开 收起
取消

发行版

暂无发行版

贡献者

全部

近期动态

加载更多
不能加载更多了
HTML
1
https://gitee.com/mrwhitebare/learn-web-gis.git
git@gitee.com:mrwhitebare/learn-web-gis.git
mrwhitebare
learn-web-gis
LearnWebGIS
master

搜索帮助

53164aa7 5694891 3bd8fe86 5694891