Openlayers3实现车辆轨迹回放功能

记录基于geoserver地图服务,Openlayers3在web前端实现车辆轨迹回放功能,并记录和解决过程中出现的linestring只描绘部分经纬度坐标问题。

参考Openlayers3 官网例子

html

<!DOCTYPE html>

<html lang="en">

<head>

<title>车辆轨迹回放</title>

<meta charset="UTF-8"/>

<meta name="viewport" content="width=device-width, initial-scale=1.0"/>

<link rel="stylesheet" href="../css/bootstrap.min.css"/>

<link rel="stylesheet" href="../ol/ol.css"/>

<style>

#map {

position: relative;

}

.popover{

min-width: 60px;

}

html{height:100%}

body{height:100%;margin:0px;padding:0px}

</style>

</head>

<body style="margin: 0px 0px 0px 0px;line-height:0px;">

<div id="content">

<!--<div id="map" style="height: 100%;width:100%"></div>-->

<div class="row-fluid">

<div>

<div id="map" class="map"></div>

</div>

</div>

<div class="row-fluid">

<div class="span3" style="position:absolute;top:0px;right:0px;">

<div class="accordion-group widget-box">

<div class="accordion-heading">

<div class="widget-title"><a data-parent="#collapse-group" href="#collapseGOne"

data-toggle="collapse"><span class="icon"><i

class="icon-map-marker"></i></span>

<h5>轨迹查询</h5>

</a>

</div>

</div>

<div class="accordion-body in collapse" id="collapseGOne">

<div class="form-actions">

<div class="control-group" style="margin-bottom: 0px">

<label class="control-label"><i class="icon-truck"></i>设备</label>

<div class="controls">

<select id="busSelect" class="span10">

<option value="*">请选择设备</option>

</select>

</div>

</div>

</div>

<div class="form-actions">

<div class="control-group" style="margin-bottom: 0px">

<label class="control-label"><i class="icon-table"></i>日期</label>

<div class="controls">

<div data-date="" class="input-append date datepicker">

<input id="traceday" type="text" data-date-format="yyyy-mm-dd" class="span10"

disabled>

<span class="add-on"><i class="icon-time"></i></span></div>

</div>

</div>

</div>

<div style="padding: 19px 20px 20px; margin-top: 20px; margin-bottom: 20px;">

<div class="control-group" style="margin-bottom: 0px">

<button id="queryBtn" class="btn btn-primary"><i class="icon-search"></i>&nbsp;轨迹查询</button>

<span class="remind"></span>

</div>

<div class="control-group" style="margin-top: 10px">

<button id="animateBtn" class="btn btn-info"><i class="icon-eye-open"></i>&nbsp;轨迹回放</button>

<input id="speed" type="range" min="1" max="100" step="10" value="10">&nbsp;<span><i class="icon-cog">速度</i></span>

</div>

</div>

</div>

</div>

</div>

</div>

</div>

</div>

<script src="../js/lib/jquery.min.js"></script>

<script src="../js/lib/bootstrap.min.js"></script>

<script src="../ol/ol-debug.js"></script>

<script src="../ol/ol.js"></script>

<script src="../js/globalVariable.js"></script>

<script src="../js/gpsQueryAndroid.js"></script>

</body>

</html>

map初始化

$(document).ready(function () {

map = new ol.Map({

logo: false,

target: document.getElementById('map'),

layers: layers,

view: view

});

initSelect();//设备下拉框列表初始化

//时间控件初始化

$('#s-traceday').val(transfromTime(new Date(),false)+" 00:00:00");

$('#e-traceday').val(transfromTime(new Date(),true));

$('.datepicker').datetimepicker({

minView:0,

format: 'yyyy-MM-dd hh:mm:ss',

todayBtn : "linked",

autoclose : true,

todayHighlight : true,

startDate: daylimit,

endDate:'+1d'//结束时间,在这时间之后都不可选

});

});

//轨迹line layer

var vsource = new ol.source.Vector({

type: 'LineString',

features: []

});

var linelayers = new ol.layer.Vector({

source: vsource,

style: new ol.style.Style({

fill: new ol.style.Fill({

color: '#0044CC'

}),

stroke: new ol.style.Stroke({

color: '#0044CC',

width: 4

})

})

});

//地图基础参数

var map;

var center = [121.6606763113213, 31.14611063632111];

var lng, lat;

var source = new ol.source.Vector({

wrapX: false

});;

var projection = new ol.proj.Projection({

code: 'EPSG:4326',

units: 'degrees',

axisOrientation: 'neu'

});

var view = new ol.View({

projection: projection,

center: center,

zoom: 16

});

var layers = [new ol.layer.Tile({

title: '、地图',

visible: true,

preload: Infinity,

source: new ol.source.TileWMS({

url: gisUrl,

params: {

'VERSION': '1.1.0',

tiled: true,

STYLES: '',

LAYERS: 'shanghai:maptest',

}

})

}),linelayers];

ajax获取坐标数据

//轨迹查询按钮点击

var positions=[];

$("#queryBtn").click(function(){

//清除之前的图层

if (centerSource.getFeatures != null) {

centerSource.clear(); }

linelayers.getSource().clear(true);

positions=[];//清空

//取值

var busnum=$("#busSelect").val();

var traceday=$("#traceday").val();

if(busnum=="*"){

$(".remind").html('<i class="icon-info-sign">请先选择车辆</i>');

return;

}else{

$(".remind").html('');

busnum=busnum.slice(2);

}

if(transfromTime(new Date(),false)==traceday){//当天

traceday="*";

}else{

traceday=traceday.replace(/(-)/g,"");

}

$(".remind").html('<i class="icon-cogs"> 正在查询...</i>');

//请求

$.getJSON(baseUrl+"trace/query/"+busnum+"/"+traceday,"",function(data){

if(data.length==0){

$(".remind").html('<i class="icon-info-sign">未查到gps数据</i>');return;

}

var position = [];

for(var i = 0;i<data.length;i++){

if(i!=0&&data[i].lon==data[i-1].lon&&data[i].lon==data[i-1].lon){//去除重复数据

continue;

}

position = [parseFloat(data[i].lon),parseFloat(data[i].lat)];

positions.push(position);

}

console.log(positions);

if(positions.length==1){

$(".remind").html('<i class="icon-info-sign">该车辆当天停在该位置未启动</i>');

centerAt(positions[0]);

return;

}

AddLayer(positions);

});

});

显示轨迹

//轨迹描绘

function AddLayer() {

var lineFeature = new ol.Feature({//路线

geometry: new ol.geom.LineString(positions,'XY'),

});

linelayers.getSource().addFeature(lineFeature);

var startFeature = new ol.Feature({//起点

geometry: new ol.geom.Point(positions[0]),

population: 4000,

rainfall: 500

});

startFeature.setStyle(startStyle);

linelayers.getSource().addFeature(startFeature);

var endFeature = new ol.Feature({//终点

geometry: new ol.geom.Point(positions[positions.length-1]),

population: 4000,

rainfall: 500

});

endFeature.setStyle(endStyle);

linelayers.getSource().addFeature(endFeature);

carFeature = new ol.Feature({//车子

geometry: new ol.geom.Point(positions[0]),

population: 4000,

rainfall: 500

});

carFeature.setStyle(carStyle);

linelayers.getSource().addFeature(carFeature);

var extent = linelayers.getSource().getExtent();//合适比例缩放居中

view.fit(extent, map.getSize());

}

显示单点

//居中 车辆不运动时居中显示图标处理

var centerLayer = null;

var centerSource = new ol.source.Vector({

features: null

});

//居中在一个位置

function centerAt(position) {

var pan = ol.animation.pan({

duration: 2000,

source: (view.getCenter())

});

view.setCenter(position);

var iconFeature = new ol.Feature({

geometry: new ol.geom.Point(position),

name: 'Null Island',

population: 4000,

rainfall: 500

});

iconFeature.setStyle(iconStyle);

centerSource.addFeature(iconFeature);

centerLayer = new ol.layer.Vector({

source: centerSource

});

map.addLayer(centerLayer);

centerLayer.setVisible(true);

}

