private void DoTest(ISpatialIndex <object> index, double queryEnvelopeExtent, IList <Envelope> sourceData)
        {
            Console.WriteLine("---------------");
            Console.WriteLine("Envelope Extent: " + queryEnvelopeExtent);
            int extraMatchCount    = 0;
            int expectedMatchCount = 0;
            int actualMatchCount   = 0;
            int queryCount         = 0;

            for (double x = 0; x < CELL_EXTENT * CELLS_PER_GRID_SIDE; x += queryEnvelopeExtent)
            {
                for (double y = 0; y < CELL_EXTENT * CELLS_PER_GRID_SIDE; y += queryEnvelopeExtent)
                {
                    var queryEnvelope   = new Envelope(x, x + queryEnvelopeExtent, y, y + queryEnvelopeExtent);
                    var expectedMatches = IntersectingEnvelopes(queryEnvelope, sourceData);
                    var actualMatches   = index.Query(queryEnvelope);
                    Assert.IsTrue(expectedMatches.Count <= actualMatches.Count);
                    extraMatchCount    += (actualMatches.Count - expectedMatches.Count);
                    expectedMatchCount += expectedMatches.Count;
                    actualMatchCount   += actualMatches.Count;
                    Compare(expectedMatches, actualMatches);
                    queryCount++;
                }
            }
            Console.WriteLine("Expected Matches: " + expectedMatchCount);
            Console.WriteLine("Actual Matches: " + actualMatchCount);
            Console.WriteLine("Extra Matches: " + extraMatchCount);
            Console.WriteLine("Query Count: " + queryCount);
            Console.WriteLine("Average Expected Matches: " + (expectedMatchCount / (double)queryCount));
            Console.WriteLine("Average Actual Matches: " + (actualMatchCount / (double)queryCount));
            Console.WriteLine("Average Extra Matches: " + (extraMatchCount / (double)queryCount));
        }
