[PostgreSQL] osm2pgsql

์ด์ „ ํฌ์ŠคํŠธ
https://blog.naver.com/sssang97/223746834114

osm2pgsql์€ OSM์„ PostgreSQL์— ๋ถ€์–ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” converter๋‹ค.

์ด๊ฑฐ ์ž์ฒด๊ฐ€ ๋…๋ฆฝ์ ์ธ ์‹œ์Šคํ…œ์€ ์•„๋‹ˆ๊ณ , ์ด๊ฑธ๋กœ ๋ฐ์ดํ„ฐ๋งŒ Postgres์— ์ง‘์–ด๋„ฃ๊ณ  PostGIS๋ฅผ ํ†ตํ•ด ์ขŒํ‘œ ์ฟผ๋ฆฌ๋ฅผ ์˜๋Š” ์‹์œผ๋กœ ์‘์šฉํ•œ๋‹ค.

๊ทธ๋ž˜์„œ ์ด๊ฑธ ์“ฐ๋ ค๋ฉด PostGIS์— ๋Œ€ํ•œ ์‚ฌ์ „์ง€์‹์ด ์žˆ๊ณ , ์„ค์น˜๋„ ๋˜์–ด์žˆ์–ด์•ผ ํ•œ๋‹ค.
https://blog.naver.com/sssang97/223381620061




PBF ํŒŒ์ผ ์ค€๋น„

๊ฐ€์žฅ ๋จผ์ € ์ง€๋„ ํŒŒ์ผ์ด ํ•„์š”ํ•˜๋‹ค.

์ „์„ธ๊ณ„์˜ ์ „์ฒด ์ง€๋„๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด ๋‹ค์Œ ๋ฏธ๋Ÿฌ ์‚ฌ์ดํŠธ์—์„œ ์ ๋‹นํžˆ ๋ฐ›์œผ๋ฉด ๋œ๋‹ค.
79gb ์ •๋„ ๋˜๋‹ˆ๊นŒ ๋„‰๋„‰ํžˆ 100gb ์ •๋„๋Š” ์—ฌ์œ ๊ณต๊ฐ„์„ ๋‘ฌ์•ผ ํ•œ๋‹ค.
https://planet.openstreetmap.org/pbf/planet-latest.osm.pbf

ํŠน์ • ๊ตญ๊ฐ€๋“ค๋งŒ ์žˆ์–ด๋„ ๋œ๋‹ค๋ฉด ๋‹ค์Œ ์‚ฌ์ดํŠธ์—์„œ ๋ถ€๋ถ„์ง‘ํ•ฉ๋“ค๋งŒ ๋ฐ›์„ ์ˆ˜๋„ ์žˆ๋‹ค.
https://download.geofabrik.de/

์ผ๋‹จ ๋‚˜๋Š” ํ•œ๊ตญ์ธก ๋ฐ์ดํ„ฐ๋งŒ ๋ฐ›์•˜๋‹ค. ๋ฏธ๋Ÿฌ ์‚ฌ์ดํŠธ๋“ค ์„ฑ๋Šฅ์ด ์ข‹์ง€ ์•Š์•„์„œ ์ž‘์€๊ฑธ๋กœ ๋ฐ›์•„๋„ ๊ฝค ์˜ค๋ž˜๊ฑธ๋ฆฐ๋‹ค.

wget -O data.pbf https://download.geofabrik.de/asia/south-korea-latest.osm.pbf




osm2pgsql ์„ค์น˜ํ•˜๊ธฐ (in Linux)

์ด์ œ ์ง์ ‘ ์„ค์น˜ํ•ด์„œ ๋Œ๋ ค๋ณด์ž.

๋จผ์ € cli๋ฅผ ์„ค์น˜ํ•˜๊ณ 

sudo apt-get install osm2pgsql

์‹คํ–‰์ด ๋˜๋ฉด ์ž˜ ๊น”๋ฆฐ ๊ฒƒ์ด๋‹ค.

