public void TestOneNodeAndOneRelation()
        {
            var ring = new LineairRing(new GeoCoordinate(0, -1), new GeoCoordinate(1, 1),
                                       new GeoCoordinate(-1, 1), new GeoCoordinate(0, -1));

            var filter = new OsmStreamFilterPoly(ring);

            filter.RegisterSource(new OsmGeo[] {
                Node.Create(1, 0, 0),
                Relation.Create(1, new RelationMember()
                {
                    MemberId   = 1,
                    MemberType = OsmGeoType.Node,
                    MemberRole = string.Empty
                })
            });
            var list = new List <OsmGeo>(
                filter);

            Assert.AreEqual(2, list.Count);
            Assert.AreEqual(1, list[0].Id);
            Assert.AreEqual(OsmGeoType.Node, list[0].Type);
            Assert.AreEqual(1, list[1].Id);
            Assert.AreEqual(OsmGeoType.Relation, list[1].Type);
        }
Exemple #2
0
        public GeoCoordinate[] Tessellate(LineairRing ring)
        {
            List <GeoCoordinate> geoCoordinateList = new List <GeoCoordinate>();

            if (ring.Coordinates.Count < 3)
            {
                throw new ArgumentOutOfRangeException("Invalid ring detected, only 1 or 2 vertices.");
            }
            List <GeoCoordinate> coordinates;

            for (LineairRing lineairRing = new LineairRing((IEnumerable <GeoCoordinate>)ring.Coordinates); lineairRing.Coordinates.Count > 3; lineairRing = new LineairRing((IEnumerable <GeoCoordinate>)coordinates))
            {
                int vertexIdx = 0;
                while (!lineairRing.IsEar(vertexIdx))
                {
                    ++vertexIdx;
                }
                GeoCoordinate[] neigbours = lineairRing.GetNeigbours(vertexIdx);
                geoCoordinateList.Add(neigbours[0]);
                geoCoordinateList.Add(neigbours[1]);
                geoCoordinateList.Add(lineairRing.Coordinates[vertexIdx]);
                coordinates = lineairRing.Coordinates;
                int index = vertexIdx;
                coordinates.RemoveAt(index);
            }
            if (ring.Coordinates.Count == 3)
            {
                geoCoordinateList.Add(ring.Coordinates[0]);
                geoCoordinateList.Add(ring.Coordinates[1]);
                geoCoordinateList.Add(ring.Coordinates[2]);
            }
            return(geoCoordinateList.ToArray());
        }
        /// <summary>
        /// Convests the polygon to osm objects.
        /// </summary>
        /// <param name="polygon"></param>
        /// <returns></returns>
        private static Feature ConvertPolygon(OsmSharp.IO.Xml.Kml.v2_1.PolygonType polygon)
        {
            IEnumerable <LineairRing> inners = KmlFeatureStreamSource.ConvertBoundary(polygon.innerBoundaryIs);
            LineairRing outer = KmlFeatureStreamSource.ConvertLinearRing(polygon.outerBoundaryIs.LinearRing).Geometry as LineairRing;

            return(new Feature(new Polygon(outer, inners)));
        }
        /// <summary>
        /// Creates a new lineair ring from the given way and updates the assigned flags array.
        /// </summary>
        /// <param name="ways"></param>
        /// <param name="way"></param>
        /// <param name="assignedFlags"></param>
        /// <param name="ring"></param>
        /// <returns></returns>
        private bool AssignRing(List <KeyValuePair <bool, CompleteWay> > ways, int way, bool[] assignedFlags, out LineairRing ring)
        {
            List <GeoCoordinate> coordinates = null;

            assignedFlags[way] = true;
            if (ways[way].Value.IsClosed())
            { // the was is closed.
                // TODO: validate geometry: this should be a non-intersecting way.
                coordinates = ways[way].Value.GetCoordinates();
            }
            else
            { // the way is open.
                bool roleFlag = ways[way].Key;

                // complete the ring.
                List <CompleteNode> nodes = new List <CompleteNode>(ways[way].Value.Nodes);
                if (this.CompleteRing(ways, assignedFlags, nodes, roleFlag))
                { // the ring was completed!
                    coordinates = new List <GeoCoordinate>(nodes.Count);
                    foreach (CompleteNode node in nodes)
                    {
                        coordinates.Add(node.Coordinate);
                    }
                }
                else
                { // oeps, assignment failed: backtrack again!
                    assignedFlags[way] = false;
                    ring = null;
                    return(false);
                }
            }
            ring = new LineairRing(coordinates);
            return(true);
        }
        /// <summary>
        /// Returns false if this mapcss interpreter does not contain an interpretation for an area with the given tags.
        /// </summary>
        /// <param name="tagsCollection"></param>
        /// <returns></returns>
        private bool AppliesToArea(TagsCollectionBase tagsCollection)
        {
            LineairRing ring = new LineairRing();

            ring.Attributes = new SimpleGeometryAttributeCollection(tagsCollection);
            List <MapCSSRuleProperties> rules = this.BuildRules(new MapCSSObject(ring));

            return(rules != null && rules.Count > 0);
        }
