OpenLayers 3: Как рассчитать расстояние между двумя точками?

Используя OpenLayers 3, как определить расстояние между двумя точками проекции Spherical Mercator (SRID: 3857)?

Я знаю, что distanceTo использовался в OpenLayers 2

point1.distanceTo(point2)

Я просмотрел документы OpenLayers 3, но я не нашел ничего подобного...

Ответ 1

Вы можете использовать объект Sphere для вычисления расстояния между двумя координатами, например:

var distance = ol.sphere.WGS84.haversineDistance([0,0],[180,0]); 
//20037508.34 meters 

Сфера предоставляет также различные алгоритмы для вычисления расстояния, такого как косинус, равноугольный и т.д. Вы также можете создать объект Sphere с радиусом другого эллипсоида.

Я не знаю, почему документы не подключены к сети, но вы можете проверить доступные методы из исходного кода объекта сферы: https://github.com/openlayers/ol3/blob/master/src/ol/sphere.js

Я лично считаю, что просмотр исходного кода - лучший способ найти ответы на OpenLayers3;)

Ответ 2

Я использую довольно простое решение. Я создаю объект ol.geom.LineString между двумя точками и вычисляю длину строки:

        this.distanceBetweenPoints = function(latlng1, latlng2){
            var line = new ol.geom.LineString([latlng1, latlng2]);
            return Math.round(line.getLength() * 100) / 100;
        };

Затем вы можете получить удобочитаемое значение, используя некоторую формулу:

        this.formatDistance = function(length) {
            if (length >= 1000) {
                length = (Math.round(length / 1000 * 100) / 100) +
                ' ' + 'km';
            } else {
                length = Math.round(length) +
                ' ' + 'm';
            }
            return length;
        }

EDIT: новый метод вычисления

Фактически, расстояние может быть ложным относительно проекции, которую вы используете. Мы довольно долго обсуждали это на ol3 github, вы можете увидеть его там: https://github.com/openlayers/ol3/issues/3533

Подводя итог, вам нужно использовать эту функцию, чтобы получить точный расчет:

/**
 * format length output
 * @param {ol.geom.LineString} line
 * @return {string}
 */
export default function mapFormatLength(projection, line) {
  var length;
  var coordinates = line.getCoordinates();
  length = 0;
  for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {
    var c1 = ol.proj.transform(coordinates[i], projection, 'EPSG:4326');
    var c2 = ol.proj.transform(coordinates[i + 1], projection, 'EPSG:4326');
    length += mapConst.wgs84Sphere.haversineDistance(c1, c2);
  }
  var output;
  if (length > 1000) {
    output = (Math.round(length / 1000 * 100) / 100) +
    ' ' + 'km';
  } else {
    output = (Math.round(length * 100) / 100) +
    ' ' + 'm';
  }
  return output;
}

Ответ 3

Просто добавьте еще один вариант. Это не зависит от ol3.

function toRad(x) {return x * Math.PI / 180;}

function SphericalCosinus(lat1, lon1, lat2, lon2) {

    var R = 6371; // km
    var dLon = toRad(lon2 - lon1),
        lat1 = toRad(lat1),
        lat2 = toRad(lat2),
        d = Math.acos(Math.sin(lat1)*Math.sin(lat2) + Math.cos(lat1)*Math.cos(lat2) * Math.cos(dLon)) * R;


    return d;
}

Ответ 4

Я написал этот для себя, я надеюсь, он будет полезен, он возвращается в метры:

function getCoordsDistance(firstPoint, secondPoint, projection) {
    projection = projection || 'EPSG:4326';

    length = 0;
    var sourceProj = mapObj.getView().getProjection();
    var c1 = ol.proj.transform(firstPoint, sourceProj, projection);
    var c2 = ol.proj.transform(secondPoint, sourceProj, projection);

    var wgs84Sphere = new ol.Sphere(6378137);
    length += wgs84Sphere.haversineDistance(c1, c2);

    return length;
}

Ответ 5

function getCoordsDistance (latlng1, latlng2) {

var markers = [];

markers.push(ol.proj.transform(latlng1, 'EPSG:4326', map.getView().getProjection()));
markers.push(ol.proj.transform(latlng2, 'EPSG:4326', map.getView().getProjection()));

var line = new ol.geom.LineString(markers, 'XY');
var length = Math.round(line.getLength() * 100) / 100;

if (length >= 1000) {
    length = (Math.round(length / 1000 * 100) / 100) +
        ' ' + 'km';
} else {
    length = Math.round(length) +
        ' ' + 'm';
}
return length;

}