Пример #1
0
        /// <summary>
        /// Converts a PBF way into an OsmSharp-way.
        /// </summary>
        public static OsmSharp.Way DecodeWay(PrimitiveBlock block, OsmSharp.IO.PBF.Way pbfWay)
        {
            var way = new OsmSharp.Way();

            Encoder.DecodeWay(block, pbfWay, way);
            return(way);
        }
Пример #2
0
        /// <summary>
        /// Encodes an OsmSharp-node into a PBF-node.
        /// </summary>
        public static OsmSharp.IO.PBF.Node EncodeNode(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, OsmSharp.Node node)
        {
            var pbfNode = new OsmSharp.IO.PBF.Node();

            Encoder.EncodeNode(block, reverseStringTable, pbfNode, node);
            return(pbfNode);
        }
Пример #3
0
        /// <summary>
        /// Converts a PBF-way into an OsmSharp-way.
        /// </summary>
        public static void DecodeWay(PrimitiveBlock block, OsmSharp.IO.PBF.Way pbfWay, OsmSharp.Way way)
        {
            // make sure old data is gone.
            if (way.Nodes != null &&
                way.Nodes.Length > 0)
            { // clear nodes list.
                way.Nodes = new long[pbfWay.refs.Count];
            }
            if (way.Tags != null)
            { // clear the tags collection.
                way.Tags.Clear();
            }
            if (way.Nodes == null)
            { // create nodes list.
                way.Nodes = new long[pbfWay.refs.Count];
            }
            if (way.Tags == null)
            { // create tags collection.
                way.Tags = new TagsCollection(pbfWay.keys.Count);
            }

            // set new stuff.
            way.Id = pbfWay.id;
            if (pbfWay.refs.Count > 0)
            { // fill nodes-list.
                long nodeId = 0;
                for (int i = 0; i < pbfWay.refs.Count; i++)
                {
                    nodeId       = nodeId + pbfWay.refs[i];
                    way.Nodes[i] = nodeId;
                }
            }
            if (pbfWay.keys.Count > 0)
            {
                for (var i = 0; i < pbfWay.keys.Count; i++)
                {
                    var key   = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfWay.keys[i]]);
                    var value = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfWay.vals[i]]);
                    if (!way.Tags.TryAdd(key, value))
                    {
                        // Addition of the tag failed
                        Logger.Log("invalid tag", TraceEventType.Error,
                                   $"Could not add tag `{key}={value}` to the tagscollection of osm.org/way/{way.Id} - possible duplicate keys?");
                    }
                }
            }
            if (pbfWay.info != null)
            { // add the metadata if any.
                way.ChangeSetId = pbfWay.info.changeset;
                way.TimeStamp   = Encoder.DecodeTimestamp(pbfWay.info.timestamp, block.date_granularity);
                way.UserId      = pbfWay.info.uid;
                way.UserName    = null;
                if (block.stringtable != null)
                {
                    way.UserName = System.Text.Encoding.UTF8.GetString(block.stringtable.s[pbfWay.info.user_sid]);
                }
                way.Version = pbfWay.info.version;
            }
            way.Visible = true;
        }
Пример #4
0
        /// <summary>
        /// Encodes a string.
        /// </summary>
        /// <returns></returns>
        public static int EncodeString(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, string value)
        {
            if (value == null)
            {
                return(0);
            }

            if (block.stringtable == null)
            {
                block.stringtable = new StringTable();
                block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes(string.Empty));
                reverseStringTable.Add(string.Empty, 0);
            }

            int id;

            if (reverseStringTable.TryGetValue(value, out id))
            {
                return(id);
            }

            block.stringtable.s.Add(System.Text.Encoding.UTF8.GetBytes(value));
            reverseStringTable.Add(value, block.stringtable.s.Count - 1);
            return(block.stringtable.s.Count - 1);
        }
Пример #5
0
        /// <summary>
        /// Converts the PBF node into an OsmSharp-node.
        /// </summary>
        public static OsmSharp.Node DecodeNode(PrimitiveBlock block, OsmSharp.IO.PBF.Node pbfNode)
        {
            var node = new OsmSharp.Node();

            Encoder.DecodeNode(block, pbfNode, node);
            return(node);
        }
Пример #6
0
        /// <summary>
        /// Converts a PBF way into an OsmSharp-relation.
        /// </summary>
        public static OsmSharp.Relation DecodeRelation(PrimitiveBlock block, OsmSharp.IO.PBF.Relation pbfRelation)
        {
            var relation = new OsmSharp.Relation();

            Encoder.DecodeRelation(block, pbfRelation, relation);
            return(relation);
        }
Пример #7
0
        /// <summary>
        /// Encodes an OsmSharp-node into a PBF-node.
        /// </summary>
        public static OsmSharp.IO.PBF.Node EncodeNode(PrimitiveBlock block, Dictionary <string, int> reverseStringTable,
                                                      OsmSharp.IO.PBF.Node pbfNode, OsmSharp.Node node)
        {
            pbfNode.id           = node.Id.Value;
            pbfNode.info         = new Info();
            pbfNode.info.version = 0;
            if (node.ChangeSetId.HasValue)
            {
                pbfNode.info.changeset = node.ChangeSetId.Value;
            }
            else
            {
                pbfNode.info.changeset = 0;
            }
            if (node.TimeStamp.HasValue)
            {
                pbfNode.info.timestamp = Encoder.EncodeTimestamp(node.TimeStamp.Value, block.date_granularity);
            }
            else
            {
                pbfNode.info.timestamp = 0;
            }
            if (node.UserId.HasValue)
            {
                pbfNode.info.uid = (int)node.UserId.Value;
            }
            else
            {
                pbfNode.info.uid = 0;
            }
            pbfNode.info.user_sid = Encoder.EncodeString(block, reverseStringTable, node.UserName);
            if (node.Version.HasValue)
            {
                pbfNode.info.version = (int)node.Version.Value;
            }
            else
            {
                pbfNode.info.version = 0;
            }
            pbfNode.lat = Encoder.EncodeLatLon(node.Latitude.Value, block.lat_offset, block.granularity);
            pbfNode.lon = Encoder.EncodeLatLon(node.Longitude.Value, block.lon_offset, block.granularity);

            if (node.Tags != null)
            {
                foreach (var tag in node.Tags)
                {
                    pbfNode.keys.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Key));
                    pbfNode.vals.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Value));
                }
            }
            else
            {
                pbfNode.keys.Clear();
                pbfNode.vals.Clear();
            }
            return(pbfNode);
        }
Пример #8
0
        /// <summary>
        /// Writes one PBF primitive block.
        /// </summary>
        /// <param name="block">The block to write.</param>
        public void ReadAll(PrimitiveBlock block)
        {
            // check parameters.
            if (block == null)
            {
                throw new ArgumentNullException("block");
            }

            // TODO: all the important stuff!
        }
Пример #9
0
        /// <summary>
        /// Encodes an OsmSharp-way into a PBF-way.
        /// </summary>
        public static OsmSharp.IO.PBF.Way EncodeWay(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, OsmSharp.Way way)
        {
            var pbfWay = new OsmSharp.IO.PBF.Way();

            pbfWay.id   = way.Id.Value;
            pbfWay.info = new Info();
            if (way.ChangeSetId.HasValue)
            {
                pbfWay.info.changeset = way.ChangeSetId.Value;
            }
            if (way.TimeStamp.HasValue)
            {
                pbfWay.info.timestamp = Encoder.EncodeTimestamp(way.TimeStamp.Value, block.date_granularity);
            }
            if (way.UserId.HasValue)
            {
                pbfWay.info.uid = (int)way.UserId.Value;
            }
            pbfWay.info.user_sid = Encoder.EncodeString(block, reverseStringTable, way.UserName);
            pbfWay.info.version  = 0;
            if (way.Version.HasValue)
            {
                pbfWay.info.version = (int)way.Version.Value;
            }

            if (way.Tags != null)
            {
                foreach (var tag in way.Tags)
                {
                    pbfWay.keys.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Key));
                    pbfWay.vals.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Value));
                }
            }

            if (way.Nodes != null &&
                way.Nodes.Length > 0)
            {
                pbfWay.refs.Add(way.Nodes[0]);
                for (var i = 1; i < way.Nodes.Length; i++)
                {
                    pbfWay.refs.Add(way.Nodes[i] - way.Nodes[i - 1]);
                }
            }
            return(pbfWay);
        }
Пример #10
0
        /// <summary>
        /// Converts the PBF node into an OsmSharp-node.
        /// </summary>
        /// <returns></returns>
        public static OsmSharp.Node DecodeNode(PrimitiveBlock block, OsmSharp.IO.PBF.Node pbfNode, OsmSharp.Node node)
        {
            // clear old data.
            if (node.Tags != null)
            { // clear tags.
                node.Tags.Clear();
            }
            if (node.Tags == null)
            { // create tags collection.
                node.Tags = new TagsCollection(0);
            }

            // set new stuff.
            node.ChangeSetId = pbfNode.info.changeset;
            node.Id          = pbfNode.id;
            node.Latitude    = Encoder.DecodeLatLon(pbfNode.lat, block.lat_offset, block.granularity);
            node.Longitude   = Encoder.DecodeLatLon(pbfNode.lon, block.lon_offset, block.granularity);
            for (var i = 0; i < pbfNode.keys.Count; i++)
            {
                var key   = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.keys[i]]);
                var value = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.vals[i]]);
                if (!node.Tags.TryAdd(key, value))
                {
                    // Addition of the tag failed
                    Logger.Log("invalid tag", TraceEventType.Error,
                               $"Could not add tag `{key}={value}` to the tagscollection of osm.org/node/{node.Id} - possible duplicate keys?");
                }
            }
            if (pbfNode.info != null)
            { // add the metadata if any.
                node.TimeStamp = Encoder.DecodeTimestamp(pbfNode.info.timestamp, block.date_granularity);
                node.Visible   = true;
                node.Version   = pbfNode.info.version;
                node.UserId    = pbfNode.info.uid;
                node.UserName  = null;
                if (block.stringtable != null)
                {
                    node.UserName = System.Text.Encoding.UTF8.GetString(block.stringtable.s[pbfNode.info.user_sid]);
                }
            }
            node.Visible = true;

            return(node);
        }
Пример #11
0
        private static void EncodeDenseNode(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, DenseNodes groupDense, OsmSharp.Node current, OsmSharp.Node previous)
        {
            groupDense.id.Add(current.Id.Value - previous.Id.Value);
            var currentLat  = Encoder.EncodeLatLon(current.Latitude.Value, block.lat_offset, block.granularity);
            var currentLon  = Encoder.EncodeLatLon(current.Longitude.Value, block.lon_offset, block.granularity);
            var previousLat = Encoder.EncodeLatLon(previous.Latitude.Value, block.lat_offset, block.granularity);
            var previousLon = Encoder.EncodeLatLon(previous.Longitude.Value, block.lon_offset, block.granularity);
            // Note that the offsets are actually cancelled out by the subtraction below
            // LatDiff equals (current.Latitude - previous.Latitude) * 100000000 / granularity
            var latDiff = currentLat - previousLat;
            var lonDiff = currentLon - previousLon;

            groupDense.lat.Add(latDiff);
            groupDense.lon.Add(lonDiff);

            if (current.Tags != null)
            {
                foreach (var nodeTag in current.Tags)
                {
                    groupDense.keys_vals.Add(Encoder.EncodeString(block, reverseStringTable, nodeTag.Key));
                    groupDense.keys_vals.Add(Encoder.EncodeString(block, reverseStringTable, nodeTag.Value));
                }
                groupDense.keys_vals.Add(0);
            }

            if (groupDense.denseinfo != null)
            {
                groupDense.denseinfo.changeset.Add(current.ChangeSetId.Value - previous.ChangeSetId.Value);
                var currentTimeStamp  = Encoder.EncodeTimestamp(current.TimeStamp.Value, block.date_granularity);
                var previousTimeStamp = previous.TimeStamp == null
                    ? 0
                    : Encoder.EncodeTimestamp(previous.TimeStamp.Value, block.date_granularity);
                groupDense.denseinfo.timestamp.Add(currentTimeStamp - previousTimeStamp);
                groupDense.denseinfo.uid.Add((int)(current.UserId.Value - previous.UserId.Value));
                groupDense.denseinfo.version.Add((int)(current.Version.Value - previous.Version.Value));
                var previousUserNameId = previous.UserName == null
                    ? 0
                    : Encoder.EncodeString(block, reverseStringTable, previous.UserName);
                var currentUserNameId = Encoder.EncodeString(block, reverseStringTable, current.UserName);
                groupDense.denseinfo.user_sid.Add(currentUserNameId - previousUserNameId);
            }
        }
