Skip to content

Commit 004a5e3

Browse files
committed
update location
1 parent 3f78707 commit 004a5e3

File tree

1 file changed

+89
-19
lines changed

1 file changed

+89
-19
lines changed

_posts/2019-02-02-car-location.md

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@
3636
}
3737
</style>
3838
<div id="head">
39-
<h1>car-location</h1>
4039
<form id="searchForm">
4140
<label for="apiKey">ApiKey:</label>
4241
<input id="apiKey" type="text" value="0XlwMJm8U42KEZ394N4p8hm2p=s=" />
@@ -72,10 +71,17 @@
7271
function getDoubleDigit(number){
7372
return number < 10 ? ('0' + number) : number;
7473
}
75-
function calcVelocity(pointStart, pointEnd){
74+
function calcVelocityAndDistance(pointStart, pointEnd){
7675
var timeCost = new Date(pointEnd.at) - new Date(pointStart.at);
7776
var distance = GPS.distance(pointStart.value.lat, pointStart.value.lon, pointEnd.value.lat, pointEnd.value.lon);
78-
return distance / timeCost;
77+
return {distance: distance, velocity: distance / timeCost};
78+
}
79+
function calcDistanceOfPoints(points){
80+
if(points.length < 2){
81+
return 0;
82+
}
83+
let pointStart = points[0], pointEnd = points[points.length - 1];
84+
return GPS.distance(pointStart.lat, pointStart.lng, pointEnd.lat, pointEnd.lng);
7985
}
8086
function getVelocityGroup(velocity){ //计算单位为米/微秒
8187
/*
@@ -102,33 +108,87 @@
102108
30: '#f3ed49',
103109
100: '#4fd27d',
104110
}
111+
function splitDatapointsByTime(dataPoints){
112+
let splitedPoints = [];
113+
let tempPoints = [dataPoints[0]];
114+
for(let i = 1; i < dataPoints.length; i++){
115+
if(new Date(dataPoints[i].at) - new Date(dataPoints[i - 1].at) > 600000){ //10分钟
116+
splitedPoints.push(tempPoints);
117+
tempPoints = [dataPoints[i]];
118+
}else{
119+
tempPoints.push(dataPoints[i]);
120+
}
121+
}
122+
splitedPoints.push(tempPoints); //最后一组
123+
return splitedPoints;
124+
}
105125
function splitDatapointsByVelocity(dataPoints){
106126
let splitedPoints = [];
107127
splitedPoints.count = dataPoints.length;
108128
splitedPoints.startTime = dataPoints[0].at;
109129
splitedPoints.endTime = dataPoints[dataPoints.length - 1].at;
110-
let currentVelocityGroup,
111-
previousVelocityGroup = getVelocityGroup(calcVelocity(dataPoints[0], dataPoints[1])),
130+
let currentVelocityGroup,
131+
currentPointsCost = calcVelocityAndDistance(dataPoints[0], dataPoints[1]);
132+
previousVelocityGroup = getVelocityGroup(currentPointsCost.velocity),
133+
reallyDistance = currentPointsCost.distance,
134+
airDistance = reallyDistance,
135+
currentStartPoint = dataPoints[0],
112136
tempPoints = {
113-
points: [getBMapPoint(dataPoints[0].value)],
137+
points: [getBMapPoint(dataPoints[0].value), getBMapPoint(dataPoints[1].value)],
114138
velocityGroup: previousVelocityGroup
115139
};
116140
splitedPoints.push(tempPoints);
117-
for(let i = 1; i < dataPoints.length - 1; i++){
118-
currentVelocityGroup = getVelocityGroup(calcVelocity(dataPoints[i], dataPoints[i + 1]));
141+
//根据速度分组并只保留长直线的端点
142+
for(let i = 2; i < dataPoints.length - 1; i++){
143+
currentPointsCost = calcVelocityAndDistance(dataPoints[i - 1], dataPoints[i]);
144+
reallyDistance += currentPointsCost.distance; //实际距离
145+
airDistance = GPS.distance(currentStartPoint.value.lat, currentStartPoint.value.lon, dataPoints[i].value.lat, dataPoints[i].value.lon); //航空距离
146+
currentVelocityGroup = getVelocityGroup(currentPointsCost.velocity);
119147
if(currentVelocityGroup == previousVelocityGroup){ //当前两个点的速度和前两个点的速度属于同一个组
148+
if(reallyDistance - airDistance < 1){
149+
tempPoints.points.length = tempPoints.points.length - 1;
150+
}
120151
tempPoints.points.push(getBMapPoint(dataPoints[i].value));
121152
}else{
122153
tempPoints = {
123154
points: [getBMapPoint(dataPoints[i-1].value), getBMapPoint(dataPoints[i].value)],
124155
velocityGroup: currentVelocityGroup
125156
};
157+
currentStartPoint = dataPoints[i - 1];
158+
reallyDistance = currentPointsCost.distance;
126159
splitedPoints.push(tempPoints);
127160
}
128161
previousVelocityGroup = currentVelocityGroup;
129162
}
130-
return splitedPoints;
163+
//去掉毛刺点 TODO: 目前算法会把长直线与周边合并掉,因为长直线的点数量小于10
164+
let concatedPoints = [splitedPoints[0]];
165+
let j;
166+
for(j = 1; j < splitedPoints.length - 1; j++){
167+
//console.log(splitedPoints[i].velocityGroup,concatedPoints[concatedPoints.length-1].velocityGroup,splitedPoints[i+1].velocityGroup);
168+
//console.log('端点距离:',calcDistanceOfPoints(splitedPoints[j].points));
169+
if(splitedPoints[j].points.length < 10 && calcDistanceOfPoints(splitedPoints[j].points) < 50 && concatedPoints[concatedPoints.length-1].velocityGroup == splitedPoints[j+1].velocityGroup){
170+
//console.log('等于:' ,concatedPoints[concatedPoints.length - 1].points,splitedPoints[i].points)
171+
concatedPoints[concatedPoints.length - 1].points = concatedPoints[concatedPoints.length - 1].points.concat(splitedPoints[j].points).concat(splitedPoints[j+1].points);
172+
++j;
173+
//splitedPoints[i].points.length = 0;
174+
//splitedPoints[i] = null;
175+
}else{
176+
concatedPoints.push(splitedPoints[j]);
177+
}
178+
}
179+
if(j < splitedPoints.length){ //倒数第二段不是毛刺的时候,j只能到length-1,这个时候需要把最后一项加进concatedPoints
180+
concatedPoints.push(splitedPoints[splitedPoints.length - 1]);
181+
}
182+
concatedPoints.startTime = splitedPoints.startTime;
183+
concatedPoints.endTime = splitedPoints.endTime;
184+
return concatedPoints;
131185
}
186+
function convertPoints(points){
187+
var pointsGroupByTime = splitDatapointsByTime(points);
188+
pointsGroupByTime = pointsGroupByTime.map(pointsGroup => splitDatapointsByVelocity(pointsGroup));
189+
pointsGroupByTime.count = points.length;
190+
return pointsGroupByTime;
191+
};
132192
function getBMapPoint(point){
133193
var bdGps = GPS.GPSToBaidu(point.lat, point.lon);
134194
return new BMap.Point(bdGps.lng, bdGps.lat);
@@ -164,11 +224,11 @@
164224
var _this = this;
165225
this._api.getDataPoints(deviceId, {datastream_id:'Gps', start: this.start, end: this.end, limit: $pointCount.value}).then(function(res){
166226
console.log('api调用完成,服务器返回data为:', res);
167-
$log.innerHTML = '当前第1页,本次共渲染' + res.data.count + '个点';
168227
if(res.data.cursor){ //加入第二页的corsor
169228
_this.cursorListOfPageIndex[1] = res.data.cursor;
170-
}
171-
var splitedPoints = splitDatapointsByVelocity(res.data.datastreams[0].datapoints);
229+
}
230+
var splitedPoints = convertPoints(res.data.datastreams[0].datapoints);
231+
$log.innerHTML = '当前第1页,本次共渲染' + splitedPoints.count + '个点';
172232
pageControl.baiduMap.resetMarker(splitedPoints);
173233
_this.pointsCache[1] = splitedPoints;
174234
});
@@ -190,7 +250,8 @@
190250
if(res.data.cursor){ //加入下一页的corsor
191251
_this.cursorListOfPageIndex[pageIndex + 1] = res.data.cursor;
192252
}
193-
var splitedPoints = splitDatapointsByVelocity(res.data.datastreams[0].datapoints);
253+
//var pointsTimeGroup = splitDatapointsByTime(res.data.datastreams[0].datapoints);
254+
var splitedPoints = convertPoints(res.data.datastreams[0].datapoints);
194255
pageControl.baiduMap.resetMarker(splitedPoints);
195256
_this.pointsCache[cursor] = splitedPoints;
196257
$log.innerHTML = '当前第' + (pageIndex + 1) + '页,本次共渲染' + splitedPoints.count + '个点';
@@ -277,27 +338,36 @@
277338
resetMarker: function(splitedPoints){
278339
this.map.clearOverlays();
279340
var _this = this;
280-
splitedPoints.forEach(item => {
341+
var edgePoints = [];
342+
splitedPoints.forEach(pointsGroup => {
343+
edgePoints = edgePoints.concat(_this.drawGroup(pointsGroup));
344+
});
345+
this.map.setViewport(edgePoints);
346+
},
347+
drawGroup: function(pointsGroup){
348+
var _this = this;
349+
var count = 0;
350+
pointsGroup.forEach(item => {
281351
_this.drawLine(item.points, VelocityGroupColor[item.velocityGroup]);
282352
});
283353
//加入marker
284354
var iconStart = new BMap.Icon('/resource/2019/markers_bg.png', new BMap.Size(25,40), {
285355
imageSize: new BMap.Size(50, 40),
286356
anchor: new BMap.Size(12, 40)
287357
});
288-
var markerStart = new BMap.Marker(splitedPoints[0].points[0], {icon:iconStart});
358+
var markerStart = new BMap.Marker(pointsGroup[0].points[0], {icon:iconStart});
289359
var iconEnd = new BMap.Icon('/resource/2019/markers_bg.png', new BMap.Size(25,40), {
290360
imageOffset: new BMap.Size(-25,0),
291361
imageSize: new BMap.Size(50, 40),
292362
anchor: new BMap.Size(12, 40)
293363
});
294-
var endPoints = splitedPoints[splitedPoints.length - 1].points;
364+
var endPoints = pointsGroup[pointsGroup.length - 1].points;
295365
var markerEnd = new BMap.Marker(endPoints[endPoints.length - 1], {icon:iconEnd});
296-
markerStart.setLabel(new BMap.Label(splitedPoints.startTime, {offset: new BMap.Size(-20,-20)}));
297-
markerEnd.setLabel(new BMap.Label(splitedPoints.endTime, {offset: new BMap.Size(-20,-20)}));
366+
markerStart.setLabel(new BMap.Label(pointsGroup.startTime, {offset: new BMap.Size(-20,-20)}));
367+
markerEnd.setLabel(new BMap.Label(pointsGroup.endTime, {offset: new BMap.Size(-20,-20)}));
298368
this.map.addOverlay(markerStart);
299369
this.map.addOverlay(markerEnd);
300-
this.map.setViewport([splitedPoints[0].points[0], endPoints[endPoints.length - 1]]);
370+
return [pointsGroup[0].points[0], endPoints[endPoints.length - 1]];
301371
},
302372
drawLine: function(pointsArr, color){
303373
var sy = new BMap.Symbol(BMap_Symbol_SHAPE_BACKWARD_OPEN_ARROW, {

0 commit comments

Comments
 (0)