Skip to content

Instantly share code, notes, and snippets.

@maxymania
Created November 12, 2018 09:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save maxymania/709e6fc5d5bb969f61e53cf70f4e35de to your computer and use it in GitHub Desktop.
Save maxymania/709e6fc5d5bb969f61e53cf70f4e35de to your computer and use it in GitHub Desktop.
package main
import "context"
import "github.com/paulmach/osm"
import "github.com/paulmach/osm/osmpbf"
import "github.com/paulmach/osm/osmxml"
import "encoding/xml"
import "fmt"
import "os"
import "flag"
import "io"
var all,nodes,ways,rels bool
var in_stdin, in_pbf bool
var limit,offset uint64
var in_file string
var out_ind bool
func init(){
flag.BoolVar(&all,"all",false,"select *")
flag.BoolVar(&nodes,"nodes",false,"select OSM Nodes")
flag.BoolVar(&ways,"ways",false,"select OSM Ways")
flag.BoolVar(&rels,"rels",false,"select OSM Relations")
flag.BoolVar(&in_stdin,"stdin",false,"use stdin as input")
flag.BoolVar(&in_pbf,"pbf",false,".pbf-format")
flag.BoolVar(&out_ind,"indent",false,"pretty-print XML")
flag.Uint64Var(&limit,"limit",0,"Max. number of elements, 0==infinity")
flag.Uint64Var(&offset,"offset",0,"Number of elements to skip")
flag.StringVar(&in_file,"file","","use file as input")
}
var pre = xml.StartElement{xml.Name{"","osm"},[]xml.Attr{
{xml.Name{"","version"},"0.6"},
{xml.Name{"","generator"},"osmselect 0.1"},
}}
var post = xml.EndElement{xml.Name{"","osm"}}
func main() {
flag.Parse()
fmt.Print(xml.Header)
enc := xml.NewEncoder(os.Stdout)
if out_ind { enc.Indent(""," ") }
enc.EncodeToken(pre)
var src io.Reader
if in_stdin {
src = os.Stdin
} else if in_file!="" {
f,err := os.Open(in_file)
if err==nil { src = f } else { fmt.Fprintf(os.Stderr,"Opening input-file %q: %v\n",in_file,err) }
}
if src==nil{
enc.EncodeToken(post)
enc.Flush()
fmt.Println()
return
}
var s osm.Scanner
if in_pbf {
s = osmpbf.New(context.Background(),src,4)
} else {
s = osmxml.New(context.Background(),src)
}
defer s.Close()
nolimit := limit==0
for s.Scan() {
o := s.Object()
if all { goto skipped }
switch o.ObjectID().Type() {
case osm.TypeNode: if !nodes { continue }
case osm.TypeWay: if !ways { continue }
case osm.TypeRelation: if !rels { continue }
}
skipped:
if offset>0 {
offset--
continue
}
if nolimit {} else if limit==0 { break }
limit--
enc.Encode(o)
}
err := s.Err()
if err!=nil { fmt.Fprintf(os.Stderr,"premature end: %v\n",err) }
enc.EncodeToken(post)
enc.Flush()
fmt.Println()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment