跳到主要内容

OpenLayers

介绍

OpenLayers 是一个专为 WebGIS 客户端开发提供的 JavaScript 类库包,用于实现标准格式发布的地图数据访问。 简单说,就是用于在网页中实现地图的动态显示和交互。

官网:https://openlayers.org/

下载:https://openlayers.org/download/

快速上手

<!DOCTYPE html>
<html lang="en">
<head>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/css/ol.css"
type="text/css"
/>
<style>
.map {
height: 400px;
width: 100%;
}
</style>
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.1.1/build/ol.js"></script>
<title>OpenLayers example</title>
</head>
<body>
<h2>My Map</h2>
<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.OSM() // 数据源
})
],
view: new ol.View({
center: ol.proj.fromLonLat([37.41, 8.82]), // 视图中心
zoom: 4 // 初始缩放层级
})
})
</script>
</body>
</html>

整个地图看作一个容器(Map),核心为地图图层(Layer),每个图层有对应的数据源(Source),并由地图视图(View)进行地图展示。地图容器上还支持一些与用户交互的控件(Control 和 Interaction),另外,OpenLayers 还支持事件机制。

加载 WMS 服务

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>index</title>
<link rel="stylesheet" href="./openlayers/ol.css" />
<script src="./openlayers/ol.js"></script>
<style>
#map {
width: 100%;
height: 100vh;
}
</style>
</head>
<body>
<div id="map"></div>
<script>
const map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://xxx/geoserver/xxx/wms', // wms服务地址
params: {
LAYERS: 'xxx:xxx', // 图层
TILED: true
},
serverType: 'geoserver' // 服务类型
})
})
],
view: new ol.View({
// 限制地图范围
// extent: fromLonLat([115.7,39.4,117.4,41.6]),
center: ol.proj.fromLonLat([116.38, 39.9]),
zoom: 11,
// 限制地图缩放级别
minZoom: 6,
maxZoom: 20
// projection: 'EPSG:3857' // 默认投影为 EPSG:3857
}),
controls: [
// 添加层级缩放控件
new ol.control.Zoom(),
// 添加比例尺控件
new ol.control.ScaleLine({
//设置度量单位为米
units: 'metric',
className: 'ol-scale-line'
})
]
})
</script>
</body>
</html>

绘制点线面

openlayers 支持的类型有 Point, LineString, LinearRing, Polygon, MultiPoint, MultiLineString, MultiPolygon, GeometryCollection, Circle

在以上代码的基础上接着添加以下代码:

// 添加一个矢量图层
const pointLayer = new ol.layer.Vector({
source: new ol.source.Vector()
})
map.addLayer(pointLayer)

// 添加交互
const drawPoint = new ol.interaction.Draw({
type: 'Point',
source: pointLayer.getSource()
})
map.addInteraction(drawPoint)

首先添加一个矢量图层,接着创建一个交互,注意添加 source: pointLayer.getSource() 用于保存绘制的内容。如果要绘制线、面等其他类型,只需更改ol.interaction.Draw()中 type 的类型即可。

