openlayer地图使用
第一部分: 认识和学习ol
简述:
OpenLayers是一个用于开发WebGIS客户端的JavaScript包
目前OpenLayers已经成为一个拥有众多开发者和帮助社区的成熟、流行的框架。
基本概念:
一般地图构成: 一个底图 + 其他各种图层 + 控件
引入js css
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>openlayers-exercise</title>
<script src="reference/ol/ol.js"></script>
<script src="reference/jq/jquery-3.2.1.js"></script>
<style>
#map {
width: 700px;
height: 700px;
}
</style>
</head>
<body>
<div id="map" class="map"></div>
</body>
<script src="./js/lyxmap.js"></script>
</html>
一个最简单的map
lyxmap.js 一个底图+ 最少一个layers
var map;
//layers、target、view是地图最基本的部分,是必需的
map = new ol.Map({
layers: [ //layers 可以理解为组件容器,里面可以放置多种组件
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
view: new ol.View({ // view可以理解为视口
projection: 'EPSG:4326', // 要指定编码格式
center: [120.372451, 29.56432], // 经纬度中心点
zoom: 8
})
});
地图出来了。
1.1叠加图层
首先需要明白的一点是,Source和Layer是一对一的关系,有一个Source,必然需要一个Layer,然后把这个Layer添加到Map上,就可以显示出来了。通过官网的API搜索ol.source可以发现有很多不同的Source,但归纳起来共三种:ol.source.Tile,ol.source.Image和ol.source.Vector。
ol.source.Tile对应的是瓦片数据源,现在网页地图服务中,绝大多数都是使用的瓦片地图,而OpenLayers 3作为一个WebGIS引擎,理所当然应该支持瓦片。
ol.source.Image对应的是一整张图,而不像瓦片那样很多张图,从而无需切片,也可以加载一些地图,适用于一些小场景地图。
ol.source.Vector对应的是矢量地图源,点,线,面等等常用的地图元素(Feature),就囊括到这里面了。这样看来,只要这两种Source就可以搞定80%的需求了。
从复杂度来分析,ol.source.Image和ol.source.Vector都不复杂,其数据格式和来源方式都简单。而ol.source.Tile则不一样,由于一些历史问题,多个服务提供商,多种标准等诸多原因,导致要支持世界上大多数的瓦片数据源,就需要针对这些差异提供不同的Tile数据源支持。在更进一步了解之前,我们先来看一下OpenLayers 3现在支持的Source具体有哪些:
我们主要来分析一下ol.source.Tile,这个由于各种原因比较复杂,其叶子节点类有很多,大致可以分为几类:
在线服务的Source,包括ol.source.BingMaps(使用的是微软提供的Bing在线地图数据),ol.source.MapQuest(使用的是MapQuest提供的在线地图数据)(注: 由于MapQuest开始收费,ol v3.17.0就移除了ol.source.MapQuest),ol.source.OSM(使用的是Open Street Map提供的在线地图数据),ol.source.Stamen(使用的是Stamen提供的在线地图数据)。没有自己的地图服务器的情况下,可直接使用它们,加载地图底图。
支持协议标准的Source,包括ol.source.TileArcGISRest,ol.source.TileWMS,ol.source.WMTS,ol.source.UTFGrid,ol.source.TileJSON。如果要使用它们,首先你得先学习对应的协议,之后必须找到支持这些协议的服务器来提供数据源,这些服务器可以是地图服务提供商提供的,也可以是自己搭建的服务器,关键是得支持这些协议。
ol.source.XYZ,这个需要单独提一下,因为是可以直接使用的,而且现在很多地图服务(在线的,或者自己搭建的服务器)都支持xyz方式的请求。国内在线的地图服务,高德,天地图等,都可以通过这种方式加载,本地离线瓦片地图也可以,用途广泛,且简单易学,需要掌握。
总结概括呢就是如果你没有地图服务器,那么你要加载地图就只能调用地图商发布的在线服务,包括在线服务的Source:ol.source.BingMaps,ol.source.OSM等地图;还有一种是ol.source.XYZ格式的在线服务地图,包括国内的一些在线服务地图,高德、百度、天地图等。
如果你有自己的地图服务器,那么你就可以发布地图服务然后在OpenLayers中调用自己发布的服务了,例如我们常见的几种发布的服务:ol.source.TileArcGISRest—ArcGIS发布的服务还有Geoserver发布的服务等等。
1、在线地图服务的加载,
<!doctype html>
<html xmlns=http://www.w3.org/1999/xhtml>
<head>
<meta http-equiv=Content-Type content="text/html;charset=utf-8">
<meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1">
<meta content=always name=referrer>
<title>在线地图加载</title>
<link href="css/ol.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="js/ol.js" charset="utf-8"></script>
</head>
<body>
<div> 显示/隐藏:
<input type="checkbox" checked="checked" onclick="checkERSI(this);" />加载ArcGIS地图
<input type="checkbox" checked="checked" onclick="checkOSM(this);"/>加载Open Street Map地图
<input type="checkbox" checked="checked" onclick="checkTDT(this);"/>加载天地图
<input type="checkbox" checked="checked" onclick="checkAmap(this);"/>加载高德地图
</div>
<div>
图层顺序:
<input name="seq" type="radio" value="" onclick="upArcGIS(this);" />ArcGIS地图在最上
<input name="seq" type="radio" value="" onclick="upOSM(this);"/>OSM地图在最上
<input name="seq" type="radio" value="" checked="checked" onclick="upTDT(this);"/>天地图在最上
<input name="seq" type="radio" value="" checked="checked" onclick="upAmap(this);"/>高德地图在最上
</div>
<div id="map" style="width: 100%"></div>
<script>
// 创建4个图层
//ArcGIS地图
var esriMapLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}'
}),
title:"ESRI影像"
});
//OSM地图
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM(),
title:"OSM影像"
});
//天地图
var tiandituSatelliteLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: "http://t3.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=008a8816d2eee25a677670273eaee891",
crossOrigin: "anonymous"
}),
title:"天地图影像"
});
//高德地图
var gaodeMapLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url:'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
})
});
var map=new ol.Map({
// 在地图上添加上面创建的四个图层,图层顺序自下而上,依次是ESRI地图,OSM地图,天地图和高德地图
layers: [esriMapLayer, osmLayer, tiandituSatelliteLayer,gaodeMapLayer],
view: new ol.View({
center: [120.374,36.073],
projection: 'EPSG:4326',
zoom: 10
}),
target: 'map'
});
map.getView().fit([120.33944,36.049352, 120.442925,36.126585], map.getSize());
// 隐藏显示esri图层
function checkERSI(elem) {
esriMapLayer.setVisible(elem.checked);
}
// 隐藏显示osm图层
function checkOSM(elem) {
osmLayer.setVisible(elem.checked);
}
// 隐藏显示天地图图层
function checkTDT(elem) {
tiandituSatelliteLayer.setVisible(elem.checked);
}
// 隐藏显示高德地图图层
function checkAmap(elem) {
gaodeMapLayer.setVisible(elem.checked);
}
// 置顶esri图层到最上面
function upArcGIS (elem) {
if (elem.checked) {
esriMapLayer.setZIndex(3);
osmLayer.setZIndex(osmLayer.getZIndex()-1);
tiandituSatelliteLayer.setZIndex(tiandituSatelliteLayer.getZIndex()-1);
gaodeMapLayer.setZIndex(gaodeMapLayer.getZIndex()-1);
}
}
// 置顶osm图层到最上面
function upOSM (elem) {
if (elem.checked) {
osmLayer.setZIndex(3);
esriMapLayer.setZIndex(esriMapLayer.getZIndex()-1);
tiandituSatelliteLayer.setZIndex(tiandituSatelliteLayer.getZIndex()-1);
gaodeMapLayer.setZIndex(gaodeMapLayer.getZIndex()-1);
}
}
// 置顶天地图图层到最上面,
function upTDT(elem) {
if (elem.checked) {
tiandituSatelliteLayer.setZIndex(3);
esriMapLayer.setZIndex(esriMapLayer.getZIndex()-1);
osmLayer.setZIndex(osmLayer.getZIndex()-1);
gaodeMapLayer.setZIndex(gaodeMapLayer.getZIndex()-1);
}
}
// 置顶高德地图图层到最上面
function upAmap(elem) {
if (elem.checked) {
gaodeMapLayer.setZIndex(3);
esriMapLayer.setZIndex(esriMapLayer.getZIndex()-1);
osmLayer.setZIndex(osmLayer.getZIndex()-1);
tiandituSatelliteLayer.setZIndex(tiandituSatelliteLayer.getZIndex()-1);
}
}
</script>
</body>
</html>
摘抄上面的代码 先来运行代码看一下效果如下图:
Tile 瓦片图层
var basemap = new ol.layer.Tile({
source: new ol.source.OSM()
});
//高德地图
var gaodeMapLayer = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://webst0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}'
})
});
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM(),
title: "OSM影像"
});
上面有三个瓦片类的图层,可以依次放到map的layers中查看。
map = new ol.Map({
layers: [ osmLayer],
target: 'map',
view: new ol.View({
projection: 'EPSG:4326',
center: [120.372451, 29.56432],
zoom: 8
})
});
加载Image图层
下面这个图层是使用自己geoserverr 配置的图层。
// 乡镇图层(无名字)
var xz = new ol.layer.Image({
zIndex: 3,
source: new ol.source.ImageWMS({
url: 'http://自己服务器的ip:8080/geoserver/zjlwjc/wms',
params: {
'LAYERS': '*****:ji******',
'STYLES': 'zjlwjc:JinDon'
},
ratio: 1,
serverType: 'geoserver'
}),
});
地图开发实战之Geoserver配置与发布地图服务, 感兴趣可以查看。
https://blog.csdn.net/MagicMHD/article/details/91430148
加载 ol.layer.Vector 矢量图层
var vectorLayer = new ol.layer.Vector({
zIndex: 99,
source: vectorSource,
});
map.addLayer(vectorLayer)
见第二部分:地图撒点案例
2.2 new ol.source 数据源
new ol.layer.Tile 的 source使用 new ol.source.WMTS
官方解释: Layer source for tile data from WMTS servers. 解析瓦片的
new ol.layer.Image 的 source使用 new ol.source.ImageWM
官方解释:Source for WMS servers providing single, untiled images. 解析图片的
那么 ,ol.source的种类有多少 官网上给出约48中
1.2 Openlayer:学习笔记之控件

这些控制器在实现上,并不是在画布上绘制的,而是使用传统的HTML元素来实现的,便于同地图分离,也便于界面实现。 具体可参考 https://blog.51cto.com/u_15349906/3717226
第二部分 业务场景和实现
- 展示地图
- 根据业务展示瓦片地图获取图片地图
- 添加点 和点的点击事件 mark lable文字标注和样式调整
- 对图层的事件操作: 飞视角 zoom调整
地图撒点:
一个点,标记到地图上,逻辑。
与加载矢量要素相同,分别实例化矢量图层(ol.layer.Vector)和矢量数据源(ol.source.Vector),将矢量图层加载到地图容器中。
其中,数据源中设置的矢量点要素,通过实例化ol.Feature创建,分别设置要素的几何信息(geometry)与属性信息(如name、population)等。矢量要素的样式通过setStyle方法进行设置,由createLabelStyle函数实现。
ol.Feature的关键参数如下:
- geometry:几何图形对象,标注点一般设置为ol.geom.Point对象
- 自定义的属性项:如name、population等,可根据需要自行定义,这些属性项可通过get方法进行获取,如feature.get(‘name’)。
// 添加点标记
/** 设置点图层 */
矢量特征对象
3 var iconFeature = new ol.Feature({
geometry: new ol.geom.Point([119.68827577544099, 29.10216260533227]),
name: 'Null Island',
population: 4000,
rainfall: 500,
});
矢量特征对象 --样式
var iconStyle = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: "图片的地址",
scale: 0.2,
}),
text: new ol.style.Text({
text: "**区人民政府",
offsetX: 0,
offsetY: -12,
scale: 1.2,
backgroundFill: "#000",
font: "10px sans-serif",
fill: new ol.style.Fill({
color: '#FF1400'
}),
})
});
iconFeature.setStyle(iconStyle);
2为矢量图层提供特征源
var vectorSource = new ol.source.Vector({
features: [iconFeature],
});
1矢量图层
var vectorLayer = new ol.layer.Vector({
zIndex: 99,
source: vectorSource,
});
map.addLayer(vectorLayer)
当地图上的点很多时, 会出现点重合,覆盖。引出另一个功能。
Openlayers 实例-点聚合
待续…