์ €์žฅ ๋Œ€์ƒ์œผ๋กœ ์“ธ postgres์— ์˜ˆ์ •๊ณผ extension์„ ๊น”์•„์ค€๋‹ค.

sudo -u postgres createuser osmuser
sudo -u postgres createdb --encoding=UTF8 --owner=osmuser osm
sudo -u postgres psql osm --command='CREATE EXTENSION postgis;'
sudo -u postgres psql osm --command='CREATE EXTENSION hstore;'

sudo -u postgres psql osm --command='ALTER USER osmuser WITH PASSWORD 'q1w2e3r4';'

์ €๊ธฐ๋‹ค๊ฐ€ ๋„ฃ์„ ๊ฒƒ์ด๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ง€๋„ ํŒŒ์ผ์„ osm2pgsql๋ฅผ ํ†ตํ•ด ๊ฐ€๊ณตํ•ด์„œ postgres์— ์—…๋กœ๋“œํ•˜๋ฉด ๋์ด๋‹ค.

osm2pgsql --database=osm --user=osmuser --password=q1w2e3r4 ./data.pbf

๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž”๋œฉ ๋จน๊ณ  ๋„๋Š”๊ฑฐ๋ผ ์‹คํ–‰์†๋„ ์ž์ฒด๋Š” ๊ดœ์ฐฎ๋‹ค. ๊ธˆ๋ฐฉ ๋Œ์•˜๋‹ค.

๊ทธ๋ฆฌ๊ณ  db์— ๋“ค์–ด๊ฐ€๋ฉด

๋ญ๊ฐ€ ์ด๋ž˜์ €๋ฆฌ ์ƒ๊ฒจ์žˆ์„ ๊ฒƒ์ด๋‹ค.
planet_osm_point๊ฐ€ ๊ฐ๊ฐ์˜ ๋„์‹œ, ๋งˆ์„ ๋“ฑ์— ๋Œ€ํ•œ ์ขŒํ‘œ๊ฐ’.
planet_osm_polygon์ด ์˜์—ญ์— ๋Œ€ํ•œ ๋‹ค๊ฐํ˜• ๊ฐ’.
planet_osm_lint์ด ์„ , planet_osm_roads๊ฐ€ ๊ธธ ๋“ฑ์ด๋‹ค.

์ €๊ธฐ ๋“ค์–ด๊ฐ€์žˆ๋Š” ๋ฐ์ดํ„ฐ๋กœ ์ฟผ๋ฆฌ ๋‚ ๋ฆฌ๋ฉด์„œ ๊ฑฐ๋ฆฌ์ธก์ •์ด๋‚˜ ์ขŒํ‘œ๊ฐ’ ๊ฐ€์ ธ์˜ค๊ณ  ๊ทธ๋Ÿฐ๊ฑธ ํ•˜๋ฉด ๋œ๋‹ค.

๋จผ์ € ํ˜„์žฌ ์œ„์น˜์—์„œ ๊ฐ€๊นŒ์šด ๋„์‹œ๋‚˜ ๋งˆ์„์„ ์ฐพ๋Š”๊ฑฐ๋ถ€ํ„ฐ ํ•ด๋ณด์ž.
planet_osm_point์€ place๋ผ๋Š” ๊ฐ’์„ ํ†ตํ•ด ๊ฐ ์ง€์ ๋“ค์˜ ํŠน์„ฑ์„ ๋ถ„๋ฅ˜ํ•ด๋†จ๋‹ค.

select distinct place from planet_osm_point;

city๊ฐ€ ์ผ๋ฐ˜์ ์ธ ๋„์‹œ, ์‹œ, ๊ด‘์—ญ์‹œ๋‹ค.
town์ด ๋ฆฌ, ๋™, ๋ฉด ๋“ฑ์˜ ํ•˜์œ„ ํ–‰์ •๊ตฌ์—ญ์ด๊ณ , ์ด๋ž˜์ €๋ž˜ ๋ญ ์žˆ๋‹ค.

