1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
#! /bin/sh
FILENAME=$0
osm.help() {
echo '
COMMANDS:
osm.help
util.osm.edit
osm.api.changeset.create create a new changeset and return its ID
osm.api.changeset.update [changeset ID], update changeset with new comment
osm.api.changeset.add [changeset ID], STDIN=osm element, add it into changeset
osm.api.changeset.close [changeset ID], close the given changeset
osm.api.fetch [element type] [element ID]
osm.api.fetch.full like .fetch, but return with all referenced elements
osm.api.fetch.history [element type] [element ID]
osm.api.member.relation [element type] [element ID] [member type] get first relations reference it as member type
osm.api.referenced.relation
osm.api.referenced.way
osm.api.upload.to
osm.file.cat
osm.file.get
osm.file.get.full
osm.file.query
osm.list.ids
osm.list.tag
osm.list.tags
osm.get.id
osm.query
osm.member.relation
osm.pbf.update
osm.osm.update
'
}
util.osm.edit() {
vim $FILENAME && source $FILENAME
}
osm.goto() {
xdg-open https://www.openstreetmap.org/$1/$2
}
#SERVER=https://master.apis.dev.openstreetmap.org
SERVER=https://api.openstreetmap.org
OSM_API=$SERVER/api/0.6
OSM_USER_PASSWD=$(cat $SETTING_DIR/tokens/osm)
# get .osm format data
osm.api.fetch() {
curl -X GET $OSM_API/$1/$2 |\
tee /tmp/osm &&\
echo content of $1 $2 is copied into /tmp/osm > /dev/tty
}
osm.api.fetch.full() {
curl -X GET $OSM_API/$1/$2/full |\
tee /tmp/osm &&\
echo "\n" content of $1 $2 and its members are copied into /tmp/osm > /dev/tty
}
osm.api.fetch.history() {
curl -X GET $OSM_API/$1/$2/history |\
tee /tmp/osm &&\
echo &&\
echo "\n" history of $1 $2 are copied into /tmp/osm > /dev/tty
}
osm.api.referenced.relation() {
curl -X GET $OSM_API/$1/$2/relations |\
tee /tmp/osm &&\
echo &&\
echo "\n" relations contain $1 $2 are copied into /tmp/osm > /dev/tty
}
osm.member.relation() {
sed -nr "/<relation/,/<\/relation/ {
/<relation/ {s/.* id=\"([^\"]+)\".*/\1/;h}
/<member type=\"$1\" ref=\"$2\" role=\"$3\"/ {g;p;q}
}
$ {s/.*//;P}
" | head -1
}
osm.file.cat() {
osmium cat $1 --output-format=osm -t $2
}
osm.api.member.relation() {
osm.api.referenced.relation $1 $2 |\
osm.member.relation $1 $2 $3
}
osm.api.referenced.way() {
curl -X GET $OSM_API/node/$1/ways |\
tee /tmp/osm &&\
echo ways contain node $1 are copied into /tmp/osm > /dev/tty
}
osm.list.tag() {
ele_pattern="(node|way|relation)"
sed -nr "/<$ele_pattern/,/<\/$ele_pattern/ {
/<tag k=\"$1\"/ {
s/.*v=\"([^\"]+)\".*/\1/
h
}
/<\/$ele_pattern/ {x;p;s/.*//;x}
}"
}
osm.list.tags() {
content=$(cat)
echo $content | osm.list.ids | tr ' ' ',' > /tmp/osm
for tag in $@
do
echo $content |\
osm.list.tag $tag |\
paste -d',' /tmp/osm - > /tmp/osm.new &&\
mv /tmp/osm.new /tmp/osm
done
cat /tmp/osm
echo "\ntag list is also copied into /tmp/osm" > /dev/tty
}
# extract an element from .osm format STDIN
# $1 as [node|way|relation], $2 as id
osm.get.id() {
echo "<osm version=\"0.6\">"
sed -nr "/^ *<$1 id=\"$2\".*/,/^ *<\/$1>/p"
echo "</osm>"
}
# get ids from .osm format STDIN
osm.list.ids() {
sed -nr 's/.*<(node|way|relation) id=\"([^"]+)\".*/\1 \2/p'
}
# upload .osm format STDIN to a given changeset
# allows multiple elements in osm body
osm.api.upload.to() {
tee /tmp/osm |\
osm.list.ids |\
sed 's#.*#osm.extract \0 < /tmp/osm#g' |\
sed "s/.*/\0 \| osm.api.changeset.add $1/g" |\
while read -r command
do
echo $command
source<(echo "($command &)")
done
}
# query .osm format STDIN
osm.query() {
osmium tags-filter - $@ --input-format=osm --output-format=osm --omit-referenced
}
# query osm-related file with .osm format output
osm.file.query() {
file=$1; shift
osmium tags-filter $file $@ --output-format=osm --omit-referenced
}
# extract an element from osm file
osm.file.get() {
file=$1; shift
osmium getid $file $@ --output-format=osm
}
osm.file.get.full() {
file=$1; shift
osmium getid $file $@ --output-format=osm --add-referenced
}
# $1 as osm file
osm.osm.update() {
while read -r line
do
array=( $(echo $line) )
cat $1 |\
sed -nr "/<$array[1] id=$array[2]/,/<\/$array[1]/ {
/<$array[1] id=$array[2]/ a \ \ \ \ <tag k=\"$array[3]\" v=$array[4]\/>
/<tag k=$array[3]/ !p
/<\/$array[1]/ q
}" >> updated.$1
done
sed -ir '1 i <osm version="0.6" generator="bash script">
$ a </osm>' updated.$1
osmium derive-changes $1 updated.$1 --output=$1.osc --overwrite &&\
rm updated.$1
}
# create a new changeset
osm.api.changeset.create() {
echo -n "type comment: "
read comment
info="<osm>
<changeset>
<tag k='comment' v='$comment'/>
<tag k='bot' v='yes'/>
</changeset>
</osm>
"
echo $info |\
curl -u $OSM_USER_PASSWD --upload-file - $OSM_API/changeset/create |\
tee /dev/tty |\
tail -1 | read changeset_id
echo " copied into clipboard"
echo "changeset created, check $SERVER/changeset/$changeset_id"
echo $changeset_id | xsel -ib
}
# add a new element into changeset
osm.api.changeset.add() {
element=$(cat)
header=$(echo $element | grep -E "<(node|way|relation)\s")
ele_type=$(echo $header | sed -r 's/.*<(node|way|relation).*$/\1/')
id=$(echo $header | sed -r 's/.* id=\"([^"]+)\".*$/\1/')
echo $element | \
sed -r "s/^( *<(node|way|relation).*version[^ ]+ )(.*)$/\1changeset=\"$1\">/" | \
curl -X PUT -u $OSM_USER_PASSWD -i -T - $OSM_API/$ele_type/$id
}
osm.api.changeset.upload() {
cat $2 |\
sed -r "/<(node|way|relation)/ s/>/ changeset=\"$1\">/" |\
curl -X POST -u $OSM_USER_PASSWD -i -T - $OSM_API/changeset/$1/upload
}
# update changeset with a new comment
osm.api.changeset.update() {
echo -n 'type comment: '
read -r comment
echo "<osm><changeset><tag k=\"comment\" v=\"$comment\"/></changeset></osm>" | \
curl -X PUT -u $OSM_USER_PASSWD -i -T - $OSM_API/changeset/$1
}
# close a changeset
osm.api.changeset.close() {
curl -X PUT -u $OSM_USER_PASSWD -i $OSM_API/changeset/$1/close
}
# update an .osm.pbf file
osm.pbf.update() {
PBF_FILE=$1
SERVER=http://download.geofabrik.de/asia/taiwan-updates
# get next sequence number and store it into NEW_SEQ
osmium fileinfo $PBF_FILE | \
grep osmosis_replication_sequence_number | \
cut -d'=' -f2 | \
sed 's/$/+1/' | bc | \
read NEW_SEQ
# while server has osc file with given sequence number,
# get it and do file update
while
SEQ_PATH=$(echo $NEW_SEQ | sed -r 's/(.{1})(.{3})/00\1\/\2/')
STATE_URL=$SERVER/000/$SEQ_PATH.state.txt
[ $(curl.code $STATE_URL) != "404" ]
do
mkdir -p changes
CHANGE_URL=$SERVER/000/$SEQ_PATH.osc.gz
echo $CHANGE_URL
curl -o changes/$NEW_SEQ.osc.gz $CHANGE_URL && \
osmium apply-changes $PBF_FILE changes/$NEW_SEQ.osc.gz \
--output-header=osmosis_replication_sequence_number=$NEW_SEQ \
--overwrite \
--output $NEW_SEQ.osm.pbf
PBF_FILE=$NEW_SEQ.osm.pbf
((NEW_SEQ++))
done
}
osm.osm.remove() {
while read -r line
do
# put element type and element ID into array
array=( $(echo $line) )
cat $1 |\
sed -i "/<$array[1] id=\"$array[2]\"/,/<\/$array[1]>/ d"
done
}
|