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

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

示例中需要使用【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={x}&y={y}&l={z}&tk=' + 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={x}&y={y}&l={z}&tk=' + 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={x}&y={y}&l={z}&tk=' + 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={x}&y={y}&l={z}&tk=' + 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

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值