Openlayers2实现的路径追踪动态效果

本功能将实现在给定的任意线路(线上可以有任意多个节点)上,要素在线的轨迹上进行匀速移动。
track.js

var map = new OpenLayers.Map("map");
function initMap(){
    var baseLayer = new OpenLayers.Layer.WMS(
        "basic",
        "http://localhost:8080/geoserver/chinaNS/wms",
        {
            layers: "chinaNS:china",
            transparent: true
        },
        {isBaseLayer:true}
    );
    var protocolObj = new OpenLayers.Protocol.WFS({
        url:"http://localhost:8080/geoserver/chinaNS/wfs",
        featureType: "heliu",
        geometryName: "the_geom"
    });

    var filterObj = new OpenLayers.Filter.Comparison({
        type: OpenLayers.Filter.Comparison.EQUAL_TO,
        property: "NAME",
        value: "金沙江"
    });

    var styles = new OpenLayers.StyleMap({
        fillColor: "#B18904",
        strokeColor: "#FE9A2E",
        strokeWidth: 1
    })

    var wfsLayer = new OpenLayers.Layer.Vector(
        'vector',
        {
            strategies: [new OpenLayers.Strategy.BBOX()],
            protocol: protocolObj,
            styleMap: styles,
            filter: filterObj
        }
    );    
    map.addLayers([baseLayer,wfsLayer]);
    map.setCenter(new OpenLayers.LonLat(108, 34), 4);
}

var movePoints=[];//运动状态的点集合
var insertResult = [];//插入点的结果集合
var timer;//定时器
var index=0;//数组索引

/**
 * 开始追踪动画,动画方法入口
 * @param {要实现动画的线,一个geometry对象} lineGeometry
 * @param {点间距} points_distance 
 * @param {闪烁频率} refresh_time 
 */
function startTracker(line,points_distance,refresh_time){
	var myStyles1 = new OpenLayers.StyleMap({
	    "default": new OpenLayers.Style({
	        strokeColor: "${color}",
	        strokeWidth: "${type}",
	    })
	});
	
	//定义图层,用于承载追踪要素
	var lineLayer = new OpenLayers.Layer.Vector(
	    'line',
	    {
	        // styleMap: new OpenLayers.StyleMap({
	        // strokeColor: "#FF4000",
	        // strokeWidth: 5
	        // })
	        //styleMap: new OpenLayers.StyleMap(myStyles)
	        styleMap:myStyles1,
	        rendererOptions: {zIndexing: true}
	    }
	);

    var points = line.getVertices();
    insertResult = insertPoint(points,points_distance);
    map.zoomToExtent(line.bounds);
    timer = window.setInterval("tracking()",refresh_time);
}

//蝌蚪状追踪效果,需要将图层样式,如myStyles1
function tracking(){
    if(index >= insertResult.length){
        window.clearInterval(timer);
        index=0;
        lineLayer.removeAllFeatures();
        return;
    }
    var features = [];
    var curPoints = insertResult.slice(index,index + 100);
    for (let i = 0; i < 5; i++) {
        var movePoints = curPoints.slice(i * 20,(i +1) *20);
        var lineGeom = new OpenLayers.Geometry.LineString(movePoints);
        var lineFeature = new OpenLayers.Feature.Vector(
            lineGeom,
            {
                type:i * 2,
                color: "#" + i + i + i + i + "FF"
            }
        );
        features.push(lineFeature);
    }
    lineLayer.removeAllFeatures();
    lineLayer.addFeatures(features);
    //map.setCenter(new OpenLayers.LonLat(insertResult[index].x,insertResult[index].y), 6);
    ++index;
}

插值算法

//本方法用于实现在一条线上进行等距插入点。

/**
 * 计算两点间的距离
 * @param {起点} point1 
 * @param {终点} point2 
 */
function getDistance(point1,point2){
        var offsetx = point2.x - point1.x
        var offsety = point2.y - point1.y;
        var distance = Math.sqrt(Math.pow(offsetx,2) + Math.pow(offsety,2));
        return distance;
    }
    
/**
 * 
 * @param {起点} startPoint 
 * @param {间隔长} length 
 * @param {线段斜率} k 
 */
function markInsertPoint(startPoint,endPoint,length,k){
    var angle = Math.atan(k);
    var ox = Math.abs(length * Math.cos(angle));
    var oy = Math.abs(length * Math.sin(angle));
    if(k >=0){
        if(endPoint.x < startPoint.x){
            ox = -ox;
            oy = -oy;
        }
    }
    if(k<0){
        if(endPoint.x < startPoint.x){
            ox = -ox;
        }else{
            oy = -oy;
        }
    }
    return new OpenLayers.Geometry.Point(startPoint.x + ox,startPoint.y + oy);
}
/**
 * 判断点是否在线段的坐标范围内
 * @param {要判断的点} point 
 * @param {起点} startpoint 
 * @param {终点} endpoint 
 */
function pointInLine(point,startpoint,endpoint){
    var minx = Math.min(startpoint.x,endpoint.x);
    var maxx = Math.max(startpoint.x,endpoint.x);
    var miny = Math.min(startpoint.y,endpoint.y);
    var maxy = Math.max(startpoint.y,endpoint.y);
    var curx = point.x;
    var cury = point.y;
    if(curx > maxx || curx < minx || cury > maxy || cury < miny){
        return false;
    }else{
        return true;
    }
}
    
/**
 * 给定一组坐标及间隔距离,进行等距插点,返回插入后的结果
 * @param {坐标点集合} pointlist 
 * @param {间隔距离} l 
 */
function insertPoint(pointlist,l){
    var newPointList=[];
    newPointList.push(pointlist[0]);
    var curLen=0; //计算当前插入点所用的长度
    var lastInsertLen=0;//上一个插入点与线段终点的长度
    for (let i = 1; i < pointlist.length; i++) {
        var sp = pointlist[i - 1];
        var ep = pointlist[i];
        var selen = getDistance(sp,ep);
        var curLen=l-lastInsertLen;
        if(selen < curLen){
            newPointList.push(ep);
            curLen = curLen -selen;
        }else{
            var k = (ep.y-sp.y)/(ep.x-sp.x);
            while(true){
                var insertPoint = markInsertPoint(sp,ep,curLen,k);
                if(pointInLine(insertPoint,sp,ep)){
                    newPointList.push(insertPoint);
                    sp = insertPoint;
                    curLen = l;
                }else{
                    newPointList.push(ep);
                    lastInsertLen = getDistance(sp,ep);
                    break;
                }
            }
        }
    }
    newPointList.push(pointlist[pointlist.length-1]);
    return newPointList;
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link href="/css/map.css" rel="stylesheet">
    <link href="/bootstrap-4.1.3-dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="/jquery-2.0.0/jquery.min.js"></script>
    <script src="/openlayers2/lib/OpenLayers.js"></script>
    <style>
        body{
            background-color:#151515;
        }
        #map{
            width: 100%;
            height: 600px;
            border: 0ch;
            background-color:#151515;
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="row">
            <div class="col-lg-12">
                <button type="button" class="btn" id ="start">开始</button>                
                <div id="map" class="map"></div>
            </div>
        </div>
    </div>
    <script src="/js/ol2/track.js"></script>
      <script src="/js/ol2/insertPointInLine.js"></script>
    <script>
        $(document).ready(function(){
            initMap();
        });
        $("#start").click(function(){            
            var dataSource = map.getLayersByName("vector");
            var features = dataSource[0].features;
            var line = features[0].geometry;
            startTracker(line,0.05,10);
        });
    </script>
</body>
</html>
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值