Exemple #6
0
        public void TestLineairRingContainsRing()
        {
            LineairRing inner = new LineairRing(new GeoCoordinate(1, 1),
                                                new GeoCoordinate(1, 0.2), new GeoCoordinate(0.2, 1), new GeoCoordinate(1, 1));
            LineairRing outer = new LineairRing(new GeoCoordinate(0, 0),
                                                new GeoCoordinate(2, 0), new GeoCoordinate(2, 2), new GeoCoordinate(0, 2), new GeoCoordinate(0, 0));

            Assert.IsTrue(outer.Contains(inner));
        }
Exemple #7
0
        /// <summary>
        /// Adds a ring.
        /// </summary>
        private void AddGeometry(LineairRing geometry, int color, float width, bool fill)
        {
            if (geometry == null)
            {
                throw new ArgumentNullException();
            }

            this.AddPolygon(geometry.Coordinates.ToArray(), color, width, fill);
        }
 public OsmStreamFilterPoly(LineairRing poly)
 {
     if (poly == null)
     {
         throw new ArgumentNullException("poly");
     }
     this._poly = poly;
     this._box  = new GeoCoordinateBox((IList <GeoCoordinate>)poly.Coordinates);
     this.Meta.Add("poly", GeoJsonConverter.ToGeoJson(this._poly));
 }
Exemple #9
0
        /// <summary>
        /// Generates GeoJson for this geometry.
        /// </summary>
        /// <param name="geometry"></param>
        /// <returns></returns>
        public static string ToGeoJson(this LineairRing geometry)
        {
            if (geometry == null)
            {
                throw new ArgumentNullException("geometry");
            }

            var jsonWriter = new JTokenWriter();

            GeoJsonConverter.Write(jsonWriter, geometry);
            return(jsonWriter.Token.ToString());
        }
Exemple #10
0
        /// <summary>
        /// Converts a lineairring into osm objects.
        /// </summary>
        /// <param name="linearRing"></param>
        /// <returns></returns>
        private static LineairRing ConvertLinearRing(OsmSharp.Xml.Kml.v2_1.LinearRingType linearRing)
        {
            // convert the coordinates.
            IList <GeoCoordinate> coordinates = KmlGeometryStreamSource.ConvertCoordinates(linearRing.coordinates);

            // create the ring.
            LineairRing ring = new LineairRing(coordinates);

            ring.Attributes = new SimpleGeometryAttributeCollection();
            ring.Attributes.Add("id", linearRing.id);

            return(ring);
        }
Exemple #11
0
        public void TestNodeAfterWay()
        {
            var ring = new LineairRing(new GeoCoordinate(0, -1), new GeoCoordinate(1, 1),
                                       new GeoCoordinate(-1, 1), new GeoCoordinate(0, -1));

            var filter = new OsmStreamFilterPoly(ring);

            filter.RegisterSource(new OsmGeo[] {
                Way.Create(1, 1, 2),
                Node.Create(2, 10, 10)
            });
            Assert.Catch <OsmStreamNotSortedException>(() =>
            {
                var list = new List <OsmGeo>(
                    filter);
            });
        }
Exemple #12
0
        public void TestOneNode()
        {
            var ring = new LineairRing(new GeoCoordinate(0, -1), new GeoCoordinate(1, 1),
                                       new GeoCoordinate(-1, 1), new GeoCoordinate(0, -1));

            var filter = new OsmStreamFilterPoly(ring);

            filter.RegisterSource(new OsmGeo[] {
                Node.Create(1, 0, 0),
                Node.Create(2, 10, 10)
            });
            var list = new List <OsmGeo>(
                filter);

            Assert.AreEqual(1, list.Count);
            Assert.AreEqual(1, list[0].Id);
        }
        public void TestGetMetaData()
        {
            var ring = new LineairRing(new GeoCoordinate(0, -1), new GeoCoordinate(1, 1),
                                       new GeoCoordinate(-1, 1), new GeoCoordinate(0, -1));

            var source = (new OsmGeo[0]).ToOsmStreamSource();

            source.Meta.Add("source", "enumeration");
            var filter = new OsmStreamFilterPoly(ring);

            filter.RegisterSource(source);

            var meta = filter.GetAllMeta();

            Assert.IsTrue(meta.ContainsKeyValue("source", "enumeration"));
            Assert.IsTrue(meta.ContainsKeyValue("poly", OsmSharp.Geo.Streams.GeoJson.GeoJsonConverter.ToGeoJson(ring)));
        }
Exemple #14
0
        public void TestLineairRingSerialization()
        {
            var geometry = 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 serialized = geometry.ToGeoJson();

            serialized = serialized.RemoveWhitespace();

            Assert.AreEqual("{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]}",
                            serialized);
        }
Exemple #15
0
        public static Feature ReadPolygon(TextReader reader)
        {
            string             str             = reader.ReadLine();
            LineairRing        outline         = PolyFileConverter.ReadRing(reader);
            LineairRing        lineairRing     = PolyFileConverter.ReadRing(reader);
            List <LineairRing> lineairRingList = new List <LineairRing>();

            for (; lineairRing != null; lineairRing = PolyFileConverter.ReadRing(reader))
            {
                lineairRingList.Add(lineairRing);
            }
            return(new Feature((Geometry) new Polygon(outline, (IEnumerable <LineairRing>)lineairRingList), (GeometryAttributeCollection) new SimpleGeometryAttributeCollection((IEnumerable <GeometryAttribute>) new GeometryAttribute[1]
            {
                new GeometryAttribute()
                {
                    Key = "name",
                    Value = (object)str
                }
            })));
        }
Exemple #16
0
        /// <summary>
        /// Tessellates the given LineairRings.
        /// </summary>
        /// <param name="ring"></param>
        /// <returns>A list of coordinates grouped per three.</returns>
        public GeoCoordinate[] Tessellate(LineairRing ring)
        {
            // TODO: yes i know this can be more efficient; proof of concept!
            // TODO: yes i know we know the number of triangles beforehand.
            // TODO: yes i know we can create a strip instead of duplicating coordinates!!

            List <GeoCoordinate> triangles = new List <GeoCoordinate>();

            if (ring.Coordinates.Count < 3)
            {
                throw new ArgumentOutOfRangeException("Invalid ring detected, only 1 or 2 vertices.");
            }
            LineairRing workRing = new LineairRing(ring.Coordinates);

            while (workRing.Coordinates.Count > 3)
            { // cut an ear.
                int earIdx = 0;
                while (!workRing.IsEar(earIdx))
                {
                    earIdx++;
                }

                // ear should be found, cut it!
                GeoCoordinate[] neighbours = workRing.GetNeigbours(earIdx);
                triangles.Add(neighbours[0]);
                triangles.Add(neighbours[1]);
                triangles.Add(workRing.Coordinates[earIdx]);

                // remove ear and update workring.
                List <GeoCoordinate> ringCoordinates = workRing.Coordinates;
                ringCoordinates.RemoveAt(earIdx);
                workRing = new LineairRing(ringCoordinates);
            }
            if (ring.Coordinates.Count == 3)
            { // this ring is already a triangle.
                triangles.Add(ring.Coordinates[0]);
                triangles.Add(ring.Coordinates[1]);
                triangles.Add(ring.Coordinates[2]);
            }
            return(triangles.ToArray());
        }
