aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rwxr-xr-xscripts/match-road.sh46
1 files changed, 25 insertions, 21 deletions
diff --git a/scripts/match-road.sh b/scripts/match-road.sh
index 7b6dad4..608fc56 100755
--- a/scripts/match-road.sh
+++ b/scripts/match-road.sh
@@ -20,9 +20,9 @@ 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=50 23LIMIT=10
24# define the lowest confidence of accepted matched points 24# define the lowest confidence of accepted matched points
25THRESHOLD=0.7 25THRESHOLD=0.3
26 26
27ORIGIN_DATA=/tmp/$(basename $1).origin 27ORIGIN_DATA=/tmp/$(basename $1).origin
28MATCHED=/tmp/$(basename $1).matched 28MATCHED=/tmp/$(basename $1).matched
@@ -30,7 +30,7 @@ MATCHED=/tmp/$(basename $1).matched
30# extract data from the given gpx file, dump data with format [coordindate] [time_to_second], like: 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 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
35 s/.*lat="([^"]+).*/\1/; H; g 35 s/.*lat="([^"]+).*/\1/; H; g
36 # If trkpt has no time, leave it blank 36 # If trkpt has no time, leave it blank
@@ -38,8 +38,8 @@ function get_data() {
38 s/.*<time>([^.]+).*<\/time>.*/\1/ 38 s/.*<time>([^.]+).*<\/time>.*/\1/
39 H; g 39 H; g
40 } 40 }
41 s/^[^\n]+\n//; s/\n/ /g; p' |\ 41 s/^[^\n]+\n//; s/\n/ /g; p' |
42 sed -r 's/^([^ ]+) ([^ ]+)/[\1,\2]/' |\ 42 sed -r 's/^([^ ]+) ([^ ]+)/[\1,\2]/' |
43 awk '!_[$2]++' 43 awk '!_[$2]++'
44} 44}
45 45
@@ -47,12 +47,12 @@ function get_data() {
47# [121.0179739,14.5515336] 1984-01-01T08:00:46 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 STDIN, 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_points() {
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
@@ -63,15 +63,15 @@ function query_matched_road() {
63# [121.0179739,14.5515336] 35 63# [121.0179739,14.5515336] 35
64# If the point is newly added, the index would be -1, like 64# If the point is newly added, the index would be -1, like
65# [121.0189339,14.5525931] -1 65# [121.0189339,14.5525931] -1
66function get_valid_data() { 66function validate_matched_points() {
67 VALID_DATA=$(jq ".features[] | select(.properties.confidence >= $THRESHOLD)") 67 VALID_DATA=$(jq ".features[] | select(.properties.confidence >= $THRESHOLD)")
68 68
69 echo $VALID_DATA |\ 69 echo $VALID_DATA |
70 jq -cr '.properties | [.matchedPoints, (.indices | map(.+1))] | transpose[] | "\(.[0]) \(.[1])"' > $MATCHED 70 jq -cr '.properties | [.matchedPoints, (.indices | map(.+1))] | transpose[] | "\(.[0]) \(.[1])"' > $MATCHED
71 71
72 echo $VALID_DATA | jq -c '.geometry.coordinates[]' |\ 72 echo $VALID_DATA | jq -c '.geometry.coordinates[]' |
73 while read point; do 73 while read point; do
74 if head -1 $MATCHED| grep -F $point; then 74 if head -1 $MATCHED | grep -F $point; then
75 sed -i 1d $MATCHED 75 sed -i 1d $MATCHED
76 else 76 else
77 echo $point -1 77 echo $point -1
@@ -87,9 +87,9 @@ function complete_data() {
87 else 87 else
88 echo $coor $index 88 echo $coor $index
89 fi 89 fi
90 done|\ 90 done|
91 # interpolate timestamps to newly added points 91 # interpolate timestamps to newly added points
92 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)}}}' |\ 92 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)}}}' |
93 while read coor unix_time; do 93 while read coor unix_time; do
94 # Transform unix timestamp into human readable time format, like following: 94 # Transform unix timestamp into human readable time format, like following:
95 # Transform [121.018088,14.5516] 18.50 95 # Transform [121.018088,14.5516] 18.50
@@ -101,7 +101,7 @@ function complete_data() {
101# Make GPX format for output 101# Make GPX format for output
102# Take input with format: [lon,lat] [time] 102# Take input with format: [lon,lat] [time]
103function make_gpx() { 103function make_gpx() {
104 sed -E 's/\[([^,]+),([^,]+)\] (.*)/ <trkpt lon="\1" lat="\2"><time>\3<\/time><\/trkpt>/' |\ 104 sed -E 's/\[([^,]+),([^,]+)\] (.*)/ <trkpt lon="\1" lat="\2"><time>\3<\/time><\/trkpt>/' |
105 sed "1i \ 105 sed "1i \
106<gpx version=\"1.1\" creator=\"Garmin Connect\"\n\ 106<gpx version=\"1.1\" creator=\"Garmin Connect\"\n\
107 xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd\"\n\ 107 xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd http://www.garmin.com/xmlschemas/GpxExtensions/v3 http://www.garmin.com/xmlschemas/GpxExtensionsv3.xsd http://www.garmin.com/xmlschemas/TrackPointExtension/v1 http://www.garmin.com/xmlschemas/TrackPointExtensionv1.xsd\"\n\
@@ -122,13 +122,17 @@ get_data $1 > $ORIGIN_DATA
122 122
123# Consume raw data with serveral request 123# Consume raw data with serveral request
124while [ -s $ORIGIN_DATA ]; do 124while [ -s $ORIGIN_DATA ]; do
125 125 # Take original data by limited points for each time: [121.0179739,14.5515336] 1984-01-01T08:00:46
126 head -$LIMIT $ORIGIN_DATA |\ # Take original data by limited points at a time: [121.0179739,14.5515336] 1984-01-01T08:00:46 126 # Make geojson body: {type: "Feature", properties: {coordTimes: [...]}, geometry: {type: "LineString", coordinates: [...]}}
127 make_geojson |\ # Make geojson body: {type: "Feature", properties: {coordTimes: [...]}, geometry: {type: "LineString", coordinates: [...]}} 127 # Call Mapbox Map Matching API: {geometry: {coordinates: [...]}, properties: {confidence: 0.9, matching: [...], indices: [...]}}
128 query_matched_road |\ # Call Mapbox Map Matching API: {geometry: {coordinates: [...]}, properties: {confidence: 0.9, matching: [...], indices: [...]}} 128 # Get valid point and index by confidence value: [121.0179739,14.5515336] 5
129 get_valid_data |\ # Get valid point and index by confidence value: [121.0179739,14.5515336] 5 129 # complete_data
130 complete_data 130 head -$LIMIT $ORIGIN_DATA |
131 make_geojson |
132 query_matched_points |
133 validate_matched_points
131 134
132 # Remove processed raw data 135 # Remove processed raw data
133 sed -i "1,$LIMIT d" $ORIGIN_DATA 136 sed -i "1,$LIMIT d" $ORIGIN_DATA
134done 137done |
138make_geojson > test.geojson