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"
|
// "goposm/osmpbf/fileformat"
|
||||||
"bytes"
|
"bytes"
|
||||||
"compress/zlib"
|
"compress/zlib"
|
||||||
|
"goposm/model"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -20,13 +21,11 @@ type PBF struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func Open(filename string) (f *PBF, err error) {
|
func Open(filename string) (f *PBF, err error) {
|
||||||
f = new(PBF)
|
|
||||||
f.filename = filename
|
|
||||||
file, err := os.Open(filename)
|
file, err := os.Open(filename)
|
||||||
f.file = file
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
f = &PBF{filename: filename, file: file}
|
||||||
return f, nil
|
return f, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +100,53 @@ func ReadPrimitiveBlock(file *os.File, offset int64, size int32) *osmpbf.Primiti
|
||||||
return block
|
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) {
|
func blockPositions(filename string) {
|
||||||
pbf, err := Open(filename)
|
pbf, err := Open(filename)
|
||||||
|
|
||||||
|
@ -121,6 +167,9 @@ func blockPositions(filename string) {
|
||||||
for _, group := range block.Primitivegroup {
|
for _, group := range block.Primitivegroup {
|
||||||
dense := group.GetDense()
|
dense := group.GetDense()
|
||||||
if dense != nil {
|
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(dense.Id)
|
||||||
}
|
}
|
||||||
nodesCounter += len(group.Nodes)
|
nodesCounter += len(group.Nodes)
|
||||||
|
|
Loading…
Reference in New Issue