parse dense nodes; add node/way/relation models
parent
4f2a3b53a0
commit
108982a729
|
@ -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)
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
}
|
55
parser.go
55
parser.go
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue