public static IEnumerable <OsmNode> DecodeDenseNodes(PrimitiveBlock data)
        {
            if (data == null || data.PrimitiveGroup == null)
            {
                yield break;
            }
            foreach (var denseNodes in data.PrimitiveGroup.Select(group => group.DenseNodes)
                     .Where(denseNodes => denseNodes != null))
            {
                var  ids    = denseNodes.Ids;
                long prevId = 0;

                var  latitudes = denseNodes.Latitudes;
                long latData   = 0;

                var  longitudes = denseNodes.Longitudes;
                long lonData    = 0;


                var tagIds   = denseNodes.KeysValues;
                var tagIndex = 0;

                if (ids.Count != latitudes.Count || ids.Count != longitudes.Count)
                {
                    throw new InvalidOperationException(
                              "Dense node should have equal couont of Ids, Longitudes and Latitudes");
                }

                for (var i = 0; i < ids.Count; i++)
                {
                    prevId  += ids[i];
                    lonData += longitudes[i];
                    latData += latitudes[i];

                    var lon = 0.000000001 * (data.LonOffset + data.Granularity * lonData);
                    var lat = 0.000000001 * (data.LatOffset + data.Granularity * latData);

                    var tags = new List <OsmTag>();

                    while (tagIds[tagIndex] != 0)
                    {
                        var key   = data.Strings[tagIds[tagIndex++]];
                        var value = data.Strings[tagIds[tagIndex++]];
                        tags.Add(new OsmTag(key, value));
                    }

                    tagIndex++;

                    var node = new OsmNode(prevId, lon, lat)
                    {
                        Tags = tags
                    };


                    yield return(node);
                }
            }
        }
        public static IEnumerable <OsmRelation> DecodeRelations(PrimitiveBlock data)
        {
            if (data.PrimitiveGroup == null)
            {
                return(Enumerable.Empty <OsmRelation>());
            }

            return(data.PrimitiveGroup.Where(x => x.Relations != null).SelectMany(x => x.Relations).Select(x => new OsmRelation
            {
                Id = x.Id,
                Items = DecodeRelationItems(x, data),
                Tags = DecodeTags(x.Keys, x.Values, data.Strings)
            }));
        }
        public static IEnumerable <OsmNode> DecodeAllNodes(PrimitiveBlock data)
        {
            if (data.PrimitiveGroup == null)
            {
                return(Enumerable.Empty <OsmNode>());
            }

            if (data.PrimitiveGroup.Any(g => g.Nodes != null && g.Nodes.Any()))
            {
                throw new NotImplementedException("Reading of plain nodes is not implemented. Only dense nodes are supported.");
            }

            return(DecodeDenseNodes(data));
        }
        public static IEnumerable <OsmWay> DecodeWays(PrimitiveBlock data)
        {
            if (data == null || data.PrimitiveGroup == null)
            {
                yield break;
            }

            foreach (var way in data.PrimitiveGroup.Where(x => x.Ways != null).SelectMany(x => x.Ways))
            {
                var ids  = DecodeDeltaItems(way.Refs);
                var tags = DecodeTags(way.Keys, way.Values, data.Strings);
                yield return(new OsmWay
                {
                    Id = way.Id,
                    NodeIds = ids,
                    Tags = tags
                });
            }
        }
Exemple #5
0
        public PrimitiveBlock ReadData()
        {
            reader.BeginReadMessage(length);
            var result = new PrimitiveBlock();

            result.PrimitiveGroup = new List <PrimitiveGroup>();
            while (reader.State == ProtobufReaderState.Field)
            {
                switch (reader.FieldNumber)
                {
                case 1:
                    result.Strings = ReadStringTable();
                    break;

                case 2:
                    result.PrimitiveGroup.Add(ReadPrimitiveGroup());
                    break;

                case 17:
                    result.Granularity = (int)reader.ReadInt64();
                    break;

                case 19:
                    result.LatOffset = reader.ReadInt64();
                    break;

                case 20:
                    result.LonOffset = reader.ReadInt64();
                    break;

                case 18:
                    result.DateGranularity = (int)reader.ReadInt64();
                    break;

                default:
                    reader.Skip();
                    break;
                }
            }
            reader.EndReadMessage();
            return(result);
        }
        private static IReadOnlyList <RelationItem> DecodeRelationItems(Relation relation, PrimitiveBlock data)
        {
            var strings = data.Strings;

            var result = new List <RelationItem>(relation.MemberIds.Count);

            var id = 0L;

            for (int i = 0; i < relation.MemberIds.Count; i++)
            {
                id += relation.MemberIds[i];
                var item = new RelationItem {
                    Id         = id,
                    MemberType = relation.MemberType[i],
                    Role       = strings[relation.Roles[i]]
                };

                result.Add(item);
            }

            return(result);
        }