通过控制图层,层级和大小来实现图层透视功能。 主要使用图层监听事件 prerender监听图层渲染之前,postrender监听图层渲染之后。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<style type="text/css">
.map {
height: 500px;
width: 100%;
}
</style>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/css/ol.css" />
<script src="https://cdn.jsdelivr.net/gh/openlayers/openlayers.github.io@master/en/v6.6.1/build/ol.js"></script>
<body>
<div id="map" class="map"></div>
</body>
<script>
// 图层
var roads = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
})
})
// 图层2
var imagery = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
})
})
// 实例
const container = document.getElementById('map')
var map = new ol.Map({
target: container,
layers: [roads, imagery],
view: new ol.View({
center: ol.proj.fromLonLat([37.41, 8.82]),
zoom: 4
})
})
</script>
</html>
- 这里我们创建了两个图层,记住图层的默认层级都是后面添加的大于前面的层级。
- 要实现图层透视的效果,其实就是在基础图层上固定范围绘制上图层来达到效果。
获取鼠标在地图上的坐标位置
// 地图像素位置
let mousePosition = null
container.addEventListener('mousemove', function (event) {
// getEventPixel(event) 根据事件当前位置 返回地图像素位置。
mousePosition = map.getEventPixel(event)
// 重新渲染地图 render()
map.render()
})
container.addEventListener('mouseout', function () {
mousePosition = null
map.render()
})
- 创建全局变量(
mousePosition
)实时保存鼠标地理位置。 - 通过监听容器的鼠标移入事件获取当前位置窗口位置,使用
getEventPixel()
转换为地理位置。 - 监听容器的鼠标移出事件取消地理位置。
- 每次监听都需要重绘地图,用于透视图层内容的更新。
监听图层事件
// 半径
let radius = 75
// 图层渲染之前
imagery.on('prerender', function (event) {
const ctx = event.context
ctx.save() // 保存
ctx.beginPath()
if (mousePosition) {
ctx.arc(mousePosition[0], mousePosition[1], radius, 0, 2 * Math.PI)
ctx.lineWidth = (5 * radius) / radius
ctx.strokeStyle = 'rgba(0,0,0,0.5)'
ctx.stroke()
}
// 使用裁剪 只加载 圆内数据
ctx.clip()
})
// 图层渲染之后
imagery.on('postrender', function (event) {
const ctx = event.context
ctx.restore()
})
- 这里绘制的是圆形,你可以自定义其他图形。
- 通过图层事件
prerender
图层渲染之前,在监听中返回的图层实例canvas
。这里一定要先保存状态ctx.save()
,通过mousePosition
获取鼠标的坐标,随意绘制图形,使用clip()
裁剪画布,只展示裁剪后的内容。 - 通过
postrender
图层渲染之后。恢复保存的canvas
内容展示。
Vector
图层通过绘制多边行的方法
使用- 绘制出省市区的多边行,把该图层添加到地图图层上,就实现了绘制省市区图形。
Vector
- 矢量图层: 在客户端呈现的矢量数据。构成一个矢量图层需要一个数据源(
source
)和一个样式(style
),数据源构成矢量图层的要素,样式规定要素显示的方式和外观。一个矢量图层包含一个到多个要素(feature
),每个要素由地理属(geometry
)和其他属性组成。 - 常用于从数据库中请求数据,接受数据,并将接收的数据解析成图层上的信息。如将鼠标移动到中国,相应的区域会以红色高亮显示出来,高亮便是矢量图层的行为。
var map = new ol.Map({
target: 'map'
})
// 图层
var layerTile = new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
})
})
// 视图
var view = new ol.View({
center: ol.proj.fromLonLat([130.41, 28.82]),
zoom: 4
})
map.setView(view)
map.addLayer(layerTile)
绘制图层
js复制代码 // 设置图层
var areaLayer = new ol.layer.Vector({
source: new ol.source.Vector({
features: []
})
})
// 添加图层
map.addLayer(areaLayer)
let areaFeature = []
geo.forEach((g) => {
var areaFeatureTem = null
let lineData = g.features[0]
if (lineData.geometry.type == 'MultiPolygon') {
areaFeatureTem = new ol.Feature({
geometry: new ol.geom.MultiPolygon(lineData.geometry.coordinates).transform('EPSG:4326', 'EPSG:3857')
})
} else if (lineData.geometry.type == 'Polygon') {
areaFeatureTem = new ol.Feature({
geometry: new ol.geom.Polygon(lineData.geometry.coordinates).transform('EPSG:4326', 'EPSG:3857')
})
}
areaFeatureTem.setStyle(
new ol.style.Style({
fill: new ol.style.Fill({ color: '#4e98f444' }),
stroke: new ol.style.Stroke({
width: 3,
color: [71, 137, 227, 1]
})
})
)
areaFeature.push(areaFeatureTem)
})
// 加入组装好的数据
areaLayer.getSource().addFeatures([...areaFeature])
- 先创建图层,然后创建要素。多边行在要素中主要分为两种,
MultiPolygon
、Polygon
,都是表示多边行的。不同的是MultiPolygon
数据格式是4维数组,Polygon
是3维数组。最后把创建好的要素放入图层中。