一种在地图中处理曲线的通用方法

一种在地图中处理曲线的通用方法

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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

1
2
// 举个小程序应用的例子
<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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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
}
})

献上效果图:

小程序地图曲线


扫一扫下方小程序码或搜索Tusi博客,即刻阅读最新文章!

Tusi博客

You forgot to set the qrcode for Alipay. Please set it in _config.yml.
You forgot to set the qrcode for Wechat. Please set it in _config.yml.
You forgot to set the business and currency_code for Paypal. Please set it in _config.yml.
You forgot to set the url Patreon. Please set it in _config.yml.
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×