Exemplo n.º 1
0
        /// <summary>
        /// Instatiates a polygon based on one extorier ring 
        /// and a collection of interior rings.
        /// </summary>
        /// <param name="exteriorRing">Exterior <see cref="LinearRing"/></param>
        /// <param name="interiorRings">Interior LinearRings</param>
        internal protected Polygon(LinearRing exteriorRing, IEnumerable<LinearRing> interiorRings)
        {
            _exteriorRing = exteriorRing;

            if (interiorRings != null)
                _interiorRings.AddRange(interiorRings);
        }
Exemplo n.º 2
0
        public void PolygonTest()
        {
            Polygon p = new Polygon();
            Assert.IsTrue(p.IsEmpty());
            Assert.AreEqual(0, p.NumInteriorRing);
            Assert.AreEqual(p.NumInteriorRing, p.InteriorRings.Count);
            Assert.IsFalse(p.Equals(null));
            Assert.IsTrue(p.Equals(new Polygon()));
            Assert.AreEqual(BoundingBox.Empty, p.GetBoundingBox());
            LinearRing ring = new LinearRing();
            ring.Vertices.Add(new Point(10, 10));
            ring.Vertices.Add(new Point(20, 10));
            ring.Vertices.Add(new Point(20, 20));
            Assert.IsFalse(ring.IsCcw());
            ring.Vertices.Add(new Point(10, 20));
            ring.Vertices.Add(ring.Vertices[0].Clone() as Point);
            Assert.IsTrue(ring.IsPointWithin(new Point(15, 15)));
            Assert.AreNotSame(ring.Clone(), ring);
            p.ExteriorRing = ring;


            Assert.AreEqual(100, p.Area);
            LinearRing ring2 = new LinearRing();
            ring2.Vertices.Add(new Point(11, 11));
            ring2.Vertices.Add(new Point(19, 11));
            ring2.Vertices.Add(new Point(19, 19));
            ring2.Vertices.Add(new Point(11, 19));
            ring2.Vertices.Add(ring2.Vertices[0].Clone() as Point);
            p.InteriorRings.Add(ring2);
            Assert.AreEqual(100 + 64, p.Area);
            // Reverse() doesn't exist for Collections
            //ring2.Vertices.Reverse();
            //Assert.AreEqual(100 - 64, p.Area);
            Assert.AreEqual(1, p.NumInteriorRing);
            Assert.AreEqual(new BoundingBox(10, 10, 20, 20), p.GetBoundingBox());

            Polygon p2 = p.Clone() as Polygon;
            Assert.AreEqual(p, p2);
            Assert.AreNotSame(p, p2);
            p2.InteriorRings.RemoveAt(0);
            Assert.AreNotEqual(p, p2);
        }
Exemplo n.º 3
0
        public void Parse_Test()
        {
            var linear = new LinearRing();
            linear.Vertices.Add(new MapPoint(3, 5));
            linear.Vertices.Add(new MapPoint(7, 5));
            linear.Vertices.Add(new MapPoint(7, 3));
            linear.Vertices.Add(new MapPoint(3, 3));
            linear.Vertices.Add(new MapPoint(3, 5));

            var polygon = new Polygon();
            polygon.Rings.Add(linear);

            var writer = new WkbWriter();
            var result = writer.Parse(polygon);

            const string data = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\b@\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0\b@\0\0\0\0\0\0\b@\0\0\0\0\0\0\b@\0\0\0\0\0\0\b@\0\0\0\0\0\0@";

            var encoder = new UTF8Encoding();
            var strings = encoder.GetString(result);

            Assert.AreEqual(data, strings);
        }
Exemplo n.º 4
0
        public void TestMultiPolygon1()
        {
            string          wkt          = "MULTIPOLYGON (((10 10, 10 20, 20 20, 20 15 , 10 10), (50 40, 50 50, 60 50, 60 40, 50 40)))";
            GeometryFactory factory      = new GeometryFactory();
            Geometry        geometry     = new GeometryWKTReader(factory).Create(wkt);
            MultiPolygon    multiPolygon = (MultiPolygon)geometry;

            //Assertion.AssertEquals("Multilinestring 1",2,multiPolygon.NumGeometries);
            Geometry   g     = multiPolygon.getGeometryN(0);
            Polygon    poly1 = (Polygon)multiPolygon.getGeometryN(0);
            LinearRing shell = poly1.shell;
            LinearRing hole  = poly1.holes[0];

            Assertion.AssertEquals("MPS 1", 10.0, shell.getCoordinates()[0].x);
            Assertion.AssertEquals("MPS 2", 10.0, shell.getCoordinates()[0].y);
            Assertion.AssertEquals("MPS 3", 10.0, shell.getCoordinates()[1].x);
            Assertion.AssertEquals("MPS 4", 20.0, shell.getCoordinates()[1].y);
            Assertion.AssertEquals("MPS 5", 20.0, shell.getCoordinates()[2].y);
            Assertion.AssertEquals("MPS 6", 20.0, shell.getCoordinates()[2].y);
            Assertion.AssertEquals("MPS 7", 20.0, shell.getCoordinates()[3].x);
            Assertion.AssertEquals("MPS 8", 15.0, shell.getCoordinates()[3].y);
            Assertion.AssertEquals("MPS 9", 10.0, shell.getCoordinates()[4].x);
            Assertion.AssertEquals("MPS 10", 10.0, shell.getCoordinates()[4].y);

            Assertion.AssertEquals("MPS 11", 50.0, hole.getCoordinates()[0].x);
            Assertion.AssertEquals("MPS 12", 40.0, hole.getCoordinates()[0].y);
            Assertion.AssertEquals("MPS 13", 50.0, hole.getCoordinates()[1].x);
            Assertion.AssertEquals("MPS 14", 50.0, hole.getCoordinates()[1].y);
            Assertion.AssertEquals("MPS 15", 60.0, hole.getCoordinates()[2].x);
            Assertion.AssertEquals("MPS 16", 50.0, hole.getCoordinates()[2].y);
            Assertion.AssertEquals("MPS 17", 60.0, hole.getCoordinates()[3].x);
            Assertion.AssertEquals("MPS 18", 40.0, hole.getCoordinates()[3].y);
            Assertion.AssertEquals("MPS 19", 50.0, hole.getCoordinates()[4].x);
            Assertion.AssertEquals("MPS 20", 40.0, hole.getCoordinates()[4].y);

            string wkt2 = new GeometryWKTWriter().Write(multiPolygon);

            Assertion.AssertEquals("wkt", true, Compare.WktStrings(wkt, wkt2));
        }
Exemplo n.º 5
0
        private bool IsInside(LinearRing innerRing, LinearRing searchRing)
        {
            Coordinates innerRingPts  = innerRing.GetCoordinates();
            Coordinates searchRingPts = searchRing.GetCoordinates();

            if (!innerRing.GetEnvelopeInternal().Intersects(searchRing.GetEnvelopeInternal()))
            {
                return(false);
            }

            Coordinate innerRingPt = IsValidOp.FindPtNotNode(innerRingPts, searchRing, _graph);
            //Assert.isTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring");

            bool isInside = _cga.IsPointInRing(innerRingPt, searchRingPts);

            if (isInside)
            {
                _nestedPt = innerRingPt;
                return(true);
            }
            return(false);
        }
Exemplo n.º 6
0
        }         // protected void AddPoints( Edge edge, bool isForward, bool isFirstEdge )

        /// <summary>
        /// This method will cause the ring to be computed. It will also check any holes, if they have been assigned.
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public bool ContainsPoint(Coordinate p)
        {
            LinearRing shell = GetLinearRing();
            Envelope   env   = shell.GetEnvelopeInternal();

            if (!env.Contains(p))
            {
                return(false);
            }
            if (!_cga.IsPointInRing(p, shell.GetCoordinates()))
            {
                return(false);
            }
            foreach (EdgeRing hole in _holes)
            {
                if (hole.ContainsPoint(p))
                {
                    return(false);
                }
            }
            return(true);
        }         // public bool ContainsPoint(Coordinate p)
Exemplo n.º 7
0
        public static LineString getCircle(Coordinate center, Coordinate point)
        {
            double             dis    = center.Distance(point);
            List <double>      X      = new List <double>();
            double             count  = 0;
            IList <Coordinate> POINTS = new List <Coordinate>();
            double             x      = center.X - dis;

            while (count < dis * 2)
            {
                X.Add(x);
                count += 0.1;
                x     += 0.1;
            }
            for (int i = 0; i < X.Count; i++)
            {
                Coordinate coor = new Coordinate();
                double     Y    = 0;
                Y      = Math.Sqrt(Math.Abs(Math.Pow(dis, 2) - Math.Pow(X[i] - center.X, 2))) + center.Y;
                coor.X = X[i];
                coor.Y = Y;
                POINTS.Add(coor);
            }
            for (int i = X.Count - 2; i > 0; i--)
            {
                Coordinate coor = new Coordinate();
                double     Y    = 0;
                Y      = -Math.Sqrt(Math.Abs(Math.Pow(dis, 2) - Math.Pow(X[i] - center.X, 2))) + center.Y;
                coor.X = X[i];
                coor.Y = Y;
                POINTS.Add(coor);
            }
            POINTS.Add(POINTS[0]);
            Coordinate[] coordinates = POINTS.ToArray <Coordinate>();
            LineString   ring        = new LinearRing(coordinates);

            return(ring);
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public virtual bool IsNonNested()
        {
            BuildQuadtree();

            for (int i = 0; i < _rings.Count; i++)
            {
                LinearRing         innerRing    = (LinearRing)_rings[i];
                IList <Coordinate> innerRingPts = innerRing.Coordinates;

                IList results = _quadtree.Query(innerRing.EnvelopeInternal);
                for (int j = 0; j < results.Count; j++)
                {
                    LinearRing         searchRing    = (LinearRing)results[j];
                    IList <Coordinate> searchRingPts = searchRing.Coordinates;

                    if (innerRing == searchRing)
                    {
                        continue;
                    }

                    if (!innerRing.EnvelopeInternal.Intersects(searchRing.EnvelopeInternal))
                    {
                        continue;
                    }

                    Coordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, _graph);
                    Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring");

                    bool isInside = CgAlgorithms.IsPointInRing(innerRingPt, searchRingPts);
                    if (isInside)
                    {
                        _nestedPt = innerRingPt;
                        return(false);
                    }
                }
            }
            return(true);
        }
        /**
         * Node a LinearRing and return a MultiPolygon containing
         * <ul>
         * <li>a single Polygon if the LinearRing is simple</li>
         * <li>several Polygons if the LinearRing auto-intersects</li>
         * </ul>
         * This is used to repair auto-intersecting Polygons
         */
        private NetTopologySuite.Geometries.Geometry getArealGeometryFromLinearRing(LinearRing ring)
        {
            if (ring.IsSimple)
            {
                return(ring.Factory.CreateMultiPolygon(new Polygon[] {
                    ring.Factory.CreatePolygon(ring, EMPTY_RING_ARRAY)
                }));
            }
            else
            {
                // Node input LinearRing and extract unique segments
                ISet <LineString> lines = nodeLineString(ring.Coordinates, ring.Factory);
                lines = getSegments(lines);

                // Polygonize the line network
                Polygonizer polygonizer = new Polygonizer();
                polygonizer.Add((ICollection <NetTopologySuite.Geometries.Geometry>)lines);

                // Computes intersections to determine the status of each polygon
                ICollection <NetTopologySuite.Geometries.Geometry> geoms = new List <NetTopologySuite.Geometries.Geometry>();
                foreach (NetTopologySuite.Geometries.Geometry g in polygonizer.GetPolygons())
                {
                    Polygon    polygon  = (Polygon)g;
                    Coordinate p        = polygon.InteriorPoint.Coordinate;
                    var        location = RayCrossingCounter.LocatePointInRing(p, ring.CoordinateSequence);
                    if (location == NetTopologySuite.Geometries.Location.Interior)
                    {
                        geoms.Add(polygon);
                    }
                }
                NetTopologySuite.Geometries.Geometry unionPoly  = UnaryUnionOp.Union(geoms);
                NetTopologySuite.Geometries.Geometry unionLines = UnaryUnionOp.Union(lines).Difference(unionPoly.Boundary);
                geoms.Clear();
                decompose(unionPoly, geoms);
                decompose(unionLines, geoms);
                return(ring.Factory.BuildGeometry(geoms));
            }
        }
Exemplo n.º 10
0
        public void writeListToDatabase(string connectionstring)
        {
            using (var conn = new NpgsqlConnection(connectionstring))
            {
                conn.Open();
                //System.Threading.Thread.Sleep(1000); // Crashes on next line??
                conn.TypeMapper.UseNetTopologySuite();

                string        CommandText   = @"DROP TABLE IF EXISTS public.tiletest; CREATE TABLE public.tiletest(id_tile_250 bigint, the_geom geometry); ";
                NpgsqlCommand createtbl_cmd = new NpgsqlCommand(CommandText, conn);
                createtbl_cmd.Connection = conn;
                createtbl_cmd.ExecuteNonQuery();

                // note that it is overkill to do bulk import for two objects, but as example...
                using (var writer = conn.BeginBinaryImport("COPY public.tiletest(id_tile_250, the_geom ) FROM STDIN (FORMAT BINARY)"))
                {
                    foreach (var entity in this.theMapList)
                    {
                        // Note the StartRow and Complete
                        // Geometry types from NetTopologySuite.Geometries
                        Coordinate[] aCoordinateArray = new Coordinate[5];
                        aCoordinateArray[0] = entity.lowerEastCorner;
                        aCoordinateArray[1] = entity.lowerWestCorner;
                        aCoordinateArray[2] = entity.upperWestCorner;
                        aCoordinateArray[3] = entity.upperEastCorner;
                        aCoordinateArray[4] = entity.lowerEastCorner;
                        LinearRing aLinearring = new LinearRing(aCoordinateArray);
                        Polygon    tile_geom   = new Polygon(aLinearring);
                        tile_geom.SRID = 3006;
                        writer.StartRow();
                        writer.Write(entity.TileID, NpgsqlDbType.Bigint);
                        writer.Write(tile_geom, NpgsqlDbType.Geometry);
                    }
                    writer.Complete();
                }
                conn.Close();
            }
        }
Exemplo n.º 11
0
        private Polygon ReadPolygonText(WktStreamTokenizer tokenizer)
        {
            string nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                return(new Polygon(new LinearRing(_factory.getCoordinateSequenceFactory().create(new Coordinate[] {}), _factory), new LinearRing[] {}, _factory));
            }

            LinearRing shell = ReadLinearRingText(tokenizer);

            ArrayList holes = new ArrayList();

            nextToken = this.GetNextCloserOrComma(tokenizer);

            while (nextToken == ",")
            {
                holes.Add(ReadLinearRingText(tokenizer));
                nextToken = this.GetNextCloserOrComma(tokenizer);
            }

            return(_factory.createPolygon(shell, (LinearRing[])holes.ToArray(typeof(LinearRing))));
        }
        public static void Run()
        {
            //ExStart: CreateMultiPolygon
            LinearRing firstRing = new LinearRing();

            firstRing.AddPoint(8.5, -2.5);
            firstRing.AddPoint(-8.5, 2.5);
            firstRing.AddPoint(8.5, -2.5);
            Polygon firstPolygon = new Polygon(firstRing);

            LinearRing secondRing = new LinearRing();

            secondRing.AddPoint(7.6, -3.6);
            secondRing.AddPoint(-9.6, 1.5);
            secondRing.AddPoint(7.6, -3.6);
            Polygon secondPolygon = new Polygon(secondRing);

            MultiPolygon multiPolygon = new MultiPolygon();

            multiPolygon.Add(firstPolygon);
            multiPolygon.Add(secondPolygon);
            //ExEnd: CreateMultiPolygon
        }
        /// <summary>
        ///
        /// </summary>
        /// <param name="p"></param>
        /// <param name="poly"></param>
        /// <returns></returns>
        public static bool ContainsPointInPolygon(Coordinate p, IPolygon poly)
        {
            if (poly.IsEmpty)
            {
                return(false);
            }
            LinearRing shell = (LinearRing)poly.Shell;

            if (!CgAlgorithms.IsPointInRing(p, shell.Coordinates))
            {
                return(false);
            }
            // now test if the point lies in or on the holes
            for (int i = 0; i < poly.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)poly.GetInteriorRingN(i);
                if (CgAlgorithms.IsPointInRing(p, hole.Coordinates))
                {
                    return(false);
                }
            }
            return(true);
        }
        public ActionResult GetStrassenabschnittByBbox(double minX, double minY, double maxX, double maxY)
        {
            try
            {
                Coordinate bottomLeft  = new Coordinate(minX, minY);
                Coordinate topRight    = new Coordinate(maxX, maxY);
                Coordinate bottomRight = new Coordinate(maxX, minY);
                Coordinate topLeft     = new Coordinate(minX, maxY);

                ILinearRing linearRing = new LinearRing(new Coordinate[] { topLeft, topRight, bottomRight, bottomLeft, topLeft });

                IGeometry filterGeom = new NetTopologySuite.Geometries.Polygon(linearRing, GISService.CreateGeometryFactory());

                IList <StrassenabschnittGIS> strassenabschnitte = strassenabschnittGISService.GetCurrentBySpatialFilter(filterGeom);

                strassenabschnitte = strassenabschnitte.Where(s => s.Shape.Intersects(filterGeom)).ToList();
                return(Content(geoJSONParseService.GenereateGeoJsonStringfromEntities(strassenabschnitte), "application/json"));
            }
            catch (Exception exc)
            {
                return(Content(GeoJSONStrings.GeoJSONFailure(exc.Message), "application/json"));
            }
        }
