From ac32b8c9608320a3201ed53182614c0ff0f432ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Legat?= Date: Sun, 29 Oct 2023 17:58:33 +0100 Subject: [PATCH] Update to ProtoBuf v1 (#74) * Update PBF support to ProtoBuf v1 --- Project.toml | 2 +- src/OSMPBF.jl | 17 - src/fileformat_pb.jl | 131 ++++--- src/osmformat_pb.jl | 826 +++++++++++++++++++++++++++++-------------- src/pbf.jl | 23 +- 5 files changed, 660 insertions(+), 339 deletions(-) diff --git a/Project.toml b/Project.toml index 5dcc21f..cbe8087 100644 --- a/Project.toml +++ b/Project.toml @@ -24,7 +24,7 @@ HTTP = "^0.7.0, ^0.8.0, ^0.9.0, ^1.2.0" JSON = "^0.20.0, ^0.21.0" LibExpat = "^0.6.1" Graphs = "^1.4.1" -ProtoBuf = "^0.11.5" +ProtoBuf = "1" StableRNGs = "^1.0.0" julia = "^1.3.0" diff --git a/src/OSMPBF.jl b/src/OSMPBF.jl index 1c03b63..0e22e06 100644 --- a/src/OSMPBF.jl +++ b/src/OSMPBF.jl @@ -1,21 +1,4 @@ -# Modified from the file automatically generated by ProtoBuf.jl -# See https://github.com/pszufe/OpenStreetMapX.jl/pull/52/ module OSMPBF - const _ProtoBuf_Top_ = @static isdefined(parentmodule(@__MODULE__), :_ProtoBuf_Top_) ? (parentmodule(@__MODULE__))._ProtoBuf_Top_ : parentmodule(@__MODULE__) - - using ProtoBuf - abstract type SimpleProtoType <: ProtoType end - set_defaults!(::SimpleProtoType) = nothing - function ProtoBuf.clear(obj::SimpleProtoType) - # FIXME how does it play with GC ? - Base.unsafe_securezero!(pointer_from_objref(obj), sizeof(typeof(obj))) - set_defaults!(obj) - return - end - Base.hasproperty(obj::SimpleProtoType, field::Symbol) = isdefined(obj, field) - Base.setproperty!(obj::SimpleProtoType, field::Symbol, value) = setfield!(obj, field, value) - ProtoBuf.setdefaultproperties!(::SimpleProtoType, ::ProtoMeta) = nothing - include("fileformat_pb.jl") include("osmformat_pb.jl") end diff --git a/src/fileformat_pb.jl b/src/fileformat_pb.jl index 45d3028..ff51fba 100644 --- a/src/fileformat_pb.jl +++ b/src/fileformat_pb.jl @@ -1,55 +1,104 @@ -# Modified from the file automatically generated by ProtoBuf.jl -# See https://github.com/pszufe/OpenStreetMapX.jl/pull/52/ -# syntax: proto2 -using ProtoBuf -import ProtoBuf.meta +# Autogenerated using ProtoBuf.jl v1.0.14 on 2023-10-26T22:07:48.079 +# original file: https://raw.githubusercontent.com/osmandapp/OsmAnd-resources/master/protos/fileformat.proto (proto2 syntax) -mutable struct Blob <: SimpleProtoType - raw_size::Int32 +import ProtoBuf as PB +using ProtoBuf: OneOf +using ProtoBuf.EnumX: @enumx + +export Blob, BlockHeader + +struct Blob raw::Vector{UInt8} + raw_size::Int32 zlib_data::Vector{UInt8} lzma_data::Vector{UInt8} - OBSOLETE_bzip2_data::Vector{UInt8} - lz4_data::Vector{UInt8} - zstd_data::Vector{UInt8} - function Blob() - return new() - end -end # mutable struct Blob -const __meta_Blob = Ref{ProtoMeta}() -function meta(::Type{Blob}) - ProtoBuf.metalock() do - if !isassigned(__meta_Blob) - __meta_Blob[] = target = ProtoMeta(Blob) - fnum = Int[2,1,3,4,5,6,7] - allflds = Pair{Symbol,Union{Type,String}}[:raw_size => Int32, :raw => Vector{UInt8}, :zlib_data => Vector{UInt8}, :lzma_data => Vector{UInt8}, :OBSOLETE_bzip2_data => Vector{UInt8}, :lz4_data => Vector{UInt8}, :zstd_data => Vector{UInt8}] - oneofs = Int[0,1,1,1,1,1,1] - oneof_names = Symbol[Symbol("data")] - meta(target, Blob, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, oneofs, oneof_names) + bzip2_data::Vector{UInt8} +end +PB.default_values(::Type{Blob}) = (;raw = UInt8[], raw_size = zero(Int32), zlib_data = UInt8[], lzma_data = UInt8[], bzip2_data = UInt8[]) +PB.field_numbers(::Type{Blob}) = (;raw = 1, raw_size = 2, zlib_data = 3, lzma_data = 4, bzip2_data = 5) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:Blob}) + raw = UInt8[] + raw_size = zero(Int32) + zlib_data = UInt8[] + lzma_data = UInt8[] + bzip2_data = UInt8[] + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + raw = PB.decode(d, Vector{UInt8}) + elseif field_number == 2 + raw_size = PB.decode(d, Int32) + elseif field_number == 3 + zlib_data = PB.decode(d, Vector{UInt8}) + elseif field_number == 4 + lzma_data = PB.decode(d, Vector{UInt8}) + elseif field_number == 5 + bzip2_data = PB.decode(d, Vector{UInt8}) + else + PB.skip(d, wire_type) end - __meta_Blob[] end + return Blob(raw, raw_size, zlib_data, lzma_data, bzip2_data) end -mutable struct BlobHeader <: SimpleProtoType - _type::AbstractString +function PB.encode(e::PB.AbstractProtoEncoder, x::Blob) + initpos = position(e.io) + !isempty(x.raw) && PB.encode(e, 1, x.raw) + x.raw_size != zero(Int32) && PB.encode(e, 2, x.raw_size) + !isempty(x.zlib_data) && PB.encode(e, 3, x.zlib_data) + !isempty(x.lzma_data) && PB.encode(e, 4, x.lzma_data) + !isempty(x.bzip2_data) && PB.encode(e, 5, x.bzip2_data) + return position(e.io) - initpos +end +function PB._encoded_size(x::Blob) + encoded_size = 0 + !isempty(x.raw) && (encoded_size += PB._encoded_size(x.raw, 1)) + x.raw_size != zero(Int32) && (encoded_size += PB._encoded_size(x.raw_size, 2)) + !isempty(x.zlib_data) && (encoded_size += PB._encoded_size(x.zlib_data, 3)) + !isempty(x.lzma_data) && (encoded_size += PB._encoded_size(x.lzma_data, 4)) + !isempty(x.bzip2_data) && (encoded_size += PB._encoded_size(x.bzip2_data, 5)) + return encoded_size +end + +struct BlockHeader + var"#type"::String indexdata::Vector{UInt8} datasize::Int32 - function BlobHeader() - return new() - end -end # mutable struct BlobHeader -const __meta_BlobHeader = Ref{ProtoMeta}() -function meta(::Type{BlobHeader}) - ProtoBuf.metalock() do - if !isassigned(__meta_BlobHeader) - __meta_BlobHeader[] = target = ProtoMeta(BlobHeader) - req = Symbol[:_type,:datasize] - allflds = Pair{Symbol,Union{Type,String}}[:_type => AbstractString, :indexdata => Vector{UInt8}, :datasize => Int32] - meta(target, BlobHeader, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +end +PB.default_values(::Type{BlockHeader}) = (;var"#type" = "", indexdata = UInt8[], datasize = zero(Int32)) +PB.field_numbers(::Type{BlockHeader}) = (;var"#type" = 1, indexdata = 2, datasize = 3) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:BlockHeader}) + var"#type" = "" + indexdata = UInt8[] + datasize = zero(Int32) + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + var"#type" = PB.decode(d, String) + elseif field_number == 2 + indexdata = PB.decode(d, Vector{UInt8}) + elseif field_number == 3 + datasize = PB.decode(d, Int32) + else + PB.skip(d, wire_type) end - __meta_BlobHeader[] end + return BlockHeader(var"#type", indexdata, datasize) end -export Blob, BlobHeader +function PB.encode(e::PB.AbstractProtoEncoder, x::BlockHeader) + initpos = position(e.io) + !isempty(x.var"#type") && PB.encode(e, 1, x.var"#type") + !isempty(x.indexdata) && PB.encode(e, 2, x.indexdata) + x.datasize != zero(Int32) && PB.encode(e, 3, x.datasize) + return position(e.io) - initpos +end +function PB._encoded_size(x::BlockHeader) + encoded_size = 0 + !isempty(x.var"#type") && (encoded_size += PB._encoded_size(x.var"#type", 1)) + !isempty(x.indexdata) && (encoded_size += PB._encoded_size(x.indexdata, 2)) + x.datasize != zero(Int32) && (encoded_size += PB._encoded_size(x.datasize, 3)) + return encoded_size +end diff --git a/src/osmformat_pb.jl b/src/osmformat_pb.jl index 7969caf..0e63680 100644 --- a/src/osmformat_pb.jl +++ b/src/osmformat_pb.jl @@ -1,347 +1,629 @@ -# Modified from the file automatically generated by ProtoBuf.jl -# See https://github.com/pszufe/OpenStreetMapX.jl/pull/52/ -# syntax: proto2 -using ProtoBuf -import ProtoBuf.meta +# Autogenerated using ProtoBuf.jl v1.0.14 on 2023-10-26T22:05:46.147 +# original file: https://raw.githubusercontent.com/osmandapp/OsmAnd-resources/master/protos/osmformat.proto (proto2 syntax) -mutable struct HeaderBBox <: SimpleProtoType - left::Int64 - right::Int64 - top::Int64 - bottom::Int64 - function HeaderBBox() - return new() - end +import ProtoBuf as PB +using ProtoBuf: OneOf +using ProtoBuf.EnumX: @enumx + +export var"Relation.MemberType", DenseInfo, StringTable, ChangeSet, HeaderBBox, Info +export DenseNodes, HeaderBlock, Relation, Node, Way, PrimitiveGroup, PrimitiveBlock + +@enumx var"Relation.MemberType" NODE=0 WAY=1 RELATION=2 + +struct DenseInfo + version::Vector{Int32} + timestamp::Vector{Int64} + changeset::Vector{Int64} + uid::Vector{Int32} + user_sid::Vector{Int32} end +PB.default_values(::Type{DenseInfo}) = (;version = Vector{Int32}(), timestamp = Vector{Int64}(), changeset = Vector{Int64}(), uid = Vector{Int32}(), user_sid = Vector{Int32}()) +PB.field_numbers(::Type{DenseInfo}) = (;version = 1, timestamp = 2, changeset = 3, uid = 4, user_sid = 5) -const __meta_HeaderBBox = Ref{ProtoMeta}() -function meta(::Type{HeaderBBox}) - ProtoBuf.metalock() do - if !isassigned(__meta_HeaderBBox) - __meta_HeaderBBox[] = target = ProtoMeta(HeaderBBox) - req = Symbol[:left,:right,:top,:bottom] - wtype = Dict(:left => :sint64, :right => :sint64, :top => :sint64, :bottom => :sint64) - allflds = Pair{Symbol,Union{Type,String}}[:left => Int64, :right => Int64, :top => Int64, :bottom => Int64] - meta(target, HeaderBBox, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, wtype, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:DenseInfo}) + version = PB.BufferedVector{Int32}() + timestamp = PB.BufferedVector{Int64}() + changeset = PB.BufferedVector{Int64}() + uid = PB.BufferedVector{Int32}() + user_sid = PB.BufferedVector{Int32}() + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + PB.decode!(d, wire_type, version) + elseif field_number == 2 + PB.decode!(d, wire_type, timestamp, Val{:zigzag}) + elseif field_number == 3 + PB.decode!(d, wire_type, changeset, Val{:zigzag}) + elseif field_number == 4 + PB.decode!(d, wire_type, uid, Val{:zigzag}) + elseif field_number == 5 + PB.decode!(d, wire_type, user_sid, Val{:zigzag}) + else + PB.skip(d, wire_type) end - __meta_HeaderBBox[] end + return DenseInfo(version[], timestamp[], changeset[], uid[], user_sid[]) end -# TODO which subtype of `AbstractString` is actually used ? -mutable struct HeaderBlock <: SimpleProtoType - bbox::HeaderBBox - required_features::Vector{AbstractString} - optional_features::Vector{AbstractString} - writingprogram::AbstractString - source::AbstractString - osmosis_replication_timestamp::Int64 - osmosis_replication_sequence_number::Int64 - osmosis_replication_base_url::AbstractString +function PB.encode(e::PB.AbstractProtoEncoder, x::DenseInfo) + initpos = position(e.io) + !isempty(x.version) && PB.encode(e, 1, x.version) + !isempty(x.timestamp) && PB.encode(e, 2, x.timestamp, Val{:zigzag}) + !isempty(x.changeset) && PB.encode(e, 3, x.changeset, Val{:zigzag}) + !isempty(x.uid) && PB.encode(e, 4, x.uid, Val{:zigzag}) + !isempty(x.user_sid) && PB.encode(e, 5, x.user_sid, Val{:zigzag}) + return position(e.io) - initpos +end +function PB._encoded_size(x::DenseInfo) + encoded_size = 0 + !isempty(x.version) && (encoded_size += PB._encoded_size(x.version, 1)) + !isempty(x.timestamp) && (encoded_size += PB._encoded_size(x.timestamp, 2, Val{:zigzag})) + !isempty(x.changeset) && (encoded_size += PB._encoded_size(x.changeset, 3, Val{:zigzag})) + !isempty(x.uid) && (encoded_size += PB._encoded_size(x.uid, 4, Val{:zigzag})) + !isempty(x.user_sid) && (encoded_size += PB._encoded_size(x.user_sid, 5, Val{:zigzag})) + return encoded_size +end - function HeaderBlock() - return new() - end -end # mutable struct HeaderBlock -#function ProtoBuf.clear(obj::HeaderBlock) -# if isdefined(obj, :required_features) -# empty!(obj.required_features) -# end -# if isdefined(obj, :optional_features) -# empty!(obj.optional_features) -# end -# return -#end -const __meta_HeaderBlock = Ref{ProtoMeta}() -function meta(::Type{HeaderBlock}) - ProtoBuf.metalock() do - if !isassigned(__meta_HeaderBlock) - __meta_HeaderBlock[] = target = ProtoMeta(HeaderBlock) - fnum = Int[1,4,5,16,17,32,33,34] - allflds = Pair{Symbol,Union{Type,String}}[:bbox => HeaderBBox, :required_features => Base.Vector{AbstractString}, :optional_features => Base.Vector{AbstractString}, :writingprogram => AbstractString, :source => AbstractString, :osmosis_replication_timestamp => Int64, :osmosis_replication_sequence_number => Int64, :osmosis_replication_base_url => AbstractString] - meta(target, HeaderBlock, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +struct StringTable + s::Vector{Vector{UInt8}} +end +PB.default_values(::Type{StringTable}) = (;s = Vector{Vector{UInt8}}()) +PB.field_numbers(::Type{StringTable}) = (;s = 1) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:StringTable}) + s = PB.BufferedVector{Vector{UInt8}}() + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + PB.decode!(d, s) + else + PB.skip(d, wire_type) end - __meta_HeaderBlock[] end + return StringTable(s[]) end -mutable struct StringTable <: SimpleProtoType - s::Vector{Vector{UInt8}} - function StringTable() - return new() +function PB.encode(e::PB.AbstractProtoEncoder, x::StringTable) + initpos = position(e.io) + !isempty(x.s) && PB.encode(e, 1, x.s) + return position(e.io) - initpos +end +function PB._encoded_size(x::StringTable) + encoded_size = 0 + !isempty(x.s) && (encoded_size += PB._encoded_size(x.s, 1)) + return encoded_size +end + +struct ChangeSet + id::Int64 +end +PB.default_values(::Type{ChangeSet}) = (;id = zero(Int64)) +PB.field_numbers(::Type{ChangeSet}) = (;id = 1) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:ChangeSet}) + id = zero(Int64) + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + id = PB.decode(d, Int64) + else + PB.skip(d, wire_type) + end end -end # mutable struct StringTable -#function ProtoBuf.clear(obj::StringTable) -# if isdefined(obj, :s) -# empty!(obj.s) -# end -# return -#end -const __meta_StringTable = Ref{ProtoMeta}() -function meta(::Type{StringTable}) - ProtoBuf.metalock() do - if !isassigned(__meta_StringTable) - __meta_StringTable[] = target = ProtoMeta(StringTable) - allflds = Pair{Symbol,Union{Type,String}}[:s => Base.Vector{Vector{UInt8}}] - meta(target, StringTable, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) + return ChangeSet(id) +end + +function PB.encode(e::PB.AbstractProtoEncoder, x::ChangeSet) + initpos = position(e.io) + x.id != zero(Int64) && PB.encode(e, 1, x.id) + return position(e.io) - initpos +end +function PB._encoded_size(x::ChangeSet) + encoded_size = 0 + x.id != zero(Int64) && (encoded_size += PB._encoded_size(x.id, 1)) + return encoded_size +end + +struct HeaderBBox + left::Int64 + right::Int64 + top::Int64 + bottom::Int64 +end +PB.default_values(::Type{HeaderBBox}) = (;left = zero(Int64), right = zero(Int64), top = zero(Int64), bottom = zero(Int64)) +PB.field_numbers(::Type{HeaderBBox}) = (;left = 1, right = 2, top = 3, bottom = 4) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:HeaderBBox}) + left = zero(Int64) + right = zero(Int64) + top = zero(Int64) + bottom = zero(Int64) + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + left = PB.decode(d, Int64, Val{:zigzag}) + elseif field_number == 2 + right = PB.decode(d, Int64, Val{:zigzag}) + elseif field_number == 3 + top = PB.decode(d, Int64, Val{:zigzag}) + elseif field_number == 4 + bottom = PB.decode(d, Int64, Val{:zigzag}) + else + PB.skip(d, wire_type) end - __meta_StringTable[] end + return HeaderBBox(left, right, top, bottom) end -mutable struct Info <: SimpleProtoType +function PB.encode(e::PB.AbstractProtoEncoder, x::HeaderBBox) + initpos = position(e.io) + x.left != zero(Int64) && PB.encode(e, 1, x.left, Val{:zigzag}) + x.right != zero(Int64) && PB.encode(e, 2, x.right, Val{:zigzag}) + x.top != zero(Int64) && PB.encode(e, 3, x.top, Val{:zigzag}) + x.bottom != zero(Int64) && PB.encode(e, 4, x.bottom, Val{:zigzag}) + return position(e.io) - initpos +end +function PB._encoded_size(x::HeaderBBox) + encoded_size = 0 + x.left != zero(Int64) && (encoded_size += PB._encoded_size(x.left, 1, Val{:zigzag})) + x.right != zero(Int64) && (encoded_size += PB._encoded_size(x.right, 2, Val{:zigzag})) + x.top != zero(Int64) && (encoded_size += PB._encoded_size(x.top, 3, Val{:zigzag})) + x.bottom != zero(Int64) && (encoded_size += PB._encoded_size(x.bottom, 4, Val{:zigzag})) + return encoded_size +end + +struct Info version::Int32 timestamp::Int64 changeset::Int64 uid::Int32 - user_sid::UInt32 - visible::Bool - function Info() - obj = new() - set_defaults!(obj) - return obj - end -end # mutable struct Info -function set_defaults!(obj::Info) - obj.version = Int32(-1) - return -end -const __meta_Info = Ref{ProtoMeta}() -function meta(::Type{Info}) - ProtoBuf.metalock() do - if !isassigned(__meta_Info) - __meta_Info[] = target = ProtoMeta(Info) - val = Dict{Symbol,Any}(:version => -1) - allflds = Pair{Symbol,Union{Type,String}}[:version => Int32, :timestamp => Int64, :changeset => Int64, :uid => Int32, :user_sid => UInt32, :visible => Bool] - meta(target, Info, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) + user_sid::Int32 +end +PB.default_values(::Type{Info}) = (;version = Int32(-1), timestamp = zero(Int64), changeset = zero(Int64), uid = zero(Int32), user_sid = zero(Int32)) +PB.field_numbers(::Type{Info}) = (;version = 1, timestamp = 2, changeset = 3, uid = 4, user_sid = 5) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:Info}) + version = Int32(-1) + timestamp = zero(Int64) + changeset = zero(Int64) + uid = zero(Int32) + user_sid = zero(Int32) + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + version = PB.decode(d, Int32) + elseif field_number == 2 + timestamp = PB.decode(d, Int64) + elseif field_number == 3 + changeset = PB.decode(d, Int64) + elseif field_number == 4 + uid = PB.decode(d, Int32) + elseif field_number == 5 + user_sid = PB.decode(d, Int32) + else + PB.skip(d, wire_type) end - __meta_Info[] end + return Info(version, timestamp, changeset, uid, user_sid) end -mutable struct DenseInfo <: SimpleProtoType - version::Vector{Int32} - timestamp::Vector{Int64} - changeset::Vector{Int64} - uid::Vector{Int32} - user_sid::Vector{Int32} - visible::Vector{Bool} - function DenseInfo() - return new() - end -end # mutable struct DenseInfo -const __meta_DenseInfo = Ref{ProtoMeta}() -function meta(::Type{DenseInfo}) - ProtoBuf.metalock() do - if !isassigned(__meta_DenseInfo) - __meta_DenseInfo[] = target = ProtoMeta(DenseInfo) - pack = Symbol[:version,:timestamp,:changeset,:uid,:user_sid,:visible] - wtype = Dict(:timestamp => :sint64, :changeset => :sint64, :uid => :sint32, :user_sid => :sint32) - allflds = Pair{Symbol,Union{Type,String}}[:version => Base.Vector{Int32}, :timestamp => Base.Vector{Int64}, :changeset => Base.Vector{Int64}, :uid => Base.Vector{Int32}, :user_sid => Base.Vector{Int32}, :visible => Base.Vector{Bool}] - meta(target, DenseInfo, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, pack, wtype, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +function PB.encode(e::PB.AbstractProtoEncoder, x::Info) + initpos = position(e.io) + x.version != Int32(-1) && PB.encode(e, 1, x.version) + x.timestamp != zero(Int64) && PB.encode(e, 2, x.timestamp) + x.changeset != zero(Int64) && PB.encode(e, 3, x.changeset) + x.uid != zero(Int32) && PB.encode(e, 4, x.uid) + x.user_sid != zero(Int32) && PB.encode(e, 5, x.user_sid) + return position(e.io) - initpos +end +function PB._encoded_size(x::Info) + encoded_size = 0 + x.version != Int32(-1) && (encoded_size += PB._encoded_size(x.version, 1)) + x.timestamp != zero(Int64) && (encoded_size += PB._encoded_size(x.timestamp, 2)) + x.changeset != zero(Int64) && (encoded_size += PB._encoded_size(x.changeset, 3)) + x.uid != zero(Int32) && (encoded_size += PB._encoded_size(x.uid, 4)) + x.user_sid != zero(Int32) && (encoded_size += PB._encoded_size(x.user_sid, 5)) + return encoded_size +end + +struct DenseNodes + id::Vector{Int64} + denseinfo::Union{Nothing,DenseInfo} + lat::Vector{Int64} + lon::Vector{Int64} + keys_vals::Vector{Int32} +end +PB.default_values(::Type{DenseNodes}) = (;id = Vector{Int64}(), denseinfo = nothing, lat = Vector{Int64}(), lon = Vector{Int64}(), keys_vals = Vector{Int32}()) +PB.field_numbers(::Type{DenseNodes}) = (;id = 1, denseinfo = 5, lat = 8, lon = 9, keys_vals = 10) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:DenseNodes}) + id = PB.BufferedVector{Int64}() + denseinfo = Ref{Union{Nothing,DenseInfo}}(nothing) + lat = PB.BufferedVector{Int64}() + lon = PB.BufferedVector{Int64}() + keys_vals = PB.BufferedVector{Int32}() + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + PB.decode!(d, wire_type, id, Val{:zigzag}) + elseif field_number == 5 + PB.decode!(d, denseinfo) + elseif field_number == 8 + PB.decode!(d, wire_type, lat, Val{:zigzag}) + elseif field_number == 9 + PB.decode!(d, wire_type, lon, Val{:zigzag}) + elseif field_number == 10 + PB.decode!(d, wire_type, keys_vals) + else + PB.skip(d, wire_type) end - __meta_DenseInfo[] end + return DenseNodes(id[], denseinfo[], lat[], lon[], keys_vals[]) end -mutable struct ChangeSet <: SimpleProtoType - id::Int64 - function ChangeSet() - return new() - end -end # mutable struct ChangeSet -const __meta_ChangeSet = Ref{ProtoMeta}() -function meta(::Type{ChangeSet}) - ProtoBuf.metalock() do - if !isassigned(__meta_ChangeSet) - __meta_ChangeSet[] = target = ProtoMeta(ChangeSet) - req = Symbol[:id] - allflds = Pair{Symbol,Union{Type,String}}[:id => Int64] - meta(target, ChangeSet, allflds, req, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +function PB.encode(e::PB.AbstractProtoEncoder, x::DenseNodes) + initpos = position(e.io) + !isempty(x.id) && PB.encode(e, 1, x.id, Val{:zigzag}) + !isnothing(x.denseinfo) && PB.encode(e, 5, x.denseinfo) + !isempty(x.lat) && PB.encode(e, 8, x.lat, Val{:zigzag}) + !isempty(x.lon) && PB.encode(e, 9, x.lon, Val{:zigzag}) + !isempty(x.keys_vals) && PB.encode(e, 10, x.keys_vals) + return position(e.io) - initpos +end +function PB._encoded_size(x::DenseNodes) + encoded_size = 0 + !isempty(x.id) && (encoded_size += PB._encoded_size(x.id, 1, Val{:zigzag})) + !isnothing(x.denseinfo) && (encoded_size += PB._encoded_size(x.denseinfo, 5)) + !isempty(x.lat) && (encoded_size += PB._encoded_size(x.lat, 8, Val{:zigzag})) + !isempty(x.lon) && (encoded_size += PB._encoded_size(x.lon, 9, Val{:zigzag})) + !isempty(x.keys_vals) && (encoded_size += PB._encoded_size(x.keys_vals, 10)) + return encoded_size +end + +struct HeaderBlock + bbox::Union{Nothing,HeaderBBox} + required_features::Vector{String} + optional_features::Vector{String} + writingprogram::String + source::String +end +PB.default_values(::Type{HeaderBlock}) = (;bbox = nothing, required_features = Vector{String}(), optional_features = Vector{String}(), writingprogram = "", source = "") +PB.field_numbers(::Type{HeaderBlock}) = (;bbox = 1, required_features = 4, optional_features = 5, writingprogram = 16, source = 17) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:HeaderBlock}) + bbox = Ref{Union{Nothing,HeaderBBox}}(nothing) + required_features = PB.BufferedVector{String}() + optional_features = PB.BufferedVector{String}() + writingprogram = "" + source = "" + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + PB.decode!(d, bbox) + elseif field_number == 4 + PB.decode!(d, required_features) + elseif field_number == 5 + PB.decode!(d, optional_features) + elseif field_number == 16 + writingprogram = PB.decode(d, String) + elseif field_number == 17 + source = PB.decode(d, String) + else + PB.skip(d, wire_type) end - __meta_ChangeSet[] end + return HeaderBlock(bbox[], required_features[], optional_features[], writingprogram, source) +end + +function PB.encode(e::PB.AbstractProtoEncoder, x::HeaderBlock) + initpos = position(e.io) + !isnothing(x.bbox) && PB.encode(e, 1, x.bbox) + !isempty(x.required_features) && PB.encode(e, 4, x.required_features) + !isempty(x.optional_features) && PB.encode(e, 5, x.optional_features) + !isempty(x.writingprogram) && PB.encode(e, 16, x.writingprogram) + !isempty(x.source) && PB.encode(e, 17, x.source) + return position(e.io) - initpos +end +function PB._encoded_size(x::HeaderBlock) + encoded_size = 0 + !isnothing(x.bbox) && (encoded_size += PB._encoded_size(x.bbox, 1)) + !isempty(x.required_features) && (encoded_size += PB._encoded_size(x.required_features, 4)) + !isempty(x.optional_features) && (encoded_size += PB._encoded_size(x.optional_features, 5)) + !isempty(x.writingprogram) && (encoded_size += PB._encoded_size(x.writingprogram, 16)) + !isempty(x.source) && (encoded_size += PB._encoded_size(x.source, 17)) + return encoded_size end -mutable struct Node <: SimpleProtoType +struct Relation id::Int64 keys::Vector{UInt32} vals::Vector{UInt32} - info::Info - lat::Int64 - lon::Int64 - function Node() - return new() - end -end # mutable struct Node -const __meta_Node = Ref{ProtoMeta}() -function meta(::Type{Node}) - ProtoBuf.metalock() do - if !isassigned(__meta_Node) - __meta_Node[] = target = ProtoMeta(Node) - req = Symbol[:id,:lat,:lon] - fnum = Int[1,2,3,4,8,9] - pack = Symbol[:keys,:vals] - wtype = Dict(:id => :sint64, :lat => :sint64, :lon => :sint64) - allflds = Pair{Symbol,Union{Type,String}}[:id => Int64, :keys => Base.Vector{UInt32}, :vals => Base.Vector{UInt32}, :info => Info, :lat => Int64, :lon => Int64] - meta(target, Node, allflds, req, fnum, ProtoBuf.DEF_VAL, pack, wtype, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) - end - __meta_Node[] - end + info::Union{Nothing,Info} + roles_sid::Vector{Int32} + memids::Vector{Int64} + types::Vector{var"Relation.MemberType".T} end +PB.default_values(::Type{Relation}) = (;id = zero(Int64), keys = Vector{UInt32}(), vals = Vector{UInt32}(), info = nothing, roles_sid = Vector{Int32}(), memids = Vector{Int64}(), types = Vector{var"Relation.MemberType".T}()) +PB.field_numbers(::Type{Relation}) = (;id = 1, keys = 2, vals = 3, info = 4, roles_sid = 8, memids = 9, types = 10) -mutable struct DenseNodes <: SimpleProtoType - id::Vector{Int64} - denseinfo::DenseInfo - lat::Vector{Int64} - lon::Vector{Int64} - keys_vals::Vector{Int32} - function DenseNodes() - return new() - end -end # mutable struct DenseNodes -const __meta_DenseNodes = Ref{ProtoMeta}() -function meta(::Type{DenseNodes}) - ProtoBuf.metalock() do - if !isassigned(__meta_DenseNodes) - __meta_DenseNodes[] = target = ProtoMeta(DenseNodes) - fnum = Int[1,5,8,9,10] - pack = Symbol[:id,:lat,:lon,:keys_vals] - wtype = Dict(:id => :sint64, :lat => :sint64, :lon => :sint64) - allflds = Pair{Symbol,Union{Type,String}}[:id => Base.Vector{Int64}, :denseinfo => DenseInfo, :lat => Base.Vector{Int64}, :lon => Base.Vector{Int64}, :keys_vals => Base.Vector{Int32}] - meta(target, DenseNodes, allflds, ProtoBuf.DEF_REQ, fnum, ProtoBuf.DEF_VAL, pack, wtype, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:Relation}) + id = zero(Int64) + keys = PB.BufferedVector{UInt32}() + vals = PB.BufferedVector{UInt32}() + info = Ref{Union{Nothing,Info}}(nothing) + roles_sid = PB.BufferedVector{Int32}() + memids = PB.BufferedVector{Int64}() + types = PB.BufferedVector{var"Relation.MemberType".T}() + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + id = PB.decode(d, Int64) + elseif field_number == 2 + PB.decode!(d, wire_type, keys) + elseif field_number == 3 + PB.decode!(d, wire_type, vals) + elseif field_number == 4 + PB.decode!(d, info) + elseif field_number == 8 + PB.decode!(d, wire_type, roles_sid) + elseif field_number == 9 + PB.decode!(d, wire_type, memids, Val{:zigzag}) + elseif field_number == 10 + PB.decode!(d, wire_type, types) + else + PB.skip(d, wire_type) end - __meta_DenseNodes[] end + return Relation(id, keys[], vals[], info[], roles_sid[], memids[], types[]) end -mutable struct Way <: SimpleProtoType +function PB.encode(e::PB.AbstractProtoEncoder, x::Relation) + initpos = position(e.io) + x.id != zero(Int64) && PB.encode(e, 1, x.id) + !isempty(x.keys) && PB.encode(e, 2, x.keys) + !isempty(x.vals) && PB.encode(e, 3, x.vals) + !isnothing(x.info) && PB.encode(e, 4, x.info) + !isempty(x.roles_sid) && PB.encode(e, 8, x.roles_sid) + !isempty(x.memids) && PB.encode(e, 9, x.memids, Val{:zigzag}) + !isempty(x.types) && PB.encode(e, 10, x.types) + return position(e.io) - initpos +end +function PB._encoded_size(x::Relation) + encoded_size = 0 + x.id != zero(Int64) && (encoded_size += PB._encoded_size(x.id, 1)) + !isempty(x.keys) && (encoded_size += PB._encoded_size(x.keys, 2)) + !isempty(x.vals) && (encoded_size += PB._encoded_size(x.vals, 3)) + !isnothing(x.info) && (encoded_size += PB._encoded_size(x.info, 4)) + !isempty(x.roles_sid) && (encoded_size += PB._encoded_size(x.roles_sid, 8)) + !isempty(x.memids) && (encoded_size += PB._encoded_size(x.memids, 9, Val{:zigzag})) + !isempty(x.types) && (encoded_size += PB._encoded_size(x.types, 10)) + return encoded_size +end + +struct Node id::Int64 keys::Vector{UInt32} vals::Vector{UInt32} - info::Info - refs::Vector{Int64} - lat::Vector{Int64} - lon::Vector{Int64} - function Way() - return new() - end -end # mutable struct Way -#function set_defaults!(obj::Way) -# obj.keys = UInt32[] -# obj.vals = UInt32[] -#end -const __meta_Way = Ref{ProtoMeta}() -function meta(::Type{Way}) - ProtoBuf.metalock() do - if !isassigned(__meta_Way) - __meta_Way[] = target = ProtoMeta(Way) - req = Symbol[:id] - fnum = Int[1,2,3,4,8,9,10] - pack = Symbol[:keys,:vals,:refs,:lat,:lon] - wtype = Dict(:refs => :sint64, :lat => :sint64, :lon => :sint64) - allflds = Pair{Symbol,Union{Type,String}}[:id => Int64, :keys => Base.Vector{UInt32}, :vals => Base.Vector{UInt32}, :info => Info, :refs => Base.Vector{Int64}, :lat => Base.Vector{Int64}, :lon => Base.Vector{Int64}] - meta(target, Way, allflds, req, fnum, ProtoBuf.DEF_VAL, pack, wtype, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) + info::Union{Nothing,Info} + lat::Int64 + lon::Int64 +end +PB.default_values(::Type{Node}) = (;id = zero(Int64), keys = Vector{UInt32}(), vals = Vector{UInt32}(), info = nothing, lat = zero(Int64), lon = zero(Int64)) +PB.field_numbers(::Type{Node}) = (;id = 1, keys = 2, vals = 3, info = 4, lat = 8, lon = 9) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:Node}) + id = zero(Int64) + keys = PB.BufferedVector{UInt32}() + vals = PB.BufferedVector{UInt32}() + info = Ref{Union{Nothing,Info}}(nothing) + lat = zero(Int64) + lon = zero(Int64) + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + id = PB.decode(d, Int64, Val{:zigzag}) + elseif field_number == 2 + PB.decode!(d, wire_type, keys) + elseif field_number == 3 + PB.decode!(d, wire_type, vals) + elseif field_number == 4 + PB.decode!(d, info) + elseif field_number == 8 + lat = PB.decode(d, Int64, Val{:zigzag}) + elseif field_number == 9 + lon = PB.decode(d, Int64, Val{:zigzag}) + else + PB.skip(d, wire_type) end - __meta_Way[] end + return Node(id, keys[], vals[], info[], lat, lon) end -const Relation_MemberType = ["NODE", "WAY", "RELATION"] +function PB.encode(e::PB.AbstractProtoEncoder, x::Node) + initpos = position(e.io) + x.id != zero(Int64) && PB.encode(e, 1, x.id, Val{:zigzag}) + !isempty(x.keys) && PB.encode(e, 2, x.keys) + !isempty(x.vals) && PB.encode(e, 3, x.vals) + !isnothing(x.info) && PB.encode(e, 4, x.info) + x.lat != zero(Int64) && PB.encode(e, 8, x.lat, Val{:zigzag}) + x.lon != zero(Int64) && PB.encode(e, 9, x.lon, Val{:zigzag}) + return position(e.io) - initpos +end +function PB._encoded_size(x::Node) + encoded_size = 0 + x.id != zero(Int64) && (encoded_size += PB._encoded_size(x.id, 1, Val{:zigzag})) + !isempty(x.keys) && (encoded_size += PB._encoded_size(x.keys, 2)) + !isempty(x.vals) && (encoded_size += PB._encoded_size(x.vals, 3)) + !isnothing(x.info) && (encoded_size += PB._encoded_size(x.info, 4)) + x.lat != zero(Int64) && (encoded_size += PB._encoded_size(x.lat, 8, Val{:zigzag})) + x.lon != zero(Int64) && (encoded_size += PB._encoded_size(x.lon, 9, Val{:zigzag})) + return encoded_size +end -mutable struct Relation <: SimpleProtoType +struct Way id::Int64 keys::Vector{UInt32} vals::Vector{UInt32} - info::Info - roles_sid::Vector{Int32} - memids::Vector{Int64} - types::Vector{Int32} - function Relation() - return new() - end -end # mutable struct Relation - -const __meta_Relation = Ref{ProtoMeta}() -function meta(::Type{Relation}) - ProtoBuf.metalock() do - if !isassigned(__meta_Relation) - __meta_Relation[] = target = ProtoMeta(Relation) - req = Symbol[:id] - fnum = Int[1,2,3,4,8,9,10] - pack = Symbol[:keys,:vals,:roles_sid,:memids,:types] - wtype = Dict(:memids => :sint64) - allflds = Pair{Symbol,Union{Type,String}}[:id => Int64, :keys => Base.Vector{UInt32}, :vals => Base.Vector{UInt32}, :info => Info, :roles_sid => Base.Vector{Int32}, :memids => Base.Vector{Int64}, :types => Base.Vector{Int32}] - meta(target, Relation, allflds, req, fnum, ProtoBuf.DEF_VAL, pack, wtype, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) + info::Union{Nothing,Info} + refs::Vector{Int64} +end +PB.default_values(::Type{Way}) = (;id = zero(Int64), keys = Vector{UInt32}(), vals = Vector{UInt32}(), info = nothing, refs = Vector{Int64}()) +PB.field_numbers(::Type{Way}) = (;id = 1, keys = 2, vals = 3, info = 4, refs = 8) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:Way}) + id = zero(Int64) + keys = PB.BufferedVector{UInt32}() + vals = PB.BufferedVector{UInt32}() + info = Ref{Union{Nothing,Info}}(nothing) + refs = PB.BufferedVector{Int64}() + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + id = PB.decode(d, Int64) + elseif field_number == 2 + PB.decode!(d, wire_type, keys) + elseif field_number == 3 + PB.decode!(d, wire_type, vals) + elseif field_number == 4 + PB.decode!(d, info) + elseif field_number == 8 + PB.decode!(d, wire_type, refs, Val{:zigzag}) + else + PB.skip(d, wire_type) end - __meta_Relation[] end + return Way(id, keys[], vals[], info[], refs[]) end -mutable struct PrimitiveGroup <: SimpleProtoType +function PB.encode(e::PB.AbstractProtoEncoder, x::Way) + initpos = position(e.io) + x.id != zero(Int64) && PB.encode(e, 1, x.id) + !isempty(x.keys) && PB.encode(e, 2, x.keys) + !isempty(x.vals) && PB.encode(e, 3, x.vals) + !isnothing(x.info) && PB.encode(e, 4, x.info) + !isempty(x.refs) && PB.encode(e, 8, x.refs, Val{:zigzag}) + return position(e.io) - initpos +end +function PB._encoded_size(x::Way) + encoded_size = 0 + x.id != zero(Int64) && (encoded_size += PB._encoded_size(x.id, 1)) + !isempty(x.keys) && (encoded_size += PB._encoded_size(x.keys, 2)) + !isempty(x.vals) && (encoded_size += PB._encoded_size(x.vals, 3)) + !isnothing(x.info) && (encoded_size += PB._encoded_size(x.info, 4)) + !isempty(x.refs) && (encoded_size += PB._encoded_size(x.refs, 8, Val{:zigzag})) + return encoded_size +end + +struct PrimitiveGroup nodes::Vector{Node} - dense::DenseNodes + dense::Union{Nothing,DenseNodes} ways::Vector{Way} relations::Vector{Relation} changesets::Vector{ChangeSet} - function PrimitiveGroup() - return new() - end -end # mutable struct PrimitiveGroup -const __meta_PrimitiveGroup = Ref{ProtoMeta}() -function meta(::Type{PrimitiveGroup}) - ProtoBuf.metalock() do - if !isassigned(__meta_PrimitiveGroup) - __meta_PrimitiveGroup[] = target = ProtoMeta(PrimitiveGroup) - allflds = Pair{Symbol,Union{Type,String}}[:nodes => Base.Vector{Node}, :dense => DenseNodes, :ways => Base.Vector{Way}, :relations => Base.Vector{Relation}, :changesets => Base.Vector{ChangeSet}] - meta(target, PrimitiveGroup, allflds, ProtoBuf.DEF_REQ, ProtoBuf.DEF_FNUM, ProtoBuf.DEF_VAL, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +end +PB.default_values(::Type{PrimitiveGroup}) = (;nodes = Vector{Node}(), dense = nothing, ways = Vector{Way}(), relations = Vector{Relation}(), changesets = Vector{ChangeSet}()) +PB.field_numbers(::Type{PrimitiveGroup}) = (;nodes = 1, dense = 2, ways = 3, relations = 4, changesets = 5) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:PrimitiveGroup}) + nodes = PB.BufferedVector{Node}() + dense = Ref{Union{Nothing,DenseNodes}}(nothing) + ways = PB.BufferedVector{Way}() + relations = PB.BufferedVector{Relation}() + changesets = PB.BufferedVector{ChangeSet}() + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + PB.decode!(d, nodes) + elseif field_number == 2 + PB.decode!(d, dense) + elseif field_number == 3 + PB.decode!(d, ways) + elseif field_number == 4 + PB.decode!(d, relations) + elseif field_number == 5 + PB.decode!(d, changesets) + else + PB.skip(d, wire_type) end - __meta_PrimitiveGroup[] end + return PrimitiveGroup(nodes[], dense[], ways[], relations[], changesets[]) +end + +function PB.encode(e::PB.AbstractProtoEncoder, x::PrimitiveGroup) + initpos = position(e.io) + !isempty(x.nodes) && PB.encode(e, 1, x.nodes) + !isnothing(x.dense) && PB.encode(e, 2, x.dense) + !isempty(x.ways) && PB.encode(e, 3, x.ways) + !isempty(x.relations) && PB.encode(e, 4, x.relations) + !isempty(x.changesets) && PB.encode(e, 5, x.changesets) + return position(e.io) - initpos +end +function PB._encoded_size(x::PrimitiveGroup) + encoded_size = 0 + !isempty(x.nodes) && (encoded_size += PB._encoded_size(x.nodes, 1)) + !isnothing(x.dense) && (encoded_size += PB._encoded_size(x.dense, 2)) + !isempty(x.ways) && (encoded_size += PB._encoded_size(x.ways, 3)) + !isempty(x.relations) && (encoded_size += PB._encoded_size(x.relations, 4)) + !isempty(x.changesets) && (encoded_size += PB._encoded_size(x.changesets, 5)) + return encoded_size end -mutable struct PrimitiveBlock <: SimpleProtoType +struct PrimitiveBlock stringtable::StringTable primitivegroup::Vector{PrimitiveGroup} granularity::Int32 lat_offset::Int64 lon_offset::Int64 date_granularity::Int32 - function PrimitiveBlock() - obj = new() - set_defaults!(obj) - return obj - end -end # mutable struct PrimitiveBlock -function set_defaults!(obj::PrimitiveBlock) - obj.granularity = Int32(100) - obj.lat_offset = 0 - obj.lon_offset = 0 - obj.date_granularity = Int32(1000) - return -end -#function ProtoBuf.clear(obj::PrimitiveBlock) -# if isdefined(obj, :stringtable) -# ProtoBuf.clear(obj.stringtable) -# end -# if isdefined(obj, :primitivegroup) -# empty!(obj.primitivegroup) -# end -# return -#end -const __meta_PrimitiveBlock = Ref{ProtoMeta}() -function meta(::Type{PrimitiveBlock}) - ProtoBuf.metalock() do - if !isassigned(__meta_PrimitiveBlock) - __meta_PrimitiveBlock[] = target = ProtoMeta(PrimitiveBlock) - req = Symbol[:stringtable] - val = Dict{Symbol,Any}(:granularity => 100, :lat_offset => 0, :lon_offset => 0, :date_granularity => 1000) - fnum = Int[1,2,17,19,20,18] - allflds = Pair{Symbol,Union{Type,String}}[:stringtable => StringTable, :primitivegroup => Base.Vector{PrimitiveGroup}, :granularity => Int32, :lat_offset => Int64, :lon_offset => Int64, :date_granularity => Int32] - meta(target, PrimitiveBlock, allflds, req, fnum, val, ProtoBuf.DEF_PACK, ProtoBuf.DEF_WTYPES, ProtoBuf.DEF_ONEOFS, ProtoBuf.DEF_ONEOF_NAMES) +end +PB.default_values(::Type{PrimitiveBlock}) = (;stringtable, primitivegroup = Vector{PrimitiveGroup}(), granularity = Int32(100), lat_offset = Int64(0), lon_offset = Int64(0), date_granularity = Int32(1000)) +PB.field_numbers(::Type{PrimitiveBlock}) = (;stringtable = 1, primitivegroup = 2, granularity = 17, lat_offset = 19, lon_offset = 20, date_granularity = 18) + +function PB.decode(d::PB.AbstractProtoDecoder, ::Type{<:PrimitiveBlock}) + stringtable = Ref{StringTable}() + primitivegroup = PB.BufferedVector{PrimitiveGroup}() + granularity = Int32(100) + lat_offset = Int64(0) + lon_offset = Int64(0) + date_granularity = Int32(1000) + while !PB.message_done(d) + field_number, wire_type = PB.decode_tag(d) + if field_number == 1 + PB.decode!(d, stringtable) + elseif field_number == 2 + PB.decode!(d, primitivegroup) + elseif field_number == 17 + granularity = PB.decode(d, Int32) + elseif field_number == 19 + lat_offset = PB.decode(d, Int64) + elseif field_number == 20 + lon_offset = PB.decode(d, Int64) + elseif field_number == 18 + date_granularity = PB.decode(d, Int32) + else + PB.skip(d, wire_type) end - __meta_PrimitiveBlock[] end + return PrimitiveBlock(stringtable[], primitivegroup[], granularity, lat_offset, lon_offset, date_granularity) end -export HeaderBlock, HeaderBBox, PrimitiveBlock, PrimitiveGroup, StringTable, Info, DenseInfo, ChangeSet, Node, DenseNodes, Way, Relation_MemberType, Relation +function PB.encode(e::PB.AbstractProtoEncoder, x::PrimitiveBlock) + initpos = position(e.io) + !isnothing(x.stringtable) && PB.encode(e, 1, x.stringtable) + !isempty(x.primitivegroup) && PB.encode(e, 2, x.primitivegroup) + x.granularity != Int32(100) && PB.encode(e, 17, x.granularity) + x.lat_offset != Int64(0) && PB.encode(e, 19, x.lat_offset) + x.lon_offset != Int64(0) && PB.encode(e, 20, x.lon_offset) + x.date_granularity != Int32(1000) && PB.encode(e, 18, x.date_granularity) + return position(e.io) - initpos +end +function PB._encoded_size(x::PrimitiveBlock) + encoded_size = 0 + !isnothing(x.stringtable) && (encoded_size += PB._encoded_size(x.stringtable, 1)) + !isempty(x.primitivegroup) && (encoded_size += PB._encoded_size(x.primitivegroup, 2)) + x.granularity != Int32(100) && (encoded_size += PB._encoded_size(x.granularity, 17)) + x.lat_offset != Int64(0) && (encoded_size += PB._encoded_size(x.lat_offset, 19)) + x.lon_offset != Int64(0) && (encoded_size += PB._encoded_size(x.lon_offset, 20)) + x.date_granularity != Int32(1000) && (encoded_size += PB._encoded_size(x.date_granularity, 18)) + return encoded_size +end diff --git a/src/pbf.jl b/src/pbf.jl index cf8df3f..f965e50 100644 --- a/src/pbf.jl +++ b/src/pbf.jl @@ -1,23 +1,28 @@ include("OSMPBF.jl") -using ProtoBuf, CodecZlib +import CodecZlib const BLOCK = Dict( - "OSMHeader" => OSMPBF.HeaderBlock(), - "OSMData" => OSMPBF.PrimitiveBlock(), + "OSMHeader" => OSMPBF.HeaderBlock, + "OSMData" => OSMPBF.PrimitiveBlock, ) +function _decode(str, ::Type{T}) where {T} + io = IOBuffer(str) + d = OSMPBF.PB.ProtoDecoder(io) + return OSMPBF.PB.decode(d, T) +end + function parseblob(io::IO) len = ntoh(read(io, Int32)) h = read(io, len) - bh = readproto(IOBuffer(h), OSMPBF.BlobHeader()) - blob_buf = IOBuffer(read(io, bh.datasize)) - b = readproto(blob_buf, OSMPBF.Blob()) - ok = transcode(ZlibDecompressor, b.zlib_data) + bh = _decode(h, OSMPBF.BlockHeader) + b = _decode(read(io, bh.datasize), OSMPBF.Blob) + ok = CodecZlib.transcode(CodecZlib.ZlibDecompressor, b.zlib_data) if length(ok) != b.raw_size @warn("Uncompressed size $(length(ok)) bytes does not match $(b.raw_size).") end - readproto(IOBuffer(ok), BLOCK[bh._type]) + return _decode(ok, BLOCK[bh.var"#type"]) end function process_block(osm::OSMData, block::OSMPBF.HeaderBlock) @@ -35,6 +40,8 @@ function tag(osm, element, table, key_id, value_id) tag(osm, element, table[key_id + 1], table[value_id + 1]) end +function process_elements(::OSMData, ::Nothing, _, _, _, _) end + function process_elements(osm::OSMData, nodes::OSMPBF.DenseNodes, table, lat_offset, lon_offset, granularity) ids = nodes.id cumsum!(ids, ids)