Represents an ESRI Shape-file. Implements methods for reading and writing.
Esempio n. 1
0
        /// <summary>
        /// Writes shapes.
        /// </summary>
        /// <param name="filename">The string value defining shape file name without .shp extension</param>
        /// <param name="geometryCollection"> MapAround.Geometry.GeometryCollection instance containing
        /// the geometries to write to shape file</param>
        public void WriteShapes(string filename, GeometryCollection geometryCollection)
        {
            if (geometryCollection.HasDifferentTypeInstances)
            {
                throw new ArgumentException("Geometries in the shape file should be the instances of the same type.", "geometryCollection");
            }

            using (FileStream shpStream = new FileStream(filename + ".shp", FileMode.Create))
            {
                using (FileStream shxStream = new FileStream(filename + ".shx", FileMode.Create))
                {
                    BigEndianBinaryWriter shpBinaryWriter = new BigEndianBinaryWriter(shpStream); //, Encoding.ASCII);
                    BigEndianBinaryWriter shxBinaryWriter = new BigEndianBinaryWriter(shxStream); //, Encoding.ASCII);

                    // body type and a handler
                    Handlers.ShapeHandler handler = ShapeFile.GetShapeHandler(ShapeFile.GetShapeType(geometryCollection[0]));//.Geometries[0]));
                    int numShapes = geometryCollection.Count;
                    // calc the length of the shp file, so it can put in the header.
                    int shpLength = 50;
                    for (int i = 0; i < numShapes; i++)
                    {
                        IGeometry body = (IGeometry)geometryCollection[i]; //.Geometries[i];
                        shpLength += 4;                                    // length of header in WORDS
                        shpLength += handler.GetLength(body);              // length of shape in WORDS
                    }

                    int shxLength = 50 + (4 * numShapes);

                    // write the .shp header
                    ShapeFileHeader shpHeader = new ShapeFileHeader();
                    shpHeader.FileLength = shpLength;

                    // get envelope in external coordinates
                    BoundingRectangle bounds = geometryCollection.GetBoundingRectangle();
                    shpHeader.SetBounds(bounds);

                    shpHeader.FileCode  = 9994;
                    shpHeader.ShapeType = (int)ShapeFile.GetShapeType(geometryCollection[0]);//.Geometries[0]);
                    shpHeader.Write(shpBinaryWriter, ShapeFile.GetShapeType(geometryCollection[0]));

                    // write the .shx header
                    ShapeFileHeader shxHeader = new ShapeFileHeader();
                    shxHeader.FileLength = shxLength;
                    shxHeader.SetBounds(shpHeader);//.Bounds = shpHeader.Bounds;

                    // assumes Geometry type of the first item will the same for all other items in the collection.
                    shxHeader.FileCode  = 9994;
                    shxHeader.ShapeType = (int)ShapeFile.GetShapeType(geometryCollection[0]);
                    shxHeader.Write(shxBinaryWriter, ShapeFile.GetShapeType(geometryCollection[0]));

                    // write the individual records.
                    int _pos = 50; // header length in WORDS
                    for (int i = 0; i < numShapes; i++)
                    {
                        IGeometry body         = geometryCollection[i];//.Geometries[i];
                        int       recordLength = handler.GetLength(body);
                        shpBinaryWriter.WriteIntBE(i + 1);
                        shpBinaryWriter.WriteIntBE(recordLength);

                        shxBinaryWriter.WriteIntBE(_pos);
                        shxBinaryWriter.WriteIntBE(recordLength);

                        _pos += 4;                            // length of header in WORDS
                        handler.Write(body, shpBinaryWriter); //, geometryFactory);
                        _pos += recordLength;                 // length of shape in WORDS
                    }

                    shxBinaryWriter.Flush();
                    shxBinaryWriter.Close();
                    shpBinaryWriter.Flush();
                    shpBinaryWriter.Close();
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Reads a record from the specified stream.
        /// </summary>
        /// <param name="stream">A System.IO.Stream instance to read</param>
        /// <param name="recordOffset">An offset of record</param>
        /// <param name="bounds">An object representing a bounds of the reading area</param>
        public ShapeFileRecord ReadRecord(Stream stream, int?recordOffset, BoundingRectangle bounds)
        {
            #region old

            //if (recordOffset != null)
            //    stream.Seek(recordOffset.Value, 0);

            //ShapeFileRecord record = new ShapeFileRecord();
            //record.Offset = stream.Position;

            //// заголовок записи
            //record.RecordNumber = ShapeFile.ReadInt32_BE(stream);
            //record.ContentLength = ShapeFile.ReadInt32_BE(stream);

            //// тип геометрической фигуры
            //record.ShapeType = ShapeFile.ReadInt32_LE(stream);

            //bool wasRead = false;
            //switch (record.ShapeType)
            //{
            //    case (int)ShapeType.NullShape:
            //        break;
            //    case (int)ShapeType.Point:
            //        wasRead = ShapeFile.ReadPoint(stream, bounds, record);
            //        break;
            //    case (int)ShapeType.PolyLine:
            //        wasRead = ShapeFile.ReadPolygon(stream, bounds, record);
            //        break;
            //    case (int)ShapeType.Polygon:
            //        wasRead = ShapeFile.ReadPolygon(stream, bounds, record);
            //        break;
            //    case (int)ShapeType.Multipoint:
            //        wasRead = ShapeFile.ReadMultipoint(stream, bounds, record);
            //        break;
            //    default:
            //        {
            //            string msg = String.Format(System.Globalization.CultureInfo.InvariantCulture, "ShapeType {0} is not supported.", (int)record.ShapeType);
            //            throw new InvalidDataException(msg);
            //        }
            //}

            //if (wasRead)
            //{
            //    this._records.Add(record);
            //    return record;
            //}
            //else return null;

            #endregion

            #region New

            if (recordOffset != null)
            {
                stream.Seek(recordOffset.Value, 0);
            }

            ShapeFileRecord record = new ShapeFileRecord();
            record.Offset = stream.Position;

            // заголовок записи
            //BigEndianBinaryReader reader = new BigEndianBinaryReader(stream);
            //record.RecordNumber = reader.ReadInt32BE();// ShapeFile.ReadInt32_BE(stream);
            //record.ContentLength = reader.ReadInt32BE();// ShapeFile.ReadInt32_BE(stream);
            record.RecordNumber  = stream.ReadInt32BE();   // ShapeFile.ReadInt32_BE(stream);
            record.ContentLength = stream.ReadInt32BE();   // ShapeFile.ReadInt32_BE(stream);


            // тип геометрической фигуры
            record.ShapeType = stream.ReadInt32();    //.ReadInt32BE();// ShapeFile.ReadInt32_LE(stream);


            ShapeHandler handler = ShapeFile.GetShapeHandler((ShapeType)record.ShapeType);

            if (handler.Read(stream, bounds, record))
            {
                this._records.Add(record);
                return(record);
            }
            else
            {
                return(null);
            }

            #endregion
        }
        private int internalQueryFeatures(IFeatureReceiver fr, BoundingRectangle bounds, bool checkBounds)
        {
            if (_cacheAccessor != null && !string.IsNullOrEmpty(fr.Alias))
            { 
                _cacheAccessor.Key = fr.Alias;
                if (_cacheAccessor.ExistsInCache)
                    return FillFromCache(_cacheAccessor, fr, bounds, _processAttributes);
                else
                    // If the object is not found in the cache, you must remove all objects from a file, to put them in the cache
                    checkBounds = false;
            }

            ShapeFile shapeFile = new ShapeFile();
            shapeFile.AttributesEncoding = _attributesEncoding;
            shapeFile.Read(_fileName, checkBounds ? bounds : null);

            if (ProcessAttributes)
            {
                fr.FeatureAttributeNames.Clear();
                foreach (string s in shapeFile.AttributeNames)
                    fr.FeatureAttributeNames.Add(s);
            }

            int result = 0;
            string layerHashStr = fr.GetHashCode().ToString();

            List<Feature> points = new List<Feature>();
            List<Feature> multiPoints = new List<Feature>();
            List<Feature> polylines = new List<Feature>();
            List<Feature> polygons = new List<Feature>();

            foreach (ShapeFileRecord record in shapeFile.Records)
            {
                if (!checkBounds ||
                    (record.MaxX >= bounds.MinX && record.MaxY >= bounds.MinY &&
                     record.MinX <= bounds.MaxX && record.MinY <= bounds.MaxY))
                {
                    Feature newFeature = null;
                    IGeometry geometry = geometryFromShapeRecord(record);
                    if (geometry != null)
                    {
                        newFeature = new Feature(geometry);
                        newFeature.UniqKey = layerHashStr + record.RecordNumber.ToString();
                        if (ProcessAttributes && record.Attributes != null)
                            newFeature.Attributes = record.Attributes.ItemArray;

                        if (processFeature(newFeature, fr, points, multiPoints, polylines, polygons))
                            result++;
                    }
                }
            }

            // If the objects are not extracted from the cache may be added to the cache.
            // This should be done only if the retrieval of all objects (checkBounds == false)
            if (_cacheAccessor != null && !string.IsNullOrEmpty(fr.Alias) &&
                checkBounds == false)
            {
                addFeaturesToCache(fr, points, multiPoints, polylines, polygons);
            }

            return result;
        }