Exemplo n.º 15
0
        }         // private void PlaceFreeHoles( ArrayList freeHoleList )

        /// <summary>
        /// Find the innermost enclosing shell EdgeRing containing the argument EdgeRing, if any.
        /// The innermost enclosing ring is the <i>smallest</i> enclosing ring.</summary>
        /// <remarks>
        /// <para>The algorithm used depends on the fact that:
        ///
        ///  ring A contains ring B iff envelope(ring A) contains envelope(ring B)
        /// </para>
        /// <para>This routine is only safe to use if the chosen point of the hole
        /// is known to be properly contained in a shell
        /// (which is guaranteed to be the case if the hole does not touch its shell)</para>
        /// </remarks>
        /// <param name="testEr"></param>
        /// <returns>
        /// Containing EdgeRing, if there is one
        /// Null if no containing EdgeRing is found
        /// </returns>
        private EdgeRing FindEdgeRingContaining(EdgeRing testEr)
        {
            LinearRing testRing = testEr.GetLinearRing();
            Envelope   testEnv  = testRing.GetEnvelopeInternal();
            Coordinate testPt   = testRing.GetCoordinateN(0);

            EdgeRing minShell = null;
            Envelope minEnv   = null;

            foreach (object obj in _shellList)
            {
                EdgeRing   tryShell = (EdgeRing)obj;
                LinearRing tryRing  = tryShell.GetLinearRing();
                Envelope   tryEnv   = tryRing.GetEnvelopeInternal();
                if (minShell != null)
                {
                    minEnv = minShell.GetLinearRing().GetEnvelopeInternal();
                }
                bool isContained = false;
                if (tryEnv.Contains(testEnv) &&
                    _cga.IsPointInRing(testPt, tryRing.GetCoordinates()))
                {
                    isContained = true;
                }

                // check if this new containing ring is smaller than the current minimum ring
                if (isContained)
                {
                    if (minShell == null ||
                        minEnv.Contains(tryEnv))
                    {
                        minShell = tryShell;
                    }
                }
            }     // foreach ( object obj in _shellList )
            return(minShell);
        }         // private EdgeRing FindEdgeRingContaining( EdgeRing testEr )
Exemplo n.º 16
0
        public bool IsNonNested()
        {
            for (int i = 0; i < rings.Count; i++)
            {
                LinearRing      innerRing    = (LinearRing)rings[i];
                ICoordinateList innerRingPts = innerRing.Coordinates;

                for (int j = 0; j < rings.Count; j++)
                {
                    LinearRing      searchRing    = (LinearRing)rings[j];
                    ICoordinateList searchRingPts = searchRing.Coordinates;

                    if (innerRing == searchRing)
                    {
                        continue;
                    }

                    if (!innerRing.Bounds.Intersects(searchRing.Bounds))
                    {
                        continue;
                    }

                    Coordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph);
                    Debug.Assert(innerRingPt != null, "Unable to find a ring point not a node of the search ring");
                    //Coordinate innerRingPt = innerRingPts[0];

                    bool IsInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts);
                    if (IsInside)
                    {
                        nestedPt = innerRingPt;
                        return(false);
                    }
                }
            }

            return(true);
        }
Exemplo n.º 17
0
/*
 *              /// <summary>
 *              /// Creates an array of Points have the given Coordinates.
 *              /// </summary>
 *              /// <param name="coordinates">The Coordinates with which to create the Points.</param>
 *              /// <returns>Returns a Point array created using this GeometryWKTReader's GeometryFactory.</returns>
 *              private   ArrayList ToPoints(ArrayList coordinates)
 *              {
 *
 *                      ArrayList points = new ArrayList();
 *                      for (int i = 0; i < coordinates.length; i++) {
 *                      points.add(geometryFactory.createPoint(coordinates[i]));
 *                      }
 *                      return (Point[]) points.ToArray(new Point[]{});
 *
 *                      throw new NotImplementedException();
 *              }
 */
        /// <summary>
        /// Creates a Polygon using the next token in the stream.
        /// </summary>
        /// <param name="tokenizer">Tokenizer over a stream of text in Well-known Text
        ///  format. The next tokens must form a &lt;Polygon Text&gt;.</param>
        /// <returns>Returns a Polygon specified by the next token
        ///  in the stream</returns>
        ///  <remarks>
        ///  ParseException is thown if the coordinates used to create the Polygon
        ///  shell and holes do not form closed linestrings, or if an unexpected
        ///  token is encountered.
        ///  </remarks>
        private Polygon ReadPolygonText(WktStreamTokenizer tokenizer)
        {
            string nextToken = GetNextEmptyOrOpener(tokenizer);

            if (nextToken == "EMPTY")
            {
                //return geometryFactory.createPolygon(geometryFactory.createLinearRing(
                //	new Coordinate[]{}), new LinearRing[]{});
                LinearRing linearRing = new LinearRing(new Coordinates(), _precisionModel, _geometryFactory.SRID);
                return(new Polygon(linearRing, _precisionModel, _geometryFactory.SRID));
            }
            ArrayList  holes = new ArrayList();
            LinearRing shell = ReadLinearRingText(tokenizer);

            nextToken = GetNextCloserOrComma(tokenizer);
            while (nextToken == ",")
            {
                LinearRing hole = ReadLinearRingText(tokenizer);
                holes.Add(hole);
                nextToken = GetNextCloserOrComma(tokenizer);
            }
            LinearRing[] array = new LinearRing[holes.Count];
            return(_geometryFactory.CreatePolygon(shell, (LinearRing[])holes.ToArray(typeof(LinearRing))));
        }
Exemplo n.º 18
0
        protected override IEnumerable <IFeature> CreateFeatures(MapFeature mapFeature)
        {
            var geometryList = new List <IPolygon>();

            foreach (MapGeometry mapGeometry in mapFeature.MapGeometries)
            {
                IEnumerable <Point2D>[] pointCollections = mapGeometry.PointCollections.Select(CreateClosedRingIfNecessary).ToArray();

                Coordinate[] outerRingCoordinates = ConvertPoint2DElementsToCoordinates(pointCollections[0]);
                ILinearRing  outerRing            = new LinearRing(outerRingCoordinates);

                var innerRings = new ILinearRing[pointCollections.Length - 1];
                for (var i = 1; i < pointCollections.Length; i++)
                {
                    Coordinate[] innerRingCoordinates = ConvertPoint2DElementsToCoordinates(pointCollections[i]);
                    innerRings[i - 1] = new LinearRing(innerRingCoordinates);
                }

                IPolygon polygon = new Polygon(outerRing, innerRings);
                geometryList.Add(polygon);
            }

            yield return(new Feature(GetGeometry(geometryList)));
        }
Exemplo n.º 19
0
        public void Parse_Test()
        {
            var linear = new LinearRing();

            linear.Vertices.Add(new MapPoint(3, 5));
            linear.Vertices.Add(new MapPoint(7, 5));
            linear.Vertices.Add(new MapPoint(7, 3));
            linear.Vertices.Add(new MapPoint(3, 3));
            linear.Vertices.Add(new MapPoint(3, 5));

            var polygon = new Polygon();

            polygon.Rings.Add(linear);

            var writer = new WkbWriter();
            var result = writer.Parse(polygon);

            const string data = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\b@\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0@\0\0\0\0\0\0\b@\0\0\0\0\0\0\b@\0\0\0\0\0\0\b@\0\0\0\0\0\0\b@\0\0\0\0\0\0@";

            var encoder = new UTF8Encoding();
            var strings = encoder.GetString(result);

            Assert.AreEqual(data, strings);
        }
Exemplo n.º 20
0
        public void Reproject_ForLinearRingWithTargetProjectionNull_ThrowArgumentNullException()
        {
            // Setup
            var p1 = new Coordinate(0.0, 0.0);
            var p2 = new Coordinate(1.1, 1.1);

            var linearRing = new LinearRing(new[]
            {
                p1,
                p2,
                p2,
                p1
            });

            ProjectionInfo projection = KnownCoordinateSystems.Projected.NationalGrids.Rijksdriehoekstelsel;

            // Call
            TestDelegate call = () => linearRing.Reproject(projection, null);

            // Assert
            string paramName = Assert.Throws <ArgumentNullException>(call).ParamName;

            Assert.AreEqual("target", paramName);
        }
Exemplo n.º 21
0
        private int Locate(Coordinate p, Polygon poly)
        {
            if (poly.IsEmpty)
            {
                return(LocationType.Exterior);
            }
            LinearRing shell = poly.ExteriorRing;

            int shellLoc = Locate(p, shell);

            if (shellLoc == LocationType.Exterior)
            {
                return(LocationType.Exterior);
            }
            if (shellLoc == LocationType.Boundary)
            {
                return(LocationType.Boundary);
            }

            // now test if the point lies in or on the holes
            for (int i = 0; i < poly.NumInteriorRings; i++)
            {
                LinearRing hole    = poly.InteriorRing(i);
                int        holeLoc = Locate(p, hole);
                if (holeLoc == LocationType.Interior)
                {
                    return(LocationType.Exterior);
                }
                if (holeLoc == LocationType.Boundary)
                {
                    return(LocationType.Boundary);
                }
            }

            return(LocationType.Interior);
        }