Exemple #2
0
        public static double CalculateLengthOfLineWithinPolygon(Geometry lineGeometry, ISpatialIndex <Geometry> geometriesToCheck)
        {
            // restrict the search space to nodes in the bounding box of the buffered line--subquadratic speedup over a naive search
            var candidateGeometriesToCheck = geometriesToCheck.Query(lineGeometry.EnvelopeInternal);

            return(CalculateLengthOfLineWithinPolygon(lineGeometry, candidateGeometriesToCheck));
        }
        /// <summary>
        /// Query shapefile by MBR.
        /// MBR coordinates MUST be in the Shapefile's coordinate system.
        ///
        /// NOTE: If you are using the default ISpatialIndex (which is an instance of the STRtree NTS class), it has some limitations.
        /// Since it works with MBRs rather than the shapes themselves, you can get some shapes that are not actually in the MBR
        /// you provided just because their MBRs are bounded by the given envelope.
        /// If you wish to avoid this behaviour, send true in the second paramter, but be weary of the consequences listed below.
        /// </summary>
        /// <param name="envelope"> The envlope to query. </param>
        /// <param name="testGeometriesActuallyInMBR">
        /// False by default, true to double-check the returned geometries against given Envelope, to avoid index error margin.
        ///
        /// It is advisable that you implement your own ISpatialIndex with your required precision rather than set this to True.
        ///
        /// **********
        /// CAUTION: If you choose to set this parameter as True, it will greatly affect performance as it
        /// will cancel any lazy mechanism implemented with reading the geometries from the file.
        /// Do not set this to True unless you either:
        /// A. Do not have any performance restrictions.
        /// Or:
        /// B. Absolutely need that precision in the geographic query.
        /// **********
        /// </param>
        /// <returns></returns>
        public IEnumerable <IShapefileFeature> ReadByMBRFilter(Envelope envelope, bool testGeometriesActuallyInMBR = false)
        {
            if (envelope == null)
            {
                throw new ArgumentNullException("envelope");
            }

            // If index creation task wasnt completed, wait for it to complete.
            if (!m_IsIndexingComplete)
            {
                m_IndexCreationTask.Wait();
            }

            var shapesInRegion = m_SpatialIndex.Query(envelope);

            if (shapesInRegion.Count == 0)
            {
                return(Enumerable.Empty <IShapefileFeature>());
            }

            var results = shapesInRegion.Select(ReadFeature);

            if (!testGeometriesActuallyInMBR)
            {
                return(results);
            }
            else
            {
                var envelopeGeo = new GeometryFactory().ToGeometry(envelope);

                return(results.Where(feature => envelopeGeo.Intersects(feature.Geometry)));
            }
        }
 private void DoTest(ISpatialIndex<object> index, double queryEnvelopeExtent, IList<Envelope> sourceData)
 {
     Console.WriteLine("---------------");
     Console.WriteLine("Envelope Extent: " + queryEnvelopeExtent);
     int extraMatchCount = 0;
     int expectedMatchCount = 0;
     int actualMatchCount = 0;
     int queryCount = 0;
     for (double x = 0; x < CELL_EXTENT * CELLS_PER_GRID_SIDE; x += queryEnvelopeExtent)
     {
         for (double y = 0; y < CELL_EXTENT * CELLS_PER_GRID_SIDE; y += queryEnvelopeExtent)
         {
             Envelope queryEnvelope = new Envelope(x, x + queryEnvelopeExtent, y, y + queryEnvelopeExtent);
             var expectedMatches = IntersectingEnvelopes(queryEnvelope, sourceData);
             var actualMatches = index.Query(queryEnvelope);
             Assert.IsTrue(expectedMatches.Count <= actualMatches.Count);
             extraMatchCount += (actualMatches.Count - expectedMatches.Count);
             expectedMatchCount += expectedMatches.Count;
             actualMatchCount += actualMatches.Count;
             Compare(expectedMatches, actualMatches);
             queryCount++;
         }
     }
     Console.WriteLine("Expected Matches: " + expectedMatchCount);
     Console.WriteLine("Actual Matches: " + actualMatchCount);
     Console.WriteLine("Extra Matches: " + extraMatchCount);
     Console.WriteLine("Query Count: " + queryCount);
     Console.WriteLine("Average Expected Matches: " + (expectedMatchCount/(double)queryCount));
     Console.WriteLine("Average Actual Matches: " + (actualMatchCount/(double)queryCount));
     Console.WriteLine("Average Extra Matches: " + (extraMatchCount/(double)queryCount));
 }
        public bool IsNonNested()
        {
            BuildIndex();

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

                var results = _index.Query(innerRing.EnvelopeInternal);
                for (int j = 0; j < results.Count; j++)
                {
                    var searchRing    = (ILinearRing)results[j];
                    var searchRingPts = searchRing.Coordinates;

                    if (innerRing == searchRing)
                    {
                        continue;
                    }

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

                    Coordinate innerRingPt = IsValidOp.FindPointNotNode(innerRingPts, searchRing, _graph);
                    // Diego Guidi: removed => see Issue 121
                    //Assert.IsTrue(innerRingPt != null, "Unable to find a ring point not a node of the search ring");

                    /**
                     * If no non-node pts can be found, this means
                     * that the searchRing touches ALL of the innerRing vertices.
                     * This indicates an invalid polygon, since either
                     * the two holes create a disconnected interior,
                     * or they touch in an infinite number of points
                     * (i.e. along a line segment).
                     * Both of these cases are caught by other tests,
                     * so it is safe to simply skip this situation here.
                     */
                    if (innerRingPt == null)
                    {
                        continue;
                    }

                    Boolean isInside = PointLocation.IsInRing(innerRingPt, searchRingPts);
                    if (isInside)
                    {
                        _nestedPt = innerRingPt;
                        return(false);
                    }
                }
            }
            return(true);
        }
Exemple #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="querySeg"></param>
        /// <returns></returns>
        public IList <LineSegment> Query(LineSegment querySeg)
        {
            var env = new Envelope(querySeg.P0, querySeg.P1);

            var visitor = new LineSegmentVisitor(querySeg);

            _index.Query(env, visitor);
            var itemsFound = visitor.Items;

            return(itemsFound);
        }
Exemple #7
0
        // <FIX> fast lookup for edges
        /// <summary>
        /// If there is an edge equal to e already in the list, return it.
        /// Otherwise return null.
        /// </summary>
        /// <param name="e"></param>
        /// <returns>
        /// equal edge, if there is one already in the list,
        /// null otherwise.
        /// </returns>
        public Edge FindEqualEdge(Edge e)
        {
            ICollection testEdges = index.Query(e.Envelope);

            for (IEnumerator i = testEdges.GetEnumerator(); i.MoveNext();)
            {
                Edge testEdge = (Edge)i.Current;
                if (testEdge.Equals(e))
                {
                    return(testEdge);
                }
            }
            return(null);
        }
