OpenStreetMapのplanetファイル(.osm.bz2)から地域データをメッチャ沢山切り出すbash


##概要
OpenStreetMapのplanetファイルはかなり大きなサイズですので、Planetから各地域のデータを切り出すのはかなり時間がかかります。
さらに、複数の多くの地域を切り出すとなると、メッチャ時間が掛かります。
さらにさらに、時系列の複数のPlanetファイルから切り出すとなると、もう気が遠くなります。

それを効率よく切り出すためのアイデアです。

##準備

###planet files
planetフィルは、　http://planet.openstreetmap.org/ からダウンロードします。
以下では、約９年分、９６ファイルの処理を行います。

```bash
# planet date list
planet_date_list=(    090421 090506 090603 090708 090805 090902 091007 091104 091202 \
 100106 100203 100303 100401 100505 100602 100707 100804 100901 101006 101103 101201 \
 110105 110202 110302 110406 110504 110602 110706 110803 110907 111005 111102 111207 \
 120104 120201 120307 120401 120508 120613 120704 120801 120912 121017 121107 121205 \
 130102 130206 130304 130417 130502 130606 130703 130814 130904 131002 131103 131203 \
 140101 140205 140305 140401 140507 140604 140703 140806 140903 141008 141105 141203 \
 150105 150202        150406 150504 150601 150713 150803 150907 151005 151102 151207 \
 160104 160201 160307 160404 160502 160606 160704 160801 160912 161003 161107 161205 \
 170102 170206 170306 170403)
```

###切り出す地域 poly
地域を切り出すpolyファイルが必要です。
polyファイルは、このあたりからダウンロードできます。 http://download.geofabrik.de/
以下では、50地域くらいの処理をしています。
切り出すデータのサイズが大きい順に並べると、より効率的に処理できると思います。

```bash
# region list : 49 + 2 regions
region_list=( russia-european-part russia-asian-part \
    us-pacific us-northeast us-west us-south us-midwest \
    france	japan germany united_kingdom spain netherlands slovakia haiti monaco \
    czech belgium luxembourg new-zealand philippines south-korea taiwan india \
    mexico cuba argentina italy switzerland denmark china canada australia \
    finland brazil morocco colombia ecuador iran thailand  south-africa-and-lesotho\
    indonesia croatia lithuania greece romania ireland-and-northern-ireland \
	turkey	portugal belarus slovenia norway hungary sweden ukraine poland austria chile )
```

###osmosis
OSMのデータを扱うライブラリです。インストールしてください。

###xargs
xargsで、並列の処理をしています。
以下では、8coreで書いてありますが、環境に合わせて書き換えてください。

## dir
コード内の、各ファイルのディレクトルの指定は、環境に合わせて適時書き換えてください。


##切り出し処理
###bash コード
以下が、bashのコードです。
全ての処理が完了すると、５０００くらいのファイルが出力される筈です。
普通にシリアルに処理すると、１〜２年くらいかかるかと・・・。たぶん。環境にもよるけど。
以下で処理すると、たぶん半年くらいで出力できるんじゃないかな・・・・。たぶん。保証はできませんが。


```bash:planet_to_region.sh
#!/bin/bash

# planet_dir
planet_dir=/osm/planet

# region_dir
region_dir=/osm/region

# poly_dir
poly_dir=/osm/poly

# temp_dir
#temp_dir=/osm/temp

#prefix
prefix=pla2reg

# planet date list
planet_date_list=(    090421 090506 090603 090708 090805 090902 091007 091104 091202 \
 100106 100203 100303 100401 100505 100602 100707 100804 100901 101006 101103 101201 \
 110105 110202 110302 110406 110504 110602 110706 110803 110907 111005 111102 111207 \
 120104 120201 120307 120401 120508 120613 120704 120801 120912 121017 121107 121205 \
 130102 130206 130304 130417 130502 130606 130703 130814 130904 131002 131103 131203 \
 140101 140205 140305 140401 140507 140604 140703 140806 140903 141008 141105 141203 \
 150105 150202        150406 150504 150601 150713 150803 150907 151005 151102 151207 \
 160104 160201 160307 160404 160502 160606 160704 160801 160912 161003 161107 161205 \
 170102 170206 170306 170403)

# region list : 49 + 2 regions
region_list=( russia-european-part russia-asian-part \
    us-pacific us-northeast us-west us-south us-midwest \
    france	japan germany united_kingdom spain netherlands slovakia haiti monaco \
    czech belgium luxembourg new-zealand philippines south-korea taiwan india \
    mexico cuba argentina italy switzerland denmark china canada australia \
    finland brazil morocco colombia ecuador iran thailand  south-africa-and-lesotho\
    indonesia croatia lithuania greece romania ireland-and-northern-ireland \
	turkey	portugal belarus slovenia norway hungary sweden ukraine poland austria chile )

######### function option {region} {date}
func_extract_region ()
{
    # planet_dir
    planet_dir=/osm/planet
    # region_dir
    region_dir=/osm/region
    # poly_dir
    poly_dir=/osm/poly

    temp_osm_data=$planet_dir/planet-$2.osm
	region_file=$region_dir/$1/$1-$2.osm.bz2

	if [ ! -e $region_file ];then
    	echo -- making  $1 : $region_file
    	osmosis --read-xml file=$temp_osm_data --bounding-polygon file=$poly_dir/$1.poly --write-xml file=- | bzip2 > $region_file
	fi
}

cd $planet_dir

#### array
for date in ${planet_date_list[@]};do

	temp_osm_data=$planet_dir/planet-$date.osm
	data_flag=0

    region_make_list=()
	for region in ${region_list[@]};do
		if [ ! -e $region_dir/$region/$region-$date.osm.bz2 ]; then
			data_flag=1
            region_make_list=(${region_make_list[@]} $region)
		fi
	done
    echo ---- $date : ${region_make_list[*]}

	if [ 1 -eq $data_flag ]; then
		echo = = = = = = = = = = =
	    echo `date +"%Y/%m/%d %H:%M:%S"` ===== extracting planet-$date.osm.bz2
		echo - - - - - - - - - - - - - - - - to $temp_osm_data
	    bzip2 -dk $planet_dir/planet-$date.osm.bz2

	    echo  `date +"%Y/%m/%d %H:%M:%S"` ---- making region files -- $date
        export -f func_extract_region
        (for region in ${region_make_list[@]};do echo $region ; done) | xargs -n8 -P8 -I % bash -c "func_extract_region % $date"
    fi

	if [ -e $temp_osm_data ]; then
    	echo `date +"%Y/%m/%d %H:%M:%S"` ===== Delete Temp file
		echo - - - - - - - - - - - - - - - - - Deleting $temp_osm_data
		rm $temp_osm_data
	fi

done
```

##まとめ
良い子は真似しない方がいいかもしれません。
数ヶ月くらい時間の余裕のある紳士淑女にはオススメです。