aboutsummaryrefslogtreecommitdiffhomepage
path: root/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/match-road.sh51
1 files changed, 32 insertions, 19 deletions
diff --git a/scripts/match-road.sh b/scripts/match-road.sh
index d59064a..6c2f242 100755
--- a/scripts/match-road.sh
+++ b/scripts/match-road.sh
@@ -20,15 +20,15 @@ set -e
20# put yout Mapbox token here 20# put yout Mapbox token here
21ACCESS_TOKEN=$(cat ~/settings/tokens/mapbox) 21ACCESS_TOKEN=$(cat ~/settings/tokens/mapbox)
22# number of coordinates for each Mapbox Map Matching API request, Maximum value is 100 22# number of coordinates for each Mapbox Map Matching API request, Maximum value is 100
23LIMIT=10 23LIMIT=50
24# define the lowest confidence of accepted matched points 24# define the lowest confidence of accepted matched points
25THRESHOLD=0.9 25THRESHOLD=0.7
26 26
27ORIGIN_DATA=/tmp/$(basename $1).origin 27ORIGIN_DATA=/tmp/$(basename $1).origin
28RESPONSE=$(basename $1).response 28MATCHED=/tmp/$(basename $1).matched
29 29
30# extract data from the given gpx file, dump coordindate and time with the following format: 30# extract data from the given gpx file, dump data with format [coordindate] [time_to_second], like:
31# [121.0179739,14.5515336] 1984-01-01T08:00:46.234 31# [121.0179739,14.5515336] 1984-01-01T08:00:46
32function get_data() { 32function get_data() {
33 sed -nr '/<trkpt /, /<\/trkpt>/ {H; /<\/trkpt>/ {x; s/\n/ /g; p; s/.*//; x}}' $1 |\ 33 sed -nr '/<trkpt /, /<\/trkpt>/ {H; /<\/trkpt>/ {x; s/\n/ /g; p; s/.*//; x}}' $1 |\
34 sed -nr 'h; s/.*lon="([^"]+).*/\1/; H; g 34 sed -nr 'h; s/.*lon="([^"]+).*/\1/; H; g
@@ -43,23 +43,40 @@ function get_data() {
43 awk '!_[$2]++' 43 awk '!_[$2]++'
44} 44}
45 45
46# Read data like the following to make GeoJSON object for Map Matching API: 46# Output GeoJSON object for Map Matching API from STDIN with format [coordinate] [time], like:
47# [121.0179739,14.5515336] 1984-01-01T08:00:46.234 47# [121.0179739,14.5515336] 1984-01-01T08:00:46
48function make_geojson() { 48function make_geojson() {
49 # change input to format like: [[lon, lat], time] 49 # change input to format like: [[lon, lat], time]
50 awk '{printf("[%s,\"%s\"]\n", $1, $2)}' |\ 50 awk '{printf("[%s,\"%s\"]\n", $1, $2)}' |\
51 jq '[inputs] | {type: "Feature", properties: {coordTimes: (map(.[1]))}, geometry: {type: "LineString", coordinates: map(.[0])}}' 51 jq '[inputs] | {type: "Feature", properties: {coordTimes: (map(.[1]))}, geometry: {type: "LineString", coordinates: map(.[0])}}'
52} 52}
53 53
54# Read GeoJSON body from input, and return result from Mapbox Map Matching API 54# Read GeoJSON body from STDIN, and return result from Mapbox Map Matching API
55function query_matched_road() { 55function query_matched_road() {
56 curl -X POST -s --data @- \ 56 curl -X POST -s --data @- \
57 --header "Content-Type:application/json" \ 57 --header "Content-Type:application/json" \
58 https://api.mapbox.com/matching/v4/mapbox.driving.json?access_token=$ACCESS_TOKEN 58 https://api.mapbox.com/matching/v4/mapbox.driving.json?access_token=$ACCESS_TOKEN
59} 59}
60 60
61# Get valid data from Map Matching API response
62# output format is [coordinates] [index-of-original-data], like:
63# [121.0179739,14.5515336] 35
64# If the point is newly added, the index would be -1, like
65# [121.0189339,14.5525931] -1
61function get_valid_data() { 66function get_valid_data() {
62 jq ".features[] | select(.properties.confidence >= $THRESHOLD)" 67 VALID_DATA=$(jq ".features[] | select(.properties.confidence >= $THRESHOLD)")
68
69 echo $VALID_DATA |\
70 jq -cr '.properties | [.matchedPoints, (.indices | map(.+1))] | transpose[] | "\(.[0]) \(.[1])"' > $MATCHED
71
72 echo $VALID_DATA | jq -c '.geometry.coordinates[]' |\
73 while read point; do
74 if head -1 $MATCHED| grep -F $point; then
75 sed -i 1d $MATCHED
76 else
77 echo $point
78 fi
79 done
63} 80}
64 81
65get_data $1 > $ORIGIN_DATA 82get_data $1 > $ORIGIN_DATA
@@ -67,29 +84,25 @@ get_data $1 > $ORIGIN_DATA
67# Consume raw data with serveral request 84# Consume raw data with serveral request
68while [ -s $ORIGIN_DATA ]; do 85while [ -s $ORIGIN_DATA ]; do
69 86
70 head -$LIMIT $ORIGIN_DATA | make_geojson | query_matched_road > $RESPONSE 87 head -$LIMIT $ORIGIN_DATA | make_geojson | query_matched_road | get_valid_data
71 cat $RESPONSE | get_valid_data
72 exit 0 88 exit 0
73
74 # Put existing timestamps to matched points, and interpolate new timestamps into new points 89 # Put existing timestamps to matched points, and interpolate new timestamps into new points
75 join -a1 \
76 <(jq -c '.features[0].geometry.coordinates[]' $RESPONSE) \
77 <(jq -cr '.features[0].properties | [.matchedPoints, (.indices | map(.+1))] | transpose[] | "\(.[0]) \(.[1])"' $RESPONSE) |\
78 sed '/ / !s/$/ -1/' |\
79 while read coor index; do 90 while read coor index; do
80 if [ $index -gt -1 ]; then 91 if [ $index -gt -1 ]; then
81 echo $coor $(sed -n "$index p" $ORIGIN_DATA | cut -d' ' -f1 | date -f - +%s) 92 echo $coor $(sed -n "$index p" $ORIGIN_DATA | cut -d' ' -f2 | date -f - +%s)
82 else 93 else
83 echo $coor $index 94 echo $coor $index
84 fi 95 fi
85 done |\ 96 done
97 exit 0
98 # interpolate timestamps to newly added points
86 awk '{COOR[NR][0]=$1; N++; COOR[NR][1]=$2} END{for (i=1; i<=N; i++) {printf COOR[i][0]; if (COOR[i][1] != -1) {print " "COOR[i][1]; LAST=i} else {while(COOR[i+n][1] == -1) n++; print " "COOR[LAST][1]+(COOR[i+n][1]-COOR[LAST][1])*(i-LAST)/(i+n-LAST)}}}' |\ 99 awk '{COOR[NR][0]=$1; N++; COOR[NR][1]=$2} END{for (i=1; i<=N; i++) {printf COOR[i][0]; if (COOR[i][1] != -1) {print " "COOR[i][1]; LAST=i} else {while(COOR[i+n][1] == -1) n++; print " "COOR[LAST][1]+(COOR[i+n][1]-COOR[LAST][1])*(i-LAST)/(i+n-LAST)}}}' |\
87 while read coor unix_time; do 100 while read coor unix_time; do
88 # Transform unix timestamp into human readable time format, like following: 101 # Transform unix timestamp into human readable time format, like following:
89 # Transform [121.018088,14.5516] 18.50 102 # Transform [121.018088,14.5516] 18.50
90 # Into [121.018088,14.5516] 1970-01-01T08:00:18.50Z 103 # Into [121.018088,14.5516] 1970-01-01T08:00:18.50Z
91 echo $coor $(date -d @$unix_time +'%Y-%m-%dT%H:%M:%S.%2NZ') 104 echo $coor $(date -d @$unix_time +'%Y-%m-%dT%H:%M:%S.%2NZ')
92 done | tee /dev/tty 105 done
93 106
94 # Remove processed raw data 107 # Remove processed raw data
95 sed -i "1,$LIMIT d" $ORIGIN_DATA 108 sed -i "1,$LIMIT d" $ORIGIN_DATA