本文分享一种可以用于处理曲线的算法,是本人在百度地图开源库基础上改造的,可以用于其他地图场景中处理点数据,只要两个以上的点,就可以得到平滑的曲线。例如小程序,将处理后得到的点赋值给polyline的points即可。

function getCurveByTwoPoints(obj1, obj2) {    if (!obj1 || !obj2) {        return null    }    var B1 = function (x) {        return 1 - 2 * x + x * x    };    var B2 = function (x) {        return 2 * x - 2 * x * x    };    var B3 = function (x) {        return x * x    };    curveCoordinates = [];    var count = 30;    var isFuture = false;    var t, h, h2, lat3, lng3, j, t2;    var LnArray = [];    var i = 0;    var inc = 0;    if (typeof(obj2) == "undefined") {        if (typeof(curveCoordinates) != "undefined") {            curveCoordinates = []        }        return    }    var lat1 = parseFloat(obj1.lat);    var lat2 = parseFloat(obj2.lat);    var lng1 = parseFloat(obj1.lng);    var lng2 = parseFloat(obj2.lng);    if (lng2 > lng1) {        if (parseFloat(lng2 - lng1) > 180) {            if (lng1 < 0) {                lng1 = parseFloat(180 + 180 + lng1)            }        }    }    if (lng1 > lng2) {        if (parseFloat(lng1 - lng2) > 180) {            if (lng2 < 0) {                lng2 = parseFloat(180 + 180 + lng2)            }        }    }    j = 0;    t2 = 0;    if (lat2 == lat1) {        t = 0;        h = lng1 - lng2    } else {        if (lng2 == lng1) {            t = Math.PI / 2;            h = lat1 - lat2        } else {            t = Math.atan((lat2 - lat1) / (lng2 - lng1));            h = (lat2 - lat1) / Math.sin(t)        }    }    if (t2 == 0) {        t2 = (t + (Math.PI / 5))    }    h2 = h / 2;    lng3 = h2 * Math.cos(t2) + lng1;    lat3 = h2 * Math.sin(t2) + lat1;    for (i = 0; i < count + 1; i++) {        curveCoordinates.push(            {                lng: (lng1 * B1(inc) + lng3 * B2(inc)) + lng2 * B3(inc),                lat: (lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc))            }        );        inc = inc + (1 / count)    }    return curveCoordinates}function getCurvePoints(points) {    var curvePoints = [];    for (var i = 0; i < points.length - 1; i++) {        var p = getCurveByTwoPoints(points[i], points[i + 1]);        if (p && p.length > 0) {            curvePoints = curvePoints.concat(p)        }    }    return curvePoints}let trackPoints = [{lng:113.281, lat:29.203}, {lng:113.567, lat:29.301}]let convertPoints = getCurvePoints(trackPoints)console.log(convertPoints)

最后再给一个微信小程序应用实例

map.wxml

// 举个小程序应用的例子<map id="map" longitude="113.324520" latitude="23.099994" scale="14" controls="{{controls}}" bindcontroltap="controltap" markers="{{markers}}" bindmarkertap="markertap" polyline="{{polyline}}" bindregionchange="regionchange" show-location style="width:100vw;height:100vh;"></map>

map.js

Page({  data: {    markers: [{      iconPath: "/resources/marker.png",      id: 0,      latitude: 23.099994,      longitude: 113.324520,      width: 50,      height: 50    }],    polyline: [],    controls: [{      id: 1,      iconPath: '/resources/location.png',      position: {        left: 0,        top: 300 - 50,        width: 50,        height: 50      },      clickable: true    }]  },  onLoad() {    this.setData({      polyline:[{        points: this.getCurvePoints([{ lng: 113.3245211, lat: 23.10229 }, { lng: 113.324520, lat: 23.21229 }]),        color: "#FF0000DD",        width: 2      }]    })  },  regionchange(e) {    console.log(e.type)  },  markertap(e) {    console.log(e.markerId)  },  controltap(e) {    console.log(e.controlId)  },  getCurveByTwoPoints(obj1, obj2) {    if (!obj1 || !obj2) {      return null    }    var B1 = function (x) {      return 1 - 2 * x + x * x    };    var B2 = function (x) {      return 2 * x - 2 * x * x    };    var B3 = function (x) {      return x * x    };    var curveCoordinates = [];    var count = 30;    var isFuture = false;    var t, h, h2, lat3, lng3, j, t2;    var LnArray = [];    var i = 0;    var inc = 0;    if (typeof (obj2) == "undefined") {      if (typeof (curveCoordinates) != "undefined") {        curveCoordinates = []      }      return    }    var lat1 = parseFloat(obj1.lat);    var lat2 = parseFloat(obj2.lat);    var lng1 = parseFloat(obj1.lng);    var lng2 = parseFloat(obj2.lng);    if (lng2 > lng1) {      if (parseFloat(lng2 - lng1) > 180) {        if (lng1 < 0) {          lng1 = parseFloat(180 + 180 + lng1)        }      }    }    if (lng1 > lng2) {      if (parseFloat(lng1 - lng2) > 180) {        if (lng2 < 0) {          lng2 = parseFloat(180 + 180 + lng2)        }      }    }    j = 0;    t2 = 0;    if (lat2 == lat1) {      t = 0;      h = lng1 - lng2    } else {      if (lng2 == lng1) {        t = Math.PI / 2;        h = lat1 - lat2      } else {        t = Math.atan((lat2 - lat1) / (lng2 - lng1));        h = (lat2 - lat1) / Math.sin(t)      }    }    if (t2 == 0) {      t2 = (t + (Math.PI / 5))    }    h2 = h / 2;    lng3 = h2 * Math.cos(t2) + lng1;    lat3 = h2 * Math.sin(t2) + lat1;    for (i = 0; i < count + 1; i++) {      curveCoordinates.push(        {          longitude: (lng1 * B1(inc) + lng3 * B2(inc)) + lng2 * B3(inc),          latitude: (lat1 * B1(inc) + lat3 * B2(inc) + lat2 * B3(inc))        }      );      inc = inc + (1 / count)    }    return curveCoordinates  },  getCurvePoints(points) {    var curvePoints = [];    for (var i = 0; i < points.length - 1; i++) {      var p = this.getCurveByTwoPoints(points[i], points[i + 1]);      if (p && p.length > 0) {        curvePoints = curvePoints.concat(p)      }    }    return curvePoints  }})

献上效果图:


首发链接