๋จผ์ € ์œ„๋„/๊ฒฝ๋„ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ฒ€์ƒ‰์„ ํ•œ๋ฒˆ ํ•ด๋ณด๊ฒ ๋‹ค.
osm2pgsql์€ ์œ„๋„/๊ฒฝ๋„๊ฐ€ ์•„๋‹ˆ๋ผ Pseudo-Mercator๋ผ๋Š” ์กฐ๊ธˆ ๋ณ€ํ˜• ์ขŒํ‘œ๋ฒ•์„ ์‚ฌ์šฉํ•œ๋‹ค. ๊ตฌ๊ธ€๋งต์ด๋‚˜ OSM ๋“ฑ๋“ฑ ๋งŽ์ด ์“ฐ๋Š” ๋ฐฉ์‹์ด๋‹ค.

์ง€๋„์—์„œ ์ ๋‹นํžˆ ์ขŒํ‘œ๋ฅผ ์ฐพ๊ฑฐ๋‚˜

๋ฐ์ดํ„ฐ ๊ธฐ๋ฐ˜์œผ๋กœ ์ถ”์ถœํ•ด๋„ ๋œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์ขŒํ‘œ์—์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ๋„์‹œ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์ฟผ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•ด๋ดค๋‹ค.

SELECT name
FROM planet_osm_point
WHERE place = 'city'
ORDER BY ST_Distance(
    way,
    ST_Transform(
      ST_SetSRID(ST_Point(127.255188, 37.429084), 4326),
      3857
    )
)
LIMIT 10;

์ข€ ๋ฒˆ๊ฑฐ๋กญ๊ธด ํ•œ๋ฐ, ์ขŒํ‘œ ๊ฐ’์„ ์œ„๋„/๊ฒฝ๋„ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•œ ๋‹ค์Œ์—(SRID=4326), ์ž์ฒด ์ขŒํ‘œ๋ฒ•์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š”(SRID=3857) ๊ณผ์ •์„ ๊ฑฐ์ณค๋‹ค.
๊ทธ๋ฆฌ๊ณ  ST_Distance๋กœ ๊ฑฐ๋ฆฌ๋ฅผ ์žฌ์„œ ๊ฐ€์žฅ ๊ฐ€๊นŒ์šด ์œ„์น˜์˜ ๋„์‹œ๋ฅผ ๊ฐ€์ ธ์˜ค๋„๋ก ํ–ˆ๋‹ค.


์ž˜ ๋™์ž‘ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๊ฑด ๋‹จ์ˆœํ•œ ์˜ˆ์‹œ์ผ ๋ฟ์ด๊ณ , ์‹ค์ œ ์‚ฌ์šฉ๋ก€์—์„œ๋Š” ์ ์ ˆํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ๋‹ค.

๊ธฐ์ค€ ์ขŒํ‘œ๊ฐ€ ๋„์‹œ ๊ฒฝ๊ณ„๋ผ๋ฉด, ํ•ด๋‹น ๋„์‹œ ์ค‘์•™๋ณด๋‹ค ๋” ๊ฐ€๊นŒ์šด ๋‹ค๋ฅธ ๋„์‹œ๋กœ ์žกํ˜€๋ฒ„๋ฆด ์ˆ˜๋„ ์žˆ๊ณ , ์ธ๋ฑ์Šค๋„ ์ž˜ ํƒ€์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค. ์‚ฌ์šฉ์‚ฌ๋ก€์— ๋งž์ถฐ์„œ ์ตœ์ ํ™”๋ฅผ ํ•˜๋ฉด ๋œ๋‹ค.

์•„๋ฌดํŠผ ์ด๋Ÿฐ ์‹์œผ๋กœ ์‘์šฉํ•˜๋ฉด ๋œ๋‹ค.



์ฐธ์กฐ
https://osm2pgsql.org/doc/manual.html
https://hub.docker.com/r/iboates/osm2pgsql
https://stackoverflow.com/questions/52180005/retrieve-closest-road-when-given-lat-long-using-osm-in-postgres-with-postgis