Ejemplo n.º 1
0
        public static LinearRing AsBoundingPolygon(CompleteRelation relation)
        {
            var thing = DefaultFeatureInterpreter.DefaultInterpreter.Interpret(relation).OfType <LinearRing>().First();

            relation.Members.Where(r => r.Role == "outer");
            return(thing);
        }
Ejemplo n.º 2
0
        public void ToGeoJson_RelationWithPolygonAndLineString_ShouldReturnMultiLineStringAfterGrouping()
        {
            var node1 = CreateNode(1);
            var node2 = CreateNode(2);
            var node3 = CreateNode(3);
            var node4 = CreateNode(4);
            var node5 = CreateNode(5);
            var node6 = CreateNode(6);
            var node7 = CreateNode(7);
            var wayPartOfLineString1 = new CompleteWay {
                Id = 8
            };
            var wayPartOfLineString2 = new CompleteWay {
                Id = 9
            };

            wayPartOfLineString1.Nodes = new[] { node1, node2 };
            wayPartOfLineString2.Nodes = new[] { node2, node3 };
            var wayPartOfPolygon1 = new CompleteWay {
                Id = 10
            };
            var wayPartOfPolygon2 = new CompleteWay {
                Id = 11
            };

            wayPartOfPolygon1.Nodes = new[] { node4, node5, node6 };
            wayPartOfPolygon2.Nodes = new[] { node4, node7, node6 };
            var relation = new CompleteRelation {
                Id = 12, Tags = new TagsCollection()
            };

            relation.Tags.Add(NAME, NAME);
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = wayPartOfLineString1
                },
                new CompleteRelationMember {
                    Member = wayPartOfLineString2
                },
                new CompleteRelationMember {
                    Member = wayPartOfPolygon1
                },
                new CompleteRelationMember {
                    Member = wayPartOfPolygon2
                },
            };

            var feature         = _converter.ToGeoJson(relation);
            var multiLineString = feature.Geometry as MultiLineString;

            Assert.IsNotNull(multiLineString);
            Assert.AreEqual(2, multiLineString.Geometries.Length);
            var lineString = multiLineString.Geometries.First();

            Assert.AreEqual(3, lineString.Coordinates.Length);
            var lineString2 = multiLineString.Geometries.Last();

            Assert.AreEqual(5, lineString2.Coordinates.Length);
            Assert.AreEqual(lineString2.Coordinates.First(), lineString2.Coordinates.Last());
        }
        /// <summary>
        /// Compares what is in the complete list against the objects in the reference source.
        /// </summary>
        /// <param name="expected"></param>
        /// <param name="actual"></param>
        private void Compare(MemoryDataSource expected, List <ICompleteOsmGeo> actual)
        {
            var exectedList = new List <ICompleteOsmGeo>();

            foreach (var node in expected.GetNodes())
            {
                var completeNode = node;
                if (completeNode != null)
                {
                    exectedList.Add(completeNode);
                }
            }
            foreach (var way in expected.GetWays())
            {
                var completeWay = CompleteWay.CreateFrom(way, expected);
                if (completeWay != null)
                {
                    exectedList.Add(completeWay);
                }
            }
            foreach (var relation in expected.GetRelations())
            {
                var completeRelation = CompleteRelation.CreateFrom(relation, expected);
                if (completeRelation != null)
                {
                    exectedList.Add(completeRelation);
                }
            }

            ComparisonHelpers.CompareComplete(exectedList, actual);
        }
Ejemplo n.º 4
0
        private Feature InterpretMultipolygonRelation(CompleteRelation relation)
        {
            Feature feature = (Feature)null;

            if (relation.Members == null)
            {
                return(feature);
            }
            List <KeyValuePair <bool, CompleteWay> > ways = new List <KeyValuePair <bool, CompleteWay> >();

            foreach (CompleteRelationMember member in (IEnumerable <CompleteRelationMember>)relation.Members)
            {
                if (member.Role == "inner" && member.Member is CompleteWay)
                {
                    ways.Add(new KeyValuePair <bool, CompleteWay>(false, member.Member as CompleteWay));
                }
                else if (member.Role == "outer" && member.Member is CompleteWay)
                {
                    ways.Add(new KeyValuePair <bool, CompleteWay>(true, member.Member as CompleteWay));
                }
            }
            List <KeyValuePair <bool, LineairRing> > rings;

            if (!this.AssignRings(ways, out rings))
            {
                Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error, string.Format("Ring assignment failed: invalid multipolygon relation [{0}] detected!", (object)relation.Id));
            }
            Geometry geometry = this.GroupRings(rings);

            if (geometry != null)
            {
                feature = new Feature(geometry, (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <Tag>)relation.Tags));
            }
            return(feature);
        }