Пример #12
0
        /// <summary>
        /// Converts the PBF node into an OsmSharp-node.
        /// </summary>
        /// <returns></returns>
        public static OsmSharp.Node DecodeNode(PrimitiveBlock block, OsmSharp.IO.PBF.Node pbfNode, OsmSharp.Node node)
        {
            // clear old data.
            if (node.Tags != null)
            { // clear tags.
                node.Tags.Clear();
            }
            if (node.Tags == null)
            { // create tags collection.
                node.Tags = new TagsCollection();
            }

            // set new stuff.
            node.ChangeSetId = pbfNode.info.changeset;
            node.Id          = pbfNode.id;
            node.Latitude    = Encoder.DecodeLatLon(pbfNode.lat, block.lat_offset, block.granularity);
            node.Longitude   = Encoder.DecodeLatLon(pbfNode.lon, block.lon_offset, block.granularity);
            for (var i = 0; i < pbfNode.keys.Count; i++)
            {
                node.Tags.Add(new Tag()
                {
                    Key   = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.keys[i]]),
                    Value = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfNode.vals[i]])
                });
            }
            if (pbfNode.info != null)
            { // add the metadata if any.
                node.TimeStamp = Encoder.DecodeTimestamp(pbfNode.info.timestamp, block.date_granularity);
                node.Visible   = true;
                node.Version   = pbfNode.info.version;
                node.UserId    = pbfNode.info.uid;
                node.UserName  = null;
                if (block.stringtable != null)
                {
                    node.UserName = System.Text.Encoding.UTF8.GetString(block.stringtable.s[pbfNode.info.user_sid]);
                }
            }
            node.Visible = true;

            return(node);
        }
Пример #13
0
        /// <summary>
        /// Converts a PBF way into an OsmSharp-relation.
        /// </summary>
        public static OsmSharp.Relation DecodeRelation(PrimitiveBlock block, OsmSharp.IO.PBF.Relation pbfRelation,
                                                       OsmSharp.Relation relation)
        {
            // make sure old data is gone.
            if (relation.Members != null &&
                relation.Members.Length > 0)
            { // clear members.
                relation.Members = new RelationMember[pbfRelation.memids.Count];
            }
            if (relation.Tags != null)
            { // clear the tags collection.
                relation.Tags.Clear();
            }
            if (relation.Members == null)
            { // clear members.
                relation.Members = new RelationMember[pbfRelation.memids.Count];
            }
            if (relation.Tags == null)
            { // create tags collection.
                relation.Tags = new TagsCollection(pbfRelation.keys.Count);
            }

            // add nex stuff.
            relation.Id = pbfRelation.id;
            long memberId = 0;

            for (var i = 0; i < pbfRelation.types.Count; i++)
            {
                memberId = memberId + pbfRelation.memids[i];
                var role = System.Text.Encoding.UTF8.GetString(
                    block.stringtable.s[pbfRelation.roles_sid[i]]);

                var member = new OsmSharp.RelationMember();
                member.Id   = memberId;
                member.Role = role;
                switch (pbfRelation.types[i])
                {
                case Relation.MemberType.NODE:
                    member.Type = OsmSharp.OsmGeoType.Node;
                    break;

                case Relation.MemberType.WAY:
                    member.Type = OsmSharp.OsmGeoType.Way;
                    break;

                case Relation.MemberType.RELATION:
                    member.Type = OsmSharp.OsmGeoType.Relation;
                    break;
                }

                relation.Members[i] = member;
            }
            for (int i = 0; i < pbfRelation.keys.Count; i++)
            {
                string key   = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfRelation.keys[i]]);
                string value = System.Text.Encoding.UTF8.GetString(block.stringtable.s[(int)pbfRelation.vals[i]]);

                relation.Tags.Add(new Tag(key, value));
            }
            if (pbfRelation.info != null)
            { // read metadata if any.
                relation.ChangeSetId = pbfRelation.info.changeset;
                relation.TimeStamp   = Encoder.DecodeTimestamp(pbfRelation.info.timestamp, block.date_granularity);
                relation.UserId      = pbfRelation.info.uid;
                relation.UserName    = null;
                if (block.stringtable != null)
                {
                    relation.UserName = System.Text.Encoding.UTF8.GetString(block.stringtable.s[pbfRelation.info.user_sid]);
                }
                relation.Version = pbfRelation.info.version;
            }
            relation.Visible = true;

            return(relation);
        }
