OpenLayers 3 入门教程
摘要
OpenLayers 3对OpenLayers网络地图库进行了根本的重新设计。版本2虽然被广泛使用,但从JavaScript开发的早期发展阶段开始,已日益现实出它的落后。 OL3已运用现代的设计模式从底层重写。
最初的版本旨在支持第2版提供的功能,提供大量商业或免费的瓦片资源以及最流行的开源矢量数据格式。与版本2一样,数据可以被任意投影。最初的版本还增加了一些额外的功能,如能够方便地旋转地图以及显示地图动画。
OpenLayers 3同时设计了一些主要的新功能,如显示三维地图,或使用WebGL快速显示大型矢量数据集,这些功能将在以后的版本中加入。
目录
基本概念 4
Map 4
View 4
Source 5
Layer 5
总结 6
Openlayers 3实践 7
1 地图显示 7
1.1创建一副地图 7
1.2 剖析你的地图 8
1.3 Openlayers的资源 11
2 图层与资源 12
2.1 网络地图服务图层 12
2.2 瓦片缓存 14
2.3 专有栅格图层(Bing) 18
2.4 矢量图层 20
2.5 矢量影像 23
3 控件与交互 24
3.1 显示比例尺 24
3.2 选择要素 26
3.3 绘制要素 29
3.4 修改要素 31
4 矢量样式 33
4.1矢量图层格式 33
4.2矢量图层样式 35
4.3 设置矢量图层的样式 38
基本概念
Map
OpenLayers 3的核心部件是Map(ol.Map)。它被呈现到对象target容器(例如,包含在地图的网页上的div元素)。所有地图的属性可以在构造时进行配置,或者通过使用setter方法,如setTarget()。
<div ></div>
<script>
var map = new ol.Map({target: 'map'});
</script>
View
ol. View负责地图的中心点,放大,投影之类的设置。
一个ol.View实例包含投影projection,该投影决定中心center 的坐标系以及分辨率的单位,如果没有指定(如下面的代码段),默认的投影是球墨卡托(EPSG:3857),以米为地图单位。
放大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);
总结
上述片段可以合并成一个自包含视图和图层的地图配置:
<div ></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>
Openlayers 3实践
1 地图显示
1.1创建一副地图
在openlayers中,Map是图层、各种交互以及处理用户交互控件的集合,地图由三个基本成分生成:标记,样式声明和初始化代码。以下是一个完整的OpenLayers3地图示例。
<!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 ,
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文件夹下,就能在地图中显示该矢量图层。
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()
]),
一个默认的比例尺将出现在地图视图的左下角。
3.1.2 移动比例尺控件
如果觉得比例尺控件在图形中看不清,一下提供几种策略来提高比例尺的可见性。在文档的CSS中添加一些样式声明,可以包括背景色,填充等,以下代码可作为参考:
.ol-scale-line, .ol-scale-line:not([ie8andbelow]) {
background: black;
padding: 5px;
}
如果地图视图拥挤难耐,为了避免过度拥挤,可以将比例尺控件移到其他位置。实现此功能,需要在标记中创建一个额外元素来存放比例尺控件。
(1) 在map.html页面的<body>范围内创建一个新的块级元素,为了更好的指向该元素,设置其id属性scale-line,代码如下:
<div >
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。