4 个版本 (重大更新)
0.5.0 | 2022年3月26日 |
---|---|
0.3.0 | 2020年1月21日 |
0.2.0 | 2020年1月11日 |
0.1.0 | 2020年1月6日 |
#144 in 地理空间
40KB
630 行
osm-tag-csv-history
使用CSV工具查看谁在OpenStreetMap中绘制了什么。
给定一个OSM历史文件,它生成一个CSV文件,其中每一行都对应于OSM数据文件中历史记录的OSM对象的标签更改(添加、删除或修改)。
获取数据
Planet.OpenStreetMap.org 提供一个“完整历史”文件,每周更新一次,您可以下载最新的完整历史文件(⚠ 99+ GB! ⚠),尽管它相当大。
使用以下方法通过BitTorrent下载:
aria2c --seed-time 0 https://planet.openstreetmap.org/pbf/full-history/history-latest.osm.pbf.torrent
Geofabrik提供了一种 下载服务,其中包括许多地区和国家的完整历史文件。您必须使用OpenStreetMap账户登录。您还可以使用此工具处理常规的非历史OSM数据文件。
安装
如果您已安装Rust,可以使用以下命令安装:
cargo install osm-tag-csv-history
您可以从Github发布页面下载预先构建的二进制文件(例如,下载v0.3.0版本)。
用法
osm-tag-csv-history -i mydata.osm.pbf -o mydata.csv.gz
如果文件以 .gz
结尾,输出将自动使用gzip进行压缩。CSV文件的文件名为 .csv
,TSV(制表符分隔)为 .tsv
。
标签过滤
默认情况下,包含所有标签更改。使用 --tag
/-t
参数,仅包括对那些标签的更改输出
要生成仅包含对 highway
或 building
标签更改的CSV,请运行以下命令
osm-tag-csv-history -i mydata.osm.pbf -o mydata.csv -t highway -t building
对象类型过滤
默认情况下,包括文件中的所有OSM对象。使用 --object-types
/-T
仅输出某些对象,例如,仅输出道路和关系的 -T wr
。
用户(ID)类型过滤
使用 --uid
只输出该 OSM 用户对象的变化(可以指定多次)
变更集标签列
示例
许多程序可以使用 CSV 文件。也可以使用一些巧妙的 Unix 命令行程序来计算爱尔兰增加了哪些加油站(在 OSM 中 amenity=fuel
)
osm-tag-csv-history -i ./ireland-and-northern-ireland-internal.osh.pbf -o - --no-header | grep '^amenity,fuel,' | cut -d, -f9 | sort | uniq -c | sort -n | tail -n 20
在这里可以找到所有将建筑物从 building=yes
更新到其他类型的记录。
osm-tag-csv-history -i data.osh.pbf -o - --no-header | grep -P '^building,[^,]+,yes,' | cat -n
通过一些其他的命令行命令,我们可以得到一个列表,显示谁通过升级 building=yes
来使 OSM 更具有描述性。
osm-tag-csv-history -i data.osh.pbf -o - --no-header | grep -P '^building,[^,]+,yes,' | xsv select 8 | sort | uniq -c | sort -n | tail -n 20
与 osmium getid
一起使用
id 列(第 4 列)可以被 osmium-tool 使用来通过对象 id 过滤 OSM 文件。这就是如何获取 OSM 中所有宠物店的文件的方法。
osm-tag-csv-history -i country-latest.osm.pbf -o - --no-header | grep '^shop,pet,' | xsv select 4 | osmium getid -i - country-latest.osm.pbf -o pets.osm.pbf -r
(对于这个简单情况,osmium 的标签过滤可能更好)
非历史文件
此程序可以很好地在非历史文件上运行。 old_value
和 old_version
将为空。这可以将 OSM 数据转换为 CSV 格式以进行进一步处理。
在隐私保护文件中使用
Geofabrik 公共下载服务 提供不包含某些元数据的非历史文件,例如用户名、uid 或变更集_id。此工具可以在此类文件上运行,并为用户名提供一个空值,为 uid 和变更集_id 提供一个空值。
如果您有 OSM 账户,您可以从 内部服务 获取完整元数据。
输出文件格式
记录通过换行符(\n
)分隔。默认包含标题行,但可以使用 --no-header
(或使用 --header
强制包含)关闭。
如果任何字符串(例如标签值、用户名)包含换行符或其他类似字符,则将使用反斜杠转义(即换行符用两个字符表示,即 \
然后 n
)。
列
可以使用 --columns
/-C
更改列,例如(-C key,new_value,uid
)。
默认值是 key,new_value,old_value,id,new_version,old_version,datetime,username,uid,changeset_id
默认值,按顺序
key
标签键new_value
当前/新版本。如果当前版本没有此键(即它已从对象中删除),则为空字符串(""
)。old_value
旧值。如果上一版本没有此键,则为空字符串(""
)。id
对象类型和id。第一个字符是类型(n
/w
/r
),然后是id。n123
是id为123的节点。这种格式被 用于osmium-tool
通过对象id过滤OSM文件new_version
当前/新版本号old_version
之前的版本号。对象的第一版本为空字符串(""
)datetime
对象创建的日期时间(UTC格式下的RFC3339)username
更改该对象的用户的用户名(记住:在OSM中,用户可以更改其用户名,UID保持不变)uid
用户的用户idchangeset_id
进行此更改的更改集id
其他可用的列
object_type_short
/object_type_long
对象的OSM类型(n
/w
/r
,或node
/way
/relation
)raw_id
对象的OSM idepoch_datetime
对象创建的日期时间(Unix纪元时间)。这是在OSM PBF文件中存储数据的方式。这(而不是ISO字符串datetime
)使处理速度快了约15%(因为将纪元秒转换为ISO日期时间格式字符串不需要进行转换)tag_count_delta
:如果标签已更改,则为0
,如果标签已添加,则为+1
,如果标签被删除,则为-1
。这是一种更稳健的方法来确定标签是否已添加或删除。将其视为“具有此键的OSM对象数量变化”
示例
想象这个简单的文件
<?xml version='1.0' encoding='UTF-8'?>
<osm version="0.6" generator="osmium/1.7.1">
<node id="1" version="1" timestamp="2019-01-01T00:00:00Z" lat="0.0" lon="0.0" user="Alice" uid="12" changeset="2">
<tag k="place" v="city"/>
<tag k="name" v="Nice City"/>
</node>
<node id="1" version="2" timestamp="2019-03-01T12:30:00Z" lat="0.0" lon="0.0" user="Bob" uid="2" changeset="10">
<tag k="place" v="city"/>
<tag k="name" v="Nice City"/>
<tag k="population" v="1000000"/>
</node>
<node id="2" version="1" timestamp="2019-04-01T00:00:00Z" lat="0.0" lon="0.0" user="Alice" uid="12" changeset="20">
<tag k="amenity" v="restaurant"/>
<tag k="name" v="TastyEats"/>
</node>
<node id="2" version="2" timestamp="2019-04-01T02:00:00Z" lat="0.0" lon="0.0" user="Alice" uid="12" changeset="21">
<tag k="amenity" v="restaurant"/>
<tag k="name" v="TastyEats"/>
<tag k="cuisine" v="regional"/>
</node>
<node id="2" version="3" timestamp="2019-04-01T03:00:00Z" lat="0.0" lon="0.0" user="Alice" uid="12" changeset="22">
<tag k="amenity" v="restaurant"/>
<tag k="name" v="TastyEats"/>
<tag k="cuisine" v="burger"/>
</node>
<node id="2" version="4" timestamp="2019-04-01T03:00:00Z" lat="1.0" lon="0.0" user="Alice" uid="12" changeset="22">
<tag k="amenity" v="restaurant"/>
<tag k="name" v="TastyEats"/>
<tag k="cuisine" v="burger"/>
</node>
<node id="3" version="1" timestamp="2019-04-01T00:00:00Z" lat="0.0" lon="0.0" user="Alice" uid="12" changeset="50">
<tag k="amenity" v="bench"/>
</node>
<node id="3" version="2" timestamp="2019-06-01T00:00:00Z" lat="0.0" lon="0.0" user="Alice" uid="12" changeset="100" visible="false">
</node>
</osm>
注意:此程序不能读取XML文件,只能读取PBF。此文件是用 osmium cat example.osm.xml -o example.osm.pbf
转换为PBF的。
运行 osm-tag-csv-history
产生此CSV文件(此处按表格格式显示,使用 csvtomd
格式化)
key | new_value | old_value | id | new_version | old_version | datetime | username | uid | changeset_id |
---|---|---|---|---|---|---|---|---|---|
name | 美丽城市 | n1 | 1 | 2019-01-01T00:00:00Z | Alice | 12 | 2 | ||
place | city | n1 | 1 | 2019-01-01T00:00:00Z | Alice | 12 | 2 | ||
population | 1000000 | n1 | 2 | 1 | 2019-03-01T12:30:00Z | Bob | 2 | 10 | |
amenity | restaurant | n2 | 1 | 2019-04-01T00:00:00Z | Alice | 12 | 20 | ||
name | TastyEats | n2 | 1 | 2019-04-01T00:00:00Z | Alice | 12 | 20 | ||
cuisine | regional | n2 | 2 | 1 | 2019-04-01T02:00:00Z | Alice | 12 | 21 | |
cuisine | burger | regional | n2 | 3 | 2 | 2019-04-01T03:00:00Z | Alice | 12 | 22 |
amenity | bench | n3 | 1 | 2019-04-01T00:00:00Z | Alice | 12 | 50 | ||
amenity | bench | n3 | 2 | 1 | 2019-06-01T00:00:00Z | Alice | 12 | 100 |
需要注意的事项
- 每个版本可以有多个记录(行)
- 如果没有更改标签,则没有行。没有节点2 v4的行,因为更改的是位置,而不是标签。
old_version
的空值表示没有之前的或更早的版本。- 当对象(及其标签)被删除时,之前的价值在
old_value
中,而new_value
是空的,就像n3 v2一样。
可能有用的工具
以下其他工具可能有用
杂项
版权所有 2020,GNU Affero 通用公共许可证(AGPL)第3版或更高版本。见 LICENCE.txt。源代码在 Sourcehut 和 Github 上。
输出文件应被视为 OpenStreetMap 数据库的派生数据库,因此根据 ODbL 1.0 许可证,与 OpenStreetMap 版权 相同。
依赖项
~44MB
~701K SLoC