parse dense nodes; add node/way/relation models

master
Oliver Tonnhofer 2013-01-19 13:50:44 +01:00
parent 4f2a3b53a0
commit 108982a729
4 changed files with 272 additions and 3 deletions

149
model/model.pb.go Normal file
View File

@ -0,0 +1,149 @@
// Code generated by protoc-gen-go.
// source: model.proto
// DO NOT EDIT!
package model
import proto "code.google.com/p/goprotobuf/proto"
import json "encoding/json"
import math "math"
// Reference proto, json, and math imports to suppress error if they are not otherwise used.
var _ = proto.Marshal
var _ = &json.SyntaxError{}
var _ = math.Inf
type RelationMember_MemberType int32
const (
RelationMember_NODE RelationMember_MemberType = 0
RelationMember_WAY RelationMember_MemberType = 1
RelationMember_RELATION RelationMember_MemberType = 2
)
var RelationMember_MemberType_name = map[int32]string{
0: "NODE",
1: "WAY",
2: "RELATION",
}
var RelationMember_MemberType_value = map[string]int32{
"NODE": 0,
"WAY": 1,
"RELATION": 2,
}
func (x RelationMember_MemberType) Enum() *RelationMember_MemberType {
p := new(RelationMember_MemberType)
*p = x
return p
}
func (x RelationMember_MemberType) String() string {
return proto.EnumName(RelationMember_MemberType_name, int32(x))
}
func (x RelationMember_MemberType) MarshalJSON() ([]byte, error) {
return json.Marshal(x.String())
}
func (x *RelationMember_MemberType) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(RelationMember_MemberType_value, data, "RelationMember_MemberType")
if err != nil {
return err
}
*x = RelationMember_MemberType(value)
return nil
}
type Tag struct {
Key *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
Val *string `protobuf:"bytes,2,req,name=val" json:"val,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (this *Tag) Reset() { *this = Tag{} }
func (this *Tag) String() string { return proto.CompactTextString(this) }
func (*Tag) ProtoMessage() {}
func (this *Tag) GetKey() string {
if this != nil && this.Key != nil {
return *this.Key
}
return ""
}
func (this *Tag) GetVal() string {
if this != nil && this.Val != nil {
return *this.Val
}
return ""
}
type Way struct {
Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"`
Tags []*Tag `protobuf:"bytes,2,rep,name=tags" json:"tags,omitempty"`
Nodes []int64 `protobuf:"varint,3,rep,packed,name=nodes" json:"nodes,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (this *Way) Reset() { *this = Way{} }
func (this *Way) String() string { return proto.CompactTextString(this) }
func (*Way) ProtoMessage() {}
func (this *Way) GetId() int64 {
if this != nil && this.Id != nil {
return *this.Id
}
return 0
}
type Relation struct {
Id *int64 `protobuf:"varint,1,req,name=id" json:"id,omitempty"`
Tags []*Tag `protobuf:"bytes,2,rep,name=tags" json:"tags,omitempty"`
Members []*RelationMember `protobuf:"bytes,3,rep,name=members" json:"members,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (this *Relation) Reset() { *this = Relation{} }
func (this *Relation) String() string { return proto.CompactTextString(this) }
func (*Relation) ProtoMessage() {}
func (this *Relation) GetId() int64 {
if this != nil && this.Id != nil {
return *this.Id
}
return 0
}
type RelationMember struct {
MemberIds *int64 `protobuf:"varint,1,req,name=member_ids" json:"member_ids,omitempty"`
MemberTypes *RelationMember_MemberType `protobuf:"varint,2,req,name=member_types,enum=model.RelationMember_MemberType" json:"member_types,omitempty"`
MemberRoles *string `protobuf:"bytes,3,req,name=member_roles" json:"member_roles,omitempty"`
XXX_unrecognized []byte `json:"-"`
}
func (this *RelationMember) Reset() { *this = RelationMember{} }
func (this *RelationMember) String() string { return proto.CompactTextString(this) }
func (*RelationMember) ProtoMessage() {}
func (this *RelationMember) GetMemberIds() int64 {
if this != nil && this.MemberIds != nil {
return *this.MemberIds
}
return 0
}
func (this *RelationMember) GetMemberTypes() RelationMember_MemberType {
if this != nil && this.MemberTypes != nil {
return *this.MemberTypes
}
return 0
}
func (this *RelationMember) GetMemberRoles() string {
if this != nil && this.MemberRoles != nil {
return *this.MemberRoles
}
return ""
}
func init() {
proto.RegisterEnum("model.RelationMember_MemberType", RelationMember_MemberType_name, RelationMember_MemberType_value)
}

31
model/model.proto Normal file
View File

@ -0,0 +1,31 @@
package model;
message Tag {
required string key = 1;
required string val = 2;
}
message Way {
required int64 id = 1;
repeated Tag tags = 2;
repeated int64 nodes = 3 [packed = true];
}
message Relation {
required int64 id = 1;
repeated Tag tags = 2;
repeated RelationMember members = 3;
}
message RelationMember {
required int64 member_ids = 1;
enum MemberType {
NODE = 0;
WAY = 1;
RELATION = 2;
}
required MemberType member_types = 2;
required string member_roles = 3;
}

40
model/nodes.go Normal file
View File

@ -0,0 +1,40 @@
package model
import "code.google.com/p/goprotobuf/proto"
import "log"
type Node struct {
Id int64
Tags map[string]string
Lon uint32
Lat uint32
}
const COORD_FACTOR float64 = 11930464.7083 // ((2<<31)-1)/360.0
func coordToInt(coord float64) uint32 {
return uint32((coord + 180.0) * COORD_FACTOR)
}
func intToCoord(coord uint32) float64 {
return float64((float64(coord) / COORD_FACTOR) - 180.0)
}
func (this *Node) WgsCoord() (lon float64, lat float64) {
lon = intToCoord(this.Lon)
lat = intToCoord(this.Lat)
return
}
func (this *Node) FromWgsCoord(lon float64, lat float64) {
this.Lon = coordToInt(lon)
this.Lat = coordToInt(lat)
}
func (this *Way) Marshal() []byte {
data, err := proto.Marshal(this)
if err != nil {
log.Fatal("marshaling error: ", err)
}
return data
}

View File

@ -7,6 +7,7 @@ import (
// "goposm/osmpbf/fileformat"
"bytes"
"compress/zlib"
"goposm/model"
"io"
"log"
"os"
@ -20,13 +21,11 @@ type PBF struct {
}
func Open(filename string) (f *PBF, err error) {
f = new(PBF)
f.filename = filename
file, err := os.Open(filename)
f.file = file
if err != nil {
return nil, err
}
f = &PBF{filename: filename, file: file}
return f, nil
}
@ -101,6 +100,53 @@ func ReadPrimitiveBlock(file *os.File, offset int64, size int32) *osmpbf.Primiti
return block
}
// type Node struct {
// Id int64
// Tags map[string]string
// Lon uint32
// Lat uint32
// }
func DenseNodeTags(stringtable []string, keyvals []int32) (tags map[string]string, nextPos int) {
tags = make(map[string]string)
nextPos = 0
for {
keyId := keyvals[nextPos]
nextPos += 1
if keyId == 0 {
return
}
key := stringtable[keyId]
valId := keyvals[nextPos]
nextPos += 1
val := stringtable[valId]
tags[key] = val
}
return
}
func ReadDenseNodes(dense *osmpbf.DenseNodes, block *osmpbf.PrimitiveBlock) (nodes []model.Node) {
var lastId int64
var lastLon, lastLat int64
nodes = make([]model.Node, len(dense.Id))
granularity := int64(block.GetGranularity())
latOffset := block.GetLatOffset()
lonOffset := block.GetLonOffset()
coordScale := 0.000000001
for i := range nodes {
lastId += dense.Id[i]
lastLon += dense.Lon[i]
lastLat += dense.Lat[i]
nodes[i].Id = lastId
nodes[i].FromWgsCoord(
(coordScale * float64(lonOffset+(granularity*lastLon))),
(coordScale * float64(latOffset+(granularity*lastLat))))
}
return nodes
}
func blockPositions(filename string) {
pbf, err := Open(filename)
@ -121,6 +167,9 @@ func blockPositions(filename string) {
for _, group := range block.Primitivegroup {
dense := group.GetDense()
if dense != nil {
nodes := ReadDenseNodes(dense, block)
lon, lat := nodes[1].WgsCoord()
fmt.Printf("%12d %10.8f %10.8f\n", nodes[0].Id, lon, lat)
nodesCounter += len(dense.Id)
}
nodesCounter += len(group.Nodes)