gOSMonaut is a Go library that decodes OpenStreetMap PBF files. Instead of returning the internal PBF data model, which uses reference-IDs of nested OSM entities, it always returns complete entities. E.g. a way contains all child nodes, including tags and coordinates, instead of just the node-IDs.
$ go get github.com/morbz/gosmonaut
In order to produce complete entities all nested entites are cached in memory. To keep the used memory low there are two filters that the decoder uses to decide which entites it needs to cache. They are passed to the Start()
method of the Gosmonaut object. Only entites that satisfy both filters will be send to the caller:
types OSMTypeSet
: Defines which OSM element types are requested (node, way, relation)
funcEntityNeeded func(OSMType, OSMTags) bool
: A callback function that the decoder will call during decoding. Based on the element type and tags, this function decides if the entity is needed.
In this example the program will output all the street names of London:
package main
import (
"io"
"log"
"os"
"github.com/MorbZ/gosmonaut"
)
func main() {
// Open the PBF file
f, err := os.Open("greater-london-140324.osm.pbf")
if err != nil {
log.Fatal(err)
}
defer f.Close()
// Create the Gosmonaut object
g, err := gosmonaut.NewGosmonaut(f)
if err != nil {
log.Fatal(err)
}
// Start decoding
g.Start(
// We only want to receive ways (nodes, ways, relations)
gosmonaut.NewOSMTypeSet(false, true, false),
// Only request highways with a name
func(t gosmonaut.OSMType, tags gosmonaut.OSMTags) bool {
return tags.Has("highway") && tags.Has("name")
},
)
// Receive found entities
for {
if i, err := g.Next(); err == io.EOF {
// Last entity received
break
} else if err != nil {
// Error during encoding
log.Fatal(err)
} else {
// Received entity, print name
tags := i.GetTags()
log.Println(tags.Get("name"))
}
}
}
When creating the Gosmonaut object, an optional configuration object can be passed.
Instead of:
gosmonaut.NewGosmonaut(f)
the configuration can be passed by calling:
gosmonaut.NewGosmonaut(
f,
gosmonaut.Config{
PrintWarnings: true,
NumProcessors: 2,
},
)
See the documentation for possible configuration parameters.
All entities can be serialized into the JSON format. The used JSON format is similar to Overpass JSON but it comes with nested entities. Here is an example of how a relation with nested member ways and nodes can look like:
{
"type": "relation",
"id": 8024698,
"tags": {
"addr:city": "Leonberg",
"addr:housenumber": "5",
"addr:postcode": "71229",
"addr:street": "Sellallee",
"building": "apartments",
"type": "multipolygon"
},
"members": [
{
"role": "outer",
"entity": {
"type": "way",
"id": 561602115,
"tags": {},
"nodes": [
{
"type": "node",
"id": 5414987608,
"lat": 48.7994117,
"lon": 9.0173691
},
{
"type": "node",
"id": 5414987609,
"lat": 48.7994205,
"lon": 9.0171999,
"tags": {
"entrance": "main"
}
}
]
}
}
]
}