使用OpenLayers Geolocation时的锁定方向

时间:2015-07-13 21:33:42

标签: geolocation openlayers-3

我们使用嵌入式地图在现场驾驶时跟踪我们的位置。目前,地图会旋转以匹配GPS的方向。我们发现它非常迷惑,我想将方向锁定在北方(0度)。我仍然希望地图跟踪位置并指示标题(如果可用)。下面是从地图的javascript文件中剪下的与地理位置相关的内容。

map.addLayer(addressLayer);
// Geolocation marker
var markerEl = document.getElementById('geolocation_marker');
var marker = new ol.Overlay({
  positioning: 'center-center',
  element: markerEl,
  stopEvent: false
});
map.addOverlay(marker);

// LineString to store the different geolocation positions. This LineString
// is time aware.
// The Z dimension is actually used to store the rotation (heading).
var positions = new ol.geom.LineString([],
    /** @type {ol.geom.GeometryLayout} */ ('XYZM'));

// Geolocation Control
var geolocation = new ol.Geolocation(/** @type {olx.GeolocationOptions} */ ({
  projection: view.getProjection(),
  tracking: true,
  trackingOptions: {
    maximumAge: 10000,
    enableHighAccuracy: true,
    timeout: 600000
  }
}));

var deltaMean = 500; // the geolocation sampling period mean in ms

// Listen to position changes
geolocation.on('change', function(evt) {
  var position = geolocation.getPosition();
  var accuracy = geolocation.getAccuracy();
  var heading = geolocation.getHeading() || 0;
  var speed = geolocation.getSpeed() || 0;
  var m = Date.now();

  addPosition(position, heading, m, speed);

  map.getView().setCenter(geolocation.getPosition());
  document.getElementById("locate").style.backgroundColor = 'rgba(0,128,0,1)';
  locateUser = true;
});

geolocation.on('error', function(error) {
  var errors = {
    1: 'Permission denied to locate device',
    2: 'Position unavailable',
    3: 'Request timeout'
  };
  if (error.code){
    document.getElementById("locate").style.backgroundColor = 'rgba(255,0,0,1)';
    locateUser = false;
  }
  alert("Error: " + errors[error.code]);
});

// convert radians to degrees
function radToDeg(rad) {
  return rad * 360 / (Math.PI * 2);
}
// convert degrees to radians
function degToRad(deg) {
  return deg * Math.PI * 2 / 360;
}
// modulo for negative values
function mod(n) {
  return ((n % (2 * Math.PI)) + (2 * Math.PI)) % (2 * Math.PI);
}

function addPosition(position, heading, m, speed) {
  var x = position[0];
  var y = position[1];
  var fCoords = positions.getCoordinates();
  var previous = fCoords[fCoords.length - 1];
  var prevHeading = previous && previous[2];
  if (prevHeading) {
    var headingDiff = heading - mod(prevHeading);

    // force the rotation change to be less than 180°
    if (Math.abs(headingDiff) > Math.PI) {
      var sign = (headingDiff >= 0) ? 1 : -1;
      headingDiff = - sign * (2 * Math.PI - Math.abs(headingDiff));
    }
    heading = prevHeading + headingDiff;
  }
  positions.appendCoordinate([x, y, heading, m]);

  // only keep the 20 last coordinates
  positions.setCoordinates(positions.getCoordinates().slice(-20));

  // FIXME use speed instead
  if (heading && speed) {
    markerEl.src = 'images/geolocation_marker_heading.png';
  } else {
    markerEl.src = 'images/geolocation_marker.png';
  }
}

var previousM = 0;

// change center and rotation before render
map.beforeRender(function(map, frameState) {
  if (frameState !== null) {
    // use sampling period to get a smooth transition
    var m = frameState.time - deltaMean * 1.5;
    m = Math.max(m, previousM);
    previousM = m;
    // interpolate position along positions LineString
    var c = positions.getCoordinateAtM(m, true);
    var view = frameState.viewState;
    if (c) {
      view.rotation = -c[2];
      marker.setPosition(c);
    }
  }
  return true; // Force animation to continue
});

// postcompose callback
function render() {
  map.render();
}

// geolocate device
var geolocateBtn = document.getElementById('locate');

geolocateBtn.addEventListener('click', function() {
  if(locateUser){
    geolocation.setTracking(false);
    geolocateBtn.style.backgroundColor = 'rgba(255,0,0,1)';
    locateUser = false;
  }
  else{
    geolocation.setTracking(true);
    map.getView().setCenter(geolocation.getPosition());
    geolocateBtn.style.backgroundColor = 'rgba(0,128,0,1)';    
    map.on('postcompose', render);
    map.render(); 
    locateUser = true;
  }
}, false);

addLocations(QueryString);

function addLocations(addressArr) {
  if (nextAddress < addressArr.length) {
    setTimeout(function(){
      if (addressArr[nextAddress] !== undefined){ 
        geocodeAddress(addressArr[nextAddress]);
      }
    }, delay);
  } 

  if(nextAddress == addressArr.length) {
      view.fitExtent(vectorSource.getExtent(), map.getSize());
  }

}

function geocodeAddress (location) {
    $.getJSON('http://maps.googleapis.com/maps/api/geocode/json?address='+location.address+'&sensor=false', null, function (data) {
      if(data.status === 'OK'){
        var p = data.results[0].geometry.location;
        var color = location.status == 'incomplete' ? 'red' : 'green';
        var pointFeature = new ol.Feature({
          geometry: new ol.geom.Point(ol.proj.transform([p.lng, p.lat], 'EPSG:4326',     
          'EPSG:3857')),
          fillColor: color,
          id: location.id
        });

        vectorSource.addFeature(pointFeature);

        addresses.push(pointFeature);
        nextAddress+=1;
        addLocations(QueryString);
      }
      if(data.status === 'OVER_QUERY_LIMIT'){
        delay += delay;
      }
    });

}

1 个答案:

答案 0 :(得分:0)

以下是导致rotation发生的相关ol3代码。

通过设置view.rotation = 0;,您可以解决问题。