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

记录基于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],
    }))
});
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 24
    评论
### 回答1: OpenLayers 5 是一个开源的 JavaScript 库,用于创建交互式地图应用。要实现在地图上绘制坐标之间的连线,可以按照以下步骤进行: 1. 首先,在 HTML 文件中导入 OpenLayers 库和样式文件: ```html <link rel="stylesheet" href="https://openlayers.org/en/v5.3.0/css/ol.css" /> <script src="https://openlayers.org/en/v5.3.0/build/ol.js"></script> ``` 2. 创建一个地图容器的 div 元素: ```html <div id="map" style="width: 400px; height: 300px;"></div> ``` 3. 在 JavaScript 文件中,创建一个用于显示地图的 map 对象: ```javascript var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([0, 0]), zoom: 2 }) }); ``` 4. 创建一个矢量图层和一个矢量源对象: ```javascript var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); map.addLayer(vectorLayer); var vectorSource = vectorLayer.getSource(); ``` 5. 为地图添加单击事件,获取击位置的坐标: ```javascript map.on('click', function(event) { var coordinate = event.coordinate; // 在此处可以将坐标添加到 vectorSource 中 }); ``` 6. 在单击事件的回调函数中,创建一个要素并添加到矢量源对象中: ```javascript var pointFeature = new ol.Feature({ geometry: new ol.geom.Point(coordinate) }); vectorSource.addFeature(pointFeature); ``` 7. 如果要连接这些坐标,可以使用 ol.geom.LineString 创建一个线要素,然后添加到矢量源对象中: ```javascript var lineStringFeature = new ol.Feature({ geometry: new ol.geom.LineString(coordinates) }); vectorSource.addFeature(lineStringFeature); ``` 最后,你将在地图上看到所有的坐标以及它们之间的连线。这是使用 OpenLayers 5 实现坐标划线的基本步骤。可以通过进一步自定义样式和处理事件来增加功能。 ### 回答2: OpenLayers 5是一个开源的JavaScript库,可用于在Web上实现地图功能。如果要在地图上绘制坐标之间的连线,可以按照以下步骤进行: 1. 初始化地图:首先,需要在页面上创建一个地图容器,然后初始化地图对象。可以指定地图的中心坐标、缩放级别等属性。 2. 添加图层:接下来,创建一个矢量图层,并将其添加到地图中。这样可以在地图上绘制矢量要素,如、线、面等。 3. 创建要素:使用OpenLayers的Point类,可以创建一个要素,其中包含要绘制的坐标的经纬度信息。 4. 创建线要素:使用OpenLayersLineString类,可以创建一个线要素,其中包含要绘制的坐标序列。 5. 绘制要素:将要素添加到图层中,再将线要素添加到图层中。这样,地图上就可见了这些要素。 以下是一个示例代码片段,展示了如何在OpenLayers 5中实现坐标划线的功能: ```javascript // 初始化地图 var map = new ol.Map({ target: 'map-container', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([0, 0]), zoom: 10 }) }); // 创建矢量图层 var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector() }); map.addLayer(vectorLayer); // 创建要素 var point1 = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon1, lat1])) }); var point2 = new ol.Feature({ geometry: new ol.geom.Point(ol.proj.fromLonLat([lon2, lat2])) }); // 创建线要素 var lineFeature = new ol.Feature({ geometry: new ol.geom.LineString([ ol.proj.fromLonLat([lon1, lat1]), ol.proj.fromLonLat([lon2, lat2]) ]) }); // 添加要素到图层 vectorLayer.getSource().addFeature(point1); vectorLayer.getSource().addFeature(point2); vectorLayer.getSource().addFeature(lineFeature); ``` 以上代码中的`map-container`是在HTML页面上用来容纳地图的一个元素,`lon1`、`lat1`、`lon2`和`lat2`是两个坐标的经纬度值。通过将要素和线要素添加到矢量图层中,即可在地图上看到这些要素,实现坐标的划线功能。 ### 回答3: 使用OpenLayers 5实现坐标划线的方法如下: 首先,创建一个地图容器,可以使用HTML中的一个div元素作为容器: ```html <div id="map" style="width: 100%; height: 500px;"></div> ``` 然后,在JavaScript中,创建一个OpenLayers地图实例并将其显示地图容器中: ```javascript var map = new ol.Map({ target: 'map', layers: [ new ol.layer.Tile({ source: new ol.source.OSM() }) ], view: new ol.View({ center: ol.proj.fromLonLat([0, 0]), zoom: 4 }) }); ``` 接下来,创建一个用于存储坐标的数组: ```javascript var coordinates = [ [0, 0], // 第一个的经纬度 [10, 10], // 第二个的经纬度 [20, 20], // 第三个的经纬度 // ... ]; ``` 然后,使用OpenLayers的Vector模块创建一个特征集合,并将坐标添加到特征集合中: ```javascript var features = new ol.Collection(); var feature = new ol.Feature({ geometry: new ol.geom.LineString(coordinates) }); features.push(feature); ``` 再创建一个用于显示特征集合的矢量层: ```javascript var vectorLayer = new ol.layer.Vector({ source: new ol.source.Vector({ features: features }) }); ``` 最后,将矢量层添加到地图上,就可以在地图显示坐标的划线了: ```javascript map.addLayer(vectorLayer); ``` 需要注意的是,以上代码只是一个简单示例,实际应用中您可能需要根据具体需求调整参数和添加其他功能。此外,还需要确保引入了OpenLayers的JavaScript文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值