add changeset parser

master
Oliver Tonnhofer 2016-12-06 15:53:10 +01:00
parent aaadf730ac
commit 41ddc76250
4 changed files with 103 additions and 0 deletions

BIN
parser/changeset/999.osm.gz Normal file

Binary file not shown.

4
parser/changeset/doc.go Normal file
View File

@ -0,0 +1,4 @@
/*
Package changeset provides a parser for OSM changeset files.
*/
package changeset

View File

@ -0,0 +1,78 @@
package changeset
import (
"compress/gzip"
"encoding/xml"
"os"
"time"
)
type changeFile struct {
XMLName string `xml:"osm"`
Generator string `xml:"generator,attr"`
Changes []Changeset `xml:"changeset"`
}
type Changeset struct {
Id int `xml:"id,attr"`
CreatedAt IsoTime `xml:"created_at,attr"`
ClosedAt IsoTime `xml:"closed_at,attr"`
Open bool `xml:"open,attr"`
User string `xml:"user,attr"`
UserId int `xml:"uid,attr"`
NumChanges int `xml:"num_changes,attr"`
MinLon float64 `xml:"min_lon,attr"`
MinLat float64 `xml:"min_lat,attr"`
MaxLon float64 `xml:"max_lon,attr"`
MaxLat float64 `xml:"max_lat,attr"`
Comments []Comment `xml:"discussion>comment"`
Tags []Tag `xml:"tag"`
}
type Comment struct {
UserId int `xml:"uid,attr"`
User string `xml:"user,attr"`
Date IsoTime `xml:"date,attr"`
Text string `xml:"text"`
}
type IsoTime struct {
time.Time
}
type Tag struct {
Key string `xml:"k,attr"`
Value string `xml:"v,attr"`
}
func (t *IsoTime) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
var v string
d.DecodeElement(&v, &start)
parse, err := time.Parse(time.RFC3339, v)
if err != nil {
return err
}
*t = IsoTime{parse}
return nil
}
// ParseAllOsmGz parses all changesets from a .osm.gz file.
func ParseAllOsmGz(change string) ([]Changeset, error) {
file, err := os.Open(change)
if err != nil {
return nil, err
}
defer file.Close()
reader, err := gzip.NewReader(file)
if err != nil {
return nil, err
}
cf := changeFile{}
err = xml.NewDecoder(reader).Decode(&cf)
if err != nil {
return nil, err
}
return cf.Changes, nil
}

View File

@ -0,0 +1,21 @@
package changeset
import "testing"
func TestParse(t *testing.T) {
changes, err := ParseAllOsmGz("999.osm.gz")
if err != nil {
t.Fatal(err)
}
if n := len(changes); n != 27 {
t.Error("expected 27 changes, got", n)
}
c := changes[0]
if c.Id != 43406602 || c.NumChanges != 314 {
t.Error("unexpected changeset", c)
}
if n := len(c.Comments); n != 3 {
t.Error("expected 3 comments in changeset", c)
}
}