手绘形状

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>freehand</title>
<link rel="stylesheet" href="./openlayers/ol.css" />
<style>
ul,
li {
list-style: none;
}
ul li {
width: 75px;
height: 28px;
line-height: 28px;
cursor: pointer;
}
ul li:hover {
background-color: #40e0d0;
}
#map {
position: relative;
width: 100%;
height: 800px;
}
.operat {
position: absolute;
top: 20px;
right: 60px;
z-index: 2000;
display: flex;
color: #fff;
background: #34495e;
padding-left: 0;
text-align: center;
}
#type {
display: none;
top: 28px;
color: #fff;
background: #34495e;
font-size: 14px;
width: 150px;
text-align: left;
outline: none;
}
#type option {
width: 150px;
height: 25px;
line-height: 25px;
}
#type option:hover {
background-color: #008080;
}
</style>
<script src="./openlayers/ol.js"></script>
</head>
<body>
<div id="map">
<ul class="operat">
<li id="shape">
Shape
<select id="type">
<option value="none">None</option>
<option value="Point">Point</option>
<option value="LineString">LineString</option>
<option value="Polygon">Polygon</option>
<option value="Circle">Circle</option>
<option value="Rectangle">Rectangle</option>
<option value="Square">Square</option>
<option value="freehandLine">freehandLine</option>
<option value="freehandPolygon">freehandPolygon</option>
</select>
</li>
<li id="disable">Disable</li>
<li id="clear">Clear</li>
</ul>
</div>
<script>
let map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'http://xxx/geoserver/xxx/wms',
params: {
LAYERS: 'xxx:xxx',
TILED: true
},
serverType: 'geoserver'
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([116.38, 39.9]),
zoom: 11,
minZoom: 6,
maxZoom: 20
}),
controls: [
new ol.control.Zoom(),
new ol.control.ScaleLine({
units: 'metric',
className: 'ol-scale-line'
})
]
})

let typeSelect = document.getElementById('type')
let shape = document.getElementById('shape')
shape.onmouseover = function() {
typeSelect.style.display = 'block'
typeSelect.size = 9
}
shape.onmouseout = function() {
typeSelect.style.display = 'none'
}
let draw

// 添加一个矢量图层
let vectorLayer = new ol.layer.Vector({
source: new ol.source.Vector(),
style: new ol.style.Style({
// 线的样式
stroke: new ol.style.Stroke({
color: '#000',
width: 2
}),
// 将点设置成圆形样式
image: new ol.style.Circle({
// 点的颜色
fill: new ol.style.Fill({
color: '#f00'
}),
// 圆形半径
radius: 5
})
})
})
map.addLayer(vectorLayer)

function addInteraction() {
let value = typeSelect.value
if (value !== 'none') {
switch (value) {
case 'Point':
draw = new ol.interaction.Draw({
type: 'Point',
source: vectorLayer.getSource()
})
break
case 'LineString':
draw = new ol.interaction.Draw({
type: 'LineString',
source: vectorLayer.getSource()
})
break
case 'Polygon':
draw = new ol.interaction.Draw({
type: 'Polygon',
source: vectorLayer.getSource()
})
break
case 'Circle':
draw = new ol.interaction.Draw({
type: 'Circle',
source: vectorLayer.getSource()
})
break
case 'Rectangle':
draw = new ol.interaction.Draw({
type: 'Circle',
source: vectorLayer.getSource(),
geometryFunction: ol.interaction.Draw.createBox()
})
break
case 'Square':
draw = new ol.interaction.Draw({
type: 'Circle',
source: vectorLayer.getSource(),
// 参数 4 表示4条边,此处可随意设置多边形
geometryFunction: ol.interaction.Draw.createRegularPolygon(4)
})
break
case 'freehandLine':
draw = new ol.interaction.Draw({
type: 'LineString',
freehand: true, // 手绘任意线
source: vectorLayer.getSource()
})
break
case 'freehandPolygon':
draw = new ol.interaction.Draw({
type: 'Polygon',
freehand: true,
source: vectorLayer.getSource()
})
break
default:
break
}
map.addInteraction(draw)
}
}

// 监听选择的值
typeSelect.onchange = function() {
//先移除上一个Interaction
map.removeInteraction(draw)
//再根据typeSelect的值绘制新的Interaction
addInteraction()
}
addInteraction()

let disableDraw = document.getElementById('disable')
disableDraw.addEventListener('click', function() {
map.removeInteraction(draw)
})

let clearDraw = document.getElementById('clear')
clearDraw.addEventListener('click', function() {
// 移除矢量图层数据
vectorLayer.getSource().clear()
// 移除交互
// map.removeInteraction(draw)
})
</script>
</body>
</html>

矢量图层

删除矢量图层

// 必须先移除矢量图层数据
vectorLayer.getSource().clear()

// 删除图层
map.removeLayer(vectorLayer)