Using OL4 and Angular 5, I want to calculate the shortest line between two geometries, because I want to draw the shortest line between two geometries.
for example I have two polygons like this:
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 geometry class has getClosestPoint
function but it return the closest point of the geometry to a passed point.
I need a similar function but it receive a geometry object instead of point.
Regards.
Actually, Mike's answer is about 95% perfect :) .. so I done some improvements and here is the final code in 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);
}