diff options
| author | typebrook <typebrook@gmail.com> | 2019-12-05 18:41:26 +0800 |
|---|---|---|
| committer | typebrook <typebrook@gmail.com> | 2019-12-05 18:41:26 +0800 |
| commit | be64be8f9da6bc2f7ef76fefcf9951288b4c3940 (patch) | |
| tree | 6b48f913cf8342e0abe46d2f042fd631af3daa25 | |
| parent | 5dde72b9b032521b5b71e8db085207059c17c209 (diff) | |
update
| -rwxr-xr-x | scripts/match-road.sh | 46 |
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 |
| 21 | ACCESS_TOKEN=$(cat ~/settings/tokens/mapbox) | 21 | ACCESS_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 |
| 23 | LIMIT=50 | 23 | LIMIT=10 |
| 24 | # define the lowest confidence of accepted matched points | 24 | # define the lowest confidence of accepted matched points |
| 25 | THRESHOLD=0.7 | 25 | THRESHOLD=0.3 |
| 26 | 26 | ||
| 27 | ORIGIN_DATA=/tmp/$(basename $1).origin | 27 | ORIGIN_DATA=/tmp/$(basename $1).origin |
| 28 | MATCHED=/tmp/$(basename $1).matched | 28 | MATCHED=/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 |
| 32 | function get_data() { | 32 | function 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 |
| 48 | function make_geojson() { | 48 | function 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 |
| 55 | function query_matched_road() { | 55 | function 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 |
| 66 | function get_valid_data() { | 66 | function 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] |
| 103 | function make_gpx() { | 103 | function 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 |
| 124 | while [ -s $ORIGIN_DATA ]; do | 124 | while [ -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 |
| 134 | done | 137 | done | |
| 138 | make_geojson > test.geojson | ||