Exemple #17
0
        public void TestLineairRingContainsPoint()
        {
            LineairRing ring = new LineairRing(new GeoCoordinate(0, 0),
                                               new GeoCoordinate(3, 0), new GeoCoordinate(0, 3), new GeoCoordinate(0, 0));

            foreach (GeoCoordinate ringCoordinate in ring.Coordinates)
            {
                Assert.IsTrue(ring.Contains(ringCoordinate));
            }

            GeoCoordinate coordinate = new GeoCoordinate(1, 1);

            Assert.IsTrue(ring.Contains(coordinate));
            coordinate = new GeoCoordinate(2, 2);
            Assert.IsFalse(ring.Contains(coordinate));
            coordinate = new GeoCoordinate(-1, 1);
            Assert.IsFalse(ring.Contains(coordinate));
            coordinate = new GeoCoordinate(0, 1);
            Assert.IsTrue(ring.Contains(coordinate));
            coordinate = new GeoCoordinate(1, 0);
            Assert.IsTrue(ring.Contains(coordinate));
        }
Exemple #18
0
        public void TestWayAfterRelation()
        {
            var ring = new LineairRing(new GeoCoordinate(0, -1), new GeoCoordinate(1, 1),
                                       new GeoCoordinate(-1, 1), new GeoCoordinate(0, -1));

            var filter = new OsmStreamFilterPoly(ring);

            filter.RegisterSource(new OsmGeo[] {
                Relation.Create(1, new RelationMember()
                {
                    MemberId   = 1,
                    MemberType = OsmGeoType.Node,
                    MemberRole = string.Empty
                }),
                Way.Create(1, 1, 2)
            });
            Assert.Catch <OsmStreamNotSortedException>(() =>
            {
                var list = new List <OsmGeo>(
                    filter);
            });
        }
Exemple #19
0
        public void TestLineairRingContainsRing()
        {
            LineairRing outer = new LineairRing(new GeoCoordinate(0, 0),
                                                new GeoCoordinate(5, 0), new GeoCoordinate(5, 5), new GeoCoordinate(0, 5), new GeoCoordinate(0, 0));
            LineairRing inner = new LineairRing(new GeoCoordinate(1, 1),
                                                new GeoCoordinate(2, 1), new GeoCoordinate(2, 2), new GeoCoordinate(1, 2), new GeoCoordinate(1, 1));

            LineairRing test = new LineairRing(new GeoCoordinate(1, 3),
                                               new GeoCoordinate(2, 3), new GeoCoordinate(2, 4), new GeoCoordinate(1, 4), new GeoCoordinate(1, 3));
            Polygon polygon = new Polygon(outer, new LineairRing[] { inner });

            Assert.IsTrue(polygon.Contains(test));

            outer = new LineairRing(new GeoCoordinate(0, 0),
                                    new GeoCoordinate(5, 0), new GeoCoordinate(5, 5), new GeoCoordinate(0, 5), new GeoCoordinate(0, 0));
            inner = new LineairRing(new GeoCoordinate(1, 1),
                                    new GeoCoordinate(4, 1), new GeoCoordinate(4, 4), new GeoCoordinate(1, 4), new GeoCoordinate(1, 1));
            test = new LineairRing(new GeoCoordinate(2, 2),
                                   new GeoCoordinate(3, 2), new GeoCoordinate(3, 3), new GeoCoordinate(2, 3), new GeoCoordinate(2, 2));
            polygon = new Polygon(outer, new LineairRing[] { inner });

            Assert.IsFalse(polygon.Contains(test));
        }
