Openlayers3 轨迹回放,点在线上运动, 解决linestring坐标显示不全

来源:互联网 发布:天涯论坛和知乎哪个好 编辑:程序博客网 时间:2024/05/08 10:55

记录基于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初始化

//轨迹line layervar 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],    }))});
0 0
原创粉丝点击