Ejemplo n.º 1
0
        /// <summary>
        /// returns only the features that have envelopes that
        /// intersect with the specified envelope.  If in indexMode, this uses the ShapeIndices to create
        /// features on demand, rather than loading all the features.  It is much faster to use selectIndices
        /// when in index mode.
        /// </summary>
        /// <param name="region">The specified region to test for intersect with</param>
        /// <param name="affectedRegion">This returns the geographic extents that contains the modified contents.</param>
        /// <returns>A List of the IFeature elements that are contained in this region</returns>
        public virtual List<IFeature> Select(IEnvelope region, out IEnvelope affectedRegion)
        {
            List<IFeature> result = new List<IFeature>();
            if(IndexMode)
            {
                ShapeRange aoi = new ShapeRange(new Extent(region));
                IEnvelope env = region.Copy();
                Extent affected = new Extent();
                List<ShapeRange> shapes = ShapeIndices;
                if(shapes != null)
                {
                    for(int shp = 0; shp < shapes.Count; shp++)
                    {
                        if (!shapes[shp].Intersects(aoi)) continue;
                        IFeature f = GetFeature(shp);
                        affected.ExpandToInclude(shapes[shp].Extent);
                        result.Add(f);
                    }
                }
                affectedRegion = affected.ToEnvelope();
                return result;
            }

            affectedRegion = new Envelope();

            foreach (IFeature feature in Features)
            {
                if (!feature.Envelope.Intersects(region)) continue;
                result.Add(feature);
                affectedRegion.ExpandToInclude(feature.Envelope);
            }
            return result;

        }
