导图社区 OpenLayer3
openlayer地图学习2.0版本,工作中有使用地图的程序,学习借鉴一下,欢迎指正。
编辑于2020-11-09 11:44:22Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程
用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的“生产者,消费者模型”。
平和保存和搜索的一些好用的网站,分享一波,好用拿走。
社区模板帮助中心,点此进入>>
Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程
用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法模拟,当然也没法说能用单线程来实现:比如最常见的“生产者,消费者模型”。
平和保存和搜索的一些好用的网站,分享一波,好用拿走。
OpenLayer3
概述
OpenLayers是一个用于开发WebGIS客户端的JavaScript包,最初基于BSD许可发行。
OpenLayers是一个开源的项目,其设计之意是为互联网客户端提供强大的地图展示功能,包括地图数据显示与相关操作,并具有灵活的扩展机制。
重写
OpenLayers 3对OpenLayers网络地图库进行了根本的重新设计。
OL3已运用现代的设计模式从底层重写(js)。
3最初版
支持2版本.
与版本2一样,数据可以被任意投影。
提供大量商业或免费的瓦片资源以及最流行的开源矢量数据格式。
能够方便地旋转地图以及显示地图动画。
新功能
OpenLayers 3同时设计了一些主要的新功能,如显示三维地图,或使用WebGL快速显示大型矢量数据集,这些功能将在以后的版本中加入。
基本概念
 
Map:地图
openlayer的核心部件Map(ol.Map)
容器
Map是图层、各种交互以及处理用户交互控件的集合
它被呈现到对象target(目标)容器(例如,包含在地图网页上的div元素)。
所有地图的属性可以在构造时进行配置,或者通过使用setter方法,如setTarget()。
<div id="map" style="width: 100%, height: 400px"></div> <script> var map = new ol.Map({target: 'map'}); </script> 
view:视图
ol. View:负责地图的中心点,放大,投影之类的设置。
一个ol.View实例包含投影projection,该投影决定中心center 的坐标系以及分辨率的单位,如果没有指定(如下面的代码段),默认的投影是球墨卡托(EPSG:3857),以米为地图单位。-默认:米
放大zoom
放大zoom 选项是一种方便的方式来指定地图的分辨率,可用的缩放级别由maxZoom (默认值为28)、zoomFactor (默认值为2)、maxResolution (默认由投影在256×256像素瓦片的有效成都来计算) 决定。 起始于缩放级别0, 以每像素maxResolution 的单位为分辨率, 后续的缩放级别是通过zoomFactor区分之前的缩放级别的分辨率来计算的, 直到缩放级别达到maxZoom 。 map.setView(new ol.View({ center: [0, 0], zoom: 2 }));
Source:资源
OpenLayers 3使用ol.source.Source子类获取远程数据图层,包含免费的和商业的地图瓦片服务,如OpenStreetMap、Bing、OGC资源(WMS或WMTS)、矢量数据(GeoJSON格式、KML格式…)等。
var osmSource = new ol.source.OSM();
Layer:图层
一个图层是资源中数据的可视化显示,OpenLayers 3包含三种基本图层类型:ol.layer.Tile、ol.layer.Image 和 ol.layer.Vector。
ol.layer.Tile
用于显示瓦片资源,这些瓦片提供了预渲染,并且由特定分别率的缩放级别组织的瓦片图片网格组成。
ol.layer.Image
用于显示支持渲染服务的图片,这些图片可用于任意范围和分辨率。
ol.layer.Vector
用于显示在客户端渲染的矢量数据。
var osmLayer = new ol.layer.Tile({source: osmSource}); map.addLayer(osmLayer);
图层是基于符合标准的WMS以及自定义瓦片缓存显示的,在线地图(或者瓦片地图客户端)主要是通过可用的专有地图瓦片服务进行广泛推广,OpenLayers提供的图层类型能通过使用它们的API来调用这些专有服务。
地图初始结构
<div id="map" style="width: 100%, height: 400px"></div> <script> new ol.Map({ layers: [ new ol.layer.Tile({source: new ol.source.OSM()}) ], view: new ol.View({ center: [0, 0], zoom: 2 }), target: 'map' }); </script>
名词释义
layer:层
contorl:控件
feature:元素
interaction:交互
Vector:矢量的
Tile:瓦片
source:资源
format:转换
projection:投影
Openlayers 3实践
1. 地图显示
1.1. 创建一副地图
 