Exemple #20
0
        /// <summary>
        /// Builds the geometry from the given coordinates.
        /// </summary>
        /// <param name="coordinates"></param>
        /// <returns></returns>
        internal static Polygon BuildPolygon(List <object> coordinates)
        {
            if (coordinates == null)
            {
                throw new ArgumentNullException();
            }
            if (coordinates.Count >= 1)
            {
                var polygonCoordinates = new List <List <GeoCoordinate> >();
                foreach (List <object> coordinates1 in coordinates)
                {
                    var lineStringCoordinates = new List <GeoCoordinate>();
                    for (int idx = 0; idx < coordinates1.Count; idx++)
                    {
                        var pointCoordinate = coordinates1[idx] as List <object>;
                        if (pointCoordinate != null &&
                            pointCoordinate.Count == 2 &&
                            pointCoordinate[0] is double &&
                            pointCoordinate[1] is double)
                        {
                            lineStringCoordinates.Add(new Math.Geo.GeoCoordinate(
                                                          (double)pointCoordinate[1], (double)pointCoordinate[0]));
                        }
                    }
                    polygonCoordinates.Add(lineStringCoordinates);
                }

                var outer = new LineairRing(polygonCoordinates[0]);
                var holes = new List <LineairRing>();
                for (int idx = 1; idx < polygonCoordinates.Count; idx++)
                {
                    holes.Add(new LineairRing(polygonCoordinates[idx]));
                }
                return(new Polygon(outer, holes));
            }
            throw new Exception("Invalid coordinate collection.");
        }