Пример #14
0
        /// <summary>
        /// Encodes the nodes into the given block.
        /// </summary>
        public static void Encode(this PrimitiveBlock block, Dictionary <string, int> reverseStringTable, List <OsmGeo> osmGeos, bool compressed)
        {
            var groupIdx = 0;
            var i        = 0;

            if (block.stringtable != null &&
                block.stringtable.s != null)
            {
                block.stringtable.s.Clear();
            }
            while (i < osmGeos.Count)
            {
                PrimitiveGroup group = null;
                if (groupIdx < block.primitivegroup.Count)
                { // get the existing group and clear it's data.
                    group = block.primitivegroup[groupIdx];
                    if (group == null)
                    {
                        group = new PrimitiveGroup();
                    }
                    if (group.dense != null)
                    {
                        if (group.dense.denseinfo != null)
                        {
                            if (group.dense.denseinfo.changeset != null)
                            {
                                group.dense.denseinfo.changeset.Clear();
                            }
                            if (group.dense.denseinfo.timestamp != null)
                            {
                                group.dense.denseinfo.timestamp.Clear();
                            }
                            if (group.dense.denseinfo.uid != null)
                            {
                                group.dense.denseinfo.uid.Clear();
                            }
                            if (group.dense.denseinfo.user_sid != null)
                            {
                                group.dense.denseinfo.user_sid.Clear();
                            }
                            if (group.dense.denseinfo.version != null)
                            {
                                group.dense.denseinfo.version.Clear();
                            }
                        }
                        if (group.dense.id != null)
                        {
                            group.dense.id.Clear();
                        }
                        if (group.dense.keys_vals != null)
                        {
                            group.dense.keys_vals.Clear();
                        }
                        if (group.dense.lat != null)
                        {
                            group.dense.lat.Clear();
                        }
                        if (group.dense.lon != null)
                        {
                            group.dense.lon.Clear();
                        }
                    }
                    if (group.changesets != null)
                    {
                        group.changesets.Clear();
                    }
                    //if (group.nodes != null) { group.nodes.Clear(); }
                    if (group.ways != null)
                    {
                        group.ways.Clear();
                    }
                    if (group.relations != null)
                    {
                        group.relations.Clear();
                    }
                }
                else
                { // add a new group.
                    group = new PrimitiveGroup();
                    block.primitivegroup.Add(group);
                }

                // build group.
                var currentNodeCount = 0;
                var groupType        = osmGeos[i].Type;
                var previousNode     = new OsmSharp.Node
                {
                    Id          = 0,
                    Longitude   = 0,
                    Latitude    = 0,
                    ChangeSetId = 0,
                    TimeStamp   = null,
                    UserId      = 0,
                    UserName    = null,
                    Version     = 0
                };
                if (groupType == OsmGeoType.Node && compressed && group.dense == null)
                {
                    group.dense = new DenseNodes {
                        denseinfo = new DenseInfo()
                    };
                }
                while (i < osmGeos.Count &&
                       osmGeos[i].Type == groupType)
                {
                    switch (groupType)
                    {
                    case OsmGeoType.Node:
                        if (compressed)
                        {
                            var currentNode = osmGeos[i] as OsmSharp.Node;
                            Encoder.EncodeDenseNode(block, reverseStringTable, group.dense, currentNode, previousNode);
                            previousNode = currentNode;
                        }
                        else
                        {
                            if (currentNodeCount < group.nodes.Count)
                            {     // overwrite existing.
                                Encoder.EncodeNode(block, reverseStringTable, group.nodes[currentNodeCount], osmGeos[i] as OsmSharp.Node);
                            }
                            else
                            {     // write new.
                                group.nodes.Add(Encoder.EncodeNode(block, reverseStringTable, osmGeos[i] as OsmSharp.Node));
                            }
                            currentNodeCount++;
                        }
                        break;

                    case OsmGeoType.Way:
                        group.ways.Add(Encoder.EncodeWay(block, reverseStringTable, osmGeos[i] as OsmSharp.Way));
                        break;

                    case OsmGeoType.Relation:
                        group.relations.Add(Encoder.EncodeRelation(block, reverseStringTable, osmGeos[i] as OsmSharp.Relation));
                        break;
                    }
                    i++;
                }


                // remove obsolete nodes.
                if (group.nodes != null)
                {
                    while (currentNodeCount < group.nodes.Count)
                    {
                        group.nodes.RemoveAt(currentNodeCount);
                    }
                }

                // move to the next group.
                groupIdx++;
            }

            while (groupIdx < block.primitivegroup.Count)
            {
                block.primitivegroup.RemoveAt(groupIdx);
            }
        }