点在线上运动,轨迹回放

//轨迹回放start 参考官网

var carFeature = null;

var speed, now;

var animating = false;

$("#animateBtn").click(function(){

if(positions.length==0){

$(".remind").html('<i class="icon-info-sign">请先查询轨迹</i>');

return;

}

if (animating) {

stopAnimation(false);

} else {

animating = true;

now = new Date().getTime();

speed = $("#speed").val();//速度

$("#animateBtn").html('<i class="icon-eye-close"></i>&nbsp;取消回放');

carFeature.setStyle(null);

// map.getView().setCenter(center);

map.on('postcompose', moveFeature);

map.render();

}

});

var moveFeature = function(event) {

var vectorContext = event.vectorContext;

var frameState = event.frameState;

if (animating) {

var elapsedTime = frameState.time - now;

// here the trick to increase speed is to jump some indexes

// on lineString coordinates

var index = Math.round(speed * elapsedTime / 1000);

if (index >= positions.length) {

stopAnimation(true);

return;

}

var currentPoint = new ol.geom.Point(positions[index]);

var feature = new ol.Feature(currentPoint);

vectorContext.drawFeature(feature, carStyle);

}

// tell OL3 to continue the postcompose animation

map.render();

};

function startAnimation() {

if (animating) {

stopAnimation(false);

} else {

animating = true;

now = new Date().getTime();

speed = speedInput.value;

$("#animateBtn").html('<i class="icon-eye-close"></i>&nbsp;取消回放');

// hide geoMarker

geoMarker.setStyle(null);

// just in case you pan somewhere else

map.getView().setCenter(center);

map.on('postcompose', moveFeature);

map.render();

}

}

function stopAnimation(ended) {

animating = false;

$("#animateBtn").html('<i class="icon-eye-open"></i>&nbsp;轨迹回放');

// if animation cancelled set the marker at the beginning

var coord = ended ? positions[positions.length - 1] : positions[0];

/** @type {ol.geom.Point} */ (carFeature.getGeometry())

.setCoordinates(coord);

//remove listener

map.un('postcompose', moveFeature);

}

//轨迹回放end

解决linestring坐标显示不全

期间碰到一个问题

var lineFeature = new ol.Feature({//路线

geometry: new ol.geom.LineString(positions,'XY'),

});

linelayers.getSource().addFeature(lineFeature);

调用这段代码显示轨迹时,从数据库取到20个坐标,就可能只显示4个坐标,本来是弯曲的轨迹,但是实际上就是折线,很尴尬。

误打误撞,和同学 交流过程中发现问题所在,特此感谢。

在ajax获取坐标数据中发现问题所在:

原先错误代码

position = [data[i].lon,data[i].lat];

positions.push(position);

正确代码

position = [parseFloat(data[i].lon),parseFloat(data[i].lat)];

positions.push(position);

原因就是没有把float类型的坐标利用parseFloat强转,导致默认的泛数据类型精确度不够,经纬度小数点后末尾几位就会被忽略,于是造成数据失效,描出的线就会有问题。

附上icon、起点、终点、车辆等地图样式

//样式,供上述代码调用

var iconStyle = new ol.style.Style({

image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({

anchor: [0.5, 0.8],

anchorXUnits: 'fraction',

anchorYUnits: 'pixels',

opacity: 0.75,

src: 'img/iconfont-weizhi-red.png'

}))

});

var startStyle = new ol.style.Style({

image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({

anchor: [0.5, 0.8],

opacity: 0.8,

src: 'img/start.png'

/*anchorXUnits: 'fraction',

anchorYUnits: 'pixels',

opacity: 0.75,*/

}))

});

var endStyle = new ol.style.Style({

image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({

src: 'img/end.png',

anchor: [0.5, 0.8],

}))

});

var carStyle = new ol.style.Style({

image: new ol.style.Icon(/** @type {olx.style.IconOptions} */ ({

src: 'img/car.png',

anchor: [0.5, 0.8],

}))

});

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Openlayers3实现车辆轨迹回放功能 的全部内容, 来源链接: utcz.com/p/218132.html

回到顶部