Exemple #21
0
        private Geometry GroupRings(List <KeyValuePair <bool, LineairRing> > rings)
        {
            Geometry geometry1 = (Geometry)null;

            bool[][] containsFlags = new bool[rings.Count][];
            KeyValuePair <bool, LineairRing> ring;

            for (int index1 = 0; index1 < rings.Count; ++index1)
            {
                containsFlags[index1] = new bool[rings.Count];
                for (int index2 = 0; index2 < index1; ++index2)
                {
                    bool[] flagArray = containsFlags[index1];
                    int    index3    = index2;
                    ring = rings[index1];
                    LineairRing lineairRing1 = ring.Value;
                    ring = rings[index2];
                    LineairRing lineairRing2 = ring.Value;
                    int         num          = lineairRing1.Contains(lineairRing2) ? 1 : 0;
                    flagArray[index3] = num != 0;
                }
            }
            bool[]       used         = new bool[rings.Count];
            MultiPolygon multiPolygon = (MultiPolygon)null;

            while (((IEnumerable <bool>)used).Contains <bool>(false))
            {
                LineairRing outline = (LineairRing)null;
                int         index   = -1;
                for (int ringIdx = 0; ringIdx < rings.Count; ++ringIdx)
                {
                    if (!used[ringIdx] && this.CheckUncontained(rings, containsFlags, used, ringIdx))
                    {
                        ring = rings[ringIdx];
                        if (!ring.Key)
                        {
                            Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error, "Invalid multipolygon relation: an 'inner' ring was detected without an 'outer'.");
                        }
                        index         = ringIdx;
                        ring          = rings[ringIdx];
                        outline       = ring.Value;
                        used[ringIdx] = true;
                        break;
                    }
                }
                if (outline != null)
                {
                    List <LineairRing> lineairRingList1 = new List <LineairRing>();
                    for (int ringIdx = 0; ringIdx < rings.Count; ++ringIdx)
                    {
                        if (!used[ringIdx] && containsFlags[index][ringIdx] && this.CheckUncontained(rings, containsFlags, used, ringIdx))
                        {
                            List <LineairRing> lineairRingList2 = lineairRingList1;
                            ring = rings[ringIdx];
                            LineairRing lineairRing = ring.Value;
                            lineairRingList2.Add(lineairRing);
                            used[ringIdx] = true;
                        }
                    }
                    bool flag = !((IEnumerable <bool>)used).Contains <bool>(false);
                    if (((multiPolygon != null ? 0 : (lineairRingList1.Count == 0 ? 1 : 0)) & (flag ? 1 : 0)) != 0)
                    {
                        geometry1 = (Geometry)outline;
                        break;
                    }
                    if (multiPolygon == null & flag)
                    {
                        geometry1 = (Geometry) new Polygon(outline, (IEnumerable <LineairRing>)lineairRingList1);
                        break;
                    }
                    multiPolygon = new MultiPolygon();
                    geometry1    = (Geometry)multiPolygon;
                    Polygon geometry2 = new Polygon(outline, (IEnumerable <LineairRing>)lineairRingList1);
                    multiPolygon.Add(geometry2);
                }
                else
                {
                    Log.TraceEvent("OsmSharp.Osm.Interpreter.SimpleGeometryInterpreter", TraceEventType.Error, "Invalid multipolygon relation: Unassigned rings left.");
                    break;
                }
            }
            return(geometry1);
        }
        /// <summary>
        /// Translates a lineair ring.
        /// </summary>
        /// <param name="scene">The scene to add primitives to.</param>
        /// <param name="projection">The projection used to convert the objects.</param>
        /// <param name="lineairRing"></param>
        private void TranslateLineairRing(Scene2D scene, IProjection projection, LineairRing lineairRing)
        {
            // build the rules.
            List <MapCSSRuleProperties> rules =
                this.BuildRules(new MapCSSObject(lineairRing));

            // validate what's there.
            if (rules.Count == 0)
            {
                return;
            }

            // get x/y.
            double[] x = null, y = null;
            if (lineairRing.Coordinates != null &&
                lineairRing.Coordinates.Count > 0)
            { // pre-calculate x/y.
                x = new double[lineairRing.Coordinates.Count];
                y = new double[lineairRing.Coordinates.Count];
                for (int idx = 0; idx < lineairRing.Coordinates.Count; idx++)
                {
                    x[idx] = projection.LongitudeToX(
                        lineairRing.Coordinates[idx].Longitude);
                    y[idx] = projection.LatitudeToY(
                        lineairRing.Coordinates[idx].Latitude);
                }

                // simplify.
                if (x.Length > 2)
                {
                    double[][] simplified = SimplifyCurve.Simplify(new double[][] { x, y }, 0.0001);
                    x = simplified[0];
                    y = simplified[1];
                }
            }
            // add the z-index.
            foreach (var rule in rules)
            {
                float minZoom = (float)projection.ToZoomFactor(rule.MinZoom);
                float maxZoom = (float)projection.ToZoomFactor(rule.MaxZoom);

                int zIndex;
                if (!rule.TryGetProperty <int>("zIndex", out zIndex))
                {
                    zIndex = 0;
                }

                // interpret the results.
                if (x != null)
                { // there is a valid interpretation of this way.
                    int color;
                    int fillColor;
                    if (rule.TryGetProperty("fillColor", out fillColor))
                    { // render as an area.
                        float fillOpacity;
                        if (rule.TryGetProperty("fillOpacity", out fillOpacity))
                        {
                            SimpleColor simpleFillColor = new SimpleColor()
                            {
                                Value = fillColor
                            };
                            fillColor = SimpleColor.FromArgb((int)(255 * fillOpacity),
                                                             simpleFillColor.R, simpleFillColor.G, simpleFillColor.B).Value;
                        }
                        uint?pointsId = scene.AddPoints(x, y);
                        if (pointsId.HasValue)
                        {
                            scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetArea, zIndex), minZoom, maxZoom, fillColor, 1, true);
                            if (rule.TryGetProperty("color", out color))
                            {
                                scene.AddStylePolygon(pointsId.Value, this.CalculateSceneLayer(OffsetCasing, zIndex), minZoom, maxZoom, color, 1, false);
                            }
                        }
                    }
                }
            }
        }
