Exemplo n.º 1
0
        /// <summary>
        /// Removes the feature with the specified index.
        /// </summary>
        /// <param name="index">Removes the feature from the specified index location.</param>
        public void RemoveAt(int index)
        {
            // Get shape range so we can update header smartly
            int         startIndex = index;
            IFeatureSet ifs        = Select(null, null, ref startIndex, 1);

            if (ifs.NumRows() > 0)
            {
                var shx = new ShapefileIndexFile();
                shx.Open(Filename);
                shx.Shapes.RemoveAt(index);
                shx.Save();

                AttributeTable dbf = GetAttributeTable(Filename);
                dbf.RemoveRowAt(index);
                if (_trackDeletedRows)
                {
                    _deletedRows = dbf.DeletedRows;
                }

                // Update extent in header if feature being deleted is NOT completely contained
                var hdr = new ShapefileHeader(Filename);

                Envelope featureEnv = ifs.GetFeature(0).Geometry.EnvelopeInternal;
                if (featureEnv.MinX <= hdr.Xmin || featureEnv.MaxX >= hdr.Xmax || featureEnv.MaxY >= hdr.Ymax || featureEnv.MinY <= hdr.Ymin)
                {
                    UpdateExtents();
                }

                // Update the Quadtree
                Quadtree?.Remove(featureEnv, index);
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Cache Index File in memory so we don't have to read it in every call to GetShapes
 /// </summary>
 /// <returns></returns>
 protected ShapefileIndexFile CacheShapeIndexFile()
 {
     if (null == _shx)
     {
         _shx = new ShapefileIndexFile();
         _shx.Open(Filename);
     }
     return(_shx);
 }
        /// <inheritdocs/>
        protected override Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp, IEnvelope envelope)
        {
            // Read from the index file because some deleted records
            // might still exist in the .shp file.
            long offset = (shx.Shapes[shp].ByteOffset);
            fs.Seek(offset, SeekOrigin.Begin);
            Shape myShape = new Shape();
            // Position     Value               Type        Number      Byte Order
            ShapeRange shape = new ShapeRange(FeatureType.Point); //--------------------------------------------------------------------
            shape.RecordNumber = fs.ReadInt32(Endian.BigEndian);     // Byte 0       Record Number       Integer     1           Big
            shape.ContentLength = fs.ReadInt32(Endian.BigEndian);    // Byte 4       Content Length      Integer     1           Big
            ShapeType shapeType = (ShapeType)fs.ReadInt32(); // Byte 8       Shape Type          Integer     1           Little
            if (shapeType == ShapeType.NullShape)
            {
                return null;
            }
            double[] vertices = fs.ReadDouble(2);
            double x = vertices[0], y = vertices[1];
            // Don't add this shape to the result
            if (envelope != null)
            {
                if (!envelope.Contains(new Coordinate(x, y)))
                {
                    return null;
                }
            }

            shape.StartIndex = 0;
            shape.NumParts = 1;
            shape.NumPoints = 1;
            shape.ShapeType = shapeType;
            shape.Extent = new Extent(x, y, x, y);
            myShape.Range = shape;
            myShape.Vertices = vertices;

            if (header.ShapeType == ShapeType.PointM)
            {
                myShape.M = fs.ReadDouble(1);
                myShape.MinM = myShape.MaxM = myShape.M[0];
                shape.Extent = new ExtentM(shape.Extent, myShape.MinM, myShape.MaxM);
            }
            else if (header.ShapeType == ShapeType.PointZ)
            {
                // For Z shapefiles, the Z part is not optional.
                myShape.Z = fs.ReadDouble(1);
                myShape.MinZ = myShape.MaxZ = myShape.Z[0];
                myShape.M = fs.ReadDouble(1);
                myShape.MinM = myShape.MaxM = myShape.M[0];
                shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, myShape.MinM, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, myShape.MaxM, myShape.MaxZ);
            }

            PartRange partR = new PartRange(myShape.Vertices, 0, 0, FeatureType.Point) { NumVertices = 1 };
            shape.Parts.Add(partR);
            myShape.Range = shape;

            return myShape;
        }