Пример #15
0
        /// <summary>
        /// Moves to the next primitive block, returns null at the end.
        /// </summary>
        /// <returns></returns>
        public PrimitiveBlock MoveNext()
        {
            // make sure previous block data is removed.
            if (_block.primitivegroup != null)
            {
                _block.primitivegroup.Clear();
            }
            if (_block.stringtable != null)
            {
                _block.stringtable.s.Clear();
            }

            // read next block.
            PrimitiveBlock block = null;
            int            length;
            bool           notFoundBut = true;

            while (notFoundBut)
            {                        // continue if there is still data but not a primitiveblock.
                notFoundBut = false; // not found.
                if (Serializer.TryReadLengthPrefix(_stream, PrefixStyle.Fixed32BigEndian, out length))
                {
                    // TODO: remove some of the v1 specific code.
                    // TODO: this means also to use the built-in capped streams.

                    // code borrowed from: http://stackoverflow.com/questions/4663298/protobuf-net-deserialize-open-street-maps

                    // I'm just being lazy and re-using something "close enough" here
                    // note that v2 has a big-endian option, but Fixed32 assumes little-endian - we
                    // actually need the other way around (network byte order):
                    // length = IntLittleEndianToBigEndian((uint)length);

                    BlobHeader header;
                    // again, v2 has capped-streams built in, but I'm deliberately
                    // limiting myself to v1 features
                    using (var tmp = new LimitedStream(_stream, length))
                    {
                        header = _runtimeTypeModel.Deserialize(tmp, null, _blockHeaderType) as BlobHeader;
                    }
                    Blob blob;
                    using (var tmp = new LimitedStream(_stream, header.datasize))
                    {
                        blob = _runtimeTypeModel.Deserialize(tmp, null, _blobType) as Blob;
                    }

                    // construct the source stream, compressed or not.
                    Stream sourceStream = null;
                    if (blob.zlib_data == null)
                    { // use a regular uncompressed stream.
                        sourceStream = new MemoryStream(blob.raw);
                    }
                    else
                    { // construct a compressed stream.
                        var ms = new MemoryStream(blob.zlib_data);
                        sourceStream = new ZLibStreamWrapper(ms);
                    }

                    // use the stream to read the block.
                    using (sourceStream)
                    {
                        if (header.type == Encoder.OSMHeader)
                        {
                            _runtimeTypeModel.Deserialize(sourceStream, null, _headerBlockType);
                            notFoundBut = true;
                        }

                        if (header.type == Encoder.OSMData)
                        {
                            block = _runtimeTypeModel.Deserialize(sourceStream, _block, _primitiveBlockType) as PrimitiveBlock;
                        }
                    }
                }
            }
            return(block);
        }
Пример #16
0
        /// <summary>
        /// Encodes the nodes into the given block.
        /// </summary>
        public static void Encode(this PrimitiveBlock block, Dictionary <string, int> reverseStringTable, List <OsmGeo> osmGeos)
        {
            var groupIdx  = 0;
            var i         = 0;
            var nodeCount = 0;

            if (block.stringtable != null &&
                block.stringtable.s != null)
            {
                block.stringtable.s.Clear();
            }
            while (i < osmGeos.Count)
            {
                PrimitiveGroup group = null;
                if (groupIdx < block.primitivegroup.Count)
                { // get the existing group and clear it's data.
                    group = block.primitivegroup[groupIdx];
                    if (group == null)
                    {
                        group = new PrimitiveGroup();
                    }
                    if (group.dense != null)
                    {
                        if (group.dense.denseinfo != null)
                        {
                            if (group.dense.denseinfo.changeset != null)
                            {
                                group.dense.denseinfo.changeset.Clear();
                            }
                            if (group.dense.denseinfo.timestamp != null)
                            {
                                group.dense.denseinfo.timestamp.Clear();
                            }
                            if (group.dense.denseinfo.uid != null)
                            {
                                group.dense.denseinfo.uid.Clear();
                            }
                            if (group.dense.denseinfo.user_sid != null)
                            {
                                group.dense.denseinfo.user_sid.Clear();
                            }
                            if (group.dense.denseinfo.version != null)
                            {
                                group.dense.denseinfo.version.Clear();
                            }
                        }
                        if (group.dense.id != null)
                        {
                            group.dense.id.Clear();
                        }
                        if (group.dense.keys_vals != null)
                        {
                            group.dense.keys_vals.Clear();
                        }
                        if (group.dense.lat != null)
                        {
                            group.dense.lat.Clear();
                        }
                        if (group.dense.lon != null)
                        {
                            group.dense.lon.Clear();
                        }
                    }
                    if (group.changesets != null)
                    {
                        group.changesets.Clear();
                    }
                    //if (group.nodes != null) { group.nodes.Clear(); }
                    if (group.ways != null)
                    {
                        group.ways.Clear();
                    }
                    if (group.relations != null)
                    {
                        group.relations.Clear();
                    }
                }
                else
                { // add a new group.
                    group = new PrimitiveGroup();
                    block.primitivegroup.Add(group);
                }

                // build group.
                var groupType = osmGeos[i].Type;
                var current   = osmGeos[i];
                while (i < osmGeos.Count &&
                       osmGeos[i].Type == groupType)
                {
                    switch (groupType)
                    {
                    case OsmGeoType.Node:
                        if (group.nodes.Count > nodeCount)
                        {     // overwrite existing.
                            Encoder.EncodeNode(block, reverseStringTable, group.nodes[nodeCount], osmGeos[i] as OsmSharp.Node);
                        }
                        else
                        {     // write new.
                            group.nodes.Add(Encoder.EncodeNode(block, reverseStringTable, osmGeos[i] as OsmSharp.Node));
                        }
                        nodeCount++;
                        break;

                    case OsmGeoType.Way:
                        group.ways.Add(Encoder.EncodeWay(block, reverseStringTable, osmGeos[i] as OsmSharp.Way));
                        break;

                    case OsmGeoType.Relation:
                        group.relations.Add(Encoder.EncodeRelation(block, reverseStringTable, osmGeos[i] as OsmSharp.Relation));
                        break;
                    }
                    i++;
                }


                // remove obsolete nodes.
                if (group.nodes != null)
                {
                    while (nodeCount < group.nodes.Count)
                    {
                        group.nodes.RemoveAt(nodeCount);
                    }
                }

                // move to the next group.
                groupIdx++;
            }

            while (groupIdx < block.primitivegroup.Count)
            {
                block.primitivegroup.RemoveAt(groupIdx);
            }
        }
