aboutsummaryrefslogtreecommitdiffhomepage
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rwxr-xr-xtools/check_upstream25
-rwxr-xr-xtools/csv.move_column18
-rwxr-xr-xtools/csv.reorder17
-rwxr-xr-xtools/csv2geojson46
-rw-r--r--tools/gpx/footer1
-rwxr-xr-xtools/gpx/gpx.check.py85
-rwxr-xr-xtools/gpx/gpx.merge_gpx.sh5
-rwxr-xr-xtools/gpx/gpx.merge_trk.sh4
-rw-r--r--tools/gpx/header10
-rwxr-xr-xtools/load-settings.sh24
-rwxr-xr-xtools/match-road.sh148
-rw-r--r--tools/mvt_decode.py11
-rwxr-xr-xtools/osm/josm_install.sh8
-rw-r--r--tools/osm/osm17
-rwxr-xr-xtools/osm/osm.api.changeset.add10
-rwxr-xr-xtools/osm/osm.api.changeset.close3
-rwxr-xr-xtools/osm/osm.api.changeset.create21
-rwxr-xr-xtools/osm/osm.api.changeset.update7
-rwxr-xr-xtools/osm/osm.api.changeset.upload6
-rwxr-xr-xtools/osm/osm.api.fetch6
-rwxr-xr-xtools/osm/osm.api.fetch.full5
-rwxr-xr-xtools/osm/osm.api.fetch.history6
-rwxr-xr-xtools/osm/osm.api.member.relation4
-rwxr-xr-xtools/osm/osm.api.referenced.relation6
-rwxr-xr-xtools/osm/osm.api.referenced.way5
-rwxr-xr-xtools/osm/osm.api.upload.to12
-rwxr-xr-xtools/osm/osm.file.get4
-rwxr-xr-xtools/osm/osm.file.get.full4
-rwxr-xr-xtools/osm/osm.file.query4
-rwxr-xr-xtools/osm/osm.goto3
-rwxr-xr-xtools/osm/osm.help34
-rwxr-xr-xtools/osm/osm.list.ids3
-rwxr-xr-xtools/osm/osm.list.tag10
-rwxr-xr-xtools/osm/osm.list.tags15
-rwxr-xr-xtools/osm/osm.member.relation8
-rwxr-xr-xtools/osm/osm.osc.by_member31
-rwxr-xr-xtools/osm/osm.osc.by_tag45
-rwxr-xr-xtools/osm/osm.osm.remove9
-rwxr-xr-xtools/osm/osm.pbf.update39
-rwxr-xr-xtools/osm/osm.query3
-rwxr-xr-xtools/osm/sequence_number.sh22
-rwxr-xr-xtools/refresh-todo.sh5
-rwxr-xr-xtools/sync.sh6
-rwxr-xr-xtools/upload-github-release-asset.sh84
-rwxr-xr-xtools/yaoren.sh16
45 files changed, 855 insertions, 0 deletions
diff --git a/tools/check_upstream b/tools/check_upstream
new file mode 100755
index 0000000..3313e5b
--- /dev/null
+++ b/tools/check_upstream
@@ -0,0 +1,25 @@
1#! /bin/bash
2
3# This script is for repo forked from others
4# check $1(repo) if upstream branch origin/master is
5# ahead of local branch $2(default to dev)
6
7if [ ! -d "$1" ]; then
8 return 0
9fi
10
11head='dev'
12if [ $# -eq 2 ]
13then
14 head=$2
15fi
16
17cd "$1" && \
18git fetch origin && \
19if ! git rev-list "$head" | grep "$(git rev-parse origin/master)" > /dev/null
20then
21 [[ $(git pull my) == 'Alrady up to date.' ]] || \
22 echo "New commit at" "$1"
23fi
24
25echo "$(date)" check "$1" >> "$SETTING_DIR/log"
diff --git a/tools/csv.move_column b/tools/csv.move_column
new file mode 100755
index 0000000..a62701f
--- /dev/null
+++ b/tools/csv.move_column
@@ -0,0 +1,18 @@
1#! /bin/bash
2
3# show each field with index in csv
4echo -------------- > /dev/tty
5head -1 < $1 | sed 's/,/ /g' | awk '{for (i=1; i<=NF; i++) printf $i "_" i " "; print ""}' > /dev/tty
6echo -------------- > /dev/tty
7echo > /dev/tty
8
9# get index of lon/lat column
10read -p "Move which column? " origin_col
11read -p "To which index? " new_col
12
13cat $1 |
14# move lon and lat to the first and second column
15awk -F',' -v OFS="," -v origin_th=$origin_col -v new_th=$new_col '\
16 {for (i=1; i<= NF; i++) if (i == new_th) printf $origin_th OFS $i OFS; else if (i == origin_th); else printf $i OFS; print ""}\
17 ' |\
18sed 's/,$//g'
diff --git a/tools/csv.reorder b/tools/csv.reorder
new file mode 100755
index 0000000..8a64239
--- /dev/null
+++ b/tools/csv.reorder
@@ -0,0 +1,17 @@
1#! /bin/bash
2
3# show each field with index in csv
4echo -------------- > /dev/tty
5head -1 < $1 | awk -F',' '{for (i=1; i<=NF; i++) printf $i "_" i " "; print ""}' > /dev/tty
6echo -------------- > /dev/tty
7echo > /dev/tty
8
9read -p "type column numbers by new order, like 3 2 1: " order
10
11arrange=$(echo $order | sed -r 's/([^ ]+)/$\1/g' | tr ' ' ',')
12
13cat $1 |\
14awk -F',' "BEGIN{OFS=\",\"}{print $arrange}" |\
15tee /tmp/csv
16
17echo "Also copied to /tmp/csv" > /dev/tty
diff --git a/tools/csv2geojson b/tools/csv2geojson
new file mode 100755
index 0000000..028aed7
--- /dev/null
+++ b/tools/csv2geojson
@@ -0,0 +1,46 @@
1#! /bin/bash
2
3# -s to skip specify columns of longitude and latitude
4for i in "$@"
5do
6case $i in
7 -s)
8 lon_col=0; lat_col=1
9 shift;;
10
11 *)
12 csv=$i
13 shift;;
14esac
15done
16
17# if no -s option, just read from input
18if [ "$lon_col" != "0" ]; then
19 # show each field with index in csv
20 echo -------------- > /dev/tty
21 head -1 < $csv | awk -F',' '{for (i=1; i<=NF; i++) printf $i "_" i " "; print ""}' > /dev/tty
22 echo -------------- > /dev/tty
23 echo > /dev/tty
24
25 # get index of lon/lat column
26 read -p "Number of latitude column: " lat_col
27 read -p "Number of longitude column: " lon_col
28fi
29
30cat $csv |
31# move lon and lat to the first and second column
32awk -F',' -v lon_th=$lon_col -v lat_th=$lat_col '\
33 BEGIN{OFS=","}\
34 {printf $lon_th "," $lat_th; for (i=1; i<= NF; i++) if (i != lat_th && i != lon_th) printf "," $i; print ""}\
35 ' |\
36# change csv into array format, like [lon, lat, "field1", field2...]
37sed 's/[^,]*/"\0"/g; s/.*/[\0]/g' |\
38# wrap other fields as a json object, like [lon, lat, {...}]
39jq -s '.[0][2:] as $fields | .[1:][] | [.[0], .[1], ([$fields, .[2:]] | transpose | map({(.[0]): .[1]}) | add)]' |\
40# create array of geojson point features
41jq '{"type": "Feature", "properties": .[2], "geometry":{ "type": "Point", "coordinates": [(.[0] | tonumber), (.[1] | tonumber)] } }' |\
42# wrap features as geojson format
43jq -s '{"type": "FeatureCollection", "features": .}' |\
44tee /tmp/geojson
45
46echo stored into /tmp/geojson > /dev/tty
diff --git a/tools/gpx/footer b/tools/gpx/footer
new file mode 100644
index 0000000..d0759c0
--- /dev/null
+++ b/tools/gpx/footer
@@ -0,0 +1 @@
</gpx>
diff --git a/tools/gpx/gpx.check.py b/tools/gpx/gpx.check.py
new file mode 100755
index 0000000..10be97c
--- /dev/null
+++ b/tools/gpx/gpx.check.py
@@ -0,0 +1,85 @@
1#!/usr/bin/env python3
2
3import sys
4import os
5import argparse
6import copy
7import fileinput
8from osgeo import ogr
9import osr
10import urllib.parse
11
12def rewrite_gpx(filename):
13 for line in fileinput.input(filename, inplace=True):
14 if fileinput.isfirstline() and "'" in line:
15 line = '<?xml version="1.0" encoding="UTF-8"?>'
16 if fileinput.filelineno() == 2 and "version" not in line:
17 line = line.replace('<gpx', '<gpx version="1.1"')
18 print(line.rstrip('\n'))
19
20def check_valid(filename, threshold, add_prefix):
21 rewrite_gpx(filename)
22
23 driver = ogr.GetDriverByName('GPX')
24 try:
25 dataSource = driver.Open(filename)
26 except Exception:
27 pass
28 if dataSource is None:
29 print("could not open")
30 sys.exit(1)
31
32 inSpatialRef = osr.SpatialReference()
33 inSpatialRef.ImportFromEPSG(4326)
34 outSpatialRef = osr.SpatialReference()
35 outSpatialRef.ImportFromEPSG(3857)
36 to3857 = osr.CoordinateTransformation(inSpatialRef, outSpatialRef)
37 to4326 = osr.CoordinateTransformation(outSpatialRef, inSpatialRef)
38
39 trkLayer = dataSource.GetLayer(4)
40 trkpt = trkLayer.GetNextFeature()
41 flag = False
42 while trkpt:
43 nextTrkpt = trkLayer.GetNextFeature()
44 if nextTrkpt:
45 geom1 = trkpt.GetGeometryRef()
46 geom1.Transform(to3857)
47 geom2 = nextTrkpt.GetGeometryRef()
48 geom2.Transform(to3857)
49 distance = geom1.Distance(geom2)
50
51 geom1.Transform(to4326)
52 geom2.Transform(to4326)
53 if distance >= threshold:
54 if not flag:
55 print(f'{filename} has problem, the following urls shows the points with distance far from {threshold}m:')
56 print()
57 flag = True
58 if add_prefix:
59 dir = os.path.dirname(filename)
60 if dir:
61 dir += '/'
62 os.rename(filename, f'{dir}invalid_{os.path.basename(filename)}')
63
64 geojson = '{{"type": "LineString", "coordinates": [[{}, {}], [{}, {}]]}}'.format(
65 geom1.GetX(), geom1.GetY(),
66 geom2.GetX(), geom2.GetY()
67 )
68 encoded = urllib.parse.quote(geojson)
69 print('http://geojson.io/#data=data:application/json,{}'.format(encoded))
70 print()
71 else:
72 break
73 trkpt = nextTrkpt
74
75def main(argv):
76 parser = argparse.ArgumentParser()
77 parser.add_argument('file', help="you can add multiple gpx files at the same time", nargs='+')
78 parser.add_argument("-i", help="add prefix to invalid files", action="store_true")
79 parser.add_argument("-d", help="distance of tolerance(m), 100 by default", dest="distance", default=100)
80 args = parser.parse_args()
81 for file in args.file:
82 check_valid(file, float(args.distance), args.i)
83
84if __name__ == '__main__':
85 main(sys.argv)
diff --git a/tools/gpx/gpx.merge_gpx.sh b/tools/gpx/gpx.merge_gpx.sh
new file mode 100755
index 0000000..4b024a7
--- /dev/null
+++ b/tools/gpx/gpx.merge_gpx.sh
@@ -0,0 +1,5 @@
1#!/bin/bash
2
3GPX_DIR=$(dirname $0)
4
5sed '/<trk/,/<\/trk>/ p' -nr | cat $GPX_DIR/header - $GPX_DIR/footer
diff --git a/tools/gpx/gpx.merge_trk.sh b/tools/gpx/gpx.merge_trk.sh
new file mode 100755
index 0000000..c3a72d4
--- /dev/null
+++ b/tools/gpx/gpx.merge_trk.sh
@@ -0,0 +1,4 @@
1#!/bin/bash
2
3sed '/<trk>/,/<\/name>/ d; /<\/trk>/ d; /<\/gpx>/ i \ \ <\/trk>' |\
4awk '/<trkseg>/ && !x {print " <trk>\n <name>combined_trk</name>"; x=1} 1'
diff --git a/tools/gpx/header b/tools/gpx/header
new file mode 100644
index 0000000..1912e8b
--- /dev/null
+++ b/tools/gpx/header
@@ -0,0 +1,10 @@
1<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
2<gpx xmlns="http://www.topografix.com/GPX/1/1" creator="MapSource 6.10.2" version="1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
3
4 <metadata>
5 <link href="http://www.garmin.com">
6 <text>Garmin International</text>
7 </link>
8 <time>2019-12-18T06:17:16Z</time>
9 <bounds maxlat="24.554773" maxlon="121.293261" minlat="24.534487" minlon="121.284309"/>
10 </metadata>
diff --git a/tools/load-settings.sh b/tools/load-settings.sh
new file mode 100755
index 0000000..30a29b0
--- /dev/null
+++ b/tools/load-settings.sh
@@ -0,0 +1,24 @@
1if [[ -z "$SETTING_DIR" ]]; then
2 SETTING_DIR=$HOME/settings
3fi
4
5# load custom aliases
6source $SETTING_DIR/alias
7
8# Add custom scripts into PATH
9PATH=$PATH:$SETTING_DIR/tools
10find $SETTING_DIR/tools -type d | sed 1d |\
11while read dir; do
12 PATH=$PATH:$dir
13done
14
15# sync with important git repos
16$SETTING_DIR/tools/sync.sh
17
18# load custom functions
19OSM_UTIL_DIR=$SETTING_DIR/tools/osm
20source $OSM_UTIL_DIR/osm
21
22# go
23PATH=$PATH:$HOME/go/bin
24
diff --git a/tools/match-road.sh b/tools/match-road.sh
new file mode 100755
index 0000000..d9beaae
--- /dev/null
+++ b/tools/match-road.sh
@@ -0,0 +1,148 @@
1#!/usr/bin/env bash
2#
3# Author: Pham
4#
5# This script accepts a single GPX file as parameter and
6# output the processed GPX body to STDOUT, using Mapbox Map Matching API v4.
7# read doc at: https://docs.mapbox.com/api/legacy/map-matching-v4/
8#
9# Example:
10#
11# match-road.sh raw.gpx > new.gpx
12#
13# Hint:
14#
15# Remember to put Mapbox Access Token at the top!
16
17#set -x
18set -e
19
20# put yout Mapbox token here
21ACCESS_TOKEN=$(cat ~/settings/tokens/mapbox)
22# number of coordinates for each Mapbox Map Matching API request, Maximum value is 100
23LIMIT=100
24# define the lowest confidence of accepted matched points
25THRESHOLD=0.0001
26
27if [[ -z $1 ]]; then echo "You need to give a gpx file!"; exit 1; fi
28ORIGIN_DATA=/tmp/$(basename $1).origin
29RESPONSES=/tmp/$(basename $1).responses && true > $RESPONSES
30MATCHED=/tmp/$(basename $1).matched
31
32# extract data from the given gpx file
33# only keep first point and remove the rest which in the same "second"
34# input: [gpx format]
35# output: [121.0179739,14.5515336] 1984-01-01T08:00:46
36get_data() {
37 sed -nr '/<trkpt /, /<\/trkpt>/ {H; /<\/trkpt>/ {x; s/\n/ /g; p; s/.*//; x}}' $1 |
38 sed -nr 'h; s/.*lon="([^"]+).*/\1/; H; g
39 s/.*lat="([^"]+).*/\1/; H; g
40 # If trkpt has no time, leave it blank
41 /time/ {
42 s/.*<time>([^.]+).*<\/time>.*/\1/
43 H; g
44 }
45 s/^[^\n]+\n//; s/\n/ /g; p' |
46 sed -r 's/^([^ ]+) ([^ ]+)/[\1,\2]/' |
47 awk '!_[$2]++'
48}
49
50# Output GeoJSON object for Map Matching API
51# input: [121.0179739,14.5515336] 1984-01-01T08:00:46
52# output: {type: "Feature", properties: {coordTimes: [...]}, geometry: {type: "LineString", coordinates: [...]}}
53make_geojson() {
54 # change input to format like: [[lon, lat], time]
55 awk '{printf("[%s,\"%s\"]\n", $1, $2)}' |
56 jq '[inputs] | {type: "Feature", geometry: {type: "LineString", coordinates: map(.[0])}, properties: {coordTimes: (map(.[1]))}}'
57}
58
59# Read GeoJSON body from STDIN, and return result from Mapbox Map Matching API
60query_matched_points() {
61 curl -X POST -s --data @- \
62 --header "Content-Type:application/json" \
63 https://api.mapbox.com/matching/v4/mapbox.driving.json?access_token=$ACCESS_TOKEN
64}
65
66# Get valid data from Map Matching API response
67# output format is [coordinates] [index-of-original-data], like:
68# [121.0179739,14.5515336] 35
69# If the point is newly added, the index would be -1, like
70# [121.0189339,14.5525931] -1
71validate_matched_points() {
72 VALID_DATA=$(jq ".features[] | if(.properties.confidence < $THRESHOLD) then .geometry.coordinates=(.properties.indices|map(.+1)) else . end")
73
74 echo $VALID_DATA |
75 jq -cr '.properties | [.matchedPoints, (.indices | map(.+1))] | transpose[] | "\(.[0]) \(.[1])"' > $MATCHED
76
77 echo $VALID_DATA | jq -c '.geometry.coordinates[]' |
78 while read point; do
79 if [[ ${point:0:1} != '[' ]]; then
80 echo $(sed -n "$point p" $ORIGIN_DATA) | while read coor time; do echo $coor $(date -d $time +%s); done
81 sed -i 1d $MATCHED
82 elif head -1 $MATCHED | grep -F $point > /dev/null; then
83 index=$(head -1 $MATCHED | cut -d' ' -f2)
84 echo $point $(sed -n "$index p" $ORIGIN_DATA | cut -d' ' -f2 | date -f - +%s)
85 sed -i 1d $MATCHED
86 else
87 echo $point -1
88 fi
89 done
90}
91
92# Put existing timestamps to matched points, and interpolate new timestamps into new points
93complete_data() {
94 # interpolate timestamps to newly added points
95 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)}}}' |
96 while read coor unix_time; do
97 # Transform unix timestamp into human readable time format, like following:
98 # Transform [121.018088,14.5516] 18.50
99 # Into [121.018088,14.5516] 1970-01-01T08:00:18.50Z
100 echo $coor $(date -d @$unix_time +'%Y-%m-%dT%H:%M:%S.%2NZ')
101 done
102}
103
104# Make GPX format for output
105# Take input with format: [lon,lat] [time]
106make_gpx() {
107 sed -E 's/\[([^,]+),([^,]+)\] (.*)/ <trkpt lon="\1" lat="\2"><time>\3<\/time><\/trkpt>/' |
108 sed "1i \
109<gpx version=\"1.1\" creator=\"Garmin Connect\"\n\
110 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\
111 xmlns=\"http://www.topografix.com/GPX/1/1\"\n\
112 xmlns:gpxtpx=\"http://www.garmin.com/xmlschemas/TrackPointExtension/v1\"\n\
113 xmlns:gpxx=\"http://www.garmin.com/xmlschemas/GpxExtensions/v3\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">\n\
114 <trk>\n <trkseg>" |
115 sed "\$a \ \ \ \ <\/trkseg>\n <\/trk>\n<\/gpx>"
116}
117
118get_data $1 > $ORIGIN_DATA
119
120#RAW_REQUEST=$(basename $1 | tr '.' '_')_request.geojson
121#cat $ORIGIN_DATA | make_geojson | jq '.properties.stroke="#ff0000"' > $RAW_REQUEST
122
123# Consume raw data with serveral request
124while [ -s $ORIGIN_DATA ]; do
125 # Take original data by limited points for each time: [121.0179739,14.5515336] 1984-01-01T08:00:46
126 # 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 # Get valid point and index by confidence value: [121.0179739,14.5515336] 5
129 # complete_data
130 head -$LIMIT $ORIGIN_DATA |
131 make_geojson |
132 query_matched_points |
133 tee -a $RESPONSES |
134 validate_matched_points |
135 complete_data
136
137 # Remove processed raw data
138 sed -i "1,$LIMIT d" $ORIGIN_DATA
139done | make_gpx
140#make_geojson > test.geojson
141
142#RAW_RESPONSE=$(basename $1 | tr '.' '_')_response.geojson
143#MATCHED_POINTS=$(basename $1 | tr '.' '_')_matched.geojson
144#jq . $RESPONSES | jq -s '.[0].features=[.[]|.features[]] | .[0] | del(.code) | .features=(.features|map(.properties.stroke="#00ff00"))' > $RAW_RESPONSE
145#jq ".features=(.features|map(select(.properties.confidence>=$THRESHOLD).geometry.coordinates=.properties.matchedPoints)|map(.properties.stroke=\"#0000ff\"))" $RAW_RESPONSE > $MATCHED_POINTS
146#
147#DEBUG=$(basename $1 | tr '.' '_')_total.geojson
148#cat $RAW_REQUEST $RAW_RESPONSE $MATCHED_POINTS | jq -s '{type: "FeatureCollection", features: ([.[0]] + .[1].features + .[2].features)}' > $DEBUG
diff --git a/tools/mvt_decode.py b/tools/mvt_decode.py
new file mode 100644
index 0000000..0f661dd
--- /dev/null
+++ b/tools/mvt_decode.py
@@ -0,0 +1,11 @@
1import mapbox_vector_tile
2import sys
3
4#Python3
5
6mvt = sys.argv[1]
7
8with open(mvt, 'rb') as f:
9 data = f.read()
10 decoded_data = mapbox_vector_tile.decode(data)
11 print(decoded_data)
diff --git a/tools/osm/josm_install.sh b/tools/osm/josm_install.sh
new file mode 100755
index 0000000..520875a
--- /dev/null
+++ b/tools/osm/josm_install.sh
@@ -0,0 +1,8 @@
1#!/bin/bash
2
3# scripts from https://josm.openstreetmap.de/wiki/Download#Webstart
4echo deb https://josm.openstreetmap.de/apt $(lsb_release -sc) universe | sudo tee /etc/apt/sources.list.d/josm.list > /dev/null &&\
5wget -q https://josm.openstreetmap.de/josm-apt.key -O- | sudo apt-key add - &&\
6sudo apt-get update &&\
7sudo apt-get remove josm josm-plugins &&\
8sudo apt-get install josm
diff --git a/tools/osm/osm b/tools/osm/osm
new file mode 100644
index 0000000..a595fb7
--- /dev/null
+++ b/tools/osm/osm
@@ -0,0 +1,17 @@
1#! /bin/sh
2
3#export OSM_SERVER=https://master.apis.dev.openstreetmap.org
4export OSM_SERVER=https://api.openstreetmap.org
5
6export OSM_API=$OSM_SERVER/api/0.6
7export OSM_USER_PASSWD=$(cat $SETTING_DIR/tokens/osm 2>/dev/null)
8
9FILENAME=$0
10
11utils.osm() {
12 vim $FILENAME && source $FILENAME
13}
14
15osm.api() {
16 curl -X GET $OSM_API/$1/$2
17}
diff --git a/tools/osm/osm.api.changeset.add b/tools/osm/osm.api.changeset.add
new file mode 100755
index 0000000..3e4878e
--- /dev/null
+++ b/tools/osm/osm.api.changeset.add
@@ -0,0 +1,10 @@
1#!/bin/sh
2
3element=$(cat)
4header=$(echo $element | grep -E "<(node|way|relation)\s")
5ele_type=$(echo $header | sed -r 's/.*<(node|way|relation).*$/\1/')
6id=$(echo $header | sed -r 's/.* id=\"([^"]+)\".*$/\1/')
7
8echo $element | \
9sed -r "s/^( *<(node|way|relation).*version[^ ]+ )(.*)$/\1changeset=\"$1\">/" | \
10curl -X PUT -u $OSM_USER_PASSWD -i -T - $OSM_API/$ele_type/$id
diff --git a/tools/osm/osm.api.changeset.close b/tools/osm/osm.api.changeset.close
new file mode 100755
index 0000000..3b016c3
--- /dev/null
+++ b/tools/osm/osm.api.changeset.close
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3curl -X PUT -u $OSM_USER_PASSWD -i $OSM_API/changeset/$1/close
diff --git a/tools/osm/osm.api.changeset.create b/tools/osm/osm.api.changeset.create
new file mode 100755
index 0000000..ed2601a
--- /dev/null
+++ b/tools/osm/osm.api.changeset.create
@@ -0,0 +1,21 @@
1#!/bin/sh
2
3echo -n "type comment: "
4read comment
5
6info="<osm>
7 <changeset>
8 <tag k='comment' v='$comment'/>
9 <tag k='created_by' v='bash script'/>
10 <tag k='bot' v='yes'/>
11 </changeset>
12 </osm>
13 "
14
15changeset_id=$(echo $info |\
16 curl -u $OSM_USER_PASSWD --upload-file - $OSM_API/changeset/create |\
17 tail -1)
18
19echo
20echo "changeset created, check $OSM_SERVER/changeset/$changeset_id"
21echo "$changeset_id is copied into clipboard"
diff --git a/tools/osm/osm.api.changeset.update b/tools/osm/osm.api.changeset.update
new file mode 100755
index 0000000..7b32741
--- /dev/null
+++ b/tools/osm/osm.api.changeset.update
@@ -0,0 +1,7 @@
1#!/bin/sh
2
3echo -n 'type comment: '
4read -r comment
5
6echo "<osm><changeset><tag k=\"comment\" v=\"$comment\"/></changeset></osm>" | \
7curl -X PUT -u $OSM_USER_PASSWD -i -T - $OSM_API/changeset/$1
diff --git a/tools/osm/osm.api.changeset.upload b/tools/osm/osm.api.changeset.upload
new file mode 100755
index 0000000..96bdff4
--- /dev/null
+++ b/tools/osm/osm.api.changeset.upload
@@ -0,0 +1,6 @@
1#!/bin/sh
2
3cat $2 |\
4sed -r "/<(node|way|relation)/ s/>/ changeset=\"$1\">/" |\
5tee /dev/tty |\
6curl -X POST -u $OSM_USER_PASSWD -i -T - $OSM_API/changeset/$1/upload
diff --git a/tools/osm/osm.api.fetch b/tools/osm/osm.api.fetch
new file mode 100755
index 0000000..8460c5f
--- /dev/null
+++ b/tools/osm/osm.api.fetch
@@ -0,0 +1,6 @@
1#! /bin/sh
2
3# get .osm format data
4curl -X GET $OSM_API/$1/$2 |\
5tee /tmp/osm &&\
6echo content of $1 $2 is copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.fetch.full b/tools/osm/osm.api.fetch.full
new file mode 100755
index 0000000..5ee78b8
--- /dev/null
+++ b/tools/osm/osm.api.fetch.full
@@ -0,0 +1,5 @@
1#! /bin/sh
2
3curl -X GET $OSM_API/$1/$2/full |\
4tee /tmp/osm &&\
5echo "\n" content of $1 $2 and its members are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.fetch.history b/tools/osm/osm.api.fetch.history
new file mode 100755
index 0000000..bc837bd
--- /dev/null
+++ b/tools/osm/osm.api.fetch.history
@@ -0,0 +1,6 @@
1#! /bin/sh
2
3curl -X GET $OSM_API/$1/$2/history |\
4tee /tmp/osm &&\
5echo &&\
6echo "\n" history of $1 $2 are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.member.relation b/tools/osm/osm.api.member.relation
new file mode 100755
index 0000000..5addef7
--- /dev/null
+++ b/tools/osm/osm.api.member.relation
@@ -0,0 +1,4 @@
1#! /bin/sh
2
3osm.api.referenced.relation $1 $2 |\
4osm.member.relation $1 $2 $3
diff --git a/tools/osm/osm.api.referenced.relation b/tools/osm/osm.api.referenced.relation
new file mode 100755
index 0000000..2ce0631
--- /dev/null
+++ b/tools/osm/osm.api.referenced.relation
@@ -0,0 +1,6 @@
1#! /bin/sh
2
3curl -X GET $OSM_API/$1/$2/relations |\
4tee /tmp/osm &&\
5echo &&\
6echo "\n" relations contain $1 $2 are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.referenced.way b/tools/osm/osm.api.referenced.way
new file mode 100755
index 0000000..1d84238
--- /dev/null
+++ b/tools/osm/osm.api.referenced.way
@@ -0,0 +1,5 @@
1#!/bin/bash
2
3curl -X GET $OSM_API/node/$1/ways |\
4tee /tmp/osm &&\
5echo ways contain node $1 are copied into /tmp/osm > /dev/tty
diff --git a/tools/osm/osm.api.upload.to b/tools/osm/osm.api.upload.to
new file mode 100755
index 0000000..3979220
--- /dev/null
+++ b/tools/osm/osm.api.upload.to
@@ -0,0 +1,12 @@
1#! /bin/sh
2
3# allows multiple elements in osm body
4tee /tmp/osm |\
5osm.list.ids |\
6sed 's#.*#osm.extract \0 < /tmp/osm#g' |\
7sed "s/.*/\0 \| osm.api.changeset.add $1/g" |\
8while read -r command
9do
10 echo $command
11 source<(echo "($command &)")
12done
diff --git a/tools/osm/osm.file.get b/tools/osm/osm.file.get
new file mode 100755
index 0000000..e2b67b4
--- /dev/null
+++ b/tools/osm/osm.file.get
@@ -0,0 +1,4 @@
1#! /bin/sh
2
3file=$1; shift
4osmium getid $file $@ --output-format=osm
diff --git a/tools/osm/osm.file.get.full b/tools/osm/osm.file.get.full
new file mode 100755
index 0000000..50ee2f1
--- /dev/null
+++ b/tools/osm/osm.file.get.full
@@ -0,0 +1,4 @@
1#! /bin/sh
2
3file=$1; shift
4osmium getid $file $@ --output-format=osm --add-referenced
diff --git a/tools/osm/osm.file.query b/tools/osm/osm.file.query
new file mode 100755
index 0000000..4a01b5b
--- /dev/null
+++ b/tools/osm/osm.file.query
@@ -0,0 +1,4 @@
1#! /bin/sh
2
3file=$1; shift
4osmium tags-filter $file $@ --output-format=osm --omit-referenced
diff --git a/tools/osm/osm.goto b/tools/osm/osm.goto
new file mode 100755
index 0000000..25bceaa
--- /dev/null
+++ b/tools/osm/osm.goto
@@ -0,0 +1,3 @@
1#!/bin/sh
2
3xdg-open https://www.openstreetmap.org/$1/$2
diff --git a/tools/osm/osm.help b/tools/osm/osm.help
new file mode 100755
index 0000000..aa3b36b
--- /dev/null
+++ b/tools/osm/osm.help
@@ -0,0 +1,34 @@
1#! /bin/sh
2
3 echo '
4COMMANDS:
5 osm.help
6 util.osm.edit
7
8 osm.api.changeset.create create a new changeset and return its ID
9 osm.api.changeset.update [changeset ID] update changeset with new comment
10 osm.api.changeset.upload [changeset ID] [osc file] upload osc file to the given changeset
11 osm.api.changeset.add [changeset ID] STDIN=osm element, add it into changeset
12 osm.api.changeset.close [changeset ID] close the given changeset
13 osm.api.fetch [element type] [element ID]
14 osm.api.fetch.full like .fetch, but return with all referenced elements
15 osm.api.fetch.history [element type] [element ID]
16 osm.api.member.relation [element type] [element ID] [member type] get first relations reference it as member type
17 osm.api.referenced.relation [element type] [element ID] get all relations reference this element
18 osm.api.referenced.way [element type] [element ID] get all ways reference this element
19 osm.api.upload.to
20
21 osm.file.cat
22 osm.file.get
23 osm.file.get.full
24 osm.file.query
25 osm.list.ids
26 osm.list.tag
27 osm.list.tags
28
29 osm.get.id
30 osm.query
31 osm.member.relation
32 osm.pbf.update
33 osm.osm.update
34 '
diff --git a/tools/osm/osm.list.ids b/tools/osm/osm.list.ids
new file mode 100755
index 0000000..8e5d870
--- /dev/null
+++ b/tools/osm/osm.list.ids
@@ -0,0 +1,3 @@
1#! /bin/sh
2
3sed -nr 's/.*<(node|way|relation) id=\"([^"]+)\".*/\1 \2/p'
diff --git a/tools/osm/osm.list.tag b/tools/osm/osm.list.tag
new file mode 100755
index 0000000..76649a0
--- /dev/null
+++ b/tools/osm/osm.list.tag
@@ -0,0 +1,10 @@
1#!/bin/bash
2
3ele_pattern="(node|way|relation)"
4sed -nr "/<$ele_pattern/,/<\/$ele_pattern/ {
5 /<tag k=\"$1\"/ {
6 s/.*v=\"([^\"]+)\".*/\1/
7 h
8 }
9 /<\/$ele_pattern/ {x;p;s/.*//;x}
10}"
diff --git a/tools/osm/osm.list.tags b/tools/osm/osm.list.tags
new file mode 100755
index 0000000..767d32a
--- /dev/null
+++ b/tools/osm/osm.list.tags
@@ -0,0 +1,15 @@
1#!/bin/bash
2
3content=$(cat)
4echo $content | osm.list.ids | tr ' ' ',' > /tmp/osm
5
6for tag in $@
7do
8 echo $content |\
9 osm.list.tag $tag |\
10 paste -d',' /tmp/osm - > /tmp/osm.new &&\
11 mv /tmp/osm.new /tmp/osm
12done
13
14cat /tmp/osm
15echo "\ntag list is also copied into /tmp/osm" > /dev/tty
diff --git a/tools/osm/osm.member.relation b/tools/osm/osm.member.relation
new file mode 100755
index 0000000..f8d4598
--- /dev/null
+++ b/tools/osm/osm.member.relation
@@ -0,0 +1,8 @@
1#! /bin/sh
2
3sed -nr "/<relation/,/<\/relation/ {
4 /<relation/ {s/.* id=\"([^\"]+)\".*/\1/;h}
5 /<member type=\"$1\" ref=\"$2\" role=\"$3\"/ {g;p;q}
6}
7$ {s/.*//;P}
8" | head -1
diff --git a/tools/osm/osm.osc.by_member b/tools/osm/osm.osc.by_member
new file mode 100755
index 0000000..5f9d9be
--- /dev/null
+++ b/tools/osm/osm.osc.by_member
@@ -0,0 +1,31 @@
1#!/bin/bash
2
3while read -r line
4do
5
6 TYPE=$(echo $line | cut -d ' ' -f1) # field1 is type
7 ID=$(echo $line | cut -d ' ' -f2) # field2 is ID
8
9 NEW_MEMBERS=$(echo $line |\
10 cut -d' ' -f3- |\
11 sed -r 's/([0-9]+)/<member type=\"relation\" ref=\"\1\" role=\"subarea\"\/>/g')
12
13 echo $NEW_MEMBERS
14
15 # print matched element with new tags to .osc file
16 cat $1 |\
17 sed -nr "/<$TYPE id=\"$ID\"/,/<\/$TYPE/ {
18 /<$TYPE id=\"$ID\"/ {
19 s/(version=\"[0-9]+\")(.*)/\1>/
20 a \ \ \ \ $NEW_MEMBERS
21 }
22 p
23 /<\/$TYPE/ q
24 }" >> $1.osc
25done
26
27# Add .osc structure for output
28sed -ir '1 i <osmChange version="0.6" generator="bash script">
29 1 i <modify>
30 $ a </modify>
31 $ a </osmChange>' $1.osc
diff --git a/tools/osm/osm.osc.by_tag b/tools/osm/osm.osc.by_tag
new file mode 100755
index 0000000..cc92c1d
--- /dev/null
+++ b/tools/osm/osm.osc.by_tag
@@ -0,0 +1,45 @@
1#!/bin/bash
2
3# create new tags from input line, for example:
4# field1 field2 field3 field4 field5 field6 field7 field8...
5# [element type] [element ID] key1_added "value1" key2_added "value2" key3_removed key4_removed...
6
7# key should not quoted, value must be quoted
8# And keys which need to be removed must be placed at the end
9while read -r line
10do
11 TYPE=$(echo $line | cut -d ' ' -f1) # field1 is type
12 ID=$(echo $line | cut -d ' ' -f2) # field2 is ID
13
14 # transform key-value pair into tag format:
15 # <tag k="[key]" v="[value]"/>
16 # keys without values are omitted
17 NEW_TAGS=$(echo $line |\
18 cut -d' ' -f3- |\
19 sed -r 's/([^ "]+) (\"[^"]+\")/<tag k=\"\1\" v=\2\/>/g; s/>[^"]*$/>/')
20
21 # get regex pattern need to removed from original osm element:
22 # key1|key2|key3|key4
23 TAG_PATTERN=$(echo $line |\
24 cut -d' ' -f3- | xargs -n2 echo |\
25 cut -d' ' -f1 | paste -s -d'|')
26
27 echo $NEW_TAGS > /dev/tty
28
29 # print matched element with new tags to .osc file
30 cat $1 |\
31 sed -nr "/<$TYPE id=\"$ID\"/,/<\/$TYPE/ {
32 /<$TYPE id=\"$ID\"/ {
33 s/(version=\"[0-9]+\")(.*)/\1>/
34 a \ \ \ \ $NEW_TAGS
35 }
36 /<tag k=\"($TAG_PATTERN)\"/ !p
37 /<\/$TYPE/ q
38 }" >> $1.osc
39done
40
41# Add .osc structure for output
42sed -ir '1 i <osmChange version="0.6" generator="bash script">
43 1 i <modify>
44 $ a </modify>
45 $ a </osmChange>' $1.osc
diff --git a/tools/osm/osm.osm.remove b/tools/osm/osm.osm.remove
new file mode 100755
index 0000000..83d6ea8
--- /dev/null
+++ b/tools/osm/osm.osm.remove
@@ -0,0 +1,9 @@
1#!/bin/bash
2
3while read -r line
4do
5 # put element type and element ID into array
6 array=( $(echo $line) )
7 cat $1 |\
8 sed -i "/<$array[1] id=\"$array[2]\"/,/<\/$array[1]>/ d"
9done
diff --git a/tools/osm/osm.pbf.update b/tools/osm/osm.pbf.update
new file mode 100755
index 0000000..cd115a7
--- /dev/null
+++ b/tools/osm/osm.pbf.update
@@ -0,0 +1,39 @@
1#!/bin/bash
2
3GEOFABRICK_SERVER=http://download.geofabrik.de/asia/taiwan-updates
4PBF_FILE=$1
5
6# get latest sequence number
7echo Fetching the latest sequence number
8LATEST_SEQ=$(curl --silent http://download.geofabrik.de/asia/taiwan-updates/state.txt |\
9 tail -1 | cut -d'=' -f2)
10echo Latest sequence number is $LATEST_SEQ
11
12# get current sequence number
13SEQ=$(osmium fileinfo $PBF_FILE |\
14 grep osmosis_replication_sequence_number |\
15 cut -d'=' -f2)
16echo File sequence number is $SEQ
17
18# while server has osc file with given sequence number,
19# get it and do file update
20while
21 (( SEQ++ ))
22 [ $SEQ -le $LATEST_SEQ ]
23do
24 mkdir -p changes
25 SEQ_PATH=$(echo $SEQ | sed -r 's/(.{1})(.{3})/00\1\/\2/')
26 CHANGE_URL=$GEOFABRICK_SERVER/000/$SEQ_PATH.osc.gz
27 echo $CHANGE_URL
28 curl -o changes/$SEQ.osc.gz $CHANGE_URL && \
29 osmium apply-changes $PBF_FILE changes/$SEQ.osc.gz \
30 --output-header=osmosis_replication_sequence_number=$SEQ \
31 --overwrite \
32 --output $SEQ.osm.pbf
33
34 mv $PBF_FILE $((SEQ-1)).osm.pbf
35 mv $SEQ.osm.pbf $PBF_FILE
36done
37
38echo
39echo File sequence number is $((SEQ-1)), already the latest one on Geofrbrik
diff --git a/tools/osm/osm.query b/tools/osm/osm.query
new file mode 100755
index 0000000..8d0b9f7
--- /dev/null
+++ b/tools/osm/osm.query
@@ -0,0 +1,3 @@
1#!/bin/bash
2
3osmium tags-filter - $@ --input-format=osm --output-format=osm --omit-referenced
diff --git a/tools/osm/sequence_number.sh b/tools/osm/sequence_number.sh
new file mode 100755
index 0000000..eb365d0
--- /dev/null
+++ b/tools/osm/sequence_number.sh
@@ -0,0 +1,22 @@
1#!/bin/bash
2
3# $1 as --hour or --minute, $2 as timestamp
4# return the latest sequence number
5
6case $1 in
7 # hour difference with Tue Jun 4 03:00:00 UTC 2019
8 # sequence number=58940
9 --hour)
10 echo $[($2 - 1559617200)/3600 + 58940]
11 ;;
12
13 # minute difference with latest planet state file
14 --minute)
15 benchmark=benchmark
16 curl https://planet.openstreetmap.org/replication/minute/state > $benchmark
17 timeString=$(tail -1 $benchmark | tr -d 'timestamp=\\')
18 timestamp=$(date -d "$timeString" +%s)
19 seq=$(sed -n 2p $benchmark | tr -d "sequenceNumber=")
20 rm $benchmark
21 echo $[$seq - ($timestamp - $2)/60 - 1 ]
22esac
diff --git a/tools/refresh-todo.sh b/tools/refresh-todo.sh
new file mode 100755
index 0000000..7931536
--- /dev/null
+++ b/tools/refresh-todo.sh
@@ -0,0 +1,5 @@
1#!/bin/bash
2
3# $1 as file, $2 as topic (Daily, Weekly, Monthly)
4# change markdown check-list to empty
5sed -i "/^## $2/,/^$/ s/\[.\]/\[ \]/" $1
diff --git a/tools/sync.sh b/tools/sync.sh
new file mode 100755
index 0000000..1c33138
--- /dev/null
+++ b/tools/sync.sh
@@ -0,0 +1,6 @@
1#!/bin/bash
2
3cd $SETTING_DIR && git pull --quiet || echo in `pwd` > /dev/tty &
4cd ~/vimwiki && git pull --quiet || echo in `pwd` > /dev/tty &
5check_upstream ~/git/tig || echo in `pwd` > /dev/tty &
6check_upstream ~/.vim_runtime || echo in `pwd` > /dev/tty &
diff --git a/tools/upload-github-release-asset.sh b/tools/upload-github-release-asset.sh
new file mode 100755
index 0000000..0325530
--- /dev/null
+++ b/tools/upload-github-release-asset.sh
@@ -0,0 +1,84 @@
1#!/usr/bin/env bash
2#
3# Author: Stefan Buck
4# License: MIT
5# https://gist.github.com/stefanbuck/ce788fee19ab6eb0b4447a85fc99f447
6#
7#
8# This script accepts the following parameters:
9#
10# * owner
11# * repo
12# * tag
13# * filename
14# * github_api_token
15# * overwrite (optional, could be ture, false, delete, default to be false)
16#
17# Script to upload a release asset using the GitHub API v3.
18#
19# Example:
20#
21# upload-github-release-asset.sh github_api_token=TOKEN owner=stefanbuck repo=playground tag=v0.1.0 filename=./build.zip overwrite=true
22#
23
24# Check dependencies.
25set -e
26xargs=$(which gxargs || which xargs)
27
28# Validate settings.
29[ "$TRACE" ] && set -x
30
31CONFIG=$@
32
33for line in $CONFIG; do
34 eval "$line"
35done
36
37# Define variables.
38GH_API="https://api.github.com"
39GH_REPO="$GH_API/repos/$owner/$repo"
40GH_TAGS="$GH_REPO/releases/tags/$tag"
41AUTH="Authorization: token $github_api_token"
42WGET_ARGS="--content-disposition --auth-no-challenge --no-cookie"
43CURL_ARGS="-LJO#"
44
45if [[ "$tag" == 'LATEST' ]]; then
46 GH_TAGS="$GH_REPO/releases/latest"
47fi
48
49# Validate token.
50curl -o /dev/null -sH "$AUTH" $GH_REPO || { echo "Error: Invalid repo, token or network issue!"; exit 1; }
51
52# Read asset tags.
53response=$(curl -sH "$AUTH" $GH_TAGS)
54
55# Get ID of the release.
56eval $(echo "$response" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=' | sed 's/id/release_id/')
57[ "$release_id" ] || { echo "Error: Failed to get release id for tag: $tag"; echo "$response" | awk 'length($0)<100' >&2; exit 1; }
58
59# Get ID of the asset based on given filename.
60# If exists, delete it.
61eval $(echo "$response" | grep -C2 "\"name\":.\+$(basename $filename)" | grep -m 1 "id.:" | grep -w id | tr : = | tr -cd '[[:alnum:]]=' | sed 's/id/asset_id/')
62if [ "$asset_id" = "" ]; then
63 echo "No need to overwrite asset"
64else
65 if [[ "$overwrite" == "true" ]] || [[ "$overwrite" == "delete" ]]; then
66 echo "Deleting asset($asset_id)... "
67 curl -X "DELETE" -H "Authorization: token $github_api_token" "https://api.github.com/repos/$owner/$repo/releases/assets/$asset_id"
68 if [[ "$overwrite" == "delete" ]]; then
69 exit 0
70 fi
71 else
72 echo "File already exists on tag $tag"
73 echo "If you want to overwrite it, set overwrite=true"
74 exit 1
75 fi
76fi
77
78# Upload asset
79echo "Uploading asset... "
80
81# Construct url
82GH_ASSET="https://uploads.github.com/repos/$owner/$repo/releases/$release_id/assets?name=$(basename $filename)"
83
84curl --data-binary @"$filename" -H "Authorization: token $github_api_token" -H "Content-Type: application/octet-stream" $GH_ASSET
diff --git a/tools/yaoren.sh b/tools/yaoren.sh
new file mode 100755
index 0000000..58d95df
--- /dev/null
+++ b/tools/yaoren.sh
@@ -0,0 +1,16 @@
1#!/bin/bash
2
3curl http://blog.sina.com.cn/u/1281912467 |\
4sed -nr "/第二列start/{
5
6}"
7# <div class="SG_connBody">
8# <div class="bloglist">
9# <div class="blog_title_h">
10# <span class="img1"></span>
11# <div id="t_10001_4c686e930102z2ft" class="blog_title">
12# <a href="http://blog.sina.com.cn/s/blog_4c686e930102z2ft.html" target="_blank">咬人画的-秋之菜饼</a>
13
14#
15
16sed -nr "s/.*real_src =\"(.*\/\/[^/]+\/)[^/]+(\/.*)&amp.*/\1orignal\2/p" tmp > jojo