Exemplo n.º 22
0
        private List <double[]> getCoordinates(BAMCIS.GeoJSON.Feature feature)
        {
            List <double[]> coordinates = new List <double[]>();

            switch (feature.Geometry.Type)
            {
            case GeoJsonType.Point:
                Point p = feature.Geometry as Point;
                coordinates.Add(new double[]
                {
                    p.Coordinates.Longitude,
                    p.Coordinates.Latitude,
                });
                return(coordinates);

            case GeoJsonType.LineString:
                LineString lineString = feature.Geometry as LineString;
                coordinates = lineString.Coordinates.Select(coord => new double[] {
                    coord.Longitude,
                    coord.Latitude
                }).ToList();
                return(coordinates);

            case GeoJsonType.Polygon:
                Polygon    polygon = feature.Geometry as Polygon;
                LinearRing outline = polygon.Coordinates.FirstOrDefault();
                coordinates = outline.Coordinates.Select(coord => new double[] {
                    coord.Longitude,
                    coord.Latitude
                }).ToList();
                return(coordinates);

            default:
                return(coordinates);
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// The left and right topological location arguments assume that the ring is oriented CW.
        /// If the ring is in the opposite orientation,
        /// the left and right locations must be interchanged.
        /// </summary>
        /// <param name="lr"></param>
        /// <param name="cwLeft"></param>
        /// <param name="cwRight"></param>
        private void AddPolygonRing(LinearRing lr, Locations cwLeft, Locations cwRight)
        {
            ICoordinate[] coord = CoordinateArrays.RemoveRepeatedPoints(lr.Coordinates);
            if (coord.Length < 4)
            {
                hasTooFewPoints = true;
                invalidPoint    = coord[0];
                return;
            }
            Locations left  = cwLeft;
            Locations right = cwRight;

            if (CGAlgorithms.IsCCW(coord))
            {
                left  = cwRight;
                right = cwLeft;
            }
            Edge e = new Edge(coord, new Label(argIndex, Locations.Boundary, left, right));

            lineEdgeMap.Add(lr, e);
            InsertEdge(e);
            // insert the endpoint as a node, to mark that it is on the boundary
            InsertPoint(argIndex, coord[0], Locations.Boundary);
        }
Exemplo n.º 24
0
        protected void CreatePolygon(Point3d[] pts)
        {
            LinearRing lr = new LinearRing();

            lr.Points = pts;

            m_polygon = new Polygon();
            m_polygon.outerBoundary    = lr;
            m_polygon.PolgonColor      = fillColor;
            m_polygon.Fill             = true;
            m_polygon.ParentRenderable = this;
            m_polygon.Outline          = true;
            m_polygon.OutlineColor     = lineColor;
            m_polygon.LineWidth        = lineWidth;

            if (m_polygonDrawer != null)
            {
                m_polygonDrawer.Dispose();
                m_polygonDrawer = null;
                //System.GC.Collect();
            }

            m_polygonDrawer = new DrawPolygons(m_polygon, World);
        }
Exemplo n.º 25
0
        protected override void OnMouseDoubleClick(GeoMouseArgs e)
        {
            _isEnabled = false;
            IMapPolygonLayer tempLayer = new MapPolygonLayer();
            List <List <System.Drawing.Point> > polygons = GIS.Common.ComputationalGeometry.ClipperOperation.DecomposeNonSimplePolygon(_points);

            foreach (List <System.Drawing.Point> polygonPoints in polygons)
            {
                _coordinatePoints.Clear();
                for (int i = 0; i < polygonPoints.Count; i++)
                {
                    _coordinatePoints.Add(_map.PixelToProj(new System.Drawing.Point(polygonPoints[i].X, polygonPoints[i].Y)));
                }
                _coordinatePoints.Add(_map.PixelToProj(new System.Drawing.Point(polygonPoints[0].X, polygonPoints[0].Y)));
                LinearRing linearRing = new LinearRing(_coordinatePoints.ToArray());;
                Polygon    polygon    = new Polygon(linearRing);
                tempLayer.DataSet.Features.Add(polygon as IGeometry);
            }
            ProcessPolygon(tempLayer);

            _points.Clear();
            _map.Refresh();
            _isEnabled = true;
        }
Exemplo n.º 26
0
        public bool IsNonNested()
        {
            for (int i = 0; i < _rings.Count; i++)
            {
                LinearRing  innerRing    = (LinearRing)_rings[i];
                Coordinates innerRingPts = innerRing.GetCoordinates();

                for (int j = 0; j < _rings.Count; j++)
                {
                    LinearRing  searchRing    = (LinearRing)_rings[j];
                    Coordinates searchRingPts = searchRing.GetCoordinates();

                    if (innerRing == searchRing)
                    {
                        continue;
                    }

                    if (!innerRing.GetEnvelopeInternal().Intersects(searchRing.GetEnvelopeInternal()))
                    {
                        continue;
                    }

                    Coordinate innerRingPt = IsValidOp.FindPtNotNode(innerRingPts, searchRing, _graph);
                    //Assert.isTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring");
                    //Coordinate innerRingPt = innerRingPts[0];

                    bool isInside = _cga.IsPointInRing(innerRingPt, searchRingPts);
                    if (isInside)
                    {
                        _nestedPt = innerRingPt;
                        return(false);
                    }
                }
            }
            return(true);
        }
        private bool IsInside(LinearRing innerRing, LinearRing searchRing)
        {
            ICoordinateList innerRingPts  = innerRing.Coordinates;
            ICoordinateList searchRingPts = searchRing.Coordinates;

            if (!innerRing.Bounds.Intersects(searchRing.Bounds))
            {
                return(false);
            }

            Coordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, graph);

            Debug.Assert(innerRingPt != null, "Unable to find a ring point not a node of the search ring");

            bool IsInside = CGAlgorithms.IsPointInRing(innerRingPt, searchRingPts);

            if (IsInside)
            {
                nestedPt = innerRingPt;
                return(true);
            }

            return(false);
        }
Exemplo n.º 28
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 public Polygon(LinearRing exteriorRing)
     : this(exteriorRing, new Collection<LinearRing>())
 {
 }
Exemplo n.º 29
0
        /// <summary>
        /// Reads and parses the geometry with ID 'oid' from the ShapeFile
        /// </summary>
        /// <remarks><see cref="FilterDelegate">Filtering</see> is not applied to this method</remarks>
        /// <param name="oid">Object ID</param>
        /// <returns>geometry</returns>
        private Geometry ReadGeometry(uint oid)
        {
            _brShapeFile.BaseStream.Seek(GetShapeIndex(oid) + 8, 0); //Skip record number and content length
            var type = (ShapeType)_brShapeFile.ReadInt32();          //Shape type

            if (type == ShapeType.Null)
            {
                return(null);
            }
            if (_shapeType == ShapeType.Point || _shapeType == ShapeType.PointM || _shapeType == ShapeType.PointZ)
            {
                return(new Point(_brShapeFile.ReadDouble(), _brShapeFile.ReadDouble()));
            }
            if (_shapeType == ShapeType.Multipoint || _shapeType == ShapeType.MultiPointM ||
                _shapeType == ShapeType.MultiPointZ)
            {
                _brShapeFile.BaseStream.Seek(32 + _brShapeFile.BaseStream.Position, 0); //skip min/max box
                var feature = new MultiPoint();
                int nPoints = _brShapeFile.ReadInt32();                                 // get the number of points
                if (nPoints == 0)
                {
                    return(null);
                }
                for (int i = 0; i < nPoints; i++)
                {
                    feature.Points.Add(new Point(_brShapeFile.ReadDouble(), _brShapeFile.ReadDouble()));
                }

                return(feature);
            }
            if (_shapeType == ShapeType.PolyLine || _shapeType == ShapeType.Polygon ||
                _shapeType == ShapeType.PolyLineM || _shapeType == ShapeType.PolygonM ||
                _shapeType == ShapeType.PolyLineZ || _shapeType == ShapeType.PolygonZ)
            {
                _brShapeFile.BaseStream.Seek(32 + _brShapeFile.BaseStream.Position, 0); //skip min/max box

                int nParts = _brShapeFile.ReadInt32();                                  // get number of parts (segments)
                if (nParts == 0)
                {
                    return(null);
                }
                int nPoints = _brShapeFile.ReadInt32(); // get number of points

                var segments = new int[nParts + 1];
                //Read in the segment indexes
                for (int b = 0; b < nParts; b++)
                {
                    segments[b] = _brShapeFile.ReadInt32();
                }
                //add end point
                segments[nParts] = nPoints;

                if ((int)_shapeType % 10 == 3)
                {
                    var mline = new MultiLineString();
                    for (int lineId = 0; lineId < nParts; lineId++)
                    {
                        var line = new LineString();
                        for (int i = segments[lineId]; i < segments[lineId + 1]; i++)
                        {
                            line.Vertices.Add(new Point(_brShapeFile.ReadDouble(), _brShapeFile.ReadDouble()));
                        }
                        mline.LineStrings.Add(line);
                    }
                    if (mline.LineStrings.Count == 1)
                    {
                        return(mline[0]);
                    }
                    return(mline);
                }
                else //(_ShapeType == ShapeType.Polygon etc...)
                {
                    //First read all the rings
                    var rings = new List <LinearRing>();
                    for (int ringId = 0; ringId < nParts; ringId++)
                    {
                        var ring = new LinearRing();
                        for (int i = segments[ringId]; i < segments[ringId + 1]; i++)
                        {
                            ring.Vertices.Add(new Point(_brShapeFile.ReadDouble(), _brShapeFile.ReadDouble()));
                        }
                        rings.Add(ring);
                    }
                    var isCounterClockWise = new bool[rings.Count];
                    int polygonCount       = 0;
                    for (int i = 0; i < rings.Count; i++)
                    {
                        isCounterClockWise[i] = rings[i].IsCCW();
                        if (!isCounterClockWise[i])
                        {
                            polygonCount++;
                        }
                    }
                    if (polygonCount == 1) //We only have one polygon
                    {
                        var poly = new Polygon {
                            ExteriorRing = rings[0]
                        };
                        if (rings.Count > 1)
                        {
                            for (int i = 1; i < rings.Count; i++)
                            {
                                poly.InteriorRings.Add(rings[i]);
                            }
                        }
                        return(poly);
                    }
                    else
                    {
                        var mpoly = new MultiPolygon();
                        var poly  = new Polygon {
                            ExteriorRing = rings[0]
                        };
                        for (var i = 1; i < rings.Count; i++)
                        {
                            if (!isCounterClockWise[i])
                            {
                                mpoly.Polygons.Add(poly);
                                poly = new Polygon(rings[i]);
                            }
                            else
                            {
                                poly.InteriorRings.Add(rings[i]);
                            }
                        }
                        mpoly.Polygons.Add(poly);
                        return(mpoly);
                    }
                }
            }

            throw (new ApplicationException("Shapefile type " + _shapeType.ToString() + " not supported"));
        }
Exemplo n.º 30
0
        // METHOD IsCCW() IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:

        /*
         *  Copyright (C) 2002 Urban Science Applications, Inc.
         *
         *  This library is free software; you can redistribute it and/or
         *  modify it under the terms of the GNU Lesser General Public
         *  License as published by the Free Software Foundation; either
         *  version 2.1 of the License, or (at your option) any later version.
         *
         *  This library is distributed in the hope that it will be useful,
         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         *  Lesser General Public License for more details.
         *
         *  You should have received a copy of the GNU Lesser General Public
         *  License along with this library; if not, write to the Free Software
         *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
         *
         */

        /// <summary>
        /// Tests whether a ring is oriented counter-clockwise.
        /// </summary>
        /// <param name="ring">Ring to test.</param>
        /// <returns>Returns true if ring is oriented counter-clockwise.</returns>
        public static bool IsCCW(LinearRing ring)
        {
            Point PrevPoint, NextPoint;
            Point p;

            // Check if the ring has enough vertices to be a ring
            if (ring.Vertices.Count < 3)
            {
                throw (new ArgumentException("Invalid LinearRing"));
            }

            // find the point with the largest Y coordinate
            Point hip = ring.Vertices[0];
            int   hii = 0;

            for (int i = 1; i < ring.Vertices.Count; i++)
            {
                p = ring.Vertices[i];
                if (p.Y > hip.Y)
                {
                    hip = p;
                    hii = i;
                }
            }
            // Point left to Hip
            int iPrev = hii - 1;

            if (iPrev < 0)
            {
                iPrev = ring.Vertices.Count - 2;
            }
            // Point right to Hip
            int iNext = hii + 1;

            if (iNext >= ring.Vertices.Count)
            {
                iNext = 1;
            }
            PrevPoint = ring.Vertices[iPrev];
            NextPoint = ring.Vertices[iNext];

            // translate so that hip is at the origin.
            // This will not affect the area calculation, and will avoid
            // finite-accuracy errors (i.e very small vectors with very large coordinates)
            // This also simplifies the discriminant calculation.
            double prev2x = PrevPoint.X - hip.X;
            double prev2y = PrevPoint.Y - hip.Y;
            double next2x = NextPoint.X - hip.X;
            double next2y = NextPoint.Y - hip.Y;
            // compute cross-product of vectors hip->next and hip->prev
            // (e.g. area of parallelogram they enclose)
            double disc = next2x * prev2y - next2y * prev2x;

            // If disc is exactly 0, lines are collinear.  There are two possible cases:
            //	(1) the lines lie along the x axis in opposite directions
            //	(2) the line lie on top of one another
            //  (2) should never happen, so we're going to ignore it!
            //	(Might want to assert this)
            //  (1) is handled by checking if next is left of prev ==> CCW

            if (disc == 0.0)
            {
                // poly is CCW if prev x is right of next x
                return(PrevPoint.X > NextPoint.X);
            }
            else
            {
                // if area is positive, points are ordered CCW
                return(disc > 0.0);
            }
        }
Exemplo n.º 31
0
        private static Polygon BuildSubMeshBoundaryGeometry(CMeshData mesh, BoundarySegmentsBuilder bsb, List <CMeshFace> boundaryFaces)
        {
            // Find connected segments
            List <LinkedList <int> > segments = bsb.BuildBoundarySegments(boundaryFaces);

            if (segments == null)
            {
                return(null);
            }

            LinearRing        shell = null;
            List <LinearRing> holes = new List <LinearRing>();

            // Create mesh boundary with segments
            for (int isegment = 0; isegment < segments.Count; isegment++)
            {
                LinkedList <int> segment = segments[isegment];
                CMeshFace        first   = boundaryFaces[segment.First.Value];
                CMeshFace        last    = boundaryFaces[segment.Last.Value];

                if (!NodeEquals(first.FromNode, last.ToNode))
                {
                    Console.Out.WriteLine("Skipping: {0,4} {1,8} {2,8} {3,8}", isegment, segment.Count, first.FromNode, last.ToNode);
                    continue;
                }

                Coordinate[] coords = new Coordinate[segment.Count + 1];

                int i = 0;
                foreach (int iFace in segment)
                {
                    CMeshFace face = boundaryFaces[iFace];
                    coords[i++] = new Coordinate(face.FromNode.X, face.FromNode.Y);
                }

                coords[segment.Count] = new Coordinate(last.ToNode.X, last.ToNode.Y);
                LinearRing ring = new LinearRing(coords);
                if (ring.IsCCW)
                {
                    if (shell != null)
                    {
                        throw new Exception("Finding two shells of a connected sub-mesh");
                    }
                    shell = ring;
                }
                else
                {
                    holes.Add(ring);
                }
            }
            Polygon p;

            if (holes.Count > 0)
            {
                p = new Polygon(shell, holes.ToArray());
            }
            else
            {
                p = new Polygon(shell);
            }
            return(p);
        }
Exemplo n.º 32
0
        /// <summary>
        /// Reads a stream and converts the shapefile record to an equilivent geometry object.
        /// </summary>
        /// <param name="file">The stream to read.</param>
        /// <param name="geometryFactory">The geometry factory to use when making the object.</param>
        /// <returns>The Geometry object that represents the shape file record.</returns>
        public override IGeometry Read(BigEndianBinaryReader file, IGeometryFactory geometryFactory)
        {
            int shapeTypeNum             = file.ReadInt32();
            ShapeGeometryTypes shapeType = (ShapeGeometryTypes)Enum.Parse(typeof(ShapeGeometryTypes), shapeTypeNum.ToString());

            if (!(shapeType == ShapeGeometryTypes.Polygon || shapeType == ShapeGeometryTypes.PolygonM ||
                  shapeType == ShapeGeometryTypes.PolygonZ || shapeType == ShapeGeometryTypes.PolygonZM))
            {
                throw new ShapefileException("Attempting to load a non-polygon as polygon.");
            }

            // Read and for now ignore bounds.
            double[] box = new double[4];
            for (int i = 0; i < 4; i++)
            {
                box[i] = file.ReadDouble();
            }

            int[] partOffsets;
            int   numParts  = file.ReadInt32();
            int   numPoints = file.ReadInt32();

            partOffsets = new int[numParts];
            for (int i = 0; i < numParts; i++)
            {
                partOffsets[i] = file.ReadInt32();
            }

            ArrayList shells = new ArrayList();
            ArrayList holes  = new ArrayList();

            int start, finish, length;

            for (int part = 0; part < numParts; part++)
            {
                start = partOffsets[part];
                if (part == numParts - 1)
                {
                    finish = numPoints;
                }
                else
                {
                    finish = partOffsets[part + 1];
                }
                length = finish - start;
                CoordinateList points = new CoordinateList();
                points.Capacity = length;
                for (int i = 0; i < length; i++)
                {
                    Coordinate external = new Coordinate(file.ReadDouble(), file.ReadDouble());
                    new PrecisionModel(geometryFactory.PrecisionModel).MakePrecise(external);
                    Coordinate internalCoord = external;
                    points.Add(internalCoord);
                }

                ILinearRing ring = geometryFactory.CreateLinearRing((Coordinate[])points.ToArray(typeof(Coordinate)));

                // If shape have only a part, jump orientation check and add to shells
                if (numParts == 1)
                {
                    shells.Add(ring);
                }
                else
                {
                    // Orientation check
                    if (CGAlgorithms.IsCCW((Coordinate[])points.ToArray(typeof(Coordinate))))
                    {
                        holes.Add(ring);
                    }
                    else
                    {
                        shells.Add(ring);
                    }
                }
            }

            // Now we have a list of all shells and all holes
            ArrayList holesForShells = new ArrayList(shells.Count);

            for (int i = 0; i < shells.Count; i++)
            {
                holesForShells.Add(new ArrayList());
            }
            // Find holes
            for (int i = 0; i < holes.Count; i++)
            {
                LinearRing  testRing = (LinearRing)holes[i];
                LinearRing  minShell = null;
                IEnvelope   minEnv   = null;
                IEnvelope   testEnv  = testRing.EnvelopeInternal;
                ICoordinate testPt   = testRing.GetCoordinateN(0);
                LinearRing  tryRing;
                for (int j = 0; j < shells.Count; j++)
                {
                    tryRing = (LinearRing)shells[j];
                    IEnvelope tryEnv = tryRing.EnvelopeInternal;
                    if (minShell != null)
                    {
                        minEnv = minShell.EnvelopeInternal;
                    }
                    bool           isContained = false;
                    CoordinateList coordList   = new CoordinateList(tryRing.Coordinates);
                    if (tryEnv.Contains(testEnv) &&
                        (CGAlgorithms.IsPointInRing(testPt, (Coordinate[])coordList.ToArray(typeof(Coordinate))) ||
                         (PointInList(testPt, coordList))))
                    {
                        isContained = true;
                    }

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (isContained)
                    {
                        if (minShell == null || minEnv.Contains(tryEnv))
                        {
                            minShell = tryRing;
                        }

                        // Suggested by Brian Macomber and added 3/28/2006:
                        // holes were being found but never added to the holesForShells array
                        // so when converted to geometry by the factory, the inner rings were never created.
                        ArrayList holesForThisShell = (ArrayList)holesForShells[j];
                        holesForThisShell.Add(holes[i]);
                    }
                }
            }

            IPolygon[] polygons = new Polygon[shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = geometryFactory.CreatePolygon((LinearRing)shells[i],
                                                            (LinearRing[])((ArrayList)holesForShells[i]).ToArray(typeof(LinearRing)));
            }

            if (polygons.Length == 1)
            {
                return(polygons[0]);
            }
            // It's a multi part
            return(geometryFactory.CreateMultiPolygon(polygons));
        }
Exemplo n.º 33
0
 /// <summary>
 /// This routine checks to see if a shell is properly contained in a hole.
 /// It assumes that the edges of the shell and hole do not
 /// properly intersect.
 /// </summary>
 /// <param name="shell"></param>
 /// <param name="hole"></param>
 /// <param name="graph"></param>
 /// <returns>
 /// <c>null</c> if the shell is properly contained, or
 /// a Coordinate which is not inside the hole if it is not.
 /// </returns>
 private static Coordinate CheckShellInsideHole(LinearRing shell, LinearRing hole, GeometryGraph graph)
 {
     IList<Coordinate> shellPts = shell.Coordinates;
     IList<Coordinate> holePts = hole.Coordinates;
     // TODO: improve performance of this - by sorting pointlists?
     Coordinate shellPt = FindPointNotNode(shellPts, hole, graph);
     // if point is on shell but not hole, check that the shell is inside the hole
     if (shellPt != null)
     {
         bool insideHole = CgAlgorithms.IsPointInRing(shellPt, holePts);
         if (!insideHole) return shellPt;
     }
     Coordinate holePt = FindPointNotNode(holePts, shell, graph);
     // if point is on hole but not shell, check that the hole is outside the shell
     if (holePt != null)
     {
         bool insideShell = CgAlgorithms.IsPointInRing(holePt, shellPts);
         return insideShell ? holePt : null;
     }
     throw new ShellHoleIdentityException();
 }
Exemplo n.º 34
0
        /// <summary>
        /// Check if a shell is incorrectly nested within a polygon.  This is the case
        /// if the shell is inside the polygon shell, but not inside a polygon hole.
        /// (If the shell is inside a polygon hole, the nesting is valid.)
        /// The algorithm used relies on the fact that the rings must be properly contained.
        /// E.g. they cannot partially overlap (this has been previously checked by
        /// <c>CheckRelateConsistency</c>).
        /// </summary>
        private void CheckShellNotNested(LinearRing shell, Polygon p, GeometryGraph graph)
        {
            IList<Coordinate> shellPts = shell.Coordinates;
            // test if shell is inside polygon shell
            LinearRing polyShell = (LinearRing)p.ExteriorRing;
            IList<Coordinate> polyPts = polyShell.Coordinates;
            Coordinate shellPt = FindPointNotNode(shellPts, polyShell, graph);
            // if no point could be found, we can assume that the shell is outside the polygon
            if (shellPt == null) return;
            bool insidePolyShell = CgAlgorithms.IsPointInRing(shellPt, polyPts);
            if (!insidePolyShell) return;
            // if no holes, this is an error!
            if (p.NumHoles <= 0)
            {
                _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedShells, shellPt);
                return;
            }

            /*
             * Check if the shell is inside one of the holes.
             * This is the case if one of the calls to checkShellInsideHole
             * returns a null coordinate.
             * Otherwise, the shell is not properly contained in a hole, which is an error.
             */
            Coordinate badNestedPt = null;
            for (int i = 0; i < p.NumHoles; i++)
            {
                LinearRing hole = (LinearRing)p.GetInteriorRingN(i);
                badNestedPt = CheckShellInsideHole(shell, hole, graph);
                if (badNestedPt == null) return;
            }
            _validErr = new TopologyValidationError(TopologyValidationErrorType.NestedShells, badNestedPt);
        }
