站长资源网络编程

Openlayers3实现车辆轨迹回放功能

整理:jimmy2025/4/21浏览2
简介记录基于geoserver地图服务,Openlayers3在web前端实现车辆轨迹回放功能,并记录和解决过程中出现的linestring只描绘部分经纬度坐标问题。参考Openlayers3 官网例子html</div> <div class="news_infos"><div id="MyContent"><p>记录基于geoserver地图服务,Openlayers3在web前端实现车辆轨迹回放功能,并记录和解决过程中出现的linestring只描绘部分经纬度坐标问题。</p> <p>参考Openlayers3 官网例子</p> <p><a href="javascript:;" onclick="showimg('/UploadFiles/2021-04-02/202092994654203.jpg');"><img src="/UploadFiles/2021-04-02/202092994654203.jpg" alt="Openlayers3实现车辆轨迹回放功能" onmousewheel="return bbimg(this)" onload="javascript:resizepic(this)" border="0"/></a></p> <p>html</p> <div class="htmlcode"> <pre class="brush:xhtml;"> <!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="/UploadFiles/2021-04-02/jquery.min.js"> <p>map初始化</p> <div class="htmlcode"> <pre class="brush:js;"> $(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];</pre> </div> <p>ajax获取坐标数据</p> <div class="htmlcode"> <pre class="brush:js;"> //轨迹查询按钮点击 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); }); });</pre> </div> <p>显示轨迹</p> <div class="htmlcode"> <pre class="brush:js;"> //轨迹描绘 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()); }</pre> </div> <p>显示单点</p> <div class="htmlcode"> <pre class="brush:js;"> //居中 车辆不运动时居中显示图标处理 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); }</pre> </div> <p>点在线上运动,轨迹回放</p> <div class="htmlcode"> <pre class="brush:js;"> //轨迹回放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 "htmlcode"> <div class="htmlcode"> <pre class="brush:js;"> var lineFeature = new ol.Feature({//路线 geometry: new ol.geom.LineString(positions,'XY'), }); linelayers.getSource().addFeature(lineFeature);</pre> </div> <p>调用这段代码显示轨迹时,从数据库取到20个坐标,就可能只显示4个坐标,本来是弯曲的轨迹,但是实际上就是折线,很尴尬。<br> 误打误撞,和同学 交流过程中发现问题所在,特此感谢。<br> 在ajax获取坐标数据中发现问题所在:<br> <strong>原先错误代码</strong></p> <div class="htmlcode"> <pre class="brush:js;"> position = [data[i].lon,data[i].lat]; positions.push(position);</pre> </div> <p><strong>正确代码</strong></p> <div class="htmlcode"> <pre class="brush:js;"> position = [parseFloat(data[i].lon),parseFloat(data[i].lat)]; positions.push(position);</pre> </div> <p>原因就是没有把float类型的坐标利用parseFloat强转,导致默认的泛数据类型精确度不够,经纬度小数点后末尾几位就会被忽略,于是造成数据失效,描出的线就会有问题。</p> <p><strong>附上icon、起点、终点、车辆等地图样式</strong><br> </p> <div class="htmlcode"> <pre class="brush:js;"> //样式,供上述代码调用 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], })) });</pre> </div> <p>以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。</p></div> </div> </div> <div class="share"> </div> <div class="nextinfo"> <p>上一篇:<a href="/3g/1/78799.html" title="解决idea开发遇到javascript动态添加html元素时中文乱码的问题">解决idea开发遇到javascript动态添加html元素时中文乱码的问题</a></p> <p>下一篇:<a href="/3g/1/78801.html" title="vue 验证两次输入的密码是否一致的方法示例">vue 验证两次输入的密码是否一致的方法示例</a></p> </div> <div class="otherlink"> <h2>最新资源</h2> <ul> <li><a href="/3g/1/623703.html" title="群星《奔赴!万人现场 第2期》[FLAC/分轨]">群星《奔赴!万人现场 第2期》[FLAC/分轨]</a></li> <li><a href="/3g/1/623702.html" title="群星《奇妙浪一夏 (上海迪士尼度假区音乐">群星《奇妙浪一夏 (上海迪士尼度假区音乐</a></li> <li><a href="/3g/1/623701.html" title="群星《奇妙浪一夏 (上海迪士尼度假区音乐">群星《奇妙浪一夏 (上海迪士尼度假区音乐</a></li> <li><a href="/3g/1/623700.html" title="【古典音乐】詹姆斯·高威《季节》1993[WA">【古典音乐】詹姆斯·高威《季节》1993[WA</a></li> <li><a href="/3g/1/623699.html" title="贝拉芳蒂《卡里普索之王》SACD[WAV+CUE]">贝拉芳蒂《卡里普索之王》SACD[WAV+CUE]</a></li> <li><a href="/3g/1/623698.html" title="小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE">小骆驼-《草原狼2(蓝光CD)》[原抓WAV+CUE</a></li> <li><a href="/3g/1/623697.html" title="群星《欢迎来到我身边 电影原声专辑》[32">群星《欢迎来到我身边 电影原声专辑》[32</a></li> <li><a href="/3g/1/623696.html" title="群星《欢迎来到我身边 电影原声专辑》[FL">群星《欢迎来到我身边 电影原声专辑》[FL</a></li> <li><a href="/3g/1/623695.html" title="雷婷《梦里蓝天HQⅡ》 2023头版限量编号低">雷婷《梦里蓝天HQⅡ》 2023头版限量编号低</a></li> <li><a href="/3g/1/623694.html" title="群星《2024好听新歌42》AI调整音效【WAV分">群星《2024好听新歌42》AI调整音效【WAV分</a></li> </ul> </div> </div> <div class="sidebar"> <div class="cloud"><h2 class="hometitle">标签云</h2><ul><a href="/search.asp?key=1080P高清&m=1">1080P高清<span>(5)</span></a><a href="/search.asp?key=高清电影&m=1">高清电影<span>(5)</span></a><a href="/search.asp?key=百度云盘&m=1">百度云盘<span>(5)</span></a><a href="/search.asp?key=网盘下载&m=1">网盘下载<span>(4)</span></a><a href="/search.asp?key=破解软件&m=1">破解软件<span>(4)</span></a><a href="/search.asp?key=绿色软件&m=1">绿色软件<span>(4)</span></a><a href="/search.asp?key=磁力链接&m=1">磁力链接<span>(3)</span></a><a href="/search.asp?key=强度天梯&m=1">强度天梯<span>(3)</span></a><a href="/search.asp?key=福利资源&m=1">福利资源<span>(2)</span></a><a href="/search.asp?key=王者荣耀&m=1">王者荣耀<span>(2)</span></a><a href="/search.asp?key=黑钻活动&m=1">黑钻活动<span>(2)</span></a><a href="/search.asp?key=WPS会员&m=1">WPS会员<span>(2)</span></a><a href="/search.asp?key=刷图排行&m=1">刷图排行<span>(1)</span></a><a href="/search.asp?key=网盘限速&m=1">网盘限速<span>(1)</span></a><a href="/search.asp?key=鬼灭之刃&m=1">鬼灭之刃<span>(1)</span></a><a href="/search.asp?key=免费韩国漫画&m=1">免费韩国漫画<span>(1)</span></a><a href="/search.asp?key=宫本重做&m=1">宫本重做<span>(1)</span></a><a href="/search.asp?key=免费动漫&m=1">免费动漫<span>(1)</span></a></ul></div> </div> <div class="sidebar"> 友情链接:<a href="http://www.imxmx.com/" title="杰晶网络" target="_blank">杰晶网络</a> <a href="/" title="DDR爱好者之家" target="_blank">DDR爱好者之家</a> <a href="http://www.nqxw.com/" title="南强小屋" target="_blank">南强小屋</a> <a href="http://www.paidiu.com/" title="黑松山资源网" target="_blank">黑松山资源网</a> <a href="http://www.dyhadc.com/" title="白云城资源网" target="_blank">白云城资源网</a> <a href="/sitemap1.xml">站点地图</a> <a href="/sitemap.xml">SiteMap</a> </div> </article> <footer> <p>Design by <a href="http://m.ddrfans.com">DDR爱好者之家</a> <a href="http://m.ddrfans.com">http://m.ddrfans.com</a></p> </footer> <script src="/images3g/nav.js"></script> <script type="text/javascript"> jQuery.noConflict(); jQuery(function() { var elm = jQuery('#left_flow2'); var startPos = jQuery(elm).offset().top; jQuery.event.add(window, "scroll", function() { var p = jQuery(window).scrollTop(); jQuery(elm).css('position', ((p) > startPos) ? 'fixed' : ''); jQuery(elm).css('top', ((p) > startPos) ? '0' : ''); }); }); </script> </body> </html>