近期项目中遇到的一个需求是将采集到的测点数据在地图上动态展示。

地图组件选用高德地图。在展示中需要将每个测点作为点绘制,该点支持点击事件,并在达到告警阀值(温度, 压力, 离线)后改变颜色。同时也需要将所有测点绘制成线展示。

为满足绘制出测点线这一需求,选择使用AMap.Polyline完成。在最初将采集到的测点数据直接作为入参调用AMap.Polyline时,其显示效果是许多线交错在一起,如图1所示,并没有成一条线。

图1

图1

在详细查看AMap.Polyline文档后发现,该方法绘制时会按照入参的顺序来连接各点。那么,图1中的效果显然是采集到的数据中各点并未按照一条线的顺序排列。

为使测点按照一条线的顺序排列,最初设想取最左侧测点坐标,通过各点与最左侧测点的距离进行排序。实现后发现因线条本身较弯曲,仅通过与一点的距离来决定顺序效果不佳。

改进后的方法为:

  1. 从原始测点数组arr中取最左侧测点坐标为anchor,将其加入result队列,并从arr中移除。

  2. 遍历arr,选出其中与anchor距离最小的测点p,将其坐标设为anchor,将其加入result,并从arr中移除。

  3. 判断arr是否为空,是则结束,否则重复2。

这样最终可获得按一条线的顺序排列的测点数组,效果如图2所示。

图2

图2

附排序部分源码

//获取最左侧点在原始数组的序号及经度
leftMark = 118.66776885034 //从原始数据中随意取出的一个最左侧点之外的点
leftPoint = 0
for(i=0;i<arr.length;i++){
    if(arr[i]['gcj02经度'] < leftMark){
        leftMark = arr[i]['gcj02经度']
        leftPoint = i
    }
}

//将最左侧点加入加入result并将其从arr移除
result = []
result.push(arr[leftPoint])
arr.splice(leftPoint,1)

//重复找出与anchor最近的点并加入result中
while(arr.length > 0){
    tpoint = result[result.length-1]
    mpoint = 0
    dis = Math.pow(arr[0]['gcj02经度'] - tpoint['gcj02经度'],2) + Math.pow(arr[0]['gcj02维度'] - tpoint['gcj02维度'],2)
    for(i=1;i<arr.length;i++){
        ndis = Math.pow(arr[i]['gcj02经度'] - tpoint['gcj02经度'],2) + Math.pow(arr[i]['gcj02维度'] - tpoint['gcj02维度'],2)
        if(ndis<dis){
            dis=ndis
            mpoint=i
        }
    }
    result.push(arr[mpoint])
    arr.splice(mpoint,1)
}



return [result]