/// <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);
        }
Beispiel #4
0
        /// <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);
        }