imposm3/binary/serialize.go

132 lines
2.9 KiB
Go
Raw Normal View History

2013-01-28 10:55:34 +04:00
package binary
import (
"bytes"
2013-01-28 10:55:34 +04:00
"code.google.com/p/goprotobuf/proto"
bin "encoding/binary"
2013-01-28 10:55:34 +04:00
"goposm/element"
"goposm/model"
)
const COORD_FACTOR float64 = 11930464.7083 // ((2<<31)-1)/360.0
2013-01-28 10:55:34 +04:00
func CoordToInt(coord float64) uint32 {
return uint32((coord + 180.0) * COORD_FACTOR)
2013-02-12 22:45:49 +04:00
}
func IntToCoord(coord uint32) float64 {
return float64((float64(coord) / COORD_FACTOR) - 180.0)
2013-02-12 22:45:49 +04:00
}
2013-01-28 10:55:34 +04:00
func Marshal(elem interface{}) ([]byte, error) {
switch typedElem := elem.(type) {
case element.Node:
2013-02-12 22:45:49 +04:00
return MarshalNode(&typedElem)
2013-01-28 10:55:34 +04:00
default:
panic("invalid elem to marshal")
}
return []byte{}, nil
}
func MarshalCoord(node *element.Node) ([]byte, error) {
data := make([]byte, 8)
buf := bytes.NewBuffer(data)
err := bin.Write(buf, bin.LittleEndian, CoordToInt(node.Long))
if err != nil {
return nil, err
}
err = bin.Write(buf, bin.LittleEndian, CoordToInt(node.Lat))
if err != nil {
return nil, err
}
return data, nil
}
func UnmarshalCoord(id int64, data []byte) (node *element.Node, err error) {
var long, lat uint32
buf := bytes.NewBuffer(data)
err = bin.Read(buf, bin.LittleEndian, &long)
if err != nil {
return nil, err
}
err = bin.Read(buf, bin.LittleEndian, &lat)
if err != nil {
return nil, err
}
node = &element.Node{}
node.Id = id
node.Long = IntToCoord(long)
node.Lat = IntToCoord(lat)
return node, nil
}
2013-02-12 22:45:49 +04:00
func MarshalNode(node *element.Node) ([]byte, error) {
2013-01-28 10:55:34 +04:00
pbfNode := &model.Node{}
2013-02-12 22:45:49 +04:00
nodeId := node.Id
pbfNode.Id = &nodeId
2013-01-28 10:55:34 +04:00
pbfNode.FromWgsCoord(node.Long, node.Lat)
pbfNode.Tags = node.TagsAsArray()
2013-01-28 10:55:34 +04:00
return proto.Marshal(pbfNode)
}
2013-02-12 22:45:49 +04:00
func UnmarshalNode(data []byte) (node *element.Node, err error) {
pbfNode := &model.Node{}
err = proto.Unmarshal(data, pbfNode)
if err != nil {
return nil, err
}
node = &element.Node{}
node.Id = *pbfNode.Id
node.Long, node.Lat = pbfNode.WgsCoord()
node.TagsFromArray(pbfNode.Tags)
2013-02-12 22:45:49 +04:00
return node, nil
}
func MarshalWay(way *element.Way) ([]byte, error) {
pbfWay := &model.Way{}
pbfWay.Id = &way.Id
2013-04-24 00:30:41 +04:00
pbfWay.Refs = way.Refs
pbfWay.Tags = way.TagsAsArray()
2013-02-12 22:45:49 +04:00
return proto.Marshal(pbfWay)
}
func UnmarshalWay(data []byte) (way *element.Way, err error) {
pbfWay := &model.Way{}
err = proto.Unmarshal(data, pbfWay)
if err != nil {
return nil, err
}
way = &element.Way{}
way.Id = *pbfWay.Id
2013-04-24 00:30:41 +04:00
way.Refs = pbfWay.Refs
way.TagsFromArray(pbfWay.Tags)
2013-02-12 22:45:49 +04:00
return way, nil
}
2013-04-08 23:45:13 +04:00
func MarshalRelation(relation *element.Relation) ([]byte, error) {
pbfRelation := &model.Relation{}
pbfRelation.Id = &relation.Id
//pbfRelation.Members = relation.Members
pbfRelation.Tags = relation.TagsAsArray()
return proto.Marshal(pbfRelation)
}
func UnmarshalRelation(data []byte) (relation *element.Relation, err error) {
pbfRelation := &model.Relation{}
err = proto.Unmarshal(data, pbfRelation)
if err != nil {
return nil, err
}
relation = &element.Relation{}
relation.Id = *pbfRelation.Id
//relation.Nodes = pbfRelation.Node
relation.TagsFromArray(pbfRelation.Tags)
return relation, nil
}