こんにちは。
Golang で osm.pbf フォーマットの OpenStreetMap データファイルの読み込みを行ないました。qedus/osmpbf (を小修正したもの)を利用しました1 2 3。pbf-parser-comparison (GitHub) にもあるように確かに処理速度が速いように見えます。
- ただしこれは、読込む osm.pbf ファイルには注意が必要で、osmconvert でクリッピングして作ったファイル(例えばbbbike.orgの extraction 機能で作られたファイル)を読み込むとメモリ消費量が大きいです。osmosisやosmium-toolで作られたファイルではこの問題は無いように見えます。
$ wget https://gist.github.com/AlekSi/d4369aa13cf1fc5ddfac3e91b67b2f7b/raw/8604f36a7357adfbd6b5292c2ea4972d9d0bfd3d/greater-london-140324.osm.pbf
$ ls -ldh greater-london-140324.osm.pbf
-rw-r--r-- 1 kkdd staff 33M 10 10 10:10 greater-london-140324.osm.pbf
$
$ go run osmpbf_progressbar.go -ncpu 4 greater-london-140324.osm.pbf
33728 / 33728 [====================================================] 100.00 % 1s
Nodes: 2,729,006, Ways: 459,055, Relations: 12,833
$ go run osmpbf_progressbar.go -ncpu 1 greater-london-140324.osm.pbf
33728 / 33728 [====================================================] 100.00 % 4s
Nodes: 2,729,006, Ways: 459,055, Relations: 12,833
osmpbf_progressbar.go
package main
import (
"os"
"io"
"fmt"
"log"
"flag"
"runtime"
"github.com/cheggaaa/pb"
"github.com/dustin/go-humanize"
"github.com/kkdd/osmpbf"
)
func main() {
ncpu := flag.Int("ncpu", 1, "number of CPU")
flag.Parse()
runtime.GOMAXPROCS(*ncpu)
for _, file := range flag.Args() {
worker(file)
}
}
func worker(file string) {
f, err := os.Open(file)
if err != nil {
log.Fatal(err)
}
defer f.Close()
stat, _ := f.Stat()
filesiz := int(stat.Size()/1024)
d := osmpbf.NewDecoder(f)
err = d.Start(runtime.GOMAXPROCS(-1))
if err != nil {
log.Fatal(err)
}
var nc, wc, rc, i int64
progressbar := pb.New(filesiz).SetUnits(pb.U_NO)
progressbar.Start()
for i = 0; ; i++ {
if v, err := d.Decode(); err == io.EOF {
break
} else if err != nil {
log.Fatal(err)
} else {
switch v := v.(type) {
case *osmpbf.Node:
nc++
case *osmpbf.Way:
wc++
case *osmpbf.Relation:
rc++
default:
log.Fatalf("unknown type %T\n", v)
}
}
if i % 131072 == 0 {
progressbar.Set(int(d.GetTotalReadSize()/1024))
}
}
progressbar.Set(filesiz)
progressbar.Finish()
fmt.Printf("Nodes: %s, Ways: %s, Relations: %s\n", humanize.Comma(nc), humanize.Comma(wc), humanize.Comma(rc))
}
-
他にも Go 用ライブラリがあるようです。例えば、paulmach/osm/osmpbf, thomersch/gosmparse, maguro/pbf, omniscale/imposm3, qedus/osmpbf, missinglink/pbf。処理速度とメモリ消費量を実験して選ぶと良いかもしれません。 ↩
-
C++ 用には、osmcode/libosmium (Python 用バインディングもあります)、CanalTP/libosmpbfreader があるようです。 ↩
-
Rust 用には、b-r-u/osmpbf, TeXitoi/osmpbfreader-rs, crate/osmpbfreader, oleksandromelchuk/rust-osm-reader があるようです。 ↩