// public static void InfuseLanduse( // this IEnumerable<(CompleteWay, List<(long, long)>)> polygons, // CompleteWay landusePolygon, string classification) // { // if (landusePolygon.IsClockwise()) // { // Array.Reverse(landusePolygon.Nodes); // } // // var landuseBBox = new BBox(landusePolygon); // // var key = "_classification:" + classification; // // foreach (var (polygon , _) in polygons) // { // Array.Reverse(polygon.Nodes); // var totalSize = 0.0; // // if (polygon.Tags == null) // { // polygon.Tags = new TagsCollection(); // } // // if (polygon.Tags.TryGetValue(key, out var value)) // { // double.TryParse(value, out totalSize); // } // // // var polygonBBox = new BBox(polygon); // if (!polygonBBox.OverlapsWith(landuseBBox)) // { // continue; // } // // // var allWays = new[] {polygon, landusePolygon}.SplitAllWays(); // // // We use splitAllWays to intersect the polygon // // Note that this is invoked by but two lines, which either intersect or do not intersect at all. // // if (allWays.Count == 2) // { // // If there are but two lines, these are the same as the original lines. // // Here, three things can happen: // // - The landusepolygon is completely contained into the polygon, // // - The polygon is completely contained in the landuse polygon // // - There is no overlap at all // // if (landusePolygon.FullyContains(polygon)) // { // totalSize += polygon.Area(); // } // else if (polygon.FullyContains(landusePolygon)) // { // totalSize += landusePolygon.Area(); // } // // // No overlap - we don't do anything // } // else // { // // There is overlap in the polygon // totalSize += SplitWays.IntersectionSurfaceBetween(polygon, landusePolygon); // } // // // polygon.Tags[key] = "" + totalSize; // } // } public static IEnumerable <(long from, long to)> IdPairs(this CompleteWay way) { for (var i = 1; i < way.Nodes.Length; i++) { yield return(way.Nodes[i - 1].Id.Value, way.Nodes[i].Id.Value); } }
public void PreprocessWithPlaceAndWay_ShouldMergePlaceIntoIt() { var node1 = CreateNode(1, 0, 0); var node2 = CreateNode(2, 0, 1); var node3 = CreateNode(3, 1, 1); var node4 = CreateNode(4, 1, 0); var node5 = CreateNode(5, 0.5, 0.6); node5.Tags.Add("place", "any"); var way1 = new CompleteWay { Id = 6, Tags = new TagsCollection { { FeatureAttributes.NAME, "name" } }, Nodes = new[] { node1, node2, node3, node4, node1 } }; var osmElements = new List <ICompleteOsmGeo> { node5, way1 }; var dictionary = new Dictionary <string, List <ICompleteOsmGeo> > { { FeatureAttributes.NAME, osmElements } }; var results = _preprocessorExecutor.Preprocess(dictionary); Assert.AreEqual(1, results[results.Keys.First()].Count); var geoLocation = results[results.Keys.First()].First().Attributes[FeatureAttributes.GEOLOCATION] as AttributesTable; Assert.IsNotNull(geoLocation); Assert.AreEqual(0.5, geoLocation[FeatureAttributes.LAT]); Assert.AreEqual(0.6, geoLocation[FeatureAttributes.LON]); }
public void PreprocessOneWayAndOneRelation_ShouldRemoveWayAndAddItToRelation() { var node1 = CreateNode(1); var node2 = CreateNode(2); var node3 = CreateNode(3); var node4 = CreateNode(4); var way1 = new CompleteWay { Id = 5, Tags = new TagsCollection(), Nodes = new[] { node1, node2 } }; way1.Tags.Add("waterway", "stream"); var way2 = new CompleteWay { Id = 6, Tags = new TagsCollection(), Nodes = new[] { node3, node4 } }; var osmElements = new List <ICompleteOsmGeo> { node1, node2, node3, node4, way1, way2 }; var dictionary = new Dictionary <string, List <ICompleteOsmGeo> > { { FeatureAttributes.NAME, osmElements } }; var results = _preprocessorExecutor.Preprocess(dictionary); Assert.AreEqual(5, results.Count); Assert.AreEqual(4, results.Count(f => f.Geometry is Point)); Assert.AreEqual(1, results.Count(f => f.Geometry is LineString)); }
public void TestUpdate_OsmChangeFileWithModification_ShouldUpdateDatabase() { var way = new CompleteWay() { Id = 1, Tags = new TagsCollection { { "highway", "track" }, { "route", "bicycle" } }, Nodes = new Node[0] }; var changes = new OsmChange { Create = new OsmGeo[0], Modify = new OsmGeo[] { way.ToSimple() }, Delete = new OsmGeo[0] }; var list = new List <Feature> { new Feature(new LineString(new Coordinate[0]), new AttributesTable()) }; _geoJsonPreprocessorExecutor .Preprocess(Arg.Is <Dictionary <string, List <ICompleteOsmGeo> > >(x => x.Values.Count == 1)) .Returns(list); _geoJsonPreprocessorExecutor .Preprocess(Arg.Is <List <CompleteWay> >(x => x.Count == 1)) .Returns(list); _osmGateway.GetCompleteWay(1).Returns(way); _service.Update(changes).Wait(); _elasticSearchGateway.Received(1).UpdatePointsOfInterestData(Arg.Is <List <Feature> >(x => x.Count == 1)); _elasticSearchGateway.Received(1).UpdateHighwaysData(Arg.Is <List <Feature> >(x => x.Count == 1)); }
/// <summary> /// Returns a linestring exactly representing the way. /// </summary> /// <param name="way">The way.</param> /// <returns>A linestring.</returns> public static LineString ToLineString(this CompleteWay way) { if (way == null) { throw new ArgumentNullException(nameof(way)); } if (way.Nodes == null) { throw new ArgumentException($"{nameof(way)} has no nodes."); } if (way.Nodes.Length < 2) { throw new ArgumentException($"{nameof(way)} has not enough nodes."); } var coordinates = new Coordinate[way.Nodes.Length]; for (var n = 0; n < way.Nodes.Length; n++) { var node = way.Nodes[n]; if (node.Longitude == null || node.Latitude == null) { continue; } coordinates[n] = new Coordinate(node.Longitude.Value, node.Latitude.Value); } return(new LineString(coordinates)); }
/// <summary> /// Compares the two complete objects. /// </summary> public static void CompareComplete(CompleteWay expected, CompleteWay 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.Nodes == null) { // ok, if the value is also null. Assert.IsNotNull(actual.Nodes); } else { // check and compare the nodes. Assert.AreEqual(expected.Nodes.Count, actual.Nodes.Count); for (int idx = 0; idx < expected.Nodes.Count; idx++) { ComparisonHelpers.CompareComplete( expected.Nodes[idx], actual.Nodes[idx]); } } } }
public void PreprocessWaysWithSameDirection_ShouldReturnOneLineString() { var node1 = CreateNode(1); var node2 = CreateNode(2); var node3 = CreateNode(3); var way1 = new CompleteWay { Id = 4, Tags = new TagsCollection() }; way1.Tags.Add(FeatureAttributes.NAME, "name"); way1.Tags.Add("place", "name"); way1.Nodes = new[] { node2, node3 }; var way2 = new CompleteWay { Id = 5, Tags = new TagsCollection() }; way2.Tags.Add(FeatureAttributes.NAME, "name"); way2.Tags.Add("place", "name"); way2.Nodes = new[] { node1, node3 }; var osmElements = new List <ICompleteOsmGeo> { node1, node2, node3, way1, way2 }; var dictionary = new Dictionary <string, List <ICompleteOsmGeo> > { { FeatureAttributes.NAME, osmElements } }; var results = _preprocessorExecutor.Preprocess(dictionary); Assert.AreEqual(1, results.Count(f => f.Geometry is LineString)); }
/// <summary> /// Returns the coordinates of a way's nodes projected and with elevation. /// </summary> /// <param name="way"></param> /// <param name="offsetX"></param> /// <param name="offsetY"></param> /// <returns></returns> public static List<Vector3> ProjectWay(CompleteWay way, Point offset, IProjection projection, Elevation elevation, bool fetchElevation = true) { var nodes = new List<Vector3>(); for (int i = 0; i < way.Nodes.Length; i++) { var node = way.Nodes[i]; // convert to X/Y var projPos = projection.Project(node); // apply offset projPos.X -= offset.X; projPos.Y -= offset.Y; // flip vertically because Z is down projPos.Y *= -1; double el = 0; if (fetchElevation) el = elevation.GetElevation(node.Latitude.Value, node.Longitude.Value); var vector = new Vector3((float)projPos.X, (float)el, (float)projPos.Y); nodes.Add(vector); } return nodes; }
/// <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); }
public void PreprocessPlaceNodeWithContainerPlaceFromDatabase_ShouldUpdateAddress() { var node1 = CreateNode(1, 0, 0); var node2 = CreateNode(2, 0, 1); var node3 = CreateNode(3, 1, 1); var node4 = CreateNode(4, 1, 0); var node5 = CreateNode(5, 0.5, 0.6); node5.Tags.Add("place", "any"); var way1 = new CompleteWay { Id = 6, Tags = new TagsCollection { { FeatureAttributes.NAME, FeatureAttributes.NAME }, { "place", "any" } }, Nodes = new[] { node1, node2, node3, node4, node1 } }; var dictionary = new Dictionary <string, List <ICompleteOsmGeo> > { { FeatureAttributes.NAME, new List <ICompleteOsmGeo> { node5, way1 } }, }; var databaseMock = _preprocessorExecutor.Preprocess(dictionary); var cloned = _preprocessorExecutor.Preprocess(dictionary); databaseMock.First().Geometry = databaseMock.Last().Geometry; var results = _preprocessorExecutor.MergePlaceNodes(cloned.Take(1).ToList(), databaseMock.Where(f => f.Geometry is Polygon).ToList()); Assert.AreEqual(1, results.Count); Assert.IsTrue(results.First().Geometry is Polygon); }
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_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()); }
public static void CombineSegments(CompleteWay subject, CompleteWay reference) { if (subject.Nodes.Last().Id == reference.Nodes.First().Id) { subject.Nodes = subject.Nodes.Concat(reference.Nodes.Skip(1)).ToArray(); } else if (subject.Nodes.Last().Id == reference.Nodes.Last().Id) { if (reference.Tags != null && reference.Tags.ContainsKey("oneway")) { throw new InvalidOperationException("Reversing a oneway"); } subject.Nodes = subject.Nodes.Concat(reference.Nodes.Reverse().Skip(1)).ToArray(); } else if (subject.Nodes.First().Id == reference.Nodes.Last().Id) { subject.Nodes = reference.Nodes.Concat(subject.Nodes.Skip(1)).ToArray(); } else if (subject.Nodes.First().Id == reference.Nodes.First().Id) { if (reference.Tags != null && reference.Tags.ContainsKey("oneway")) { throw new InvalidOperationException("Reversing a oneway"); } subject.Nodes = reference.Nodes.Reverse().Concat(subject.Nodes.Skip(1)).ToArray(); } else { throw new Exception("Ways are not end-to-end, and can't be combined"); } }
public void PreprocessArea_ShouldGetGeoLocationCenter() { var node1 = CreateNode(1, 0, 0); var node2 = CreateNode(1, 0, 1); var node3 = CreateNode(1, 1, 1); var node4 = CreateNode(1, 1, 0); var way = new CompleteWay { Nodes = new[] { node1, node2, node3, node4, node1 }, Tags = new TagsCollection { { FeatureAttributes.NAME, "name" } } }; var osmElements = new List <ICompleteOsmGeo> { way }; 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(0.5, geoLocation[FeatureAttributes.LAT]); Assert.AreEqual(0.5, geoLocation[FeatureAttributes.LAT]); }
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 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); }
/// <summary> /// Returns the centroid of a building. /// </summary> private static LatLon GetCentroid(CompleteWay building) { var points = building.Nodes.Select( x => new GeoAPI.Geometries.Coordinate(x.Latitude.Value, x.Longitude.Value)) .ToArray(); var poly = new NetTopologySuite.Geometries.Polygon(new NetTopologySuite.Geometries.LinearRing(points)); var centroid = poly.Centroid.Coordinate; return(new LatLon(centroid.X, centroid.Y)); }
/// <summary> /// Splits a way into individual segments /// </summary> public static IEnumerable <CompleteWay> AsSegments(this CompleteWay way) { for (var i = 1; i < way.Nodes.Length; i++) { yield return(new CompleteWay() { Nodes = new[] { way.Nodes[i - 1], way.Nodes[i] } }); } }
public void TestToSimple() { var completeWay = new CompleteWay() { ChangeSetId = 1, Id = 10, Nodes = new Node[] { new Node() { Id = 1 }, new Node() { Id = 2 }, new Node() { Id = 3 } }, Tags = new Tags.TagsCollection( new Tags.Tag("tag1", "value1"), new Tags.Tag("tag2", "value2")), TimeStamp = DateTime.Now, UserName = "******", UserId = 1, Version = 23, Visible = true }; var osmGeo = completeWay.ToSimple(); Assert.IsNotNull(osmGeo); Assert.IsInstanceOf <Way>(osmGeo); var way = osmGeo as Way; Assert.AreEqual(completeWay.Id, way.Id); Assert.AreEqual(completeWay.ChangeSetId, way.ChangeSetId); Assert.AreEqual(completeWay.TimeStamp, way.TimeStamp); Assert.AreEqual(completeWay.UserName, way.UserName); Assert.AreEqual(completeWay.UserId, way.UserId); Assert.AreEqual(completeWay.Version, way.Version); Assert.AreEqual(completeWay.Visible, way.Visible); Assert.IsNotNull(way.Nodes); Assert.AreEqual(completeWay.Nodes.Length, way.Nodes.Length); for (var i = 0; i < completeWay.Nodes.Length; i++) { Assert.AreEqual(completeWay.Nodes[i].Id, way.Nodes[i]); } }
/// <summary> /// Gets the coordinates from the given way. /// </summary> public static List <Coordinate> GetCoordinates(this CompleteWay way) { if (way.Nodes != null) { var coordinates = new List <Coordinate>(); for (int i = 0; i < way.Nodes.Length; i++) { coordinates.Add(way.Nodes[i].GetCoordinate()); } return(coordinates); } return(null); }
public void ToGeoJson_WayWithOneNode_ShouldReturnNull() { var node = CreateNode(1); var way = new CompleteWay { Id = 2, Tags = new TagsCollection() }; way.Nodes = new[] { node }; way.Tags.Add(NAME, NAME); var feature = _converter.ToGeoJson(way); Assert.IsNull(feature); }
/// <summary> /// Completes an uncompleted ring. /// </summary> /// <param name="ways"></param> /// <param name="assignedFlags"></param> /// <param name="nodes"></param> /// <param name="role"></param> /// <returns></returns> private bool CompleteRing(List <KeyValuePair <bool, CompleteWay> > ways, bool[] assignedFlags, List <CompleteNode> nodes, bool?role) { for (int idx = 0; idx < ways.Count; idx++) { if (!assignedFlags[idx]) { // way not assigned. KeyValuePair <bool, CompleteWay> wayEntry = ways[idx]; CompleteWay nextWay = wayEntry.Value; if (!role.HasValue || wayEntry.Key == role.Value) { // only try matching roles if the role has been set. List <CompleteNode> nextNodes = null; if (nodes[nodes.Count - 1].Id == nextWay.Nodes[0].Id) { // last node of the previous way is the first node of the next way. nextNodes = nextWay.Nodes.GetRange(1, nextWay.Nodes.Count - 1); assignedFlags[idx] = true; } else if (nodes[nodes.Count - 1].Id == nextWay.Nodes[nextWay.Nodes.Count - 1].Id) { // last node of the previous way is the last node of the next way. nextNodes = nextWay.Nodes.GetRange(0, nextWay.Nodes.Count - 1); nextNodes.Reverse(); assignedFlags[idx] = true; } // add the next nodes if any. if (assignedFlags[idx]) { // yep, way was assigned! nodes.AddRange(nextNodes); if (nodes[nodes.Count - 1].Id == nodes[0].Id) { // yes! a closed ring was found! return(true); } else { // noo! ring not closed yet! if (this.CompleteRing(ways, assignedFlags, nodes, role)) { // yes! a complete ring was found return(true); } else { // damn complete ring not found. backtrack people! assignedFlags[idx] = false; nodes.RemoveRange(nodes.Count - nextNodes.Count, nextNodes.Count); } } } } } } return(false); }
private static Polygon ToPolygon(CompleteWay w) { var coordinates = new Coordinate[w.Nodes.Length]; var i = 0; foreach (var n in w.Nodes) { var p = new Coordinate(n.Longitude.Value, n.Latitude.Value); coordinates[i] = p; i++; } return(new Polygon(new LinearRing(coordinates))); }
public static CompleteWay Reduce(CompleteWay way) { var lineString = way.AsLineString(); var reducer = new NetTopologySuite.Precision.GeometryPrecisionReducer(new PrecisionModel() { }); NetTopologySuite.Simplify.DouglasPeuckerLineSimplifier.Simplify(way.GetCoordinates().ToArray(), .0004); var geometry = (LineString)reducer.Reduce(lineString); //way = return(way); }
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 static Way AsOsmGeo(this CompleteWay way) { return(new Way() { Id = way.Id, Nodes = way.Nodes.Select(n => n.Id.Value).ToArray(), Tags = way.Tags, Version = way.Version, Visible = way.Visible, ChangeSetId = way.ChangeSetId, TimeStamp = way.TimeStamp, UserId = way.UserId, UserName = way.UserName }); }
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; } }
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(); } }