OSM数据导入数据库
osm2pgsql
osm2pgsql 是一个命令行工具,主要用于将 OpenStreetMap (OSM) 数据导入到 PostgreSQL/PostGIS 数据库中。
以上 osm2pgsql 的使用范例:
osm2pgsql.exe -c -d [数据库名] -U [用户名] -H [主机名] -P [端口] -S [样式文件路径] [数据文件路径]
示例:执行以下命令后,会提示输入数据库密码:
osm2pgsql.exe -c -d osm-test -U postgres -H 127.0.0.1 -P 5433 -S default.style --slim -W shaanxi-260329.osm.pbf
参数详解:
-c (create):创建一个新的表结构。如果是更新已有数据,通常使用 -a (append)。
-d:指定目标数据库的名称。
-U:数据库用户名。
-H:数据库主机地址(本地通常为 localhost)。
-P:端口号(默认通常是 5432)。
-S:指定样式文件 (style file);default.style 是一个默认的样式文件,它决定了哪些 OSM 标签会被导入到数据库列中;
-W:运行时提示输入数据库密码。
--slim:对于较大的数据集,建议使用该模式以节省内存并允许后续更新
注意:
osm2pgsql 中 -S 指定样式文件 (style file),其实是一个字段映射表,它决定了以下两件事:
1> 数据过滤:哪些标签(Tags)会被导入数据库,哪些会被直接忽略(为了节省空间和提升性能)。
2> Schema 结构:哪些标签应该被转换成数据库中独立的列(Columns),哪些则被塞进特殊的 hstore 或 jsonb 列里。
虽然它被习惯性地称为“样式文件”(style file),但它和 MapLibre 或 Mapbox 那种定义颜色、线宽的视觉样式完全不是一回事。
全量导入所有 OSM 地图数据
osm2pgsql -d osm -U postgres -H localhost -P 5432 --create --slim --output=flex --style=./flex.lua --cache=8000 --number-processes=8 --flat-nodes=./nodes.bin --hstore --extra-attributes --log-progress=true shaanxi.osm.pbf
-c (create):创建一个新的表结构用于保存导入数据;如果是更新已有数据,要使用 -a (append);
-d:指定目标数据库的名称;
-U:数据库用户名;
-H:数据库主机地址(本地通常为 localhost);
-P:端口号(默认通常是 5432);
--output:指定输出模式;flex 是当前推荐模式,通过 Lua 脚本自定义数据库结构(已逐步取代旧的 pgsql 模式);
--style:指定 Lua 样式文件(仅在 flex 模式下使用);用于定义表结构、字段以及数据如何从 OSM 映射到数据库;
--slim:启用 slim 模式;将中间数据写入数据库而非内存,适用于大数据量,并支持后续增量更新;
--cache:设置内存缓存大小(单位 MB);用于缓存节点数据,数值越大通常导入越快(受限于机器内存);
--number-processes:并行处理线程数;用于提升导入速度,通常设置为 CPU 核心数;
--flat-nodes:将 node 数据存储到指定文件中(而非数据库);显著降低数据库压力,适用于大规模数据导入(如省级或 planet 数据);
--hstore:将所有未结构化的 OSM tags 存入 hstore 字段中;方便后续扩展和查询,但会增加存储体积;
--extra-attributes:导入额外属性(如 version、timestamp、changeset、uid 等);用于审计或数据分析场景;
--log-progress:在导入过程中输出进度日志(如百分比、速度等);便于监控导入状态;
shaanxi.osm.pbf:待导入的 OSM 数据文件(PBF 格式,压缩的二进制格式,适合大规模数据);
全量导入的 Lua 格式的样式文件内容:
local tables = {}
tables.nodes = osm2pgsql.define_node_table('nodes', {
{ column = 'id', type = 'bigint' },
{ column = 'tags', type = 'jsonb' },
{ column = 'geom', type = 'point', projection = 4326 }
})
tables.ways = osm2pgsql.define_way_table('ways', {
{ column = 'id', type = 'bigint' },
{ column = 'tags', type = 'jsonb' },
{ column = 'geom', type = 'linestring', projection = 4326 }
})
tables.relations = osm2pgsql.define_relation_table('relations', {
{ column = 'id', type = 'bigint' },
{ column = 'tags', type = 'jsonb' }
})
function osm2pgsql.process_node(object)
tables.nodes:insert({
id = object.id,
tags = object.tags,
geom = object:as_point()
})
end
function osm2pgsql.process_way(object)
tables.ways:insert({
id = object.id,
tags = object.tags,
geom = object:as_linestring()
})
end
function osm2pgsql.process_relation(object)
tables.relations:insert({
id = object.id,
tags = object.tags
})
end