在上一篇《利用全能电子地图下载器+GeoWebCache发布Arcgis Server缓存瓦片过程全记录》中,我们利用GeoWebCache作为瓦片地图服务器发布了瓦片地图。虽然在其中可以直接浏览,但是在GeoWebCache1.10.0中,官方内置的是OpenLayers2的版本,这个版本比较老旧,不能很好的适应诸如触屏设备等应用环境。所以,我想利用OpenLayers2的升级版OpenLayers3来进行地图显示,并增加显示地图标记和点击标记后显示弹出框的功能,这两个也是比较常用的。
这篇文章可能会比较长,我会对在标题中提到的总目标(在地图上显示标记并点击标记后显示弹出框)进行模块分解,并配上所用的API解析,化整为零嘛~各位也可以各取所需~
模块分解如下:
1、显示瓦片地图
2、在地图上显示标记
3、在点击标记后显示弹出框
Let’s Start~
- GeoWebCache:1.10.0
- OpenLayers:3.13.1
GeoWebCache本身就是一个WMS服务,所以只需要利用OpenLayers3与这个WMS服务对接即可。
<link rel="stylesheet" type="text/css" href="../ol.css" />
<script src="../ol.js">script>
<script src="https://code.jquery.com/jquery-3.3.1.js">script>
<div id="map">div>
需要记住这个id值,后面的脚本会用到
//获取投影坐标系
var pos = ol.proj.get('EPSG:3857');
var map = new ol.Map({
//地图容器div的ID
target: 'map',
//地图容器中加载的图层
layers: [],
view: new ol.View({
//设置地图投影坐标系
projection: pos,
//设置地图加载时的初始中心点
center: [13276805.940731, 3008561.497087],
//缩放级别
zoom: 19
}),
});
相关API:
1、new ol.Map
2、new ol.View
关于View构造参数的说明:
1、center
参数的获取方式:
a、在GeoWebCache中进入地图浏览模式,利用浏览器的开发者工具(这里以Google Chrome为例)打开NetWork选项卡
b、随机点击Type值为png的连接,在Preview选项卡中,要是有瓦片地图的状态,而不是网格的状态,并记下URL,后续步骤要使用
这是我们想要的效果:
这不是我们想要的效果:
c、找到URL中的BBOX参数
BBOX=13280473.174523,3009173.884415,13281084.670715,3009785.380607
d、将前两个值,这里是13280473.174523
和3009173.884415
填入center
属性即可。
2、zoom
参数:为下载瓦片地图时选择的地图级别。
注意二者要对应起来,zoom
信息可以在Header(如果是Chrome浏览器的调试窗口)中找到
var mlayer = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://XXX.xxx.com/geowebcache/service/wms',
params: {
'LAYERS': 'fzgl',
'FORMAT': 'image/png',
'SRS': 'EPSG:3857'
},
tileGrid: new ol.tilegrid.TileGrid({
resolutions: [156543.0339, 78271.51696, 39135.75848, 19567.87924, 9783.939621, 4891.96981, 2445.984905, 1222.992453, 611.496226, 305.748113, 152.874057, 76.437028, 38.218514, 19.109257, 9.554629, 4.777314, 2.388657, 1.194329, 0.597164, 0.298582],
origin: [-20037508.3427892, 20037508.3430388]
})
})
})
相关API:
1、new ol.layer.Tile
2、new ol.source.TileWMS
3、new ol.tilegrid.TileGrid
关于Tile对象的构造参数的说明:
1、url
参数:如果你的Web Server(eg.Tomcat)没有经过特殊配置的话,直接替换XXX.xxx.com为你的地址即可
2、params
参数、FORMAT
参数、SRS
参数,都可以从Step3中记下的URL里的对应参数位置找到
3、resolutions
参数:可以从geowebcache对应的地图预览的网页源代码找到
4、origin
参数:可以从Arcgis瓦片的conf.xml中找到
4、这几个参数是最基本的,如果有缺失或填写错误,地图将无法正常渲染
map.addLayer(mlayer)
相关API
1、map.addLayer
Done!
实例演示,点这里
在地图上显示标记,相当于在原来的瓦片地图层上由新叠加了一层,在OpenLayers中称为矢量层。可以把这种叠加的原理理解为PS中的图层,通过各种图层的叠加,达到我们想要的效果。这些地图上的图标,就存在与矢量层上。所以,我们只需要创建矢量层,并添加进map中即可。
注:在OpenLayers中,每一个地图上的图标,称做一个Feature,这个矢量容器就是用来装Feature的
var vectorSource = new ol.source.Vector({});
相关API:
1、new ol.source.Vector
//创建图标特性
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point([t1, t2], "XY"),
name: "my Icon",
});
//将图标特性添加进矢量中
vectorSource.addFeature(iconFeature);
相关API:
1、new ol.Feature
2、new ol.geom.Point
3、vectorSource.addFeature
几点说明:
1、上面代码中的t1、t2即要显示标记的位置,填入你想让标记出现的经纬度即可。
//创建图标样式
var iconStyle = new ol.style.Style({
image: new ol.style.Icon({
opacity: 0.75,
src: "http://openlayers.org/en/v3.9.0/examples/data/icon.png"
}),
});
相关API:
1、new ol.style.Style
2、new ol.style.Icon
//创建矢量层
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
//添加进map层
map.addLayer(vectorLayer);
相关API:
1、new ol.layer.Vector
Done!
示例演示,点这里
这个是在这几个案例中最复杂的一个了。
分析:在OpenLayers3中,弹出框是一个Overlay,overlay的中文是覆盖物的意思,弹出框不就是一个覆盖物吗?
这里又牵扯到一个新的知识点,那就是地图的事件监听,在map类中有一个on方法,但这个方法的确能对点击事件进行监听,但是是对整个map的。也就是说,我点击地图上的任何位置,都会触发这个监听事件,效果上并不是我们想要的。我们想要的是在点击标记后才触发监听事件。幸运的是,OpenLayers在map类中为我们提供了一个函数,叫forEachFeatureAtPixe
,这个函数的工作原理有点类似物理中的光电门,这个函数会对所给定的像素范围进行扫描,如果发现Feature(标记就是一个Feature),就会触发回掉函数。那么如何给定点击像素呢?OpenLayers又很贴心地给我们准备了getEventPixe
函数,这个函数会在事件触发时,返回对应的像素范围。
总结思路: 在点击地图时触发getEventPixel
函数返回区域->调用forEachFeatureAtPixel
进行像素区域扫描,如果发现Feature,则激活弹出框。
<div id="popup" class="ol-popup">
"#" id="popup-closer" class="ol-popup-closer">
<div id="popup-content">div>
div>
1、这里所有的id都需要记录
2、这里还需要对弹出框设定样式,例子CSS样式将在文章最后的源码中给出
var container = document.getElementById("popup");
var content = document.getElementById("popup-content");
var popupCloser = document.getElementById("popup-closer");
1、container:最外层包含所有元素的div
2、content:显示弹出框具体内容的div
3、popupCloser:弹出框的关闭按钮,是一个a标签
var overlay = new ol.Overlay({
//设置弹出框的容器
element: container,
//是否自动平移,即假如标记在屏幕边缘,弹出时自动平移地图使弹出框完全可见
autoPan: true
});
相关API:
1、new ol.Overlay
map.on('click',function(e){
//在点击时获取像素区域
var pixel = map.getEventPixel(e.originalEvent);
map.forEachFeatureAtPixel(pixel,function(feature){
//coodinate存放了点击时的坐标信息
var coodinate = e.coordinate;
//设置弹出框内容,可以HTML自定义
content.innerHTML = "你点击的坐标为:"
+ coodinate + "";
//设置overlay的显示位置
overlay.setPosition(coodinate);
//显示overlay
map.addOverlay(overlay);
});
});
相关API:
1、map.on
2、map.getEventPixel
3、map.forEachFeatureAtPixel
4、overlay.setPosition
5、map.addOverlay
Done! 至此,在地图上点击标记时,就会有弹出框显示了~
示例演示,点这里
GitHub
演示合集
Openlayer3.13.1的几个API的部分翻译
1、Openlayers3 加载Geowebcache 发布的 ArcGIS 切片地图
2、Openlayer 3 的点击弹出框
由于OpenLayers3几乎没有中文的API,于是乎就去翻译了,翻译了两天,部分语句采用了Google Translate的翻译结果。如果出现错误可以在评论区反馈~多谢谅解~~其实翻译一遍在结合代码理解会更清晰一些~