Пример #17
0
        /// <summary>
        /// Encodes an OsmSharp-relation into a PBF-relation.
        /// </summary>
        /// <returns></returns>
        public static OsmSharp.IO.PBF.Relation EncodeRelation(PrimitiveBlock block, Dictionary <string, int> reverseStringTable, OsmSharp.Relation relation)
        {
            var pbfRelation = new OsmSharp.IO.PBF.Relation();

            pbfRelation.id   = relation.Id.Value;
            pbfRelation.info = new Info();
            if (relation.ChangeSetId.HasValue)
            {
                pbfRelation.info.changeset = relation.ChangeSetId.Value;
            }
            if (relation.TimeStamp.HasValue)
            {
                pbfRelation.info.timestamp = Encoder.EncodeTimestamp(relation.TimeStamp.Value, block.date_granularity);
            }
            if (relation.UserId.HasValue)
            {
                pbfRelation.info.uid = (int)relation.UserId.Value;
            }
            pbfRelation.info.user_sid = Encoder.EncodeString(block, reverseStringTable, relation.UserName);
            pbfRelation.info.version  = 0;
            if (relation.Version.HasValue)
            {
                pbfRelation.info.version = (int)relation.Version.Value;
            }

            if (relation.Tags != null)
            {
                foreach (var tag in relation.Tags)
                {
                    pbfRelation.keys.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Key));
                    pbfRelation.vals.Add((uint)Encoder.EncodeString(block, reverseStringTable, tag.Value));
                }
            }

            if (relation.Members != null &&
                relation.Members.Length > 0)
            {
                pbfRelation.memids.Add(relation.Members[0].Id);
                pbfRelation.roles_sid.Add(Encoder.EncodeString(block, reverseStringTable, relation.Members[0].Role));
                switch (relation.Members[0].Type)
                {
                case OsmGeoType.Node:
                    pbfRelation.types.Add(Relation.MemberType.NODE);
                    break;

                case OsmGeoType.Way:
                    pbfRelation.types.Add(Relation.MemberType.WAY);
                    break;

                case OsmGeoType.Relation:
                    pbfRelation.types.Add(Relation.MemberType.RELATION);
                    break;
                }
                for (var i = 1; i < relation.Members.Length; i++)
                {
                    pbfRelation.memids.Add(relation.Members[i].Id -
                                           relation.Members[i - 1].Id);
                    pbfRelation.roles_sid.Add(Encoder.EncodeString(block, reverseStringTable, relation.Members[i].Role));
                    switch (relation.Members[i].Type)
                    {
                    case OsmGeoType.Node:
                        pbfRelation.types.Add(Relation.MemberType.NODE);
                        break;

                    case OsmGeoType.Way:
                        pbfRelation.types.Add(Relation.MemberType.WAY);
                        break;

                    case OsmGeoType.Relation:
                        pbfRelation.types.Add(Relation.MemberType.RELATION);
                        break;
                    }
                }
            }
            return(pbfRelation);
        }