Exemplo n.º 4
0
        /// <inheritdocs/>
        public Shape[] GetShapes(int[] indices)
        {
            Shape[] result = new Shape[indices.Length];

            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);

            // 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);

            try
            {
                if (fs.Length == 100)
                {
                    // The shapefile is empty so we can simply return here
                    return(result);
                }
                int numShapes = shx.Shapes.Count;
                for (int j = 0; j < indices.Length; j++)
                {
                    int index = indices[j];
                    if (index < numShapes)
                    {
                        result[j] = GetShapeAtIndex(fs, shx, header, index, null);
                    }
                }
                return(result);
            }
            finally
            {
                fs.Close();
            }
        }
Exemplo n.º 5
0
 /// <summary>
 /// Creates a new instance of the ShapefileShapeSource with the specified
 /// shapefile as the source and supplied spatial and shape indices.
 /// </summary>
 /// <param name="fileName"></param>
 /// <param name="spatialIndex"></param>
 /// <param name="shx"></param>
 protected ShapefileShapeSource(string fileName, ISpatialIndex spatialIndex, ShapefileIndexFile shx)
 {
     Filename      = fileName;
     _spatialIndex = spatialIndex;
     _shx          = shx;
 }
Exemplo n.º 6
0
 /// <summary>
 /// Get the shape at the specified index.  Must be implemented by all shape sources derived from ShapefileShapeSource
 /// </summary>
 /// <param name="fs"></param>
 /// <param name="shx"></param>
 /// <param name="header"></param>
 /// <param name="shp"></param>
 /// <param name="envelope"></param>
 /// <returns></returns>
 protected abstract Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp,
                                          IEnvelope envelope);
Exemplo n.º 7
0
 /// <inheritdocs/>
 public void EndGetShapesSession()
 {
     _shx = null;
 }
        /// <inheritdocs/>
        public void RemoveAt(int index)
        {
            // Get shape range so we can update header smartly
            int startIndex = index;
            IFeatureSet ifs = Select(null, null, ref startIndex, 1);
            if (ifs.NumRows() > 0)
            {
                var shx = new ShapefileIndexFile();
                shx.Open(Filename);
                shx.Shapes.RemoveAt(index);
                shx.Save();

                AttributeTable dbf = GetAttributeTable(Filename);
                dbf.RemoveRowAt(index);
                if (_trackDeletedRows)
                    _deletedRows = dbf.DeletedRows;

                // Update extent in header if feature being deleted is NOT completely contained
                var hdr = new ShapefileHeader(Filename);

                IEnvelope featureEnv = ifs.GetFeature(0).Envelope;
                if (featureEnv.Left() <= hdr.Xmin || featureEnv.Right() >= hdr.Xmax || featureEnv.Top() >= hdr.Ymax || featureEnv.Bottom() <= hdr.Ymin)
                {
                    UpdateExtents();
                }

                // Update the Quadtree
                if (null != Quadtree)
                {
                    Quadtree.Remove(featureEnv, index);
                }
            }
        }
 /// <summary>
 /// Creates a new instance of the PolygonShapefileShapeSource with the specified polygon shapefile as the source and provided indices
 /// </summary>
 /// <param name="fileName"></param>
 /// <param name="spatialIndex"></param>
 /// <param name="shx"></param>
 public PolygonShapefileShapeSource(string fileName, ISpatialIndex spatialIndex, ShapefileIndexFile shx)
     : base(fileName, spatialIndex, shx)
 {
 }
Exemplo n.º 10
0
 /// <summary>
 /// Get the shape at the specified index.  Must be implemented by all shape sources derived from ShapefileShapeSource
 /// </summary>
 /// <param name="fs"></param>
 /// <param name="shx"></param>
 /// <param name="header"></param>
 /// <param name="shp"></param>
 /// <param name="envelope"></param>
 /// <returns></returns>
 protected abstract Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp,
                                          IEnvelope envelope);
Exemplo n.º 11
0
 /// <summary>
 /// Cache Index File in memory so we don't have to read it in every call to GetShapes
 /// </summary>
 /// <returns></returns>
 protected ShapefileIndexFile CacheShapeIndexFile()
 {
     if (null == _shx)
     {
         _shx = new ShapefileIndexFile();
         _shx.Open(Filename);
     }
     return _shx;
 }
Exemplo n.º 12
0
 /// <inheritdocs/>
 public void EndGetShapesSession()
 {
     _shx = null;
 }
