本文分享一種能夠用於處理曲線的算法,是本人在百度地圖開源庫基礎上改造的,能夠用於其餘地圖場景中處理點數據,只要兩個以上的點,就能夠獲得平滑的曲線。例如小程序,將處理後獲得的點賦值給polyline
的points便可。javascript
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)
最後再給一個微信小程序應用實例html
map.wxml
java
// 舉個小程序應用的例子 <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
git
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 } })
獻上效果圖:算法
首發連接小程序