Пример #18
0
        /// <summary>
        /// Decodes the block.
        /// </summary>
        public static bool Decode(this PrimitiveBlock block, IPBFOsmPrimitiveConsumer primitivesConsumer,
                                  bool ignoreNodes, bool ignoreWays, bool ignoreRelations, out bool hasNodes, out bool hasWays, out bool hasRelations)
        {
            var success = false;

            hasNodes     = false;
            hasWays      = false;
            hasRelations = false;

            if (block.primitivegroup != null)
            {
                foreach (var primitivegroup in block.primitivegroup)
                {
                    if (primitivegroup.dense != null && primitivegroup.dense.id.Count > 0)
                    {
                        hasNodes = true;
                        if (!ignoreNodes)
                        {
                            int  keyValsIdx       = 0;
                            long currentId        = 0;
                            long currentLat       = 0;
                            long currentLon       = 0;
                            long currentChangeset = 0;
                            long currentTimestamp = 0;
                            int  currentUid       = 0;
                            int  currentUserSid   = 0;
                            int  currentVersion   = 0;

                            for (int idx = 0; idx < primitivegroup.dense.id.Count; idx++)
                            {
                                // do the delta decoding stuff.
                                currentId = currentId +
                                            primitivegroup.dense.id[idx];
                                currentLat = currentLat +
                                             primitivegroup.dense.lat[idx];
                                currentLon = currentLon +
                                             primitivegroup.dense.lon[idx];
                                if (primitivegroup.dense.denseinfo != null)
                                { // add all the metadata.
                                    currentChangeset = currentChangeset +
                                                       primitivegroup.dense.denseinfo.changeset[idx];
                                    currentTimestamp = currentTimestamp +
                                                       primitivegroup.dense.denseinfo.timestamp[idx];
                                    currentUid = currentUid +
                                                 primitivegroup.dense.denseinfo.uid[idx];
                                    currentUserSid = currentUserSid +
                                                     primitivegroup.dense.denseinfo.user_sid[idx];
                                    currentVersion = currentVersion +
                                                     primitivegroup.dense.denseinfo.version[idx];
                                }

                                var node = new Node();
                                node.id             = currentId;
                                node.info           = new Info();
                                node.info.changeset = currentChangeset;
                                node.info.timestamp = (int)currentTimestamp;
                                node.info.uid       = currentUid;
                                node.info.user_sid  = currentUserSid;
                                node.info.version   = currentVersion;
                                node.lat            = currentLat;
                                node.lon            = currentLon;

                                // get the keys/vals.
                                var keyVals = primitivegroup.dense.keys_vals;
                                while (keyVals.Count > keyValsIdx &&
                                       keyVals[keyValsIdx] != 0)
                                {
                                    node.keys.Add((uint)keyVals[keyValsIdx]);
                                    keyValsIdx++;
                                    node.vals.Add((uint)keyVals[keyValsIdx]);
                                    keyValsIdx++;
                                }
                                keyValsIdx++;

                                success  = true;
                                hasNodes = true;
                                primitivesConsumer.ProcessNode(block, node);
                            }
                        }
                    }
                    else
                    {
                        if (primitivegroup.nodes != null && primitivegroup.nodes.Count > 0)
                        {
                            hasNodes = true;
                            if (!ignoreNodes)
                            {
                                foreach (var node in primitivegroup.nodes)
                                {
                                    success = true;
                                    primitivesConsumer.ProcessNode(block, node);
                                }
                            }
                        }
                        if (primitivegroup.ways != null && primitivegroup.ways.Count > 0)
                        {
                            hasWays = true;
                            if (!ignoreWays)
                            {
                                foreach (var way in primitivegroup.ways)
                                {
                                    success = true;
                                    primitivesConsumer.ProcessWay(block, way);
                                }
                            }
                        }
                        if (primitivegroup.relations != null && primitivegroup.relations.Count > 0)
                        {
                            hasRelations = true;
                            if (!ignoreRelations)
                            {
                                foreach (var relation in primitivegroup.relations)
                                {
                                    success = true;
                                    primitivesConsumer.ProcessRelation(block, relation);
                                }
                            }
                        }
                    }
                }
            }
            return(success);
        }