public static LinearRing AsBoundingPolygon(CompleteRelation relation) { var thing = DefaultFeatureInterpreter.DefaultInterpreter.Interpret(relation).OfType <LinearRing>().First(); relation.Members.Where(r => r.Role == "outer"); return(thing); }
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); }
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); }
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); }
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); }
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))); }
/// <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); }
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); }
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; } } } } }
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); }
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))); }
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); }
/// <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); }
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); }
/// <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(); }
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); }
/// <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; } }
/// <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); }
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(); } }
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); }
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); }
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]); }
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); }
/// <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--; } } }
/// <summary> /// Adds a relation to the target. /// </summary> /// <param name="relation"></param> public abstract void AddRelation(CompleteRelation relation);
/// <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; }
/// <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[]> >()); }
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); }