예제 #1
0
파일: Extensions.cs 프로젝트: OsmSharp/core
        // Recursive, safe against circular references, may return duplciate nodes.
        private static IEnumerable <OsmGeo> ToSimpleWithChildrenCircularSafe(
            this CompleteRelation complete, HashSet <OsmGeoKey> seenGeoKeys)
        {
            if (complete.Members == null)
            {
                return(new[] { complete.ToSimple() });
            }

            var children = new List <OsmGeo>();

            foreach (var completeMember in complete.Members.Where(m => m != null))
            {
                var key = new OsmGeoKey(completeMember.Member.Type, completeMember.Member.Id);

                if (seenGeoKeys.Add(key)) // Returns true if element was not already present
                {
                    switch (completeMember.Member)
                    {
                    case Node node:
                        children.Add(node);
                        break;

                    case CompleteWay way:
                        children.AddRange(way.ToSimpleWithChildren());
                        break;

                    case CompleteRelation relation:
                        children.AddRange(relation.ToSimpleWithChildrenCircularSafe(seenGeoKeys));
                        break;

                    default:
                        throw new Exception("Unknown Complete Element Type.");
                    }
                }
            }

            return(children.Append(complete.ToSimple()));
        }
예제 #2
0
파일: Extensions.cs 프로젝트: OsmSharp/core
        /// <summary>
        /// Converts a complete relation into its simple counterpart,
        /// including the simple versions of all members, and their components, recursively.
        /// </summary>
        public static OsmGeo[] ToSimpleWithChildren(this CompleteRelation relation)
        {
            var withChildren = relation.ToSimpleWithChildrenCircularSafe(new HashSet <OsmGeoKey>());

            return(withChildren.DistinctByGeoKey().ToArray());
        }
예제 #3
0
파일: Extensions.cs 프로젝트: OsmSharp/core
        /// <summary>
        /// Creates a complete relation.
        /// </summary>
        public static CompleteRelation CreateComplete(this Relation relation, IOsmGeoSource osmGeoSource)
        {
            if (relation == null)
            {
                throw new ArgumentNullException("relation");
            }
            if (relation.Id == null)
            {
                throw new Exception("relation.Id is null");
            }
            if (osmGeoSource == null)
            {
                throw new ArgumentNullException("osmGeoSource");
            }

            var completeRelation = new CompleteRelation();

            completeRelation.Id = relation.Id.Value;

            completeRelation.ChangeSetId = relation.ChangeSetId;
            if (relation.Tags != null)
            {
                completeRelation.Tags = new TagsCollection(relation.Tags);
            }
            if (relation.Members != null)
            {
                var relationMembers = new List <CompleteRelationMember>();
                for (var i = 0; i < relation.Members.Length; i++)
                {
                    var memberId = relation.Members[i].Id;
                    var role     = relation.Members[i].Role;
                    var member   = new CompleteRelationMember();
                    member.Role = role;
                    switch (relation.Members[i].Type)
                    {
                    case OsmGeoType.Node:
                        var memberNode = osmGeoSource.GetNode(memberId);
                        if (memberNode == null)
                        {
                            continue;
                        }
                        var completeMemberNode = memberNode;
                        if (completeMemberNode != null)
                        {
                            member.Member = completeMemberNode;
                        }
                        else
                        {
                            continue;
                        }
                        break;

                    case OsmGeoType.Way:
                        var memberWay = osmGeoSource.GetWay(memberId);
                        if (memberWay == null)
                        {
                            continue;
                        }
                        var completeMemberWay = memberWay.CreateComplete(osmGeoSource);
                        if (completeMemberWay != null)
                        {
                            member.Member = completeMemberWay;
                        }
                        else
                        {
                            continue;
                        }
                        break;

                    case OsmGeoType.Relation:
                        if (relation.Id == memberId)
                        {
                            continue;
                        }
                        var relationMember = osmGeoSource.GetRelation(memberId);
                        if (relationMember == null)
                        {
                            continue;
                        }
                        var completeMemberRelation = relationMember.CreateComplete(osmGeoSource);
                        if (completeMemberRelation != null)
                        {
                            member.Member = completeMemberRelation;
                        }
                        else
                        {
                            continue;
                        }
                        break;
                    }
                    relationMembers.Add(member);
                }
                completeRelation.Members = relationMembers.ToArray();
            }
            completeRelation.TimeStamp = relation.TimeStamp;
            completeRelation.UserName  = relation.UserName;
            completeRelation.UserId    = relation.UserId;
            completeRelation.Version   = relation.Version;
            completeRelation.Visible   = relation.Visible;
            return(completeRelation);
        }