Ejemplo n.º 5
0
        public void ToGeoJson_RelationWithOuterOnly_ShouldReturnMultiPolygon()
        {
            var node1 = CreateNode(1);
            var node2 = CreateNode(2);
            var node3 = CreateNode(3);
            var node4 = CreateNode(1);
            var way   = new CompleteWay
            {
                Id    = 4,
                Nodes = new[] { node1, node2, node3, node4 }
            };
            var relation = new CompleteRelation {
                Id = 5, Tags = new TagsCollection()
            };

            relation.Tags.Add("type", "boundary");
            relation.Members = new[] { new CompleteRelationMember {
                                           Member = way, Role = "outer"
                                       } };

            var feature      = _converter.ToGeoJson(relation);
            var multiPolygon = feature.Geometry as MultiPolygon;

            Assert.IsNotNull(multiPolygon);
            Assert.AreEqual(4, multiPolygon.Coordinates.Length);
            Assert.AreEqual(node1.Latitude, multiPolygon.Coordinates.First().Y);
            Assert.AreEqual(node4.Longitude, multiPolygon.Coordinates.Last().X);
        }
Ejemplo n.º 6
0
        public void ToGeoJson_RelationWithNodes_ShouldReturnMultiPoint()
        {
            var node1    = CreateNode(1);
            var node2    = CreateNode(2);
            var relation = new CompleteRelation {
                Id = 3, Tags = new TagsCollection()
            };

            relation.Tags.Add(NAME, NAME);
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = node1
                },
                new CompleteRelationMember {
                    Member = node2
                }
            };

            var feature    = _converter.ToGeoJson(relation);
            var multiPoint = feature.Geometry as MultiPoint;

            Assert.IsNotNull(multiPoint);
            Assert.AreEqual(2, multiPoint.Coordinates.Length);
            var position1 = multiPoint.Coordinates.First();

            Assert.IsNotNull(position1);
            Assert.AreEqual(node1.Latitude, position1.Y);
            var position2 = multiPoint.Coordinates.Last();

            Assert.IsNotNull(position2);
            Assert.AreEqual(node2.Longitude, position2.X);
        }