Ejemplo n.º 2
0
        ///// <summary>
        ///// Obsolete and slow.  First get the X and Y array once, and then access the members directly from that array.
        ///// </summary>
        //public double[][] Vertices
        //{
        //    get
        //    {
        //        int len = _vertices.Length/2;
        //        double[][] result = new double[len][];
        //        for (int i = 0; i < len; i++)
        //        {
        //            result[i] = new[] { _vertices[i*2], _vertices[i*2+1] };
        //        }
        //        return result;
        //    }
        //    protected set
        //    {
        //        for(int i = 0; i < value.Length; i++)
        //        {
        //            _vertices[i*2] = value[i][0];
        //            _vertices[i*2 + 1] = value[i][1];
        //        }
        //    }
        //}

        /// <summary>
        /// After changing coordinates, this will force the re-calculation of envelopes on a feature
        /// level as well as on the featureset level.  If this featureset is in index mode, 
        /// this will update the shape extents instead.
        /// </summary>
        public void UpdateEnvelopes()
        {
            if (InternalDataSet != null)
            {
                InternalDataSet.UpdateEnvelopes();
                return;
            }
            _envelope = new Envelope();
            _extent = new Extent();
            if(!_indexMode)
            {
                if (Features == null || Features.Count <= 0)
                {
                    _extent = new Extent(-180, -90, 180, 90);
                    _envelope = _extent.ToEnvelope();
                    return;
                }
                for (int shp = 0; shp < Features.Count; shp++)
                {
                    Features[shp].UpdateEnvelope();
                    _envelope.ExpandToInclude(Features[shp].Envelope);
                }
                _extent = new Extent(_envelope);
            }
            else
            {
                if(_shapeIndices == null || _shapeIndices.Count == 0)
                {
                    _extent = new Extent(-180, -90, 180, 90);
                    _envelope = _extent.ToEnvelope();
                    return;
                }
                foreach (ShapeRange range in _shapeIndices)
                {
                    _extent.ExpandToInclude(range.Extent);
                }
                _envelope = _extent.ToEnvelope();
            }
            
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Obtains a typed list of ShapefilePoint structures with double values associated with the various coordinates.
        /// </summary>
        /// <param name="filename">A string filename</param>
        /// <param name="progressHandler">A progress indicator</param>
        private void FillPoints(string filename, IProgressHandler progressHandler)
        {
            

            // Check to ensure the filename is not null
            if (filename == null)
            {
                throw new NullReferenceException(MessageStrings.ArgumentNull_S.Replace("%S",filename));
            }

            if (File.Exists(filename) == false)
            {
                throw new FileNotFoundException(MessageStrings.FileNotFound_S.Replace("%S", filename));
            }

            // Reading the headers gives us an easier way to track the number of shapes and their overall length etc.
            List<ShapeHeader> shapeHeaders = ReadIndexFile(filename);

            // Get the basic header information.  
            ShapefileHeader header = new ShapefileHeader(filename);
            Extent = new Extent(new[] { header.Xmin, header.Ymin, header.Xmax, header.Ymax });
            Envelope = Extent.ToEnvelope();
            // Check to ensure that the filename is the correct shape type
            if (header.ShapeType != ShapeTypes.Point && header.ShapeType != ShapeTypes.PointM && header.ShapeType != ShapeTypes.PointZ)
            {
                throw new ApplicationException(MessageStrings.FileNotPoints_S.Replace("%S", filename));
            }

            // This will set up a reader so that we can read values in huge chunks, which is much faster than one value at a time.
            IO.BufferedBinaryReader bbReader = new IO.BufferedBinaryReader(filename, progressHandler);

            if (bbReader.FileLength == 100)
            {
                bbReader.Close();
                // the file is empty so we are done reading
                return;
            }

            // Skip the shapefile header by skipping the first 100 bytes in the shapefile
            bbReader.Seek(100, SeekOrigin.Begin);
            int numShapes = shapeHeaders.Count;
            byte[] bigEndian = new byte[numShapes * 8];
            byte[] allCoords = new byte[numShapes * 16];
            bool isM = false;
            bool isZ = false;
            if(header.ShapeType == ShapeTypes.PointM || header.ShapeType == ShapeTypes.PointZ)
            {
                isM = true;
            }
            if (header.ShapeType == ShapeTypes.PointZ)
            {
                isZ = true;
            }
            byte[] allM = new byte[8];
            if(isM) allM = new byte[numShapes * 8];
            byte[] allZ = new byte[8];
            if(isZ) allZ = new byte[numShapes * 8];
            for (int shp = 0; shp < numShapes; shp++)
            {
                // Read from the index file because some deleted records
                // might still exist in the .shp file.
                long offset = (shapeHeaders[shp].ByteOffset);
                bbReader.Seek(offset, SeekOrigin.Begin);
                bbReader.Read(bigEndian, shp * 8, 8);
                ShapeTypes type = (ShapeTypes)bbReader.ReadInt32();
                //bbReader.Seek(4, SeekOrigin.Current);
                bbReader.Read(allCoords, shp * 16, 16);
                if(isZ)
                {
                    bbReader.Read(allZ, shp*8, 8);
                }
                if (isM)
                {
                    bbReader.Read(allM, shp*8, 8);
                }
                ShapeRange shape = new ShapeRange(FeatureTypes.Point);
                shape.StartIndex = shp;
                shape.ContentLength = 8;
                shape.NumPoints = 1;
                shape.NumParts = 1;
                ShapeIndices.Add(shape);
            }
            double[] vert = new double[2 * numShapes];
            Buffer.BlockCopy(allCoords, 0, vert, 0, numShapes*16);
            Vertex = vert;
            if(isM)
            {
                double[] m = new double[numShapes];
                Buffer.BlockCopy(allM, 0, m, 0, numShapes * 8);
                M = m;
            }
            if(isZ)
            {
                double[] z = new double[numShapes];
                Buffer.BlockCopy(allZ, 0, z, 0, numShapes * 8);
                Z = z;
            }
            for (int shp = 0; shp < numShapes; shp++)
            {
                PartRange part = new PartRange(vert, shp, 0, FeatureTypes.Point);
                part.NumVertices = 1;
                ShapeRange shape = ShapeIndices[shp];
                shape.Parts.Add(part);
                shape.Extent = new Extent(new[] {vert[shp*2], vert[shp*2 + 1], vert[shp*2], vert[shp*2 + 1]});
            }

                bbReader.Dispose();
            
            
            
  
        }