Exemplo n.º 13
0
        /// <inheritdocs/>
        protected override Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp, IEnvelope envelope)
        {
            // Read from the index file because some deleted records
            // might still exist in the .shp file.
            long offset = (shx.Shapes[shp].ByteOffset);

            fs.Seek(offset, SeekOrigin.Begin);
            Shape myShape = new Shape();
            // Position     Value               Type        Number      Byte Order
            ShapeRange shape = new ShapeRange(FeatureType.Point); //--------------------------------------------------------------------

            shape.RecordNumber  = fs.ReadInt32(Endian.BigEndian); // Byte 0       Record Number       Integer     1           Big
            shape.ContentLength = fs.ReadInt32(Endian.BigEndian); // Byte 4       Content Length      Integer     1           Big
            ShapeType shapeType = (ShapeType)fs.ReadInt32();      // Byte 8       Shape Type          Integer     1           Little

            if (shapeType == ShapeType.NullShape)
            {
                return(null);
            }
            double[] vertices = fs.ReadDouble(2);
            double   x = vertices[0], y = vertices[1];

            // Don't add this shape to the result
            if (envelope != null)
            {
                if (!envelope.Contains(new Coordinate(x, y)))
                {
                    return(null);
                }
            }

            shape.StartIndex = 0;
            shape.NumParts   = 1;
            shape.NumPoints  = 1;
            shape.ShapeType  = shapeType;
            shape.Extent     = new Extent(x, y, x, y);
            myShape.Range    = shape;
            myShape.Vertices = vertices;

            if (header.ShapeType == ShapeType.PointM)
            {
                myShape.M    = fs.ReadDouble(1);
                myShape.MinM = myShape.MaxM = myShape.M[0];
                shape.Extent = new ExtentM(shape.Extent, myShape.MinM, myShape.MaxM);
            }
            else if (header.ShapeType == ShapeType.PointZ)
            {
                // For Z shapefiles, the Z part is not optional.
                myShape.Z    = fs.ReadDouble(1);
                myShape.MinZ = myShape.MaxZ = myShape.Z[0];
                myShape.M    = fs.ReadDouble(1);
                myShape.MinM = myShape.MaxM = myShape.M[0];
                shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, myShape.MinM, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, myShape.MaxM, myShape.MaxZ);
            }

            PartRange partR = new PartRange(myShape.Vertices, 0, 0, FeatureType.Point)
            {
                NumVertices = 1
            };

            shape.Parts.Add(partR);
            myShape.Range = shape;

            return(myShape);
        }
