Openlayers 3 차량 궤적 재생 기능 실현

14960 단어 Openlayers3궤적
기록 은 geoserver 지도 서 비 스 를 바탕 으로 Openlayers 3 는 웹 전단 에서 차량 궤적 재생 기능 을 실현 하고 기록 과 해결 과정 에서 나타 난 linestring 은 일부 경위도 좌표 문제 만 묘사 합 니 다.
Openlayers 3 홈 페이지 참조예시

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>
맵 초기 화

$(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],
 }))
});
이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기