Exemple #23
0
        private bool AssignRing(List <KeyValuePair <bool, CompleteWay> > ways, int way, bool[] assignedFlags, out LineairRing ring)
        {
            assignedFlags[way] = true;
            List <GeoCoordinate> geoCoordinateList;

            if (ways[way].Value.IsClosed())
            {
                geoCoordinateList = ways[way].Value.GetCoordinates();
            }
            else
            {
                bool        key   = ways[way].Key;
                List <Node> nodes = new List <Node>((IEnumerable <Node>)ways[way].Value.Nodes);
                if (this.CompleteRing(ways, assignedFlags, nodes, new bool?(key)))
                {
                    geoCoordinateList = new List <GeoCoordinate>(nodes.Count);
                    foreach (Node node in nodes)
                    {
                        geoCoordinateList.Add(node.Coordinate);
                    }
                }
                else
                {
                    assignedFlags[way] = false;
                    ring = (LineairRing)null;
                    return(false);
                }
            }
            ring = new LineairRing((IEnumerable <GeoCoordinate>)geoCoordinateList);
            return(true);
        }
        /// <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>
        /// Interprets an OSM-object and returns the corresponding geometry.
        /// </summary>
        /// <param name="osmObject"></param>
        /// <returns></returns>
        public override GeometryCollection Interpret(CompleteOsmGeo osmObject)
        {
            // DISCLAIMER: this is a very very very simple geometry interpreter and
            // contains hardcoded all relevant tags.

            GeometryCollection collection = new GeometryCollection();
            TagsCollectionBase tags;

            if (osmObject != null)
            {
                switch (osmObject.Type)
                {
                case CompleteOsmType.Node:
                    TagsCollection newCollection = new TagsCollection(
                        osmObject.Tags);
                    newCollection.RemoveKey("FIXME");
                    newCollection.RemoveKey("node");
                    newCollection.RemoveKey("source");

                    if (newCollection.Count > 0)
                    {     // there is still some relevant information left.
                        collection.Add(new Point((osmObject as CompleteNode).Coordinate));
                    }
                    break;

                case CompleteOsmType.Way:
                    tags = osmObject.Tags;

                    bool isArea = false;
                    if ((tags.ContainsKey("building") && !tags.IsFalse("building")) ||
                        (tags.ContainsKey("landuse") && !tags.IsFalse("landuse")) ||
                        (tags.ContainsKey("amenity") && !tags.IsFalse("amenity")) ||
                        (tags.ContainsKey("harbour") && !tags.IsFalse("harbour")) ||
                        (tags.ContainsKey("historic") && !tags.IsFalse("historic")) ||
                        (tags.ContainsKey("leisure") && !tags.IsFalse("leisure")) ||
                        (tags.ContainsKey("man_made") && !tags.IsFalse("man_made")) ||
                        (tags.ContainsKey("military") && !tags.IsFalse("military")) ||
                        (tags.ContainsKey("natural") && !tags.IsFalse("natural")) ||
                        (tags.ContainsKey("office") && !tags.IsFalse("office")) ||
                        (tags.ContainsKey("place") && !tags.IsFalse("place")) ||
                        (tags.ContainsKey("power") && !tags.IsFalse("power")) ||
                        (tags.ContainsKey("public_transport") && !tags.IsFalse("public_transport")) ||
                        (tags.ContainsKey("shop") && !tags.IsFalse("shop")) ||
                        (tags.ContainsKey("sport") && !tags.IsFalse("sport")) ||
                        (tags.ContainsKey("tourism") && !tags.IsFalse("tourism")) ||
                        (tags.ContainsKey("waterway") && !tags.IsFalse("waterway")) ||
                        (tags.ContainsKey("wetland") && !tags.IsFalse("wetland")) ||
                        (tags.ContainsKey("water") && !tags.IsFalse("water")) ||
                        (tags.ContainsKey("aeroway") && !tags.IsFalse("aeroway")))
                    {     // these tags usually indicate an area.
                        isArea = true;
                    }

                    if (tags.IsTrue("area"))
                    {     // explicitly indicated that this is an area.
                        isArea = true;
                    }
                    else if (tags.IsFalse("area"))
                    {     // explicitly indicated that this is not an area.
                        isArea = false;
                    }

                    if (isArea)
                    {     // area tags leads to simple polygon
                        LineairRing lineairRing = new LineairRing((osmObject as CompleteWay).GetCoordinates().ToArray <GeoCoordinate>());
                        lineairRing.Attributes = new SimpleGeometryAttributeCollection(tags);
                        collection.Add(lineairRing);
                    }
                    else
                    {     // no area tag leads to just a line.
                        LineString lineString = new LineString((osmObject as CompleteWay).GetCoordinates().ToArray <GeoCoordinate>());
                        lineString.Attributes = new SimpleGeometryAttributeCollection(tags);
                        collection.Add(lineString);
                    }
                    break;

                case CompleteOsmType.Relation:
                    CompleteRelation relation = (osmObject as CompleteRelation);
                    tags = relation.Tags;

                    string typeValue;
                    if (tags.TryGetValue("type", out typeValue))
                    {     // there is a type in this relation.
                        if (typeValue == "multipolygon")
                        { // this relation is a multipolygon.
                            Geometry geometry = this.InterpretMultipolygonRelation(relation);
                            if (geometry != null)
                            {     // add the geometry.
                                collection.Add(geometry);
                            }
                        }
                        else if (typeValue == "boundary")
                        {     // this relation is a boundary.
                        }
                    }
                    break;
                }
            }
            return(collection);
        }