Exemple #8
0
        public IEnumerable <TItem> ElementsIn(Rectangle bounds)
        {
            if (_index == null)
            {
                _index = new SpatialQuadTreeIndex <TItem> {
                    BoundsOf  = item => new Rectangle(this.GetLocation(item), this.GetSize(item)),
                    HasBounds = item => this.HasLocation(item) && this.HasSize(item)
                };
                _index.AddRange(this.changedLocations.Keys);
            }
            var result = _index.Query(bounds);

            return(result);
        }
Exemple #9
0
        // <FIX> fast lookup for edges
        /// <summary> If there is an edge equal to e already in the list, return it.
        /// Otherwise return null.
        /// </summary>
        /// <returns>  equal edge, if there is one already in the list
        /// null otherwise
        /// </returns>
        public Edge FindEqualEdge(Edge e)
        {
            IList testEdges = index.Query(e.Envelope);

            int nCount = testEdges.Count;

            for (int i = 0; i < nCount; i++)
            {
                Edge testEdge = (Edge)testEdges[i];
                if (testEdge.Equals(e))
                {
                    return(testEdge);
                }
            }

            return(null);
        }
        private void DoTest(ISpatialIndex <object> index, double queryEnvelopeExtent, List <Envelope> sourceData)
        {
            if (Verbose)
            {
                //System.Console.WriteLine("---------------");
                //System.Console.WriteLine("Envelope Extent: " + queryEnvelopeExtent);
            }
            int extraMatchCount    = 0;
            int expectedMatchCount = 0;
            int actualMatchCount   = 0;
            int queryCount         = 0;

            for (double x = 0d; x < CellExtent * CellsPerGridSide; x += queryEnvelopeExtent)
            {
                for (double y = 0d; y < CellExtent * CellsPerGridSide; y += queryEnvelopeExtent)
                {
                    var queryEnvelope   = new Envelope(x, x + queryEnvelopeExtent, y, y + queryEnvelopeExtent);
                    var expectedMatches = IntersectingEnvelopes(queryEnvelope, sourceData);
                    var actualMatches   = index.Query(queryEnvelope);
                    // since index returns candidates only, it may return more than the expected value
                    if (expectedMatches.Count > actualMatches.Count)
                    {
                        IsSuccess = false;
                    }
                    extraMatchCount    += (actualMatches.Count - expectedMatches.Count);
                    expectedMatchCount += expectedMatches.Count;
                    actualMatchCount   += actualMatches.Count;
                    Compare(expectedMatches, actualMatches);
                    queryCount++;
                }
            }

            if (Verbose)
            {
                //System.Console.WriteLine("Expected Matches: " + expectedMatchCount);
                //System.Console.WriteLine("Actual Matches: " + actualMatchCount);
                //System.Console.WriteLine("Extra Matches: " + extraMatchCount);
                //System.Console.WriteLine("Query Count: " + queryCount);
                //System.Console.WriteLine("Average Expected Matches: " + (expectedMatchCount/(double) queryCount));
                //System.Console.WriteLine("Average Actual Matches: " + (actualMatchCount/(double) queryCount));
                //System.Console.WriteLine("Average Extra Matches: " + (extraMatchCount/(double) queryCount));
            }
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public bool IsNonNested()
        {
            BuildQuadtree();

            for (int i = 0; i < _rings.Count; i++)
            {
                var innerRing    = _rings[i];
                var innerRingPts = innerRing.Coordinates;

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

                    if (innerRing == searchRing)
                    {
                        continue;
                    }

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

                    var 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 = PointLocation.IsInRing(innerRingPt, searchRingPts);
                    if (isInside)
                    {
                        _nestedPt = innerRingPt;
                        return(false);
                    }
                }
            }
            return(true);
        }
        /// <inheritdocs/>
        public Dictionary <int, Shape> GetShapes(ref int startIndex, int count, IEnvelope envelope)
        {
            Dictionary <int, Shape> result = new Dictionary <int, Shape>();
            ShapefileIndexFile      shx    = CacheShapeIndexFile();

            // Check to ensure the fileName is not null
            if (Filename == null)
            {
                throw new NullReferenceException(Filename);
            }

            if (File.Exists(Filename) == false)
            {
                throw new FileNotFoundException(Filename);
            }

            // Get the basic header information.
            ShapefileHeader header = new ShapefileHeader(Filename);
            Extent          ext    = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax });

            if (envelope != null)
            {
                if (!ext.Intersects(envelope))
                {
                    return(result);
                }
            }

            // Check to ensure that the fileName is the correct shape type
            if (header.ShapeType != ShapeType &&
                header.ShapeType != ShapeTypeM &&
                header.ShapeType != ShapeTypeZ)
            {
                throw new ArgumentException("Wrong feature type.");
            }

            FileStream fs = new FileStream(Filename, FileMode.Open, FileAccess.Read, FileShare.Read);

            if (fs.Length == 100)
            {
                // The shapefile is empty so we can simply return here
                fs.Close();
                return(result);
            }

            int shapesTested   = 0;
            int shapesReturned = 0;

            // Use spatial index if we have one
            if (null != _spatialIndex && null != envelope)
            {
                IList spatialQueryResults = _spatialIndex.Query(envelope);

                // Sort the results from low to high index
                var sqra = new int[spatialQueryResults.Count];
                spatialQueryResults.CopyTo(sqra, 0);
                Array.Sort(sqra);

                foreach (int shp in sqra)
                {
                    if (shp >= startIndex)
                    {
                        Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope);
                        shapesTested++;
                        if (null != myShape)
                        {
                            shapesReturned++;
                            result.Add(shp, myShape);
                            if (shapesReturned >= count)
                            {
                                break;
                            }
                        }
                    }
                }
            }
            else
            {
                int numShapes = shx.Shapes.Count;
                for (int shp = startIndex; shp < numShapes; shp++)
                {
                    Shape myShape = GetShapeAtIndex(fs, shx, header, shp, envelope);
                    shapesTested++;
                    if (null != myShape)
                    {
                        shapesReturned++;
                        result.Add(shp, myShape);
                        if (shapesReturned >= count)
                        {
                            break;
                        }
                    }
                }
            }
            startIndex += shapesTested;
            fs.Close();
            return(result);
        }
 private IList <EdgeRing> QueryOverlappingShells(Envelope ringEnv)
 {
     return(_shellIndex.Query(ringEnv));
 }
        private void DoTest(ISpatialIndex<object> index, double queryEnvelopeExtent, List<Envelope> sourceData)
        {
            if (Verbose)
            {
                Console.WriteLine("---------------");
                Console.WriteLine("Envelope Extent: " + queryEnvelopeExtent);
            }
            int extraMatchCount = 0;
            int expectedMatchCount = 0;
            int actualMatchCount = 0;
            int queryCount = 0;
            for (var x = 0d; x < CellExtent*CellsPerGridSide; x += queryEnvelopeExtent)
            {
                for (var y = 0d; y < CellExtent*CellsPerGridSide; y += queryEnvelopeExtent)
                {
                    var queryEnvelope = new Envelope(x, x + queryEnvelopeExtent, y, y + queryEnvelopeExtent);
                    var expectedMatches = IntersectingEnvelopes(queryEnvelope, sourceData);
                    var actualMatches = index.Query(queryEnvelope);
                    // since index returns candidates only, it may return more than the expected value
                    if (expectedMatches.Count > actualMatches.Count)
                    {
                        IsSuccess = false;
                    }
                    extraMatchCount += (actualMatches.Count - expectedMatches.Count);
                    expectedMatchCount += expectedMatches.Count;
                    actualMatchCount += actualMatches.Count;
                    Compare(expectedMatches, actualMatches);
                    queryCount++;
                }
            }

            if (Verbose)
            {
                Console.WriteLine("Expected Matches: " + expectedMatchCount);
                Console.WriteLine("Actual Matches: " + actualMatchCount);
                Console.WriteLine("Extra Matches: " + extraMatchCount);
                Console.WriteLine("Query Count: " + queryCount);
                Console.WriteLine("Average Expected Matches: " + (expectedMatchCount/(double) queryCount));
                Console.WriteLine("Average Actual Matches: " + (actualMatchCount/(double) queryCount));
                Console.WriteLine("Average Extra Matches: " + (extraMatchCount/(double) queryCount));
            }
        }
Exemple #15
0
        public static int CountIntersectingGeometries(Geometry lineGeometry, ISpatialIndex <Geometry> geometriesToCheck)
        {
            var candidateGeometriesToCheck = geometriesToCheck.Query(lineGeometry.EnvelopeInternal);

            return(candidateGeometriesToCheck.Count(x => x.Intersects(lineGeometry)));
        }