Exemplo n.º 14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PointShapefileShapeSource"/> class with the specified polygon shapefile as the source and provided indices
 /// </summary>
 /// <param name="fileName">The file name.</param>
 /// <param name="spatialIndex">The spatial index.</param>
 /// <param name="shx">The shapefile index file.</param>
 public PointShapefileShapeSource(string fileName, ISpatialIndex <int> spatialIndex, ShapefileIndexFile shx)
     : base(fileName, spatialIndex, shx)
 {
 }
 /// <summary>
 /// Creates a new instance of the LineShapefileShapeSource with the specified polygon shapefile as the source and provided indices
 /// </summary>
 /// <param name="fileName"></param>
 /// <param name="spatialIndex"></param>
 /// <param name="shx"></param>
 public LineShapefileShapeSource(string fileName, ISpatialIndex spatialIndex, ShapefileIndexFile shx)
     : base(fileName, spatialIndex, shx)
 {
 }
        /// <inheritdocs/>
        protected override Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp, IEnvelope envelope)
        {
            // Read from the index file because some deleted records
            // might still exist in the .shp file.
            long offset = (shx.Shapes[shp].ByteOffset);
            fs.Seek(offset, SeekOrigin.Begin);
            Shape myShape = new Shape();
            // Position     Value               Type        Number      Byte Order
            ShapeRange shape = new ShapeRange(FeatureType.Line);
            //--------------------------------------------------------------------
            shape.RecordNumber = fs.ReadInt32(Endian.BigEndian);
            // Byte 0       Record Number       Integer     1           Big
            shape.ContentLength = fs.ReadInt32(Endian.BigEndian);
            // Byte 4       Content Length      Integer     1           Big
            shape.ShapeType = (ShapeType)fs.ReadInt32();
            // Byte 8       Shape Type          Integer     1           Little
            shape.StartIndex = 0;
            if (shape.ShapeType == ShapeType.NullShape)
            {
                return null;
            }

            myShape.Range = shape;

            //bbReader.Read(allBounds, shp*32, 32);
            double xMin = fs.ReadDouble(); // Byte 12      Xmin                Double      1           Little
            double yMin = fs.ReadDouble(); // Byte 20      Ymin                Double      1           Little
            double xMax = fs.ReadDouble(); // Byte 28      Xmax                Double      1           Little
            double yMax = fs.ReadDouble(); // Byte 36      Ymax                Double      1           Little
            shape.Extent = new Extent(xMin, yMin, xMax, yMax);
            // Don't add this shape to the result
            if (envelope != null)
            {
                if (!myShape.Range.Extent.Intersects(envelope))
                {
                    return null;
                }
            }

            shape.NumParts = fs.ReadInt32(); // Byte 44      NumParts            Integer     1           Little
            //feature.NumPoints = bbReader.ReadInt32();             // Byte 48      NumPoints           Integer     1           Little
            shape.NumPoints = fs.ReadInt32();

            // Create an envelope from the extents box in the file.
            //feature.Envelope = new Envelope(xMin, xMax, yMin, yMax);
            int[] partIndices = fs.ReadInt32(shape.NumParts);
            myShape.Vertices = fs.ReadDouble(shape.NumPoints * 2);

            if (header.ShapeType == ShapeType.PolyLineM)
            {
                // These are listed as "optional" but there isn't a good indicator of how to determine if they were added.
                // To handle the "optional" M values, check the contentLength for the feature.
                // The content length does not include the 8-byte record header and is listed in 16-bit words.
                if (shape.ContentLength * 2 > 44 + 4 * shape.NumParts + 16 * shape.NumPoints)
                {
                    myShape.MinM = fs.ReadDouble();
                    myShape.MaxM = fs.ReadDouble();

                    myShape.M = fs.ReadDouble(shape.NumPoints);
                    shape.Extent = new ExtentM(shape.Extent, myShape.MinM, myShape.MaxM);
                }
            }
            else if (header.ShapeType == ShapeType.PolyLineZ)
            {
                bool hasM = shape.ContentLength * 2 > 60 + 4 * shape.NumParts + 24 * shape.NumPoints;
                myShape.MinZ = fs.ReadDouble();
                myShape.MaxZ = fs.ReadDouble();

                // For Z shapefiles, the Z part is not optional.
                myShape.Z = fs.ReadDouble(shape.NumPoints);

                // These are listed as "optional" but there isn't a good indicator of how to determine if they were added.
                // To handle the "optional" M values, check the contentLength for the feature.
                // The content length does not include the 8-byte record header and is listed in 16-bit words.)
                if (hasM)
                {
                    myShape.MinM = fs.ReadDouble();
                    myShape.MaxM = fs.ReadDouble();
                    myShape.M = fs.ReadDouble(shape.NumPoints);
                    shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, myShape.MinM, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, myShape.MaxM, myShape.MaxZ);
                }
                else
                    shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, double.MaxValue, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, double.MinValue, myShape.MaxZ);
            }

            myShape.Range = shape;

            for (int part = 0; part < shape.NumParts; part++)
            {
                int partOff = partIndices[part];
                int pointCount = shape.NumPoints - partOff;
                if (part < shape.NumParts - 1)
                {
                    pointCount = partIndices[part + 1] - partOff;
                }
                PartRange partR = new PartRange(myShape.Vertices, 0, partOff, FeatureType.Line) { NumVertices = pointCount };
                shape.Parts.Add(partR);
            }
            return myShape;
        }
