Openlayers - получите кратчайшую линию между двумя геометриями - PullRequest
0 голосов
/ 21 ноября 2018

Используя OL4 и Angular 5, я хочу вычислить самую короткую линию между двумя геометриями, потому что я хочу нарисовать самую короткую линию между двумя геометриями.

например, у меня есть два многоугольника, подобные этому:

const geom1 = new ol_geom_Polygon([[[39.08317178, 34.94428969], [40.15753633, 35.19891679], 
        [40.09419625, 35.46617166], [39.0198317, 35.21154456], [39.08317178, 34.94428969]]]);

const geom2 = new ol_geom_Polygon([[[42.06884752, 37.70855705], [41.28393081, 37.41465862], 
        [41.93091268, 36.88185002], [42.06884752, 37.70855705]]]);

Класс геометрии OL4 имеет функцию getClosestPoint, но он возвращает ближайшую точку геометрии к пройденной точке.

Мне нужна аналогичная функция, но она получает геометриюобъект вместо точки.

С уважением.

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

На самом деле, ответ Майка примерно на 95% идеален :) .. поэтому я сделал некоторые улучшения, и вот окончательный код в TypeScript:

  public getShortestLine(geom1: ol_geom_Geometry, geom2: ol_geom_Geometry): ol_geom_LineString {
    if (geom1.getType() === 'Point' && geom2.getType() === 'Point') {
      return new ol_geom_LineString([(geom1 as ol_geom_Point).getCoordinates(), (geom2 as ol_geom_Point).getCoordinates()]);
    }

    let result = [];
    let distanceSq = Infinity;

    let geom1Coordinates = [];
    if (geom1.getType() === 'Polygon') {
      geom1Coordinates = (geom1 as ol_geom_Polygon).getLinearRing(0).getCoordinates();
    } else if (geom1.getType() === 'Point') {
      geom1Coordinates = [(geom1 as ol_geom_Point).getCoordinates()];
    } else {
      geom1Coordinates = (geom1 as any).getCoordinates();
    }

    let geom2Coordinates = [];
    if (geom2.getType() === 'Polygon') {
      geom2Coordinates = (geom2 as ol_geom_Polygon).getLinearRing(0).getCoordinates();
    } else if (geom2.getType() === 'Point') {
      geom2Coordinates = [(geom2 as ol_geom_Point).getCoordinates()];
    } else {
      geom2Coordinates = (geom2 as any).getCoordinates();
    }

    geom1Coordinates.forEach(coordinates => {
      const closest = geom2.getClosestPoint(coordinates);
      const distanceNew = Math.pow(closest[0] - coordinates[0], 2) + Math.pow(closest[1] - coordinates[1], 2);
      if (distanceNew < distanceSq) {
        distanceSq = distanceNew;
        result = [coordinates, closest];
      }
    });

    geom2Coordinates.forEach(coordinates => {
      const closest = geom1.getClosestPoint(coordinates);
      const distanceNew = Math.pow(closest[0] - coordinates[0], 2) + Math.pow(closest[1] - coordinates[1], 2);
      if (distanceNew < distanceSq) {
        distanceSq = distanceNew;
        result = [closest, coordinates];
      }
    });

    return new ol_geom_LineString(result);
  }
0 голосов
/ 22 ноября 2018

Я думаю, что любая самая короткая линия всегда будет включать одну из вершин одной из линий линий (для многоугольников линии строк будут внешними кольцами), поэтому любая из этих координат дает ближайшую ближайшую точку - самую короткую линию.Я проверил исходный код getClosestPoint, и он использует простое вычисление расстояния Пифагора, поэтому перед вызовом такой функции следует преобразовать геометрию в координаты карты, которая возвращает строку из geom1 в geom2, где геометрии могут быть отдельными полигонами и /или одиночные строки.

function getShortestLine(geom1, geom2) {

    var result;
    var distanceSq = Infinity;

    (geom1.getLinearRing ? geom1.getLinearRing(0) : geom1).getCoordinates().forEach(function(coordinates) {
        var closest = geom2.getClosestPoint(coordinates);
        var distanceNew = Math.pow(closest[0]-coordinates[0],2) + Math.pow(closest[1]-coordinates[1],2);
        if (distanceNew < distanceSq) {
            distanceSq = distanceNew;
            result = [ coordinates, closest ];
        }
    });

    (geom2.getLinearRing ? geom2.getLinearRing(0) : geom2).getCoordinates().forEach(function(coordinates) {
        var closest = geom1.getClosestPoint(coordinates);
        var distanceNew = Math.pow(closest[0]-coordinates[0],2) + Math.pow(closest[1]-coordinates[1],2);
        if (distanceNew < distanceSq) {
            distanceSq = distanceNew;
            result = [ closest, coordinates ];
        }
    });

    return new ol.geom.LineString(result);

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...