本功能将实现在给定的任意线路(线上可以有任意多个节点)上,要素在线的轨迹上进行匀速移动。
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>