Exemplo n.º 17
0
 /// <summary>
 /// Creates a new instance of the ShapefileShapeSource with the specified
 /// shapefile as the source and supplied spatial and shape indices.
 /// </summary>
 /// <param name="fileName"></param>
 /// <param name="spatialIndex"></param>
 /// <param name="shx"></param>
 protected ShapefileShapeSource(string fileName, ISpatialIndex spatialIndex, ShapefileIndexFile shx)
 {
     Filename = fileName;
     _spatialIndex = spatialIndex;
     _shx = shx;
 }
        /// <inheritdocs/>
        protected override Shape GetShapeAtIndex(FileStream fs, ShapefileIndexFile shx, ShapefileHeader header, int shp, IEnvelope envelope)
        {
            // Read from the index file because some deleted records
            // might still exist in the .shp file.
            long offset = (shx.Shapes[shp].ByteOffset);

            fs.Seek(offset, SeekOrigin.Begin);
            // Position     Value               Type        Number      Byte Order
            ShapeRange shape = new ShapeRange(FeatureType.Polygon); //--------------------------------------------------------------------

            shape.RecordNumber  = fs.ReadInt32(Endian.BigEndian);   // Byte 0       Record Number       Integer     1           Big
            shape.ContentLength = fs.ReadInt32(Endian.BigEndian);   // Byte 4       Content Length      Integer     1           Big
            shape.ShapeType     = (ShapeType)fs.ReadInt32();        // Byte 8       Shape Type          Integer     1           Little
            shape.StartIndex    = 0;
            if (shape.ShapeType == ShapeType.NullShape)
            {
                return(null);
            }

            Shape myShape = new Shape();

            myShape.Range = shape;

            //bbReader.Read(allBounds, shp*32, 32);
            double xMin = fs.ReadDouble();                // Byte 12      Xmin                Double      1           Little
            double yMin = fs.ReadDouble();                // Byte 20      Ymin                Double      1           Little
            double xMax = fs.ReadDouble();                // Byte 28      Xmax                Double      1           Little
            double yMax = fs.ReadDouble();                // Byte 36      Ymax                Double      1           Little

            shape.Extent = new Extent(xMin, yMin, xMax, yMax);
            // Don't add this shape to the result
            if (envelope != null)
            {
                if (!myShape.Range.Extent.Intersects(envelope))
                {
                    return(null);
                }
            }

            shape.NumParts = fs.ReadInt32();              // Byte 44      NumParts            Integer     1           Little
            //feature.NumPoints = bbReader.ReadInt32();             // Byte 48      NumPoints           Integer     1           Little
            shape.NumPoints = fs.ReadInt32();

            // Create an envelope from the extents box in the file.
            //feature.Envelope = new Envelope(xMin, xMax, yMin, yMax);
            int[] partIndices = fs.ReadInt32(shape.NumParts);
            myShape.Vertices = fs.ReadDouble(shape.NumPoints * 2);

            if (header.ShapeType == ShapeType.PolygonM)
            {
                // These are listed as "optional" but there isn't a good indicator of how to determine if they were added.
                // To handle the "optional" M values, check the contentLength for the feature.
                // The content length does not include the 8-byte record header and is listed in 16-bit words.
                if (shape.ContentLength * 2 > 44 + 4 * shape.NumParts + 16 * shape.NumPoints)
                {
                    myShape.MinM = fs.ReadDouble();
                    myShape.MaxM = fs.ReadDouble();

                    myShape.M    = fs.ReadDouble(shape.NumPoints);
                    shape.Extent = new ExtentM(shape.Extent, myShape.MinM, myShape.MaxM);
                }
            }
            else if (header.ShapeType == ShapeType.PolygonZ)
            {
                bool hasM = shape.ContentLength * 2 > 60 + 4 * shape.NumParts + 24 * shape.NumPoints;
                myShape.MinZ = fs.ReadDouble();
                myShape.MaxZ = fs.ReadDouble();
                // For Z shapefiles, the Z part is not optional.
                myShape.Z = fs.ReadDouble(shape.NumPoints);

                // These are listed as "optional" but there isn't a good indicator of how to determine if they were added.
                // To handle the "optional" M values, check the contentLength for the feature.
                // The content length does not include the 8-byte record header and is listed in 16-bit words.)
                if (hasM)
                {
                    myShape.MinM = fs.ReadDouble();
                    myShape.MaxM = fs.ReadDouble();
                    myShape.M    = fs.ReadDouble(shape.NumPoints);
                    shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, myShape.MinM, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, myShape.MaxM, myShape.MaxZ);
                }
                else
                {
                    shape.Extent = new ExtentMZ(shape.Extent.MinX, shape.Extent.MinY, double.MaxValue, myShape.MinZ, shape.Extent.MaxX, shape.Extent.MaxY, double.MinValue, myShape.MaxZ);
                }
            }

            myShape.Range = shape;

            for (int part = 0; part < shape.NumParts; part++)
            {
                int partOff    = partIndices[part];
                int pointCount = shape.NumPoints - partOff;
                if (part < shape.NumParts - 1)
                {
                    pointCount = partIndices[part + 1] - partOff;
                }
                PartRange partR = new PartRange(myShape.Vertices, 0, partOff, FeatureType.Polygon)
                {
                    NumVertices = pointCount
                };
                shape.Parts.Add(partR);
            }

            return(myShape);
        }
Exemplo n.º 19
0
        /// <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);
        }