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


举报

© 著作权归作者所有


0