ArcGIS JavaScript API实现Polyline外两点分割该线

背景:

  某项目要做一个公交换乘查询。以最简单的情况为例,即只需乘坐一次车,不需换乘即可到达。线路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;
        }


示例:

换乘结果展示:


完整的线路:





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值