/// <summary> /// Groups the rings into polygons. /// </summary> /// <param name="rings"></param> /// <returns></returns> private Geometry GroupRings(List<KeyValuePair<bool, LineairRing>> rings) { Geometry geometry = null; bool[][] containsFlags = new bool[rings.Count][]; // means [x] contains [y] for (int x = 0; x < rings.Count; x++) { containsFlags[x] = new bool[rings.Count]; for (int y = 0; y < x; y++) { containsFlags[x][y] = rings[x].Value.Contains(rings[y].Value); } } bool[] used = new bool[rings.Count]; MultiPolygon multiPolygon = null; while (used.Contains(false)) { // select a ring not contained by any other. LineairRing outer = null; int outerIdx = -1; for (int idx = 0; idx < rings.Count; idx++) { if (!used[idx] && this.CheckUncontained(rings, containsFlags, used, idx)) { // this ring is not contained in any other used rings. if (!rings[idx].Key) { OsmSharp.Logging.Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error, "Invalid multipolygon relation: an 'inner' ring was detected without an 'outer'."); } outerIdx = idx; outer = rings[idx].Value; used[idx] = true; break; } } if (outer != null) { // an outer ring was found, find inner rings. List<LineairRing> inners = new List<LineairRing>(); // select all rings contained by inner but not by any others. for (int idx = 0; idx < rings.Count; idx++) { if (!used[idx] && containsFlags[outerIdx][idx] && this.CheckUncontained(rings, containsFlags, used, idx)) { inners.Add(rings[idx].Value); used[idx] = true; } } bool unused = !used.Contains(false); if (multiPolygon == null && inners.Count == 0 && unused) { // there is just one lineair ring. geometry = outer; break; } else if (multiPolygon == null && unused) { // there is just one polygon. Polygon polygon = new Polygon( outer, inners); geometry = polygon; break; } else { // there have to be other polygons. { multiPolygon = new MultiPolygon(); geometry = multiPolygon; } Polygon polygon = new Polygon( outer, inners); multiPolygon.Add(polygon); } } else { // unused rings left but they cannot be designated as 'outer'. OsmSharp.Logging.Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error, "Invalid multipolygon relation: Unassigned rings left."); break; } } return geometry; }
/// <summary> /// Translates a multipolygon. /// </summary> /// <param name="scene">The scene to add primitives to.</param> /// <param name="projection">The projection used to convert the objects.</param> /// <param name="multiPolygon"></param> private void TranslateMultiPolygon(Scene2D scene, IProjection projection, MultiPolygon multiPolygon) { foreach(Polygon polygon in multiPolygon) { polygon.Attributes = multiPolygon.Attributes; this.TranslatePolygon(scene, projection, polygon); } }
public void TestMultiPolygonSerialization() { var geometry1 = new Polygon(new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0), new GeoCoordinate(0, 0) })); var geometry2 = new Polygon(new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 2), new GeoCoordinate(2, 2), new GeoCoordinate(2, 0), new GeoCoordinate(0, 0) })); var geometry3 = new Polygon(new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 3), new GeoCoordinate(3, 3), new GeoCoordinate(3, 0), new GeoCoordinate(0, 0) })); var geometryCollection = new MultiPolygon(new Polygon[] { geometry1, geometry2, geometry3 }); var serialized = geometryCollection.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]],[[[0.0,0.0],[2.0,0.0],[2.0,2.0],[0.0,2.0],[0.0,0.0]]],[[[0.0,0.0],[3.0,0.0],[3.0,3.0],[0.0,3.0],[0.0,0.0]]]]}", serialized); }
/// <summary> /// Generates GeoJson for the given geometry collection. /// </summary> /// <param name="writer"></param> /// <param name="geometryCollection"></param> internal static void Write(JsonWriter writer, MultiPolygon geometryCollection) { if (writer == null) { throw new ArgumentNullException("writer"); } if (geometryCollection == null) { throw new ArgumentNullException("geometryCollection"); } writer.WriteStartObject(); writer.WritePropertyName("type"); writer.WriteValue("MultiPolygon"); writer.WritePropertyName("coordinates"); writer.WriteStartArray(); foreach (var geometry in geometryCollection) { writer.WriteStartArray(); writer.WriteStartArray(); foreach (var coordinate in geometry.Ring.Coordinates) { writer.WriteStartArray(); writer.WriteValue(coordinate.Longitude); writer.WriteValue(coordinate.Latitude); writer.WriteEndArray(); } writer.WriteEndArray(); foreach (var hole in geometry.Holes) { writer.WriteStartArray(); foreach (var coordinate in hole.Coordinates) { writer.WriteStartArray(); writer.WriteValue(coordinate.Longitude); writer.WriteValue(coordinate.Latitude); writer.WriteEndArray(); } writer.WriteEndArray(); } writer.WriteEndArray(); } writer.WriteEndArray(); writer.WriteEndObject(); }
public void TestGeometryCollectionSerialization() { var geometry1 = new LineString( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0) }); var geometry2 = new LineString( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 2), new GeoCoordinate(2, 2), new GeoCoordinate(2, 0) }); var geometry3 = new LineString( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 3), new GeoCoordinate(3, 3), new GeoCoordinate(3, 0) }); var geometry4 = new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0), new GeoCoordinate(0, 0) }); var geometry5 = new Polygon(new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 1), new GeoCoordinate(1, 1), new GeoCoordinate(1, 0), new GeoCoordinate(0, 0) })); var geometry6 = new MultiPolygon(geometry5, new Polygon(new LineairRing( new GeoCoordinate[] { new GeoCoordinate(0, 0), new GeoCoordinate(0, 2), new GeoCoordinate(2, 2), new GeoCoordinate(2, 0), new GeoCoordinate(0, 0) }))); var geometry7 = new Point(new GeoCoordinate(0, 1)); var geometry8 = new MultiPoint(geometry7, new Point(new GeoCoordinate(0, 2))); var geometryCollection = new GeometryCollection( geometry1, geometry2, geometry3, geometry4, geometry5, geometry6, geometry7, geometry8); var serialized = geometryCollection.ToGeoJson(); serialized = serialized.RemoveWhitespace(); Assert.AreEqual("{\"type\":\"GeometryCollection\",\"geometries\":[{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]]},{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[2.0,0.0],[2.0,2.0],[0.0,2.0]]},{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[3.0,0.0],[3.0,3.0],[0.0,3.0]]},{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]},{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]},{\"type\":\"MultiPolygon\",\"coordinates\":[[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]],[[[0.0,0.0],[2.0,0.0],[2.0,2.0],[0.0,2.0],[0.0,0.0]]]]},{\"type\":\"Point\",\"coordinates\":[1.0,0.0]},{\"type\":\"MultiPoint\",\"coordinates\":[[1.0,0.0],[2.0,0.0]]}]}", serialized); }