背景:
某项目要做一个公交换乘查询。以最简单的情况为例,即只需乘坐一次车,不需换乘即可到达。线路A包含若干个站点(A0,A1,A2,...,An),其中A0为线路起始站点,An为终止站点。已获取出发的站点(As,其中0<=s<n)、到达的点(Ae,其中0<e<=n,且s<e),以及线路(一个Polyline对象,包含Paths个数为1)。
As、Ae位于站点图层中,其坐标在空间上可能位于线路Polyline上,也可能与线路稍有偏差,不落在线上。
在进行乘车线路展示时,需要截取该线路位于出发站点As、到达站点Ae之间的Polyline的一段。
代码如是:
/**
* 使用两点(可能在线上,也可在线外)切割一条Polyline,截取两点之间的Polyline
* @param {[type]} firstPoint [第一个切割点]
* @param {[type]} secondPoint [第二个切割点]
* @param {[type]} targetPolyline [被切割的Polyline]
* @return {[type]} [Polyline]
*/
getCutLine: function(firstPoint,secondPoint,targetPolyline) {
console.log("firstPoint : ",firstPoint," secondPoint : ",secondPoint," targetPolyline : ",targetPolyline);
//获取与两个切割点最近的目标Polyline上的点
var firstNearestPoint = geometryEngine.nearestCoordinate(targetPolyline,firstPoint).coordinate;
var secondNearestPoint = geometryEngine.nearestCoordinate(targetPolyline,secondPoint).coordinate;
console.log("firstNearestPoint : ",firstNearestPoint," secondNearestPoint : ",secondNearestPoint);
//构造第一条切割线
var firstFromX = firstNearestPoint.x + 1;
var firstFromY = firstNearestPoint.y + 1;
var firstToX = firstNearestPoint.x - 1;
var firstToY = firstNearestPoint.y - 1;
var firstFromPoint = new esri.geometry.Point(firstFromX, firstFromY, this.map.spatialReference);
var firstToPoint = new esri.geometry.Point(firstToX, firstToY, this.map.spatialReference);
var firstCuttingLine = new esri.geometry.Polyline(this.map.spatialReference);
firstCuttingLine.addPath([firstFromPoint, firstNearestPoint, firstToPoint]);
//构造第二条切割线
var secondFromX = secondNearestPoint.x + 1;
var secondFromY = secondNearestPoint.y + 1;
var secondToX = secondNearestPoint.x - 1;
var secondToY = secondNearestPoint.y - 1;
var secondFromPoint = new esri.geometry.Point(secondFromX, secondFromY, this.map.spatialReference);
var secondToPoint = new esri.geometry.Point(secondToX, secondToY, this.map.spatialReference);
var secondCuttingLine = new esri.geometry.Polyline(this.map.spatialReference);
secondCuttingLine.addPath([secondFromPoint, secondNearestPoint, secondToPoint]);
//第一次切割之后的结果(使用第一条切割线,切得两条Polyline)
var firstCutResult = geometryEngine.cut(targetPolyline,firstCuttingLine);
//两次切割之后的结果集(三条Polyline)
var lineSegments=[];
//使用第二条切割线,对第一次切割之后的结果进行切割
firstCutResult.forEach(function(aLine){
var cutLines = geometryEngine.cut(aLine,secondCuttingLine);
cutLines.forEach(function(aLineSegment){
lineSegments.push(aLineSegment);
});
});
console.log(lineSegments);
//要返回的结果(为传入的Polyline的一段。默认为结果集中的第一条记录)
var lineSegment = lineSegments[0];
//结果段长度
var pathLength = lineSegment.paths[0].length;
//首末两个点
var fromPoint = lineSegment.paths[0][0];
var toPoint = lineSegment.paths[0][pathLength-1];
/**
* 取首末两点,与两个切割点求距离平方和(以下简称距离)
* 正反方向两次距离计算,取二者较小者
**/
var minDistance1 = Math.pow((firstPoint.x-fromPoint[0]),2)+Math.pow((firstPoint.y-fromPoint[1]),2)+ Math.pow((secondPoint.x-toPoint[0]),2)+Math.pow((secondPoint.y-toPoint[1]),2);
var minDistance2 = Math.pow((firstPoint.x-toPoint[0]),2)+Math.pow((firstPoint.y-toPoint[1]),2)+ Math.pow((secondPoint.x-fromPoint[0]),2)+Math.pow((secondPoint.y-fromPoint[1]),2);
var minDistance = (minDistance1<=minDistance2)?minDistance1:minDistance2;
console.log("PathLength : ",pathLength,"MinDistance1 : ",minDistance1,"MinDistance2 : ",minDistance2,"MinDistance : ",minDistance);
//循环结果集中的每一条记录,分别计算距离
lineSegments.forEach(function(aSegment,nIndex){
if(0<nIndex){ //跳过第一个
var tempPathLength = aSegment.paths[0].length;
var tempFromPoint = aSegment.paths[0][0];
var tempToPoint = aSegment.paths[0][tempPathLength-1];
var tempMinDistance1= Math.pow((firstPoint.x-tempFromPoint[0]),2)+Math.pow((firstPoint.y-tempFromPoint[1]),2)+ Math.pow((secondPoint.x-tempToPoint[0]),2)+Math.pow((secondPoint.y-tempToPoint[1]),2);
var tempMinDistance2 = Math.pow((firstPoint.x-tempToPoint[0]),2)+Math.pow((firstPoint.y-tempToPoint[1]),2)+ Math.pow((secondPoint.x-tempFromPoint[0]),2)+Math.pow((secondPoint.y-tempFromPoint[1]),2);
console.log("TempPathLength : ",tempPathLength," TempMinDistance1 : ",tempMinDistance1," TempMinDistance2 : ",tempMinDistance2);
//若当前距离小于最小距离,则将当前结果记录保存为备选返回记录
if(tempMinDistance1<minDistance||tempMinDistance2<minDistance){
console.log("aSegment : ",aSegment);
lineSegment = aSegment;
}
}
});
console.log("LineSegment : ",lineSegment);
return lineSegment;
}
示例:
换乘结果展示:
完整的线路: