0
点赞
收藏
分享

微信扫一扫

WebGIS实现客户端可视化要素动画

NicoalsNC 2022-01-06 阅读 56

本文的示例主要展示如何在地图中添加点的要素动画效果,具体效果如下图所示:

示例中需要使用【include-openlayers-local.js】开发库,首先创建地图对象,添加天地图底图,通过定时器生成随机点。为地图容器map添加postcompose事件(地图渲染中)使其形成由半径从小到大的显示效果,以及为为要素源添加addfeature事件(当要素添加时)。

主要步骤

1. 引用开发库:

本示例引用 local 本地【include-openlayers-local.js 】开发库;

2. 创建布局:

创建id="mapCon"的 div 作为地图容器,并设置其样式;

3. 创建地图对象:

创建地图对象,设置地图必要参数;

//初始化地图容器
map = new ol.Map({
target: 'mapCon', //地图容器div的ID
controls: ol.control.defaults({
attributionOptions: {
collapsible: true,
},
}),
view: new ol.View({
center: [0, 0], //地图初始中心点
maxZoom: 28, //最大瓦片显示级数
minZoom: 1, //最小瓦片显示级数
zoom: 2, //地图初始显示级数
projection: 'EPSG:4326',
}),
})

4. 添加天地图:

创建天地图图层,添加到地图中;

var tdk = '4c27d6e0e8a90715b23a989d42272fd8' //天地图密钥
//加载天地图瓦片图层数据
map.addLayer(
new ol.layer.Tile({
title: '天地图影像图层',
source: new ol.source.XYZ({
url: 'http://t0.tianditu.com/DataServer?T=vec_w{x}{y}{z}' + tdk,
wrapX: false,
}),
projection: 'EPSG:4326',
})
)
map.addLayer(
new ol.layer.Tile({
title: '天地图矢量注记图层',
source: new ol.source.XYZ({
url: 'http://t0.tianditu.com/DataServer?T=cva_w{x}{y}{z}' + tdk,
wrapX: false,
}),
projection: 'EPSG:4326',
})
)

5. 创建空图层:

创建一个空图层,用于存储后续创建点要素动画效果时的点;

var source = new ol.source.Vector({
wrapX: false,
})
var vector = new ol.layer.Vector({
source: source,
})
map.addLayer(vector)

6. 添加随机点:

通过定时器每隔一定时间添加一个随机点;

var intervalID = window.setInterval(addRandomFeature, 1000)
var count = 0
function addRandomFeature() {
if (count >= 500) {
window.clearInterval(intervalID)
} else {
count++
}

var x = Math.random() * 360 - 180
var y = Math.random() * 160 - 80
var geom = new ol.geom.Point([x, y])
var feature = new ol.Feature(geom)
source.addFeature(feature)
}
 

7. 添加要素动画: 为要素源添加addfeature事件(当要素添加时)。

source.on('addfeature', function(e) {
flash(e.feature)
})
function flash(feature) {
var start = new Date().getTime()
var listenerKey = map.on('postcompose', animate)

function animate(event) {
var vectorContext = event.vectorContext
var frameState = event.frameState
var flashGeom = feature.getGeometry().clone()
var elapsed = frameState.time - start
var elapsedRatio = elapsed / duration
// radius will be 5 at start and 30 at end.
var radius = ol.easing.easeOut(elapsedRatio) * 25 + 5
var opacity = ol.easing.easeOut(1 - elapsedRatio)

var style = new ol.style.Style({
image: new ol.style.Circle({
radius: radius,
stroke: new ol.style.Stroke({
color: 'rgba(255, 0, 0, ' + opacity + ')',
width: 0.25 + opacity,
}),
}),
})

vectorContext.setStyle(style)
vectorContext.drawGeometry(flashGeom)
if (elapsed > duration) {
ol.Observable.unByKey(listenerKey)
return
}
// tell OpenLayers to continue postcompose animation
map.render()
}
}
 

关键接口

1.ol.Map

详细信息见 openlayers API

【Methods】addLayer(layer)

详细信息见 openlayers API

【Methods】render()

详细信息见 openlayers API

2.ol.source.Vector

详细信息见 openlayers API

【Methods】addFeature(feature)

详细信息见 openlayers API

【Methods】on(type, listener)

详细信息见 openlayers API

代码块

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title></title>
<!--当前示例页面样式表引用-->
<link rel="stylesheet" href="./static/demo/openlayers/example/style.css" />
<script include="jquery" src="./static/libs/include-lib-local.js"></script>
<script src="./static/libs/include-openlayers-local.js"></script>
<script type="text/javascript">
var map = null
function init() {
//初始化地图容器
map = new ol.Map({
target: 'mapCon', //地图容器div的ID
controls: ol.control.defaults({
attributionOptions: {
collapsible: true,
},
}),
view: new ol.View({
center: [0, 0], //地图初始中心点
maxZoom: 28, //最大瓦片显示级数
minZoom: 1, //最小瓦片显示级数
zoom: 2, //地图初始显示级数
projection: 'EPSG:4326',
}),
})
var tdk = '4c27d6e0e8a90715b23a989d42272fd8' //天地图密钥
//加载天地图瓦片图层数据
map.addLayer(
new ol.layer.Tile({
title: '天地图影像图层',
source: new ol.source.XYZ({
url: 'http://t0.tianditu.com/DataServer?T=vec_w{x}{y}{z}' + tdk,
wrapX: false,
}),
projection: 'EPSG:4326',
})
)
map.addLayer(
new ol.layer.Tile({
title: '天地图矢量注记图层',
source: new ol.source.XYZ({
url: 'http://t0.tianditu.com/DataServer?T=cva_w{x}{y}{z}' + tdk,
wrapX: false,
}),
projection: 'EPSG:4326',
})
)
var source = new ol.source.Vector({
wrapX: false,
})
var vector = new ol.layer.Vector({
source: source,
})
map.addLayer(vector)

var count = 0
function addRandomFeature() {
if (count >= 500) {
window.clearInterval(intervalID)
} else {
count++
}

var x = Math.random() * 360 - 180
var y = Math.random() * 160 - 80
var geom = new ol.geom.Point([x, y])
var feature = new ol.Feature(geom)
source.addFeature(feature)
}

var duration = 3000
function flash(feature) {
var start = new Date().getTime()
var listenerKey = map.on('postcompose', animate)

function animate(event) {
var vectorContext = event.vectorContext
var frameState = event.frameState
var flashGeom = feature.getGeometry().clone()
var elapsed = frameState.time - start
var elapsedRatio = elapsed / duration
// radius will be 5 at start and 30 at end.
var radius = ol.easing.easeOut(elapsedRatio) * 25 + 5
var opacity = ol.easing.easeOut(1 - elapsedRatio)

var style = new ol.style.Style({
image: new ol.style.Circle({
radius: radius,
stroke: new ol.style.Stroke({
color: 'rgba(255, 0, 0, ' + opacity + ')',
width: 0.25 + opacity,
}),
}),
})

vectorContext.setStyle(style)
vectorContext.drawGeometry(flashGeom)
if (elapsed > duration) {
ol.Observable.unByKey(listenerKey)
return
}
// tell OpenLayers to continue postcompose animation
map.render()
}
}

source.on('addfeature', function(e) {
flash(e.feature)
})

var intervalID = window.setInterval(addRandomFeature, 1000)
}
</script>
</head>

<body onload="init()">
<div id="mapCon"></div>
</body>
</html>

领取免费完整版GIS开发课程icon-default.png?t=LBL2https://www.wjx.cn/vj/e68jhwR.aspx

举报

相关推荐

Redis可视化客户端

0 条评论