使用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
功能,但它将几何的最接近点返回到传递点。
我需要类似的功能,但它接收的是几何对象而不是点。
致谢。
答案 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);
}