Ejemplo n.º 7
0
        private Feature ConvertRelation(CompleteRelation relation)
        {
            if (IsMultipolygon(relation))
            {
                return(ConvertToMultipolygon(relation));
            }

            var nodes = relation.Members.Select(m => m.Member).OfType <Node>().ToList();

            if (nodes.Any())
            {
                var multiPoint = new MultiPoint(nodes.Select(n => new Point(ConvertNode(n)) as IPoint).ToArray());
                return(new Feature(multiPoint, ConvertTags(relation)));
            }

            var geometries = GetGeometriesFromWays(GetAllWays(relation));

            if (!geometries.Any())
            {
                return(null);
            }
            var jointLines = geometries.OfType <ILineString>().ToList();

            jointLines.AddRange(geometries.OfType <Polygon>().Select(p => new LineString(p.Coordinates) as ILineString));
            var multiLineString = new MultiLineString(jointLines.ToArray());

            return(new Feature(multiLineString, ConvertTags(relation)));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Parse a CompleteRelation into a Geometry. Avoids recursion to allow for much larger objects to be processed than the default OSMSharp FeatureInterpreter.
        /// </summary>
        /// <param name="relation">The CompleteRelation to process</param>
        /// <returns>the Geometry to use in the application elsewhere, or null if an error occurred generating the Geometry. </returns>
        private Geometry InterpretMultipolygonRelationNoRecursion(CompleteRelation relation)
        {
            //Feature feature = null;
            if (relation.Members == null)
            { // the relation has no members.
                return(null);
            }

            // build lists of outer and inner ways.
            var inners = new List <CompleteWay>();
            var outers = new List <CompleteWay>(relation.Members.Count());

            foreach (var member in relation.Members)
            {
                switch (member.Role)
                {
                case "inner" when member.Member is CompleteWay:
                    inners.Add(member.Member as CompleteWay);
                    break;

                case "outer" when member.Member is CompleteWay:
                    outers.Add(member.Member as CompleteWay);
                    break;

                default:
                    break;
                }
            }

            var geometry = BuildGeometry(outers, inners);

            return(geometry);
        }
Ejemplo n.º 9
0
        public void ToGeoJson_MultiPolygonWithTwoHoles_ShouldReturnMultiPlygonWithSinglePolygon()
        {
            var id     = 1;
            var node1  = CreateNode(id++, 0, 0);
            var node2  = CreateNode(id++, 1, 0);
            var node3  = CreateNode(id++, 1, 1);
            var node4  = CreateNode(id++, 0, 1);
            var node5  = CreateNode(id++, 0.5, 0.5);
            var node6  = CreateNode(id++, 0.5, 0.6);
            var node7  = CreateNode(id++, 0.6, 0.6);
            var node8  = CreateNode(id++, 0.6, 0.5);
            var node9  = CreateNode(id++, 0.3, 0.3);
            var node10 = CreateNode(id++, 0.3, 0.4);
            var node11 = CreateNode(id++, 0.4, 0.4);
            var node12 = CreateNode(id++, 0.4, 0.3);

            var wayOuter = new CompleteWay
            {
                Id    = id++,
                Nodes = new[] { node1, node2, node3, node4, node1 }
            };
            var wayInner1 = new CompleteWay
            {
                Id    = id++,
                Nodes = new[] { node5, node6, node7, node8, node5 }
            };
            var wayInner2 = new CompleteWay
            {
                Id    = id++,
                Nodes = new[] { node9, node10, node11, node12, node9 }
            };
            var relation = new CompleteRelation
            {
                Id      = id++,
                Tags    = new TagsCollection(),
                Members = new[]
                {
                    new CompleteRelationMember {
                        Member = wayInner1, Role = "inner"
                    },
                    new CompleteRelationMember {
                        Member = wayInner2, Role = "inner"
                    },
                    new CompleteRelationMember {
                        Member = wayOuter, Role = "outer"
                    }
                }
            };

            relation.Tags.Add("type", "boundary");

            var geoJson = _converter.ToGeoJson(relation);

            var multiPlygon = geoJson.Geometry as MultiPolygon;

            Assert.IsNotNull(multiPlygon);
            Assert.IsTrue(multiPlygon.IsValid);
            Assert.AreEqual(1, multiPlygon.Geometries.Length);
        }
Ejemplo n.º 10
0
        public Agency(CompleteRelation rel, Dictionary <long, RouteRelation> routes)
        {
            string name    = null;
            string id      = null;
            string url     = null;
            string phone   = null;
            string fareUrl = null;
            string email   = null;

            if (Config.AgencyIDTag == null)
            {
                id = Util.OsmIDString(rel);
            }

            foreach (Tag tag in rel.Tags)
            {
                if (tag.Key == Config.AgencyIDTag)
                {
                    id = Config.PatternExtract(tag.Value, Config.AgencyIDPattern);
                }

                if (tag.Key == Config.AgencyNameTag)
                {
                    name = Config.PatternExtract(tag.Value, Config.AgencyNamePattern);
                }
                else if (tag.Key.StartsWith("name:") && name == null)
                {
                    name = tag.Value;
                }
                else if (tag.Key == "website" || tag.Key == "contact:website")
                {
                    url = tag.Value;
                }
                else if (tag.Key == "phone" || tag.Key == "contact:phone")
                {
                    phone    = tag.Value;
                    UsePhone = true;
                }
                else if (tag.Key == "website:fares" || tag.Key == "contact:website:fares")
                {
                    fareUrl = tag.Value;
                    UseFare = true;
                }
                else if (tag.Key == "email" || tag.Key == "contact:email")
                {
                    email    = tag.Value;
                    UseEmail = true;
                }
            }

            Name    = name;
            ID      = id;
            Url     = url;
            Phone   = phone;
            FareUrl = fareUrl;
            Email   = email;

            AddRoutes(routes, this, rel);
        }
        /// <summary>
        /// Compares the two complete objects.
        /// </summary>
        public static void CompareComplete(CompleteRelation expected, CompleteRelation actual)
        {
            if (expected == null)
            { // ok, if the value is also null.
                Assert.IsNull(actual);
            }
            else
            { // check and compare the value.
                Assert.IsNotNull(actual);
                Assert.AreEqual(expected.Id, actual.Id);
                Assert.AreEqual(expected.ChangeSetId, actual.ChangeSetId);
                Assert.AreEqual(expected.TimeStamp, actual.TimeStamp);
                Assert.AreEqual(expected.User, actual.User);
                Assert.AreEqual(expected.UserId, actual.UserId);
                Assert.AreEqual(expected.Version, actual.Version);
                Assert.AreEqual(expected.Visible, actual.Visible);

                if (expected.Members == null)
                { // ok, if the value is also null.
                    Assert.IsNotNull(actual.Members);
                }
                else
                { // check and compare the nodes.
                    Assert.AreEqual(expected.Members.Count, actual.Members.Count);
                    for (int idx = 0; idx < expected.Members.Count; idx++)
                    {
                        CompleteRelationMember expectedMember = expected.Members[idx];
                        CompleteRelationMember actualMember   = actual.Members[idx];

                        Assert.AreEqual(expectedMember.Role, actualMember.Role);
                        Assert.IsNotNull(expectedMember.Member);
                        Assert.IsNotNull(actualMember.Member);
                        Assert.AreEqual(expectedMember.Member.Type, actualMember.Member.Type);

                        switch (expectedMember.Member.Type)
                        {
                        case CompleteOsmType.Node:
                            ComparisonHelpers.CompareComplete(
                                expectedMember.Member as Node,
                                actualMember.Member as Node);
                            break;

                        case CompleteOsmType.Way:
                            ComparisonHelpers.CompareComplete(
                                expectedMember.Member as CompleteWay,
                                actualMember.Member as CompleteWay);
                            break;

                        case CompleteOsmType.Relation:
                            ComparisonHelpers.CompareComplete(
                                expectedMember.Member as CompleteRelation,
                                actualMember.Member as CompleteRelation);
                            break;
                        }
                    }
                }
            }
        }
Ejemplo n.º 12
0
        public void ToGeoJson_RelationWithTwoSubRelationsWithInnerRole_ShouldReturnMultiPolygon()
        {
            int id    = 1;
            var node1 = CreateNode(id++);
            var node2 = CreateNode(id++);
            var node3 = CreateNode(id++);

            var way1 = new CompleteWay
            {
                Id    = 4,
                Nodes = new[] { node1, node2, node3, node1 }
            };
            var node4 = CreateNode(id++);
            var node5 = CreateNode(id++);
            var node6 = CreateNode(id++);
            var way2  = new CompleteWay
            {
                Id    = id++,
                Nodes = new[] { node4, node5, node6, node4 }
            };
            var subRelation1 = new CompleteRelation
            {
                Id      = id++,
                Members = new[] { new CompleteRelationMember {
                                      Member = way1, Role = "outer"
                                  } }
            };
            var subRelation2 = new CompleteRelation
            {
                Id      = id++,
                Members = new[] { new CompleteRelationMember {
                                      Member = way2, Role = "outer"
                                  } }
            };
            var relation = new CompleteRelation {
                Id = id++, Tags = new TagsCollection()
            };

            relation.Tags.Add("type", "multipolygon");
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = subRelation1
                },
                new CompleteRelationMember {
                    Member = subRelation2
                }
            };

            var feature      = _converter.ToGeoJson(relation);
            var multiPolygon = feature.Geometry as MultiPolygon;

            Assert.IsNotNull(multiPolygon);
            Assert.AreEqual(8, multiPolygon.Coordinates.Length);
            Assert.AreEqual(node1.Latitude, multiPolygon.Coordinates.First().Y);
            Assert.AreEqual(node4.Longitude, multiPolygon.Coordinates.Last().X);
        }
Ejemplo n.º 13
0
        private Feature ConvertToMultipolygon(CompleteRelation relation)
        {
            var allWaysInRelationByRole = GetAllWaysGroupedByRole(relation);
            var outerWays     = allWaysInRelationByRole.Where(kvp => kvp.Key == OUTER).SelectMany(kvp => kvp.Value).ToList();
            var outerPolygons = GetGeometriesFromWays(outerWays).OfType <Polygon>().ToList();
            var innerWays     = allWaysInRelationByRole.Where(kvp => kvp.Key != OUTER).SelectMany(kvp => kvp.Value).ToList();
            var innerPolygons = GetGeometriesFromWays(innerWays).OfType <Polygon>().ToList();
            var multiPolygon  = MergeInnerIntoOuterPolygon(outerPolygons, innerPolygons);

            return(new Feature(multiPolygon, ConvertTags(relation)));
        }
Ejemplo n.º 14
0
        public void ToGeoJson_RelationWithoutWays_ShouldReturnMultiPoint()
        {
            var relation = new CompleteRelation {
                Id = 3, Tags = new TagsCollection(), Members = new CompleteRelationMember[0]
            };

            relation.Tags.Add(NAME, NAME);

            var feature = _converter.ToGeoJson(relation);

            Assert.IsNull(feature);
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Tries to interpret a given multipolygon relation.
        /// </summary>
        /// <param name="relation"></param>
        /// <returns></returns>
        private Feature InterpretMultipolygonRelation(CompleteRelation relation)
        {
            Feature feature = null;

            if (relation.Members == null)
            { // the relation has no members.
                return(feature);
            }

            // build lists of outer and inner ways.
            var ways = new List <KeyValuePair <bool, CompleteWay> >(); // outer=true

            foreach (var member in relation.Members)
            {
                if (member.Role == "inner" &&
                    member.Member is CompleteWay)
                { // an inner member.
                    ways.Add(new KeyValuePair <bool, CompleteWay>(
                                 false, member.Member as CompleteWay));
                }
                else if (member.Role == "outer" &&
                         member.Member is CompleteWay)
                { // an outer member.
                    ways.Add(new KeyValuePair <bool, CompleteWay>(
                                 true, member.Member as CompleteWay));
                }
            }

            // started a similar algorithm and then found this:
            // loosely based on: http://wiki.openstreetmap.org/wiki/Relation:multipolygon/Algorithm

            // recusively try to assign the rings.
            List <KeyValuePair <bool, LineairRing> > rings;

            if (!this.AssignRings(ways, out rings))
            {
                OsmSharp.Logging.Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error,
                                                string.Format("Ring assignment failed: invalid multipolygon relation [{0}] detected!", relation.Id));
            }
            // group the rings and create a multipolygon.
            var geometry = this.GroupRings(rings);

            if (geometry != null)
            {
                feature = new Feature(geometry,
                                      new SimpleGeometryAttributeCollection(relation.Tags));
            }
            return(feature);
        }
Ejemplo n.º 16
0
        public void ToGeoJson_RelationWithTouchingPolygones_ShouldReturnValidMultiPolygon()
        {
            int id            = 1;
            var node1         = CreateNode(id++, 0, 0);
            var node2         = CreateNode(id++, 0, 1);
            var node3         = CreateNode(id++, 1, 1);
            var node4         = CreateNode(id++, 1, 0);
            var node5         = CreateNode(id++, 0, 2);
            var node6         = CreateNode(id++, 1, 2);
            var node7         = CreateNode(id++, -1, -1);
            var node8         = CreateNode(id++, 3, -1);
            var node9         = CreateNode(id++, 3, 3);
            var node10        = CreateNode(id++, -1, 3);
            var polygon1inner = new CompleteWay {
                Id = id++, Nodes = new[] { node1, node2, node3, node4, node1 }
            };
            var polygon2inner = new CompleteWay {
                Id = id++, Nodes = new[] { node2, node5, node6, node3, node2 }
            };
            var polygonOuter = new CompleteWay {
                Id = id++, Nodes = new[] { node7, node8, node9, node10, node7 }
            };

            var relation = new CompleteRelation {
                Id = id++, Tags = new TagsCollection()
            };

            relation.Tags.Add(NAME, NAME);
            relation.Tags.Add("type", "multipolygon");
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = polygonOuter, Role = "outer"
                },
                new CompleteRelationMember {
                    Member = polygon1inner
                },
                new CompleteRelationMember {
                    Member = polygon2inner
                }
            };

            var feature      = _converter.ToGeoJson(relation);
            var multiPolygon = feature.Geometry as MultiPolygon;

            Assert.IsNotNull(multiPolygon);
            var isValidOp = new IsValidOp(multiPolygon);

            Assert.IsTrue(isValidOp.IsValid);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Interprets an OSM-object and returns the correctponding geometry.
        /// </summary>
        /// <param name="simpleOsmGeo"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public virtual GeometryCollection Interpret(OsmGeo simpleOsmGeo, IDataSourceReadOnly data)
        {
            switch (simpleOsmGeo.Type)
            {
            case OsmGeoType.Node:
                return(this.Interpret(simpleOsmGeo as Node));

            case OsmGeoType.Way:
                return(this.Interpret(CompleteWay.CreateFrom(simpleOsmGeo as Way, data)));

            case OsmGeoType.Relation:
                return(this.Interpret(CompleteRelation.CreateFrom(simpleOsmGeo as Relation, data)));
            }
            throw new ArgumentOutOfRangeException();
        }
Ejemplo n.º 18
0
        public void ToGeoJson_Convert8Shape_ShouldConvertToMultipolygon()
        {
            int id    = 1;
            var node1 = CreateNode(id++, 0, 0);
            var node2 = CreateNode(id++, 0, 1);
            var node3 = CreateNode(id++, 1, 1);

            var node4 = CreateNode(id++, 1, 0);
            var node5 = CreateNode(id++, 0, -1);
            var node6 = CreateNode(id++, -1, -1);

            var node7 = CreateNode(id++, -1, 0);
            var way1  = new CompleteWay {
                Id = id++, Nodes = new[] { node1, node2, node3 }
            };
            var way2 = new CompleteWay {
                Id = id++, Nodes = new[] { node3, node4, node1, node5, node6 }
            };
            var way3 = new CompleteWay {
                Id = id++, Nodes = new[] { node6, node7, node1 }
            };

            var relation = new CompleteRelation {
                Id = id++, Tags = new TagsCollection()
            };

            relation.Tags.Add(NAME, NAME);
            relation.Tags.Add("type", "multipolygon");
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = way1, Role = "outer"
                },
                new CompleteRelationMember {
                    Member = way2, Role = "outer"
                },
                new CompleteRelationMember {
                    Member = way3, Role = "outer"
                }
            };

            var feature      = _converter.ToGeoJson(relation);
            var multiPolygon = feature.Geometry as MultiPolygon;

            Assert.IsNotNull(multiPolygon);
            var isValidOp = new IsValidOp(multiPolygon);

            Assert.IsTrue(isValidOp.IsValid);
        }
Ejemplo n.º 19
0
        /// <summary>
        /// Translates the given OSM objects into corresponding geometries.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="projection"></param>
        /// <param name="source"></param>
        /// <param name="osmGeo"></param>
        public virtual void Translate(Scene2D scene, IProjection projection, IDataSourceReadOnly source, OsmGeo osmGeo)
        {
            switch (osmGeo.Type)
            {
            case OsmGeoType.Node:
                this.Translate(scene, projection, CompleteNode.CreateFrom(osmGeo as Node));
                break;

            case OsmGeoType.Way:
                this.Translate(scene, projection, CompleteWay.CreateFrom(osmGeo as Way, source));
                break;

            case OsmGeoType.Relation:
                this.Translate(scene, projection, CompleteRelation.CreateFrom(osmGeo as Relation, source));
                break;
            }
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Tries to interpret a given multipolygon relation.
        /// </summary>
        private Feature InterpretMultipolygonRelation(CompleteRelation relation)
        {
            Feature feature = null;

            if (relation.Members == null)
            { // the relation has no members.
                return(null);
            }

            // build lists of outer and inner ways.
            var ways = new List <KeyValuePair <bool, CompleteWay> >(); // outer=true

            foreach (var member in relation.Members)
            {
                switch (member.Role)
                {
                case "inner" when member.Member is CompleteWay:     // an inner member.
                    ways.Add(new KeyValuePair <bool, CompleteWay>(
                                 false, member.Member as CompleteWay));
                    break;

                case "outer" when member.Member is CompleteWay:     // an outer member.
                    ways.Add(new KeyValuePair <bool, CompleteWay>(
                                 true, member.Member as CompleteWay));
                    break;
                }
            }

            // started a similar algorithm and then found this:
            // loosely based on: http://wiki.openstreetmap.org/wiki/Relation:multipolygon/Algorithm

            // recusively try to assign the rings.
            if (!this.AssignRings(ways, out var rings))
            {
                Logging.Logger.Log("DefaultFeatureInterpreter", TraceEventType.Error,
                                   $"Ring assignment failed: invalid multipolygon relation [{relation.Id}] detected!");
            }
            // group the rings and create a multipolygon.
            var geometry = this.GroupRings(rings);

            if (geometry != null)
            {
                feature = new Feature(geometry, TagsAndIdToAttributes(relation));
            }
            return(feature);
        }
Ejemplo n.º 21
0
        public virtual FeatureCollection Interpret(OsmGeo simpleOsmGeo, IDataSourceReadOnly data)
        {
            switch (simpleOsmGeo.Type)
            {
            case OsmGeoType.Node:
                return(this.Interpret((ICompleteOsmGeo)(simpleOsmGeo as Node)));

            case OsmGeoType.Way:
                return(this.Interpret((ICompleteOsmGeo)CompleteWay.CreateFrom(simpleOsmGeo as Way, (INodeSource)data)));

            case OsmGeoType.Relation:
                return(this.Interpret((ICompleteOsmGeo)CompleteRelation.CreateFrom(simpleOsmGeo as Relation, (IOsmGeoSource)data)));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Ejemplo n.º 22
0
        public void ToGeoJson_MultiPolygonWithHole_ShouldReturnMultiPlygonWithSinglePolygon()
        {
            var node1    = CreateNode(1, 0, 0);
            var node2    = CreateNode(2, 1, 0);
            var node3    = CreateNode(3, 1, 1);
            var node4    = CreateNode(4, 0, 1);
            var node5    = CreateNode(5, 0.5, 0.5);
            var node6    = CreateNode(6, 0.5, 0.6);
            var node7    = CreateNode(7, 0.6, 0.6);
            var node8    = CreateNode(8, 0.6, 0.5);
            var wayOuter = new CompleteWay
            {
                Id    = 9,
                Nodes = new[] { node1, node2, node3, node4, node1 }
            };
            var wayInner = new CompleteWay
            {
                Id    = 9,
                Nodes = new[] { node5, node6, node7, node8, node5 }
            };
            var relation = new CompleteRelation
            {
                Id      = 10,
                Tags    = new TagsCollection(),
                Members = new[]
                {
                    new CompleteRelationMember {
                        Member = wayInner, Role = "inner"
                    },
                    new CompleteRelationMember {
                        Member = wayOuter, Role = "outer"
                    }
                }
            };

            relation.Tags.Add("boundary", "true");

            var geoJson = _converter.ToGeoJson(relation);

            var multiPlygon = geoJson.Geometry as MultiPolygon;

            Assert.IsNotNull(multiPlygon);
            Assert.IsTrue(multiPlygon.IsValid);
            Assert.AreEqual(1, multiPlygon.Geometries.Length);
        }
Ejemplo n.º 23
0
        public void ToGeoJson_UnsortedRelation_ShouldReturnMultiLineStringAfterGrouping()
        {
            var node1 = CreateNode(1);
            var node2 = CreateNode(2);
            var node3 = CreateNode(3);
            var node4 = CreateNode(4);
            var wayPartOfLineString1 = new CompleteWay {
                Id = 8
            };
            var wayPartOfLineString2 = new CompleteWay {
                Id = 9
            };
            var wayPartOfLineString3 = new CompleteWay {
                Id = 10
            };

            wayPartOfLineString1.Nodes = new[] { node1, node2 };
            wayPartOfLineString2.Nodes = new[] { node3, node4 };
            wayPartOfLineString3.Nodes = new[] { node3, node2 };
            var relation = new CompleteRelation {
                Id = 11, Tags = new TagsCollection()
            };

            relation.Tags.Add(NAME, NAME);
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = wayPartOfLineString1
                },
                new CompleteRelationMember {
                    Member = wayPartOfLineString2
                },
                new CompleteRelationMember {
                    Member = wayPartOfLineString3
                }
            };

            var feature         = _converter.ToGeoJson(relation);
            var multiLineString = feature.Geometry as MultiLineString;

            Assert.IsNotNull(multiLineString);
            Assert.AreEqual(1, multiLineString.Geometries.Length);
            var lineString = multiLineString.Geometries.First();

            Assert.AreEqual(4, lineString.Coordinates.Length);
        }
Ejemplo n.º 24
0
        public void PreprocessAreaRelationRoute_ShouldGetGeoLocationAtStart()
        {
            var node1 = CreateNode(1, 0, 0);
            var node2 = CreateNode(2, 1, 1);
            var node3 = CreateNode(3, 1, 0);
            var way1  = new CompleteWay
            {
                Nodes = new[] { node1, node2, node3 },
            };
            var way2 = new CompleteWay
            {
                Nodes = new[] { node3, node1 },
            };
            var relaction = new CompleteRelation
            {
                Members = new []
                {
                    new CompleteRelationMember {
                        Member = way1, Role = ""
                    },
                    new CompleteRelationMember {
                        Member = way2, Role = ""
                    },
                },
                Tags = new TagsCollection
                {
                    { "route", "bike" }
                }
            };
            var osmElements = new List <ICompleteOsmGeo> {
                relaction
            };
            var dictionary = new Dictionary <string, List <ICompleteOsmGeo> > {
                { FeatureAttributes.NAME, osmElements }
            };

            var results = _preprocessorExecutor.Preprocess(dictionary);

            Assert.AreEqual(1, results.Count);
            var geoLocation = results.First().Attributes[FeatureAttributes.POI_GEOLOCATION] as IAttributesTable;

            Assert.IsNotNull(geoLocation);
            Assert.AreEqual(node1.Latitude, geoLocation[FeatureAttributes.LAT]);
        }
Ejemplo n.º 25
0
        public void ToGeoJson_ConvertLoopAndLines_ShouldCreateValidMultiLine()
        {
            int id    = 1;
            var node1 = CreateNode(id++, 0, 0);
            var node2 = CreateNode(id++, 0, 1);
            var node3 = CreateNode(id++, 1, 1);
            var node4 = CreateNode(id++, 1, 0);

            var node5 = CreateNode(id++, 0, -1);

            var way1 = new CompleteWay {
                Id = id++, Nodes = new[] { node1, node5 }
            };
            var way2 = new CompleteWay {
                Id = id++, Nodes = new[] { node1, node2, node3, node4, node1 }
            };

            var relation = new CompleteRelation {
                Id = id++, Tags = new TagsCollection()
            };

            relation.Tags.Add(NAME, NAME);
            relation.Members = new[] {
                new CompleteRelationMember {
                    Member = way1, Role = "outer"
                },
                new CompleteRelationMember {
                    Member = way2, Role = "outer"
                }
            };

            var feature         = _converter.ToGeoJson(relation);
            var multiLineString = feature.Geometry as MultiLineString;

            Assert.IsNotNull(multiLineString);
            var isValidOp = new IsValidOp(multiLineString);

            Assert.IsTrue(isValidOp.IsValid);
        }
Ejemplo n.º 26
0
        /// <summary>
        /// Translates the given OSM objects into corresponding geometries.
        /// </summary>
        /// <param name="scene"></param>
        /// <param name="projection"></param>
        /// <param name="source"></param>
        /// <param name="osmGeo"></param>
        public virtual void Translate(Scene2D scene, IProjection projection, IDataSourceReadOnly source, OsmGeo osmGeo)
        {
            switch (osmGeo.Type)
            {
            case OsmGeoType.Node:
                var node = osmGeo as Node;
                if (node.Tags == null)
                {     // make sure that a node has a tag collection by default.
                    node.Tags = new TagsCollection();
                }
                this.Translate(scene, projection, node);
                break;

            case OsmGeoType.Way:
                this.Translate(scene, projection, CompleteWay.CreateFrom(osmGeo as Way, source));
                break;

            case OsmGeoType.Relation:
                this.Translate(scene, projection, CompleteRelation.CreateFrom(osmGeo as Relation, source));
                break;
            }
        }
        public void Scene2DSimpleSerializeDeserializeTest()
        {
            // create the MapCSS image source.
            var imageSource = new MapCSSDictionaryImageSource();

            // load mapcss style interpreter.
            var mapCSSInterpreter = new MapCSSInterpreter(
                Assembly.GetExecutingAssembly().GetManifestResourceStream(
                    "OsmSharp.UI.Test.Unittests.Data.MapCSS.test.mapcss"),
                imageSource);

            // initialize the data source.
            var xmlSource = new XmlOsmStreamSource(
                Assembly.GetExecutingAssembly().GetManifestResourceStream(
                    "OsmSharp.UI.Test.Unittests.Data.test.osm"));
            IEnumerable <OsmGeo> dataSource = xmlSource;
            MemoryDataSource     source     = MemoryDataSource.CreateFrom(xmlSource);

            // get data.
            var scene            = new Scene2DSimple();
            var projection       = new WebMercator();
            GeoCoordinateBox box = null;

            foreach (var osmGeo in dataSource)
            {
                CompleteOsmGeo completeOsmGeo = null;
                switch (osmGeo.Type)
                {
                case OsmGeoType.Node:
                    completeOsmGeo = CompleteNode.CreateFrom(osmGeo as Node);
                    break;

                case OsmGeoType.Way:
                    completeOsmGeo = CompleteWay.CreateFrom(osmGeo as Way,
                                                            source);
                    break;

                case OsmGeoType.Relation:
                    completeOsmGeo = CompleteRelation.CreateFrom(osmGeo as Relation,
                                                                 source);
                    break;
                }

                // update box.
                if (completeOsmGeo != null)
                {
                    if (box == null)
                    {
                        box = completeOsmGeo.BoundingBox;
                    }
                    else if (completeOsmGeo.BoundingBox != null)
                    {
                        box = box + completeOsmGeo.BoundingBox;
                    }
                }

                // translate each object into scene object.
                mapCSSInterpreter.Translate(scene, projection, source, osmGeo as OsmGeo);
            }

            // create the stream.
            var stream = new MemoryStream();

            scene.Serialize(stream, false);

            // deserialize the stream.
            IScene2DPrimitivesSource sceneSource = Scene2DSimple.Deserialize(stream, false);

            if (box != null)
            {
                // query both and get the same results.
                int counter = 100;
                var rand    = new Random();
                while (counter > 0)
                {
                    var queryBox = new GeoCoordinateBox(
                        box.GenerateRandomIn(rand),
                        box.GenerateRandomIn(rand));
                    var    zoomFactor = (float)projection.ToZoomFactor(15);
                    View2D testView   = View2D.CreateFromBounds(
                        projection.LatitudeToY(queryBox.MaxLat),
                        projection.LongitudeToX(queryBox.MinLon),
                        projection.LatitudeToY(queryBox.MinLat),
                        projection.LongitudeToX(queryBox.MaxLon));
                    var testScene = new Scene2DSimple();
                    sceneSource.Get(testScene, testView, zoomFactor);

//                    var resultIndex = new HashSet<Scene2DPrimitive>(testScene.Get(testView, zoomFactor));
//                    var resultReference = new HashSet<Scene2DPrimitive>(scene.Get(testView, zoomFactor));

                    //Assert.AreEqual(resultReference.Count, resultIndex.Count);
                    //foreach (var data in resultIndex)
                    //{
                    //    Assert.IsTrue(resultReference.Contains(data));
                    //}
                    //foreach (var data in resultReference)
                    //{
                    //    Assert.IsTrue(resultIndex.Contains(data));
                    //}
                    counter--;
                }
            }
        }
Ejemplo n.º 28
0
 /// <summary>
 /// Adds a relation to the target.
 /// </summary>
 /// <param name="relation"></param>
 public abstract void AddRelation(CompleteRelation relation);
Ejemplo n.º 29
0
        /// <summary>
        /// Tries to interpret a given multipolygon relation.
        /// </summary>
        /// <param name="relation"></param>
        /// <returns></returns>
        private Geometry InterpretMultipolygonRelation(CompleteRelation relation)
        {
            Geometry geometry = null;
            if (relation.Members == null)
            { // the relation has no members.
                return geometry;
            }

            // build lists of outer and inner ways.
            var ways = new List<KeyValuePair<bool, CompleteWay>>(); // outer=true
            foreach (CompleteRelationMember member in relation.Members)
            {
                if (member.Role == "inner" &&
                    member.Member is CompleteWay)
                { // an inner member.
                    ways.Add(new KeyValuePair<bool, CompleteWay>(
                        false, member.Member as CompleteWay));
                }
                else if (member.Role == "outer" &&
                    member.Member is CompleteWay)
                { // an outer member.
                    ways.Add(new KeyValuePair<bool, CompleteWay>(
                        true, member.Member as CompleteWay));
                }
            }

            // started a similar algorithm and then found this:
            // loosely based on: http://wiki.openstreetmap.org/wiki/Relation:multipolygon/Algorithm

            // recusively try to assign the rings.
            List<KeyValuePair<bool, LineairRing>> rings;
            if (!this.AssignRings(ways, out rings))
            {
                OsmSharp.Logging.Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error,
                    string.Format("Ring assignment failed: invalid multipolygon relation [{0}] detected!", relation.Id));
            }
            // group the rings and create a multipolygon.
            geometry = this.GroupRings(rings);
            if (geometry != null)
            {
                // assign attributes.
                geometry.Attributes = new SimpleGeometryAttributeCollection(relation.Tags);
            }
            return geometry;
        }
Ejemplo n.º 30
0
 /// <summary>
 /// Returns all restrictions that are represented by the given node.
 /// </summary>
 /// <param name="completeRelation"></param>
 /// <returns></returns>
 public List <KeyValuePair <Vehicle, long[]> > CalculateRestrictions(CompleteRelation completeRelation)
 {
     return(new List <KeyValuePair <Vehicle, long[]> >());
 }
Ejemplo n.º 31
0
        private static Dictionary <string, List <CompleteWay> > GetAllWaysGroupedByRole(CompleteRelation relation)
        {
            var dicionary = relation.Members.GroupBy(m => m.Role ?? string.Empty)
                            .ToDictionary(g => g.Key, g => g.Select(k => k.Member)
                                          .OfType <CompleteWay>().ToList());

            if (relation.Members.All(m => m.Member.Type != OsmGeoType.Relation))
            {
                return(dicionary);
            }
            var subRelations = relation.Members.Select(m => m.Member).OfType <CompleteRelation>();

            foreach (var subRelation in subRelations)
            {
                var subRelationDictionary = GetAllWaysGroupedByRole(subRelation);
                foreach (var key in subRelationDictionary.Keys)
                {
                    if (dicionary.ContainsKey(key))
                    {
                        dicionary[key].AddRange(subRelationDictionary[key]);
                    }
                    else
                    {
                        dicionary[key] = subRelationDictionary[key];
                    }
                }
            }
            return(dicionary);
        }