Exemple #26
0
        public void TestFeatureSerialization()
        {
            // a feature with a point.
            var geometry = (Geometry) new Point(new GeoCoordinate(0, 1));
            var feature  = new Feature(geometry);

            var serialized = feature.ToGeoJson();

            serialized = serialized.RemoveWhitespace();

            Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1.0,0.0]}}",
                            serialized);

            feature = new Feature(geometry, new SimpleGeometryAttributeCollection(new GeometryAttribute[]
            {
                new GeometryAttribute()
                {
                    Key   = "key1",
                    Value = "value1"
                }
            }));

            serialized = feature.ToGeoJson();
            serialized = serialized.RemoveWhitespace();

            Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{\"key1\":\"value1\"},\"geometry\":{\"type\":\"Point\",\"coordinates\":[1.0,0.0]}}",
                            serialized);

            // a feature with a linestring.
            geometry = new LineString(
                new GeoCoordinate[]
            {
                new GeoCoordinate(0, 0),
                new GeoCoordinate(0, 1),
                new GeoCoordinate(1, 1),
                new GeoCoordinate(1, 0)
            });
            feature = new Feature(geometry);

            serialized = feature.ToGeoJson();
            serialized = serialized.RemoveWhitespace();

            Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"LineString\",\"coordinates\":[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0]]}}",
                            serialized);

            // a featurer with a linearring.
            geometry = new LineairRing(
                new GeoCoordinate[]
            {
                new GeoCoordinate(0, 0),
                new GeoCoordinate(0, 1),
                new GeoCoordinate(1, 1),
                new GeoCoordinate(1, 0),
                new GeoCoordinate(0, 0)
            });
            feature = new Feature(geometry);

            serialized = feature.ToGeoJson();
            serialized = serialized.RemoveWhitespace();

            Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]}}",
                            serialized);

            // a featurer with a polygon.
            geometry = 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)
            }));
            feature = new Feature(geometry);

            serialized = feature.ToGeoJson();
            serialized = serialized.RemoveWhitespace();

            Assert.AreEqual("{\"type\":\"Feature\",\"properties\":{},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0.0,0.0],[1.0,0.0],[1.0,1.0],[0.0,1.0],[0.0,0.0]]]}}",
                            serialized);
        }
Exemple #27
0
        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);
        }