Exemplo n.º 35
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 public SiRtreePointInRing(LinearRing ring)
 {
     _ring = ring;
     BuildIndex();
 }
Exemplo n.º 36
0
        public void PolygonHoles()
        {
            Coordinate[] coords = new Coordinate[20];
            Random rnd = new Random();
            Coordinate center = new Coordinate((rnd.NextDouble() * 360) - 180, (rnd.NextDouble() * 180) - 90);

            // Shell Coordinates
            GeoAPI.Geometries.ICoordinate[] coordscheck = new GeoAPI.Geometries.ICoordinate[20];
            for (int i = 0; i < 19; i++)
            {
                double x = center.X + Math.Cos((i * 10) * Math.PI / 10);
                double y = center.Y + (i * 10) * Math.PI / 10;
                coords[i] = new Coordinate(x, y);
                coordscheck[i] = new GisSharpBlog.NetTopologySuite.Geometries.Coordinate(x, y);
            }
            coordscheck[19] = new GisSharpBlog.NetTopologySuite.Geometries.Coordinate(coords[0].X, coords[0].Y);
            coords[19] = new Coordinate(coords[0].X, coords[0].Y);


            // Shell Rings
            LinearRing ring = new LinearRing(coords);
            GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory gf = new GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory();
            GeoAPI.Geometries.ILinearRing ringCheck = gf.CreateLinearRing(coordscheck);


            // Hole Coordinates
            GeoAPI.Geometries.ICoordinate[] coordsholecheck = new GeoAPI.Geometries.ICoordinate[20];
            Coordinate[] coordshole = new Coordinate[20];
            for (int i = 0; i < 20; i++)
            {
                double x = center.X + Math.Cos((i * 10) * Math.PI / 20);
                double y = center.Y + (i * 10) * Math.PI / 20;
                coordshole[i] = new Coordinate(x, y);
                coordsholecheck[i] = new GisSharpBlog.NetTopologySuite.Geometries.Coordinate(x, y);
            }
            coordshole[19] = new Coordinate(coordshole[0].X, coordshole[0].Y);
            coordsholecheck[19] = new GisSharpBlog.NetTopologySuite.Geometries.Coordinate(coordshole[0].X, coordshole[0].Y);

            // Hole LinearRing Arrays
            LinearRing hole = new LinearRing(coordshole);
            ILinearRing[] holes = new ILinearRing[1];
            GeoAPI.Geometries.ILinearRing holeCheck = gf.CreateLinearRing(coordsholecheck);
            GeoAPI.Geometries.ILinearRing[] holescheck = new GeoAPI.Geometries.ILinearRing[1];
            holes[0] = hole;
            holescheck[0] = holeCheck;


            Polygon pg = new Polygon(ring, holes);
            GeoAPI.Geometries.IPolygon polygonCheck = gf.CreatePolygon(ringCheck, holescheck);
            double areaCheck = polygonCheck.Area;
            double area = pg.Area;
            Assert.AreEqual(area, areaCheck);
        }
