Openlayers-获得两个几何之间的最短线

时间:2018-11-21 15:01:09

标签: openlayers

使用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 :(得分:1)

我认为任何最短的线将始终包含其中一个线串的顶点之一(对于多边形,线串将是外环),因此,那些坐标中给出最接近的点中的任何一个为最短线。我已经检查了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);

}

答案 1 :(得分:0)

实际上,迈克的答案大约是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);
  }