在openlayers中,Map是图层、各种交互以及处理用户交互控件的集合,地图由三个基本成分生成:标记,样式声明和初始化代码。以下是一个完整的OpenLayers3地图示例。
步骤
(1)下载https://github.com/openlayers/ol3-workshop/archive/resources.zip,并将该文件夹放在网络服务器的根目录下;
(2)创建一个新的文件,命名为map.html,将以上代码复制进该文件后放入下载的文件夹的根目录下;
(3)在浏览器中输入:http://localhost:8000/ol_workshop/map.html,我们将打开一个工作的地图。
1.2. 剖析地图
1.2.1地图标记
标记为上例中的地图生成的一个文档元素: <div id="map"></div> 在此示例中,我们用<div>元素作为地图显示的容器,其他块级元素也能做视图的容器。在这种情况下,我们设置容器的id属性,所以我们可以将其作为地图的对象。
块级元素作为地图的容器
1.2.2地图样式
OpenLayers带有一个默认的样式表,指定地图相关的元素应如何显示,我们明确的将样式表引用到map.html页面中。 OpenLayers不对地图的大小做预定义,因此在默认样式表之后,我们需要包括至少一个自定义样式声明来说明地图在页面上的空间。 <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { height: 256px; width: 512px; } </style> 在该示例中,我们使用地图容器的id值作为选择器,并明确定义地图容器的高为256px,宽为512px。样式声明直接包含在文档的<head>部分。在大多数情况下,地图相关的样式说明是链接到外部样式表的一个大型主题网站的一部分。 预定义样式:地图的大小
需要预定义地图的大小
1.2.3地图初始化
生成地图的下一步包含一些初始化代码,在该示例中,我们在文档的<body>前添加<script> 元素来实现。 <script> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }) ], view: new ol.View({ projection: 'EPSG:4326', center: [0, 0], zoom: 0, maxResolution: 0.703125 }) }); </script> 注:这些步骤的顺序很重要,OpenLayers库必须在在自定义脚本执行之前加载,在此示例中,OpenLayers库在文档的<head>部分加载(<script src="ol3/ol.js"></script>)。同样的,在文档中作为显示容器的元素(该实例中为<div id="map"></div>)准备好之前,自定义地图初始化代码是不能执行的,将初始化代码添加到文档中<body>的后面,我们能在地图生成前,确保库已加载,显示容器已准备好。 接下来,将详细介绍初始化脚本的内容。脚本创建了一个包含一些配置选项的ol.Map对象: target: 'map' 我们使用显示容器的id属性来告诉地图构造函数将地图交付到何处,在该示例中,我们通过字符串“map”作为地图构造函数的对象。这个语法方便快捷,也可以更详细的使用元素的直接引用(e.g. document.getElementById("map"))。 图层配置创建了一个显示在地图中的图层: layers: [ new ol.layer.Tile({ source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }) ], 不用担心对以上的语法不了解,图层创建在后续章节中会有详细的介绍。最重要的是理解地图显示的是图层的集合。为了显示一副地图,至少需要添加一个图层。 最后一步是定义视图,指定投影、中心点,放大级别,在该示例中,还指定了maxResolution,以确保请求的范围不超过GeoWebCache能处理的范围。 view: new ol.View({ projection: 'EPSG:4326', center: [0, 0], zoom: 0, maxResolution: 0.703125 }) 以上,成功剖析了一副地图的显示,接下来将介绍更多关于OpenLayers的开发。
先定义ol库,在执行js
添加底图
1.3. Openlayers的资源
OpenLayer的示例代码以及库的功能
http://openlayers.org/en/master/examples/
API文档:方法名/对象属性
https://openlayers.org/en/latest/apidoc/
2. 图层与资源
2.1. 网络地图服务图层
当向地图中添加图层,图层的资源通常用来获取将要显示的数据,数据请求可以是影像数据,也可以是矢量数据。栅格数据是服务端提供的图片信息,矢量数据是服务器交付的结构化信息,在客户端(浏览器)进行显示。
有许多不同类型的服务提供栅格地图数据,这部分涉及到符合OGC网络地图服务(WMS)规范的供应商。
添加图层,显示数据 栅格-图片,矢量-结构化信息
2.1.1 创建图层
在1.1 创建的地图示例的基础上,修改图层来理解其运行机制。 layers: [ new ol.layer.Tile({ title: "Global Imagery", source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }) ] 
2.1.2 The ol.layer.Tile构造函数
在1.1创建的示例中,使用的数据资源是ol.source.TileWMS,我们可以从title关键字的字面上理解它的含义,但是基本上来说,这里的关键字可以是任意名称,在OpenLayers 3中,图层和资源有一个区别,而在OpenLayers 2中,这两部分一起组成了一个图层。 ol.layer.Tile表示图像的规则网格,ol.layer.Image表示单个图像,基于图层类型,我们将使用不同的资源(ol.source.TileWMS与ol.source.ImageWMS)。
基于图层类型使用不同的资源:-- tile:图像的网格规则--ol.source.TileWMS Image:单个图像--ol.source.ImageWMS
2.1.3 The ol.source.TileWMS构造函数
url指向的是WMS服务的在线资源,params是对象参数名称及其值,由于在OpenLayers中,默认WMS版本是1.3.0,如果WMS不支持该版本,需要在params中提供一个低版本。 (1)该示例中WMS提供了一个名为“openstreetmap”的图层,将LAYERS 参数的值由“bluemarble”改为“openstreetmap”,代码如下:street街道 new ol.layer.Tile({ title: "Global Imagery", source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'openstreetmap', VERSION: '1.1.1'} }) }) (2)改变图层与资源,用单一图像取代瓦片,再这个过程中,需要将资源的url修改为 http://suite.opengeo.org/geoserver/wms,将LAYERS 参数的值修改为“opengeo:countries”,完成修改后,利用浏览器的开发工具,确保请求的是单一图像而不是256×256像素的瓦片。
url:在线网络资源
param:对象参数名称及其值
默认WMS版本1.3,如果WMS不支持该版本,需要在params中提供一个低版本。
2.2. 瓦片缓存
默认情况在,瓦片图层请求一个256×256像素的图像来填充地图视窗,当你平移或缩放地图,将发出更多图片请求来填充你没有访问过的地方。浏览器会缓存一些请求的图像,这通常需要大量的处理器来动态渲染图像。
图像填充,访问加载
由于瓦片图层以规律的网格请求图像,这使得服务器能够缓存这些图片请求并且在下次浏览相同区域的时候返回该缓存结果,从而获得更好的性能。
2.2.1 ol.source.XYZ
网络地图服务规范使得客户端能够请求的内容具有灵活性,如果没有限制,在实践中,缓存会变得困难甚至不可能实现。 另一种几段情况是,服务器可能只提供固定缩放级别和规律网格的瓦片,这种情况可以概括为XYZ资源的瓦片图层——X/Y代表网格的行与列,Z代表缩放级别。
XYZ资源的瓦片图层--X/Y代表网格的行与列,Z代表缩放级别。
2.2.2 ol.source.OSM
OpenStreetMap (OSM)投影是为了收集并免费提供世界地图的数据,OSM提供了一些不同的数据渲染作为瓦片缓存集,这些渲染符合基本的XYZ网格配置,并且可以在OpenLayers地图中使用。ol.source.OSM图层可以访问OpenStreetMap瓦片资源。 (1)打开1.1创建的map.html文件,将地图初始化代码替换为以下代码: <script> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.transform([-93.27, 44.98], 'EPSG:4326', 'EPSG:3857'), zoom: 9 }), controls: ol.control.defaults({ attributionOptions: { collapsible: false } }) }); </script> (2)在文档的<head>中,添加以下图层属性的样式说明: <style> #map { width: 512px; height: 256px; } .ol-attribution a { color: black; } </style> (3)保存修改,在浏览器中查看该页面:http://localhost:8000/ol_workshop/map.html 
2.2.2.1 投影
回顾地图的视图定义: view: new ol.View({ center: ol.proj.transform([-93.27, 44.98], 'EPSG:4326', 'EPSG:3857'), zoom: 9 }) 地理空间数据可能来自各种坐标参照系,一个数据集可能是以度为单位的地理(经纬)坐标系,另一个可能是以米为单位的投影坐标系,对坐标系的全面讨论超出了本实践的范围,但了解其基本概念是很重要的。 OpenLayers 3需要知道所使用数据的坐标系,在内部,由ol.proj.Projection对象展现,ol.proj命名空间中的transform 方法使用字符串表示坐标参考系(上述示例中的"EPSG:4326"以及"EPSG:3857")。 OpenStreetMap 瓦片数据是墨卡托投影,因此,我们需要使用墨卡托坐标了设置初始化时的中心点。由于一个地方的地理坐标相对来说更容易知道,使用ol.proj.transform方法将地理坐标系("EPSG:4326")转化为墨卡托坐标系("EPSG:3857")。 OpenLayers 3包含地理坐标系与墨卡托坐标系间相互转换的方法,因此我们可以使用ol.proj.transform方法而不需要任何额外的工作。如果想要使用其他投影的数据,再使用ol.proj.transform方法之前需要添加一些额外的信息。 例如,使用"EPSG:21781" 坐标参照系的数据,添加以下两条script标签到页面中: <script src="http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.2.1/proj4.js" type="text/javascript"></script> <script src="http://epsg.io/21781-1753.js" type="text/javascript"></script> 然后在应用程序代码中,注册该投影并设置其有效范围,代码如下: // This creates a projection object for the EPSG:21781 projection // and sets a "validity extent" in that projection object. var projection = ol.proj.get('EPSG:21781'); projection.setExtent([485869.5728, 76443.1884, 837076.5648, 299941.7864]);
地理(经纬)坐标系(度°)
投影坐标系(米)
ol.proj.Projection对象
ol.proj命名空间中的transform 方法使用字符串表示坐标参考系
"EPSG:4326"/"EPSG:3857"
OpenStreetMap 瓦片数据是墨卡托投影
OpenStreetMap 瓦片数据是墨卡托投影,因此,我们需要使用墨卡托坐标了设置初始化时的中心点。由于一个地方的地理坐标相对来说更容易知道,使用ol.proj.transform方法将地理坐标系("EPSG:4326")转化为墨卡托坐标系("EPSG:3857")。 OpenLayers 3包含地理坐标系与墨卡托坐标系间相互转换的方法,因此我们可以使用ol.proj.transform方法而不需要任何额外的工作。
1.设置中心点
2.地理坐标-墨卡托坐标
其他坐标转换
如果想要使用其他投影的数据,再使用ol.proj.transform方法之前需要添加一些额外的信息。 例如,使用"EPSG:21781" 坐标参照系的数据,添加以下两条script标签到页面中: <script src="http://cdnjs.cloudflare.com/ajax/libs/proj4js/2.2.1/proj4.js" type="text/javascript"></script> <script src="http://epsg.io/21781-1753.js" type="text/javascript"></script> 然后在应用程序代码中,注册该投影并设置其有效范围,代码如下: // This creates a projection object for the EPSG:21781 projection // and sets a "validity extent" in that projection object. var projection = ol.proj.get('EPSG:21781'); projection.setExtent([485869.5728, 76443.1884, 837076.5648, 299941.7864]);
2.2.2.2 图层创建
layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], 之前的示例中,创建一个新图层后,将其添加到地图配置对象的图层数组中,以上代码接受资源的所有默认选项。
创建矢量图层
1.创建图层对象,然后将对象添加到底图中 this.drowLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); map.addLayer(drowLayer); 2.直接初始化 /*地图底图*/ this.map = new ol.Map({ layers: [self.wmsLayer, self.layer,self.substationLayer,drowLayer]//单个图层 //layers: [self.wmsLayer],图层组 target: 'map_element', view: new ol.View({ center: ol.proj.transform(self.center, 'EPSG:2363', 'EPSG:3857'), zoom: 0, rotation:0, minZoom: 10, projection: 'EPSG:3857' }), }); 3.直接在底图中添加图层 var source2 = new ol.source.Vector(); var map = new ol.Map({ target:'map', layers:[ new ol.layer.Tile({ //title:"底图", source:new ol.source.TileWMS({ url:'', params:{ 'LAYERS': '', //此处可以是单个图层名称,也可以是图层组名称,或多个图层名称 'TILED': false, 'wrapX': false, //'angle':140 }, serverType: '', //服务器类型 }) }), //显示数据层 this.msglayer=new ol.layer.Vector({ source: new ol.source.Vector() }), //点击层 this.drawlayer = new ol.layer.Vector({ source: source2 }) ],
2.2.2.3 样式
.ol-attribution a { color: black; } 如何处理地图控件是本章节意外的内容,但是这里的样式声明让你先睹为快。默认情况下ol.control.Attribution控件被添加到所有地图中,这使得地图视窗中显示图层资源的归属信息来源,上述声明改变了地图中归属信息的样式(版权行再地图的右下方)。 掌握了公开可用的缓存瓦片集的图层用法,接下来将介绍专有的栅格图层,详见2.3 。
2.2.2.4 属性控件配置
默认情况下,ol.control.Attribution控件在页面上添加了一个i(information)按钮,点击即可显示归属地信息。为了符合OpenStreetMap的使用条款,并且将OpenStreetMap的归属地信息一直展现出来,可添加以下代码在ol.Map构造函数中最为可选对象。 controls: ol.control.defaults({ attributionOptions: { collapsible: false } }) 这段代码移除了i按钮,使得归属地信息一直展现在视图中。
2.3. 专有栅格图层(Bing)
在前面的章节中,图层是基于符合标准的WMS以及自定义瓦片缓存显示的,在线地图(或者瓦片地图客户端)主要是通过可用的专有地图瓦片服务进行广泛推广,OpenLayers提供的图层类型能通过使用它们的API来调用这些专有服务。 本章节使用的示例,是在上一章节示例的基础上,添加一个使用Bing瓦片的图层。 (1)将map.html文件中配置OSM资源的代码替换为ol.source.BingMaps: source: new ol.source.BingMaps({ imagerySet: 'Road', key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3' }) 注:Bing瓦片API要求用户注册一个API密钥,该密钥将在地图应用程序中使用,示例中的 密钥不能再产品中使用。 (1)保存修改,在浏览器中查看该页面:http://localhost:8000/ol_workshop/map.html: 完整示例代码如下: <!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { height: 256px; width: 512px; } .ol-attribution a { color: black; } </style> <script src="ol3/ol.js" type="text/javascript"></script> <title>OpenLayers 3 example</title> </head> <body> <h1>My Map</h1> <div id="map" class="map"></div> <script type="text/javascript"> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.BingMaps({ imagerySet: 'Road', key: 'Ak-dzM4wZjSqTlzveKz5u0d4IQ4bRzVI309GxmkgSVr1ewS6iPSrOvOKhA-CJlm3' }) }) ], view: new ol.View({ center: ol.proj.transform([-93.27, 44.98], 'EPSG:4326', 'EPSG:3857'), zoom: 9 }) }); </script> </body> </html> 
注册API密钥
2.4. 矢量图层
矢量图层由ol.layer.Vector展示,并处理客户端矢量数据的显示。以下将使用最初的WMS示例来获取一个世界地图,并在其基础上添加一个带有一些要素的矢量图层。 基础图层(底图)如下: <!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { height: 256px; width: 512px; } </style> <title>OpenLayers 3 example</title> <script src="ol3/ol.js" type="text/javascript"></script> </head> <body> <h1>My Map</h1> <div id="map"></div> <script type="text/javascript"> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ title: "Global Imagery", source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }) ], view: new ol.View({ projection: 'EPSG:4326', center: [0, 0], zoom: 0, maxResolution: 0.703125 }) }); </script> </body> </html>
2.4.1 添加矢量图层
(1)打开map.html文件,将初始化WMS的示例复制其中,保存修改后在浏览器中确定地图正常显示:http://localhost:8000/ol_workshop/map.html。 (2)在地图初始化代码中,找到瓦片图层的加载,在其后添加一下新的图层,以下代码实现请求一组存放在GeoJSON中的要素: new ol.layer.Vector({ title: 'Earthquakes', source: new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }), style: new ol.style.Style({ image: new ol.style.Circle({ radius: 3, fill: new ol.style.Fill({color: 'white'}) }) }) }) 以上示例显示 了世界地图,附以白色的圆圈代表地震带。  注:GeoJSON数据坐标系与地图视图的相同,均为EPSG:4326,因此无需再次设置投影,只有在资源与视图的投影不同的情况下,才需要在资源中明确指定projection 属性来表示要素缓存的投影,这以为着地图视图的投影通常可以被指定。
2.4.2 详细说明
上述示例中,设置图层的标题title为“Earthquakes”,使用ol.source.GeoJSON类型的资源source,该资源指向一个明确的url。 如果你希望要素的样式基于其属性,可以使用一个样式函数替代ol.style.Style,从而配置ol.layer.Vector的样式。 (1)上述示例中地图上白色的圆圈代表ol.layer.Vector图层中的ol.Feature对象,每一个要素都包含title 和summary 属性信息。地图中注册一个命名为forEachFeatureAtPixel的单击监听事件,并在地图视图下在显示地震信息。 (2)矢量图层的数据来自于美国地质调查局(USGS)公布的地震资料(http://earthquake.usgs.gov/earthquakes/catalogs/),找到OpenLayers 3支持格式的矢量图层信息保存为文档,将该文档放置在项目的data文件夹下,就能在地图中显示该矢量图层。
ol.style.Style配置要素样式
ol.feature
title/summary属性
地图中注册一个命名为forEachFeatureAtPixel的单击监听事件,显示属性
2.5. 矢量影像
在上一章节的示例中,使用了ol.layer.Vector类,在动态缩放的过程中,要素不断重新渲染(点符号大小保持固定),在矢量图层中,OpenLayers 基于每一动画帧重新渲染资源数据,这使得在视图的分辨率变化后,笔划、点符号、标签持续的渲染。 另一种渲染策略是避免在视图转换的过程中重渲染,并将之前视图的状态下的渲染输出重定位和改变其规模。通过使用包含ol.source.ImageVector的ol.layer.Image可以实现以上效果。这种结合,使得当视图没有动态变化时,保存渲染数据的“快照”,在视图转换过程中,重利用这些“快照”。 以下示例使用了包含ol.source.ImageVector的ol.layer.Image类,实现分块渲染,使用该类可以仅渲染数据的一小部分,这种结合将适用于包含大量相对静态数据渲染的应用程序。
2.5.1 ol.source.ImageVector
回顾2.4 添加的包含地震数据的地图示例,将此示例改为分块渲染,将矢量图层替换为如下代码: new ol.layer.Image({ title: 'Earthquakes', source: new ol.source.ImageVector({ source: new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }), style: new ol.style.Style({ image: new ol.style.Circle({ radius: 3, fill: new ol.style.Fill({color: 'white'}) }) }) }) }) 通过以上方式,矢量数据由图像描绘,但视觉上仍是要素的形式,实现了性能和质量之间本质的折中。
2.5.2 详细说明
在上述代码中,使用ol.layer.Image代替ol.layer.Vector,然而,仍可以通过ol.source.ImageVector连接原始的ol.source.GeoJSON类型数据,从而使用是矢量数据,这里的样式提供了对ol.source.ImageVector的配置,而不是直接配置图层。
3. .控件于交互
3.1. 显示比例尺
比例尺是显示在地图上的典型窗口小部件,OpenLayers 3提供了ol.control.SaleLine来实现。
3.1.1创建比例尺
在地图配置的范围内,添加如下代码,给地图创建一个新的比例尺控件: 一个默认的比例尺将出现在地图视图的左下角。 controls: ol.control.defaults().extend([ new ol.control.ScaleLine() ]), 坐标拾取控件 controls: ol.control.defaults().extend([ new ol.control.MousePosition()//坐标拾取 ]),
3.1.2 移动比例尺控件
如果觉得比例尺控件在图形中看不清,一下提供几种策略来提高比例尺的可见性。在文档的CSS中添加一些样式声明,可以包括背景色,填充等,以下代码可作为参考: .ol-scale-line, .ol-scale-line:not([ie8andbelow]) { background: black; padding: 5px; } 如果地图视图拥挤难耐,为了避免过度拥挤,可以将比例尺控件移到其他位置。实现此功能,需要在标记中创建一个额外元素来存放比例尺控件。 (1)在map.html页面的<body>范围内创建一个新的块级元素,为了更好的指向该元素,设置其id属性scale-line,代码如下: <div id="scale-line" class="scale-line"></div> 将以上代码放置在<div id="map"></div> 后最合理。 (2)修改比例尺控件的创建代码,使其指向scale-line元素: controls: ol.control.defaults().extend([ new ol.control.ScaleLine({ className: 'ol-scale-line', target: document.getElementById('scale-line') }) ]), (3)添加比例尺控件的样式声明: .scale-line { position: absolute; top: 350px; } .ol-scale-line { position: relative; bottom: 0px; left: 0px; } 保存修改,在浏览器中查看该页面:http://localhost:8000/ol_workshop/map.html:  实现比例尺控件在地图视图以外。
注:想要创建自定义控件,可以从ol.control.Control继承(通过使用ol.inherits)。
3.2. 选择要素
在本节示例中,将创建一个矢量图层,用户可以选择和查看要素信息。 之前的示例展示了ol.control.Control的用法,控件可以在地图上直接显示,或者在文档中添加一个DOM元素,ol.interaction.Interaction负责处理用户交互,但是通常没有视觉上的展现。以下示例将展示ol.interaction.Select的使用,实现与矢量图层上的要素交互。
矢量数据服务的一大优点是,用户可以和数据交互
矢量图实例
回顾2.4 中矢量图层的创建,在其基础上,添加选择交互工具,完整代码如下: <!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { height: 256px; width: 512px; } </style> <script src="ol3/ol.js" type="text/javascript"></script> <title>OpenLayers 3 example</title> </head> <body> <h1>My Map</h1> <div id="map"></div> <script type="text/javascript"> var map = new ol.Map({ interactions: ol.interaction.defaults().extend([//红色点 new ol.interaction.Select({ style: new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#FF0000' }), stroke: new ol.style.Stroke({ color: '#000000' }) }) }) }) ]), target: 'map', layers: [ new ol.layer.Tile({ title: "Global Imagery", source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }), new ol.layer.Vector({//地震带 title: 'Earthquakes', source: new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }), style: new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#0000FF' }), stroke: new ol.style.Stroke({ color: '#000000' }) }) }) }) ], view: new ol.View({ projection: 'EPSG:4326', center: [0, 0], zoom: 1 }) }); </script> </body> </html> 保存修改,在浏览器中打开:http://localhost:8000/ol_workshop/map.html.使用鼠标点击事件选择地震带,查看要素选择的效果。
效果显示

3.3. 绘制要素
回顾2.4 中矢量图层的创建,在其基础上,添加绘制交互工具,完整代码如下: <!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { height: 256px; width: 512px; } </style> <script src="ol3/ol.js" type="text/javascript"></script> <title>OpenLayers 3 example</title> </head> <body> <h1>My Map</h1> <div id="map"></div> <script type="text/javascript"> var source = new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }); var draw = new ol.interaction.Draw({ source: source, type: 'Point' }); var map = new ol.Map({ interactions: ol.interaction.defaults().extend([draw]), target: 'map', layers: [ new ol.layer.Tile({ title: "Global Imagery", source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }), new ol.layer.Vector({ title: 'Earthquakes', source: source, style: new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#0000FF' }), stroke: new ol.style.Stroke({ color: '#000000' }) }) }) }) ], view: new ol.View({ projection: 'EPSG:4326', center: [0, 0], zoom: 1 }) }); </script> </body> </html> 保存修改,在浏览器中打开:http://localhost:8000/ol_workshop/map.html.点击地图来添加新的要素,实现点几何对象的绘制。
通过使用ol.interaction.Draw可以绘制新的要素
一个绘制交互工具由矢量资源和几何类型构成。
绘制要素的语法
source:-- var source = new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }); 绘制元素:-- var draw = new ol.interaction.Draw({ source: source, type: 'Point' }); 交互:-- interactions: ol.interaction.defaults().extend([draw]), map.addInteraction(draw); 矢量图层:-- new ol.layer.Vector({ title: 'Earthquakes', source: source, style: new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#0000FF' }), stroke: new ol.style.Stroke({ color: '#000000' }) }) }) })
效果显示

3.4. 修改要素
回顾2.4 中矢量图层的创建,在其基础上,添加选择与修改交互工具,完整代码如下: <!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { height: 256px; width: 512px; } </style> <script src="ol3/ol.js" type="text/javascript"></script> <title>OpenLayers 3 example</title> </head> <body> <h1>My Map</h1> <div id="map"></div> <script type="text/javascript"> var source = new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }); var style = new ol.style.Style({ image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: [0, 153, 255, 1] }), stroke: new ol.style.Stroke({ color: [255, 255, 255, 0.75], width: 1.5 }) }), zIndex: 100000 }); var select = new ol.interaction.Select({style: style}); var modify = new ol.interaction.Modify({ features: select.getFeatures() }); var map = new ol.Map({ interactions: ol.interaction.defaults().extend([select, modify]), target: 'map', layers: [ new ol.layer.Tile({ title: "Global Imagery", source: new ol.source.TileWMS({ url: 'http://maps.opengeo.org/geowebcache/service/wms', params: {LAYERS: 'bluemarble', VERSION: '1.1.1'} }) }), new ol.layer.Vector({ title: 'Earthquakes', source: source, style: new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#0000FF' }), stroke: new ol.style.Stroke({ color: '#000000' }) }) }) }) ], view: new ol.View({ projection: 'EPSG:4326', center: [0, 0], zoom: 1 }) }); </script> </body> </html> 保存修改,在浏览器中打开:http://localhost:8000/ol_workshop/map.html.使用鼠标点击事件选择地震带,拖动该点,实现要素修改。
修改要素需要联合使用ol.interaction.Select和ol.interaction.Modify,它们有一个共同的要素集(ol.Collection)。
ol.interaction.Modify对ol.interaction.Select选择的要素进行修改。
修改要素语法
source:-- var source = new ol.source.GeoJSON({ url: 'data/layers/7day-M2.5.json' }); 绘制元素:-- // var draw = new ol.interaction.Draw({ // source: source, // type: 'Point' // }); //修改样式 var style = new ol.style.Style({ image: new ol.style.Circle({ radius: 7, fill: new ol.style.Fill({ color: [0, 153, 255, 1] }), stroke: new ol.style.Stroke({ color: [255, 255, 255, 0.75], width: 1.5 }) }), zIndex: 100000 }); 交互:-- interactions: ol.interaction.defaults().extend([draw]), interactions: ol.interaction.defaults().extend([select, modify]), //选择样式 var select = new ol.interaction.Select({style: style}); //改变元素 var modify = new ol.interaction.Modify({ features: select.getFeatures() }); 矢量图层:-- new ol.layer.Vector({ title: 'Earthquakes', source: source, style: new ol.style.Style({ image: new ol.style.Circle({ radius: 5, fill: new ol.style.Fill({ color: '#0000FF' }), stroke: new ol.style.Stroke({ color: '#000000' }) }) }) })
4. 矢量样式
4.1. 矢量图层格式
基础的ol.layer.Vector构造函数提供了一个相对固定的图层类型,默认情况下,当创建一个新的矢量图层时,并不知道图层的要素来源,因为这是的ol.source.Vector内容。接下来将介绍自定义渲染风格,以及矢量数据的基本格式。
基础的ol.layer.Vector构造函数提供了一个相对固定的图层类型
4.1.1 ol.format
OpenLayers 3中的ol.format类负责解析服务器中代表是两要素的数据,大多数情况下,不会直接使用该类,但是会使用其相应的资源(比如:ol.source.KML)。该格式将原始要素数据转变为ol.Feature对象。 考虑以下两个数据块,它们都表示同一个ol.Feature对象(西班牙巴塞罗那的一个点)。第一种序列化为GeoJSON(使用ol.format.GeoJSON解析),第二种序列化为KML(使用ol.format.KML解析)。 (1)GeoJSON Example (2)KML Example
(1)GeoJSON Example
{ "type": "Feature", "id": "OpenLayers.Feature.Vector_107", "properties": {}, "geometry": { "type": "Point", "coordinates": [-104.98, 39.76] } }
(2)KML Example
<?xml version="1.0" encoding="utf-8"?> <kml xmlns="http://earth.google.com/kml/2.2"> <Placemark> <Point> <coordinates>-104.98,39.76</coordinates> </Point> </Placemark> </kml>
4.2. 矢量图层样式
设置HTML元素样式,使用如下CSS: .someClass { background-color: blue; border-width: 1px; border-color: olive; } .someClass是一个选择器(选择所有Class属性值为"someClass"的对象),后面的内容是一组已命名的属性与其对应的值,称之为样式声明。
4.2.1 基础样式
一个矢量图层可以有样式,更明确的说法是,一个矢量图层可以由一个ol.style.Style对象、一组ol.style.Style对象或者一个返回值为一组ol.style.Style对象的方法配置。 (1)由静态样式配置的矢量图层: var layer = new ol.layer.Vector({ source: new ol.source.Vector(), style: new ol.style.Style({ // ... }) }); (2)由样式方法配置的矢量图层,将所有Class属性值为"someClass"的对象设置为同一样式: var layer = new ol.layer.Vector({ source: new ol.source.Vector(), style: function(feature, resolution) { if (feature.get('class') === 'someClass') { // create styles... return styles; } }, });
矢量图层样式由ol.style.Style对象配置样式
(1)由静态样式配置的矢量图层
var layer = new ol.layer.Vector({ source: new ol.source.Vector(), style: new ol.style.Style({ // ... }) });
( 2 )由样式方法配置的矢量图层
var layer = new ol.layer.Vector({ source: new ol.source.Vector(), style: function(feature, resolution) { if (feature.get('class') === 'someClass') { // create styles... return styles; } }, });
4.2.2 符号化
OpenLayers 3中的符号化相当于CSS中声明的块(下面是关于ol.style.*的典型示例)。在一个蓝色的背景下用1像素宽的线条绘制区要素,将运用的如下两个符号化对象: new ol.style.Style({ fill: new ol.style.Fill({ color: 'blue' }), stroke: new ol.style.Stroke({ color: 'olive', width: 1 }) }); 不同的符号化对象使用于不同的几何类型,区可以由线组成,但没有填充,点可以用ol.style.Circle和ol.style.Icon进行样式说明。前者呈现圆形的形状,后者使用文件中的图片(比如:png图像)。下面是用圆形样式的示例: new ol.style.Circle({ radius: 20, fill: new ol.style.Fill({ color: '#ff9900', opacity: 0.6 }), stroke: new ol.style.Stroke({ color: '#ffcc00', opacity: 0.4 }) });
OpenLayers 3中的符号化相当于CSS中声明的块(下面是关于ol.style.*的典型示例)。
4.2.3 ol.style.Style
以下示例实现将class 属性值为的"someClass"对象中的要素设置为1像素宽的蓝色,其余所有要素设置为红色。(最好将样式方法在对象外创建,以便重用,但以下代码为简单起见,将方法写在对象内。) style: (function() { var someStyle = [new ol.style.Style({ fill: new ol.style.Fill({ color: 'blue' }), stroke: new ol.style.Stroke({ color: 'olive', width: 1 }) })]; var otherStyle = [new ol.style.Style({ fill: new ol.style.Fill({ color: 'red' }) })]; return function(feature, resolution) { if (feature.get('class') === "someClass") { return someStyle; } else { return otherStyle; } }; }()) 注:一个要素也有样式配置选项,只需设置resolution 参数就能实现对个别要素的样式设置(基于分辨率)。
一个ol.style.Style对象有四个关键属性:fill填充, image图像, stroke描边 和 text文字,外加一个zIndex属性选项。下面的样式方法将返回一组ol.style.Style对象。
注:一个要素也有样式配置选项,只需设置resolution 参数就能实现对个别要素的样式设置(基于分辨率)。
4.2.4伪类
CSS允许选择器中存在伪类,这限制了基于上下文的样式声明的应用,使得样式声明不容器在选择器中表示,比如鼠标位置,附近的元素或者浏览器历史。在OpenLayers 3中,有一种类似的概念:在ol.interaction.Select中添加样式配置选项,示例代码如下: var select = new ol.interaction.Select({ style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255,255,255,0.5)' }) }) }); 了解了基础的样式,接下来将介绍矢量图层的样式设置。
在ol.interaction.Select中添加样式配置选项
4.3. 设置矢量图层的额样式
建筑示例
本节示例将展示矢量图层中的建筑平面图,完整示例代码如下: <!doctype html> <html lang="en"> <head> <link rel="stylesheet" href="ol3/ol.css" type="text/css"> <style> #map { background-color: gray; height: 256px; width: 512px; } </style> <title>OpenLayers 3 example</title> <script src="ol3/ol.js" type="text/javascript"></script> </head> <body> <h1>My Map</h1> <div id="map"></div> <script type="text/javascript"> var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Vector({ title: 'Buildings', source: new ol.source.KML({ url: 'data/layers/buildings.kml', extractStyles: false }), style: new ol.style.Style({ stroke: new ol.style.Stroke({color: 'red', width: 2}) }) }) ], view: new ol.View({ projection: 'EPSG:4326', center: [-122.791859392, 42.3099154789], zoom: 16 }) }); </script> </body> </html>
在浏览器中打开map.html文件:http://localhost:8000/ol_workshop/map.html,将看到带有红色轮廓的建筑群。
根据面积的大小,使建筑显示为不同的颜色
创建一个样式方法,根据面积的大小,使建筑显示为不同的颜色,将一下代码,将Buildings 图层的样式配置选项替换为如下代码: style: (function() { var defaultStyle = [new ol.style.Style({ fill: new ol.style.Fill({color: 'navy'}), stroke: new ol.style.Stroke({color: 'black', width: 1}) })]; var ruleStyle = [new ol.style.Style({ fill: new ol.style.Fill({color: 'olive'}), stroke: new ol.style.Stroke({color: 'black', width: 1}) })]; return function(feature, resolution) { if (feature.get('shape_area') < 3000) { return ruleStyle; } else { return defaultStyle; } }; })() 保存修改,在浏览器中查看:http://localhost:8000/ol_workshop/map.html。
添加标签
最后给建筑添加标签,为了简单化,我们使用黑色轮廓的样式,并只使用一种标签。 style: (function() { var stroke = new ol.style.Stroke({ color: 'black' }); var textStroke = new ol.style.Stroke({ color: '#fff', width: 3 }); var textFill = new ol.style.Fill({ color: '#000' }); return function(feature, resolution) { return [new ol.style.Style({ stroke: stroke, text: new ol.style.Text({ font: '12px Calibri,sans-serif', text: feature.get('key'), fill: textFill, stroke: textStroke }) })]; }; })() 保存修改,在浏览器中查看:http://localhost:8000/ol_workshop/map.html。