Exemplo n.º 37
0
 /// <summary>
 /// Instatiates a polygon based on one extorier ring and a collection of interior rings.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 /// <param name="interiorRings">Interior rings</param>
 public Polygon(LinearRing exteriorRing, IList<LinearRing> interiorRings)
 {
     _ExteriorRing = exteriorRing;
     _InteriorRings = interiorRings ?? new Collection<LinearRing>();
 }
Exemplo n.º 38
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="reader"></param>
 /// <returns></returns>
 protected virtual IGeometry ReadPolygon(BinaryReader reader)
 {
     int numRings = reader.ReadInt32();
     ILinearRing exteriorRing = ReadRing(reader);
     ILinearRing[] interiorRings = new LinearRing[numRings - 1];
     for (int i = 0; i < numRings - 1; i++)
         interiorRings[i] = ReadRing(reader);
     return Factory.CreatePolygon(exteriorRing, interiorRings);
 }
Exemplo n.º 39
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="geometryFactory"></param>
 /// <returns></returns>
 public virtual IPolygon ToPolygon(IGeometryFactory geometryFactory)
 {
     ILinearRing[] holeLr = new LinearRing[_holes.Count];
     for (int i = 0; i < _holes.Count; i++)
         holeLr[i] = ((EdgeRing)_holes[i]).LinearRing;
     IPolygon poly = geometryFactory.CreatePolygon(LinearRing, holeLr);
     return poly;
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 public virtual void Add(LinearRing ring)
 {
     _rings.Add(ring);
     _totalEnv.ExpandToInclude(ring.EnvelopeInternal);
 }
Exemplo n.º 41
0
        private static LinearRing CreateWKBLinearRing(BinaryReader reader, WkbByteOrder byteOrder)
        {
            var l = new LinearRing();
            //l.Vertices.AddRange(ReadCoordinates(reader, byteOrder));
            var arrPoint = ReadCoordinates(reader, byteOrder);
            foreach (var t in arrPoint)
            {
                l.Vertices.Add(t);
            }

            //if polygon isn't closed, add the first point to the end (this shouldn't occur for correct WKB data)
            // ReSharper disable CompareOfFloatsByEqualityOperator
            if ((l.Vertices[0].X != l.Vertices[l.Vertices.Count - 1].X) ||
                (l.Vertices[0].Y != l.Vertices[l.Vertices.Count - 1].Y))
                l.Vertices.Add(new Point(l.Vertices[0].X, l.Vertices[0].Y));
            // ReSharper restore CompareOfFloatsByEqualityOperator
            return l;
        }
Exemplo n.º 42
0
        public IGeometry ToGeometry(IExtents envelopeInternal)
        {
            ICoordinate[] verticies = new ICoordinate[5];

            ICoordinate min = envelopeInternal.Min;
            ICoordinate max = envelopeInternal.Max;

            verticies[0] = max;
            verticies[1] = CoordinateFactory.Create(min[Ordinates.X], max[Ordinates.Y]);
            verticies[2] = min;
            verticies[3] = CoordinateFactory.Create(max[Ordinates.X], min[Ordinates.Y]);
            verticies[4] = max;

            LinearRing ring = new LinearRing(verticies);
            ring.Factory = this;
            Polygon p = new Polygon(ring);
            p.Factory = this;
            return p;
        }
Exemplo n.º 43
0
 public ILinearRing CreateLinearRing(IEnumerable<Point> coordinates)
 {
     LinearRing l = new LinearRing(Enumerable.Upcast<IPoint, Point>(coordinates));
     l.Factory = this;
     return l;
 }
Exemplo n.º 44
0
 public ILinearRing CreateLinearRing(IEnumerable<ICoordinate> coordinates)
 {
     LinearRing l = new LinearRing(coordinates);
     l.Factory = this;
     return l;
 }
Exemplo n.º 45
0
        private IGeometry CreatePolygonFromDataRow(DataRow dr, string ShapeColumnName)
        {
            byte[] shapeBytes = dr[ShapeColumnName] as byte[];
            //紧接着前两个点是几何的包围盒,也就是16*2=32个字节
            //然后是4个字节,代表有几个部分;然后是4个字节,代表有多少个点,紧接着的每四个字节代表每个部分开始点的位置
            byte[] numSkipByte = new byte[4];
            Array.Copy(shapeBytes, 4 + 32, numSkipByte, 0, 4);
            int numParts = BitConverter.ToInt32(numSkipByte, 0);

            byte[] numPtByte = new byte[4];
            Array.Copy(shapeBytes, 4 + 32 + 4, numPtByte, 0, 4);
            int numPt = BitConverter.ToInt32(numPtByte, 0);

            //获取各个多边形的分割索引号起始点序号
            int[]  startIdx = new int[numParts];
            byte[] temp     = new byte[4];
            for (int k = 0; k < numParts; k++)
            {
                Array.Copy(shapeBytes, 4 + 32 + 4 + 4 + k * 4, temp, 0, 4);
                startIdx[k] = BitConverter.ToInt32(temp, 0);
            }

            //去掉坐标点之前的字节
            byte[] shapeIgnoreHeadByte = new byte[shapeBytes.Length - 4 - 32 - 4 - 4 - 4 * numParts];
            Array.Copy(shapeBytes, 4 + 32 + 4 + 4 + 4 * numParts, shapeIgnoreHeadByte, 0, shapeIgnoreHeadByte.Length);

            ILinearRing[] linearRings = new ILinearRing[numParts];
            for (int k = 0; k < startIdx.Length; k++)
            {
                int sIdx = startIdx[k];
                //下一个部分起点序号
                int endIdx = k + 1 < startIdx.Length ? startIdx[k + 1] : numPt;

                //4+32:几何类型和包围盒字节
                //紧接着的4+4是多边形个数和总点数;
                //跳过4 * numPolygon个字节
                Coordinate[] pCoords = new Coordinate[endIdx - sIdx];

                int        i = 0;
                Coordinate coor;
                byte[]     geo = new byte[8];
                for (int j = sIdx * 16; j < endIdx * 16; j += 16)
                {
                    Array.Copy(shapeIgnoreHeadByte, j, geo, 0, geo.Length);
                    coor   = new Coordinate();
                    coor.X = BitConverter.ToDouble(geo, 0);
                    Array.Copy(shapeIgnoreHeadByte, j + 8, geo, 0, geo.Length);
                    coor.Y       = BitConverter.ToDouble(geo, 0);
                    pCoords[i++] = coor;
                }
                ILinearRing t_Ring = new LinearRing(pCoords);
                linearRings[k] = t_Ring;
                pCoords        = null;
            }

            IGeometry result = null;

            if (linearRings.Length == 1)
            {
                result = new Polygon(linearRings[0]);
            }
            else
            {
                //通过测试初步判定,多边形孔紧跟着外壳存储
                Stack <Polygon> pStack = new Stack <Polygon>();
                pStack.Push(new Polygon(linearRings[0]));
                for (int i = 1; i < linearRings.Length; i++)
                {
                    Polygon pGeo = pStack.Pop();
                    if (pGeo.Contains(linearRings[i]))
                    {
                        Polygon       poly  = pGeo as Polygon;
                        ILinearRing[] holes = new LinearRing[poly.Holes.Length + 1];
                        Array.Copy(poly.Holes, holes, poly.Holes.Length);
                        holes[holes.Length - 1] = linearRings[i];
                        pStack.Push(new Polygon(poly.Shell, holes));
                    }
                    else
                    {
                        pStack.Push(pGeo);//还原
                        pStack.Push(new Polygon(linearRings[i]));
                    }
                }
                if (pStack.Count > 1)
                {
                    result = new MultiPolygon(pStack.ToArray());
                }
                else
                {
                    result = pStack.Pop();
                }
            }
            shapeIgnoreHeadByte = null;//释放
            shapeBytes          = null;
            //return new Polygon(shell, holes.ToArray());
            return(result);
        }
Exemplo n.º 46
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="linearRing"></param>
 /// <param name="writer"></param>
 protected virtual void Write(LinearRing linearRing, XmlTextWriter writer)
 {
     writer.WriteStartElement("LinearRing");
     Write(linearRing.Coordinates, writer);
     writer.WriteEndElement();
 }
Exemplo n.º 47
0
        private void ReadPolygonShape(Shape shape)
        {
            List <ILinearRing> shells = new List <ILinearRing>();
            List <ILinearRing> holes  = new List <ILinearRing>();

            foreach (PartRange part in shape.Range.Parts)
            {
                List <Coordinate> coords = new List <Coordinate>();
                int i = part.StartIndex;
                foreach (Vertex d in part)
                {
                    Coordinate c = new Coordinate(d.X, d.Y);
                    if (shape.M != null && shape.M.Length > 0)
                    {
                        c.M = shape.M[i];
                    }
                    if (shape.Z != null && shape.Z.Length > 0)
                    {
                        c.Z = shape.Z[i];
                    }
                    i++;
                    coords.Add(c);
                }
                LinearRing ring = new LinearRing(coords.ToArray());
                if (shape.Range.Parts.Count == 1)
                {
                    shells.Add(ring);
                }
                else
                {
                    if (CGAlgorithms.IsCCW(ring.Coordinates))
                    {
                        holes.Add(ring);
                    }
                    else
                    {
                        shells.Add(ring);
                    }
                }
            }
            if (shells.Count == 0 && holes.Count > 0)
            {
                shells = holes;
                holes  = new List <ILinearRing>();
            }
            //// Now we have a list of all shells and all holes
            List <ILinearRing>[] holesForShells = new List <ILinearRing> [shells.Count];
            for (int i = 0; i < shells.Count; i++)
            {
                holesForShells[i] = new List <ILinearRing>();
            }

            // Find holes
            for (int i = 0; i < holes.Count; i++)
            {
                ILinearRing testRing = holes[i];
                ILinearRing minShell = null;
                Envelope    minEnv   = null;
                Envelope    testEnv  = testRing.EnvelopeInternal;
                Coordinate  testPt   = testRing.Coordinates[0];
                for (int j = 0; j < shells.Count; j++)
                {
                    ILinearRing tryRing = shells[j];
                    Envelope    tryEnv  = tryRing.EnvelopeInternal;
                    if (minShell != null)
                    {
                        minEnv = minShell.EnvelopeInternal;
                    }

                    // Check if this new containing ring is smaller than the current minimum ring
                    if (tryEnv.Contains(testEnv) && (CGAlgorithms.IsPointInRing(testPt, tryRing.Coordinates) || (PointInList(testPt, tryRing.Coordinates))))
                    {
                        if (minShell == null || minEnv.Contains(tryEnv))
                        {
                            minShell = tryRing;
                        }
                        holesForShells[j].Add(holes[i]);
                    }
                }
            }

            var polygons = new IPolygon[shells.Count];

            for (int i = 0; i < shells.Count; i++)
            {
                polygons[i] = new Polygon(shells[i], holesForShells[i].ToArray());
            }

            if (polygons.Length == 1)
            {
                _basicGeometry = polygons[0];
            }
            else
            {
                // It's a multi part
                _basicGeometry = new MultiPolygon(polygons);
            }
            _featureType = FeatureType.Polygon;
        }
Exemplo n.º 48
0
 public ILinearRing CreateLinearRing()
 {
     LinearRing l = new LinearRing();
     l.Factory = this;
     return l;
 }
Exemplo n.º 49
0
        public void PolygonHoles()
        {
            var coords = new Coordinate[20];
            var rnd = new Random();
            var center = new Coordinate((rnd.NextDouble() * 360) - 180, (rnd.NextDouble() * 180) - 90);

            // Shell Coordinates
            var coordscheck = new GeoAPI.Geometries.Coordinate[20];
            for (var i = 0; i < 19; i++)
            {
                var x = center.X + Math.Cos((i * 10) * Math.PI / 10);
                var y = center.Y + (i * 10) * Math.PI / 10;
                coords[i] = new Coordinate(x, y);
                coordscheck[i] = new GeoAPI.Geometries.Coordinate(x, y);
            }
            coordscheck[19] = new GeoAPI.Geometries.Coordinate(coords[0].X, coords[0].Y);
            coords[19] = new Coordinate(coords[0].X, coords[0].Y);


            // Shell Rings
            var ring = new LinearRing(coords);
            var gf = new NetTopologySuite.Geometries.GeometryFactory();
            var ringCheck = gf.CreateLinearRing(coordscheck);


            // Hole Coordinates
            var coordsholecheck = new GeoAPI.Geometries.Coordinate[20];
            var coordshole = new Coordinate[20];
            for (var i = 0; i < 20; i++)
            {
                var x = center.X + Math.Cos((i * 10) * Math.PI / 20);
                var y = center.Y + (i * 10) * Math.PI / 20;
                coordshole[i] = new Coordinate(x, y);
                coordsholecheck[i] = new GeoAPI.Geometries.Coordinate(x, y);
            }
            coordshole[19] = new Coordinate(coordshole[0].X, coordshole[0].Y);
            coordsholecheck[19] = new GeoAPI.Geometries.Coordinate(coordshole[0].X, coordshole[0].Y);

            // Hole LinearRing Arrays
            var hole = new LinearRing(coordshole);
            var holes = new ILinearRing[1];
            var holeCheck = gf.CreateLinearRing(coordsholecheck);
            var holescheck = new GeoAPI.Geometries.ILinearRing[1];
            holes[0] = hole;
            holescheck[0] = holeCheck;


            var pg = new Polygon(ring, holes);
            var polygonCheck = gf.CreatePolygon(ringCheck, holescheck);
            var areaCheck = polygonCheck.Area;
            var area = pg.Area;
            Assert.IsTrue(Math.Abs(area - areaCheck) < 1e-6);
        }
Exemplo n.º 50
0
 /// <summary>
 /// Instatiates a polygon based on one exterior ring.
 /// </summary>
 /// <param name="exteriorRing">Exterior ring</param>
 internal protected Polygon(LinearRing exteriorRing)
     : this(exteriorRing, null)
 {
 }
 /// <summary>
 ///
 /// </summary>
 /// <param name="ring"></param>
 public virtual void Add(LinearRing ring)
 {
     _rings.Add(ring);
 }
Exemplo n.º 52
0
        // METHOD IsCCW() IS MODIFIED FROM ANOTHER WORK AND IS ORIGINALLY BASED ON GeoTools.NET:
        /*
         *  Copyright (C) 2002 Urban Science Applications, Inc.
         *
         *  This library is free software; you can redistribute it and/or
         *  modify it under the terms of the GNU Lesser General Public
         *  License as published by the Free Software Foundation; either
         *  version 2.1 of the License, or (at your option) any later version.
         *
         *  This library is distributed in the hope that it will be useful,
         *  but WITHOUT ANY WARRANTY; without even the implied warranty of
         *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
         *  Lesser General Public License for more details.
         *
         *  You should have received a copy of the GNU Lesser General Public
         *  License along with this library; if not, write to the Free Software
         *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
         *
         */
        /// <summary>
        ///     Tests whether a ring is oriented counter-clockwise.
        /// </summary>
        /// <param name="ring">Ring to test.</param>
        /// <returns>Returns true if ring is oriented counter-clockwise.</returns>
        public static bool IsCCW(LinearRing ring)
        {
            // Check if the ring has enough vertices to be a ring
            if (ring.Vertices.Count < 3) throw new ArgumentException("Invalid LinearRing");

            // find the point with the largest Y coordinate
            var hip = ring.Vertices[0];
            var hii = 0;
            for (var i = 1; i < ring.Vertices.Count; i++)
            {
                var p = ring.Vertices[i];
                if (p.Y > hip.Y)
                {
                    hip = p;
                    hii = i;
                }
            }
            // Point left to Hip
            var iPrev = hii - 1;
            if (iPrev < 0) iPrev = ring.Vertices.Count - 2;
            // Point right to Hip
            var iNext = hii + 1;
            if (iNext >= ring.Vertices.Count) iNext = 1;
            var prevPoint = ring.Vertices[iPrev];
            var nextPoint = ring.Vertices[iNext];

            // translate so that hip is at the origin.
            // This will not affect the area calculation, and will avoid
            // finite-accuracy errors (i.e very small vectors with very large coordinates)
            // This also simplifies the discriminant calculation.
            var prev2X = prevPoint.X - hip.X;
            var prev2Y = prevPoint.Y - hip.Y;
            var next2X = nextPoint.X - hip.X;
            var next2Y = nextPoint.Y - hip.Y;
            // compute cross-product of vectors hip->next and hip->prev
            // (e.g. area of parallelogram they enclose)
            var disc = next2X*prev2Y - next2Y*prev2X;
            // If disc is exactly 0, lines are collinear.  There are two possible cases:
            //	(1) the lines lie along the x axis in opposite directions
            //	(2) the line lie on top of one another
            //  (2) should never happen, so we're going to ignore it!
            //	(Might want to assert this)
            //  (1) is handled by checking if next is left of prev ==> CCW

            // ReSharper disable once CompareOfFloatsByEqualityOperator
            if (disc == 0.0)
                return prevPoint.X > nextPoint.X;
            // if area is positive, points are ordered CCW
            return disc > 0.0;
        }