/// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
		public static DbaseFieldDescriptor ShapeField()
		{
			DbaseFieldDescriptor shpfield = new DbaseFieldDescriptor();
			shpfield.Name="Geometry";
			shpfield._type='B';
			return shpfield;
		}
        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
		public static char GetDbaseType(Type type)
		{
			DbaseFieldDescriptor dbaseColumn = new DbaseFieldDescriptor();
            if (type == typeof(Char))
                return 'C';
            if (type == typeof(string))
                return 'C';
            else if (type == typeof(Double))
                return 'N';
            else if (type == typeof(Single))
                return 'N';
            else if (type == typeof(Int16))
                return 'N';
            else if (type == typeof(Int32))
                return 'N';
            else if (type == typeof(Int64))
                return 'N';
            else if (type == typeof(UInt16))
                return 'N';
            else if (type == typeof(UInt32))
                return 'N';
            else if (type == typeof(UInt64))
                return 'N';
            else if (type == typeof(Decimal))
                return 'N';
            else if (type == typeof(Boolean))
                return 'L';
            else if (type == typeof(DateTime))
                return 'D';

			throw new NotSupportedException(String.Format("{0} does not have a corresponding dbase type.", type.Name));
		}
Ejemplo n.º 3
0
        /// <summary>
        /// Initializes a new instance of the ShapefileDataReader class.
        /// </summary>
        /// <param name="filename">The shapefile to read (minus the .shp extension)</param>
        ///<param name="geometryFactory">The GeometryFactory to use.</param>
        public ShapefileDataReader(string filename, IGeometryFactory geometryFactory)
        {
            if (String.IsNullOrEmpty(filename))
            {
                throw new ArgumentNullException("filename");
            }
            if (geometryFactory == null)
            {
                throw new ArgumentNullException("geometryFactory");
            }
            _open = true;

            string dbfFile = Path.ChangeExtension(filename, "dbf");

            _dbfReader = new DbaseFileReader(dbfFile);
            string shpFile = Path.ChangeExtension(filename, "shp");

            _shpReader = new ShapefileReader(shpFile, geometryFactory);

            _dbfHeader   = _dbfReader.GetHeader();
            _recordCount = _dbfHeader.NumRecords;

            // copy dbase fields to our own array. Insert into the first position, the shape column
            _dbaseFields    = new DbaseFieldDescriptor[_dbfHeader.Fields.Length + 1];
            _dbaseFields[0] = DbaseFieldDescriptor.ShapeField();
            for (int i = 0; i < _dbfHeader.Fields.Length; i++)
            {
                _dbaseFields[i + 1] = _dbfHeader.Fields[i];
            }

            _shpHeader     = _shpReader.Header;
            _dbfEnumerator = _dbfReader.GetEnumerator();
            _shpEnumerator = _shpReader.GetEnumerator();
            _moreRecords   = true;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
		public static DbaseFieldDescriptor IdField()
		{
			DbaseFieldDescriptor shpfield = new DbaseFieldDescriptor();
			shpfield.Name="Row";
			shpfield._type='I';
			return shpfield;
		}
        public ShapefileDataReader(IStreamProviderRegistry streamProviderRegistry, IGeometryFactory geometryFactory)
        {
            if (streamProviderRegistry == null)
            {
                throw new ArgumentNullException("streamProviderRegistry");
            }
            if (geometryFactory == null)
            {
                throw new ArgumentNullException("geometryFactory");
            }
            _open = true;

            _dbfReader = new DbaseFileReader(streamProviderRegistry);
            _shpReader = new ShapefileReader(streamProviderRegistry, geometryFactory);

            _dbfHeader   = _dbfReader.GetHeader();
            _recordCount = _dbfHeader.NumRecords;

            // copy dbase fields to our own array. Insert into the first position, the shape column
            _dbaseFields    = new DbaseFieldDescriptor[_dbfHeader.Fields.Length + 1];
            _dbaseFields[0] = DbaseFieldDescriptor.ShapeField();
            for (int i = 0; i < _dbfHeader.Fields.Length; i++)
            {
                _dbaseFields[i + 1] = _dbfHeader.Fields[i];
            }

            _shpHeader     = _shpReader.Header;
            _dbfEnumerator = _dbfReader.GetEnumerator();
            _shpEnumerator = _shpReader.GetEnumerator();
            _moreRecords   = true;
        }
Ejemplo n.º 6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public static char GetDbaseType(Type type)
        {
            DbaseFieldDescriptor dbaseColumn = new DbaseFieldDescriptor();

            if (type == typeof(Char))
            {
                return('C');
            }
            if (type == typeof(string))
            {
                return('C');
            }
            else if (type == typeof(Double))
            {
                return('N');
            }
            else if (type == typeof(Single))
            {
                return('N');
            }
            else if (type == typeof(Int16))
            {
                return('N');
            }
            else if (type == typeof(Int32))
            {
                return('N');
            }
            else if (type == typeof(Int64))
            {
                return('N');
            }
            else if (type == typeof(UInt16))
            {
                return('N');
            }
            else if (type == typeof(UInt32))
            {
                return('N');
            }
            else if (type == typeof(UInt64))
            {
                return('N');
            }
            else if (type == typeof(Decimal))
            {
                return('N');
            }
            else if (type == typeof(Boolean))
            {
                return('L');
            }
            else if (type == typeof(DateTime))
            {
                return('D');
            }

            throw new NotSupportedException(String.Format("{0} does not have a corresponding dbase type.", type.Name));
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static DbaseFieldDescriptor ShapeField()
        {
            DbaseFieldDescriptor shpfield = new DbaseFieldDescriptor();

            shpfield.Name  = "Geometry";
            shpfield._type = 'B';
            return(shpfield);
        }
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        public static DbaseFieldDescriptor IdField()
        {
            DbaseFieldDescriptor shpfield = new DbaseFieldDescriptor();

            shpfield.Name  = "Row";
            shpfield._type = 'I';
            return(shpfield);
        }
        public static DbaseFileHeader GetHeader(DbaseFieldDescriptor[] dbFields, int count)
        {
            DbaseFileHeader header = new DbaseFileHeader();
            header.NumRecords = count;

            foreach (DbaseFieldDescriptor dbField in dbFields)
                header.AddColumn(dbField.Name, dbField.DbaseType, dbField.Length, dbField.DecimalCount);

            return header;
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Initializes a new instance of the ShapefileDataReader class.
        /// </summary>
        /// <param name="filename">The shapefile to read (minus the .shp extension)</param>
        ///<param name="geometryFactory">The GeometryFactory to use.</param>
        public ShapeMemoryStreamDataReader(Stream shpStream, Stream dbfStream, IGeometryFactory geometryFactory)
        {
            if (shpStream == null)
            {
                throw new ArgumentNullException("shpStream");
            }
            if (dbfStream == null)
            {
                throw new ArgumentNullException("dbfStream");
            }
            if (geometryFactory == null)
            {
                throw new ArgumentNullException("geometryFactory");
            }
            _open = true;

            //if (filename.ToLower().EndsWith(".shp"))
            //    filename = filename.ToLower().Replace(".shp", String.Empty);

            _shpReader = new ShapeMemoryStreamReader(shpStream, geometryFactory);
            _dbfReader = new DbaseMemoryStreamReader(dbfStream);

            //_dbfReader = new DbaseFileReader(filename + ".dbf");
            //_shpReader = new ShapefileReader(filename + ".shp", geometryFactory);

            _dbfHeader = _dbfReader.GetHeader();

            _recordCount = _dbfHeader.NumRecords;

            // copy dbase fields to our own array. Insert into the first position, the shape column
            _dbaseFields    = new DbaseFieldDescriptor[_dbfHeader.Fields.Length + 1];
            _dbaseFields[0] = DbaseFieldDescriptor.ShapeField();
            for (int i = 0; i < _dbfHeader.Fields.Length; i++)
            {
                _dbaseFields[i + 1] = _dbfHeader.Fields[i];
            }

            _shpHeader     = _shpReader.Header;
            _dbfEnumerator = _dbfReader.GetEnumerator();
            _shpEnumerator = _shpReader.GetEnumerator();
            _moreRecords   = true;
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Remove a column from this DbaseFileHeader.
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns>return index of the removed column, -1 if no found.</returns>
        public int RemoveColumn(string fieldName)
        {
            int retCol     = -1;
            int tempLength = 1;

            DbaseFieldDescriptor[] tempFieldDescriptors =
                new DbaseFieldDescriptor[_fieldDescriptions.Length - 1];
            for (int i = 0, j = 0; i < _fieldDescriptions.Length; i++)
            {
                if (fieldName.ToLower() != (_fieldDescriptions[i].Name.Trim().ToLower()))
                {
                    // if this is the last field and we still haven't found the
                    // named field
                    if (i == j && i == _fieldDescriptions.Length - 1)
                    {
                        return(retCol);
                    }
                    tempFieldDescriptors[j]             = _fieldDescriptions[i];
                    tempFieldDescriptors[j].DataAddress = tempLength;
                    tempLength += tempFieldDescriptors[j].Length;
                    // only increment j on non-matching fields
                    j++;
                }
                else
                {
                    retCol = i;
                }
            }

            // set the new fields.
            _fieldDescriptions = tempFieldDescriptors;
            _headerLength      = 33 + 32 * _fieldDescriptions.Length;
            _numFields         = _fieldDescriptions.Length;
            _recordLength      = tempLength;

            return(retCol);
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Read the header data from the DBF file.
        /// </summary>
        /// <param name="reader">BinaryReader containing the header.</param>
        /// <param name="cpgStreamProvider">A stream provider to read the contents of the CPG Encoding</param>
        public void ReadHeader(BinaryReader reader, IStreamProvider cpgStreamProvider)
        {
            // type of reader.
            _fileType = reader.ReadByte();
            if (_fileType != 0x03)
            {
                throw new NotSupportedException("Unsupported DBF reader Type " + _fileType);
            }

            // parse the update date information.
            int year  = reader.ReadByte();
            int month = reader.ReadByte();
            int day   = reader.ReadByte();

            _updateDate = new DateTime(year + 1900, month, day);

            // read the number of records.
            _numRecords = reader.ReadInt32();

            // read the length of the header structure.
            _headerLength = reader.ReadInt16();

            // read the length of a record
            _recordLength = reader.ReadInt16();

            // skip the reserved bytes in the header.
            //in.skipBytes(20);
            byte[] data     = reader.ReadBytes(20);
            byte   ldid     = data[29 - 12]; //get the 29th byte in the file... we've first to read into arry was no 12
            var    encoding = DetectEncoding(ldid, cpgStreamProvider);

            if (_encoding == null)
            {
                _encoding = encoding;
            }

            //Replace reader with one with correct encoding..
            reader = new BinaryReader(reader.BaseStream, _encoding);
            // calculate the number of Fields in the header
            _numFields = (_headerLength - FileDescriptorSize - 1) / FileDescriptorSize;

            // read all of the header records
            _fieldDescriptions = new DbaseFieldDescriptor[_numFields];
            for (int i = 0; i < _numFields; i++)
            {
                _fieldDescriptions[i] = new DbaseFieldDescriptor();

                // read the field name
                byte[] buffer = reader.ReadBytes(11);
                // NOTE: only this _encoding.GetString method is available in Silverlight
                string name      = DbaseEncodingUtility.Latin1.GetString(buffer, 0, buffer.Length);
                int    nullPoint = name.IndexOf((char)0);
                if (nullPoint != -1)
                {
                    name = name.Substring(0, nullPoint);
                }
                _fieldDescriptions[i].Name = name;

                // read the field type
                _fieldDescriptions[i].DbaseType = (char)reader.ReadByte();

                // read the field data address, offset from the start of the record.
                _fieldDescriptions[i].DataAddress = reader.ReadInt32();

                // read the field length in bytes
                int tempLength = reader.ReadByte();
                if (tempLength < 0)
                {
                    tempLength = tempLength + 256;
                }
                _fieldDescriptions[i].Length = tempLength;

                // read the field decimal count in bytes
                _fieldDescriptions[i].DecimalCount = reader.ReadByte();

                // read the reserved bytes.
                //reader.skipBytes(14);
                reader.ReadBytes(14);
            }

            // Last byte is a marker for the end of the field definitions.
            // Trond Benum: This fails for some presumeably valid test shapefiles, so I have commented it out.
            /*byte lastByte = */ reader.ReadByte();//s(1)[0];
            // if (lastByte != 0x0d)
            //   throw new ShapefileException("DBase Header is not terminated");

            // Assure we are at the end of the header!
            if (reader.BaseStream.Position != _headerLength)
            {
                reader.BaseStream.Seek(_headerLength, SeekOrigin.Begin);
            }
        }
Ejemplo n.º 13
0
        /// <summary>
        ///  Add a column to this DbaseFileHeader.
        /// </summary>
        /// <param name="fieldName">The name of the field to add.</param>
        /// <param name="fieldType">The type is one of (C N L or D) character, number, logical(true/false), or date.</param>
        /// <param name="fieldLength"> The Field length is the total length in bytes reserved for this column.</param>
        /// <param name="decimalCount">The decimal count only applies to numbers(N), and floating point values (F), and refers to the number of characters to reserve after the decimal point.</param>
        public void AddColumn(string fieldName, char fieldType, int fieldLength, int decimalCount)
        {
            if (Encoding == null)
            {
                //throw new InvalidOperationException("Must not add columns when the Encoding is not set");
                Encoding = DefaultEncoding;
            }

            if (fieldLength <= 0)
            {
                fieldLength = 1;
            }
            int tempLength = 1;  // the length is used for the offset, and there is a * for deleted as the first byte

            DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_fieldDescriptions.Length + 1];
            for (int i = 0; i < _fieldDescriptions.Length; i++)
            {
                _fieldDescriptions[i].DataAddress = tempLength;
                tempLength = tempLength + _fieldDescriptions[i].Length;
                tempFieldDescriptors[i] = _fieldDescriptions[i];
            }
            tempFieldDescriptors[_fieldDescriptions.Length]              = new DbaseFieldDescriptor();
            tempFieldDescriptors[_fieldDescriptions.Length].Length       = fieldLength;
            tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = decimalCount;
            tempFieldDescriptors[_fieldDescriptions.Length].DataAddress  = tempLength;

            // set the field name
            string tempFieldName = fieldName;

            if (tempFieldName == null)
            {
                tempFieldName = "NoName";
            }
            if (tempFieldName.Length > FieldNameMaxLength)
            {
                string s = String.Format("FieldName {0} is longer than {1} characters", fieldName, FieldNameMaxLength);
                throw new ArgumentException(s);
            }
            tempFieldDescriptors[_fieldDescriptions.Length].Name = tempFieldName;

            // the field type
            switch (fieldType)
            {
            case 'C':
            case 'c':
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'C';
                if (fieldLength > 254)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Which is longer than 254, not consistent with dbase III");
                }
                break;

            case 'S':
            case 's':
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'C';
                Trace.WriteLine("Field type for " + fieldName + " set to S which is flat out wrong people!, I am setting this to C, in the hopes you meant character.");
                if (fieldLength > 254)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Which is longer than 254, not consistent with dbase III");
                }
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 8;
                break;

            case 'D':
            case 'd':
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'D';
                if (fieldLength != 8)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Setting to 8 digets YYYYMMDD");
                }
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 8;
                break;

            case 'F':
            case 'f':
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'F';
                if (fieldLength > 20)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Preserving length, but should be set to Max of 20 not valid for dbase IV, and UP specification, not present in dbaseIII.");
                }
                break;

            case 'N':
            case 'n':
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'N';
                if (fieldLength > 18)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Preserving length, but should be set to Max of 18 for dbase III specification.");
                }
                if (decimalCount < 0)
                {
                    Trace.WriteLine("Field Decimal Position for " + fieldName + " set to " + decimalCount + " Setting to 0 no decimal data will be saved.");
                    tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = 0;
                }
                if (decimalCount > fieldLength - 1)
                {
                    Trace.WriteLine("Field Decimal Position for " + fieldName + " set to " + decimalCount + " Setting to " + (fieldLength - 1) + " no non decimal data will be saved.");
                    tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = fieldLength - 1;
                }
                break;

            case 'L':
            case 'l':
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'L';
                if (fieldLength != 1)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Setting to length of 1 for logical fields.");
                }
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 1;
                break;

            default:
                throw new NotSupportedException("Unsupported field type " + fieldType + " For column " + fieldName);
            }
            // the length of a record
            tempLength = tempLength + tempFieldDescriptors[_fieldDescriptions.Length].Length;

            // set the new fields.
            _fieldDescriptions = tempFieldDescriptors;
            _headerLength      = 33 + 32 * _fieldDescriptions.Length;
            _numFields         = _fieldDescriptions.Length;
            _recordLength      = tempLength;
        }
Ejemplo n.º 14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="columnValues"></param>
        public void Write(IList columnValues)
        {
            if (columnValues == null)
            {
                throw new ArgumentNullException("columnValues");
            }
            if (!_headerWritten)
            {
                throw new InvalidOperationException("Header records need to be written first.");
            }
            int i = 0;

            _writer.Write((byte)0x20); // the deleted flag
            foreach (object columnValue in columnValues)
            {
                DbaseFieldDescriptor headerField = _header.Fields[i];

                if (columnValue == null || columnValue == DBNull.Value)
                {
                    // Don't corrupt the file by not writing if the value is null.
                    // Instead, treat it like an empty string.
                    Write(string.Empty, headerField.Length);
                }
                else if (headerField.Type == typeof(string))
                {
                    // If the column is a character column, the values in that
                    // column should be treated as text, even if the column value
                    // is not a string.
                    Write(columnValue.ToString(), headerField.Length);
                }
                else if (IsRealType(columnValue.GetType()))
                {
                    Write(Convert.ToDecimal(columnValue), headerField.Length, headerField.DecimalCount);
                }
                else if (IsIntegerType(columnValue.GetType()))
                {
                    Write(Convert.ToDecimal(columnValue), headerField.Length, headerField.DecimalCount);
                }
                else if (columnValue is Decimal)
                {
                    Write((decimal)columnValue, headerField.Length, headerField.DecimalCount);
                }
                else if (columnValue is Boolean)
                {
                    Write((bool)columnValue);
                }
                else if (columnValue is string)
                {
                    Write((string)columnValue, headerField.Length);
                }
                else if (columnValue is DateTime)
                {
                    Write((DateTime)columnValue);
                }
                else if (columnValue is Char)
                {
                    Write((Char)columnValue, headerField.Length);
                }

                i++;
            }
        }
Ejemplo n.º 15
0
		/// <summary>
		/// Initializes a new instance of the ColumnStructure class.
		/// </summary>
        /// <param name="dbaseField"></param>
        /// <param name="index"></param>
		public ColumnStructure(DbaseFieldDescriptor dbaseField, int index) : base(dbaseField.Name, null)
		{
			_dbaseField = dbaseField;
			_index=index;	
		}
Ejemplo n.º 16
0
        /// <summary>
        /// Read the header data from the DBF file.
        /// </summary>
        /// <param name="reader">BinaryReader containing the header.</param>
        /// <param name="filename">Filename </param>
        public void ReadHeader(BinaryReader reader, string filename)
        {
            // type of reader.
            _fileType = reader.ReadByte();
            if (_fileType != 0x03)
                throw new NotSupportedException("Unsupported DBF reader Type " + _fileType);

            // parse the update date information.
            int year = reader.ReadByte();
            int month = reader.ReadByte();
            int day = reader.ReadByte();
            _updateDate = new DateTime(year + 1900, month, day);

            // read the number of records.
            _numRecords = reader.ReadInt32();

            // read the length of the header structure.
            _headerLength = reader.ReadInt16();

            // read the length of a record
            _recordLength = reader.ReadInt16();

            // skip the reserved bytes in the header.
            //in.skipBytes(20);
            byte[] data = reader.ReadBytes(20);
            byte lcid = data[29 - 12]; //get the 29th byte in the file... we've first to read into arry was no 12
            _encoding = DetectEncodingFromMark(lcid, filename);

            //Replace reader with one with correct encoding..
            reader = new BinaryReader(reader.BaseStream, _encoding);
            // calculate the number of Fields in the header
            _numFields = (_headerLength - FileDescriptorSize - 1) / FileDescriptorSize;

            // read all of the header records
            _fieldDescriptions = new DbaseFieldDescriptor[_numFields];
            for (int i = 0; i < _numFields; i++)
            {
                _fieldDescriptions[i] = new DbaseFieldDescriptor();

                // read the field name				
                byte[] buffer = reader.ReadBytes(11);
                // NOTE: only this _encoding.GetString method is available in Silverlight
                String name = _encoding.GetString(buffer, 0, buffer.Length);
                int nullPoint = name.IndexOf((char)0);
                if (nullPoint != -1)
                    name = name.Substring(0, nullPoint);
                _fieldDescriptions[i].Name = name;

                // read the field type
                _fieldDescriptions[i].DbaseType = (char)reader.ReadByte();

                // read the field data address, offset from the start of the record.
                _fieldDescriptions[i].DataAddress = reader.ReadInt32();

                // read the field length in bytes
                int tempLength = reader.ReadByte();
                if (tempLength < 0) tempLength = tempLength + 256;
                _fieldDescriptions[i].Length = tempLength;

                // read the field decimal count in bytes
                _fieldDescriptions[i].DecimalCount = reader.ReadByte();

                // read the reserved bytes.
                //reader.skipBytes(14);
                reader.ReadBytes(14);
            }

            // Last byte is a marker for the end of the field definitions.
            // Trond Benum: This fails for some presumeably valid test shapefiles, so I have commented it out. 
            byte lastByte = reader.ReadBytes(1)[0];
            // if (lastByte != 0x0d)
            //   throw new ShapefileException("DBase Header is not terminated");

            // Assure we are at the end of the header!
            if (reader.BaseStream.Position != _headerLength)
                reader.BaseStream.Seek(_headerLength, SeekOrigin.Begin);
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Read the header data from the DBF file.
        /// </summary>
        /// <param name="reader">BinaryReader containing the header.</param>
        public void ReadHeader(BinaryReader reader)
        {
            // type of reader.
            _fileType = reader.ReadByte();
            if (_fileType != 0x03)
            {
                throw new NotSupportedException("Unsupported DBF reader Type " + _fileType);
            }

            // parse the update date information.
            int year  = (int)reader.ReadByte();
            int month = (int)reader.ReadByte();
            int day   = (int)reader.ReadByte();

            _updateDate = new DateTime(year + 1900, month, day);

            // read the number of records.
            _numRecords = reader.ReadInt32();

            // read the length of the header structure.
            _headerLength = reader.ReadInt16();

            // read the length of a record
            _recordLength = reader.ReadInt16();

            // skip the reserved bytes in the header.
            //in.skipBytes(20);
            reader.ReadBytes(20);
            // calculate the number of Fields in the header
            _numFields = (_headerLength - FileDescriptorSize - 1) / FileDescriptorSize;

            // read all of the header records
            _fieldDescriptions = new DbaseFieldDescriptor[_numFields];
            for (int i = 0; i < _numFields; i++)
            {
                _fieldDescriptions[i] = new DbaseFieldDescriptor();

                // read the field name
                char[] buffer = new char[11];
                buffer = reader.ReadChars(11);
                string name      = new string(buffer);
                int    nullPoint = name.IndexOf((char)0);
                if (nullPoint != -1)
                {
                    name = name.Substring(0, nullPoint);
                }
                _fieldDescriptions[i].Name = name;

                // read the field type
                _fieldDescriptions[i].DbaseType = (char)reader.ReadByte();

                // read the field data address, offset from the start of the record.
                _fieldDescriptions[i].DataAddress = reader.ReadInt32();

                // read the field length in bytes
                int tempLength = (int)reader.ReadByte();
                if (tempLength < 0)
                {
                    tempLength = tempLength + 256;
                }
                _fieldDescriptions[i].Length = tempLength;

                // read the field decimal count in bytes
                _fieldDescriptions[i].DecimalCount = (int)reader.ReadByte();

                // read the reserved bytes.
                //reader.skipBytes(14);
                reader.ReadBytes(14);
            }

            // Last byte is a marker for the end of the field definitions.
            if (reader.ReadBytes(1)[0] != 0x0d)
            {
                throw new ShapefileException("DBase Header is not terminated");
            }

            // Assure we are at the end of the header!
            if (reader.BaseStream.Position != _headerLength)
            {
                reader.BaseStream.Seek(_headerLength, SeekOrigin.Begin);
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbaseFields"></param>
        /// <param name="columnValues"></param>
		public RowStructure(DbaseFieldDescriptor[] dbaseFields, ArrayList columnValues) 
		{
			_dbaseFields = dbaseFields;
			_columnValues  = columnValues;
		}
Ejemplo n.º 19
0
        /// <summary>
        /// Write the enumeration of features to shapefile (shp, shx and dbf)
        /// </summary>
        /// <param name="filename">Filename to create</param>
        /// <param name="features">Enumeration of features to write, features will be enumerated once</param>
        /// <param name="fields">Fields that should be written, only those attributes specified here will be mapped from the feature attributetable while writing</param>
        /// <param name="shapeGeometryType">Type of geometries shapefile</param>
        /// <param name="dbfEncoding">Optional Encoding to be used when writing the DBF-file (default Windows-1252)</param>
        public static void WriteFeatures(string filename, IEnumerable<IFeature> features, DbaseFieldDescriptor[] fields, ShapeGeometryType shapeGeometryType,
            Encoding dbfEncoding = null)
        {

            // Set default encoding if not specified
            if (dbfEncoding == null)
                dbfEncoding = Encoding.GetEncoding(1252);

            // Open shapefile and dbase stream writers
            using (var shpWriter = new ShapefileWriter(Path.ChangeExtension(filename, ".shp"), shapeGeometryType))
            {
                using (var dbfWriter = new DbaseFileWriter(Path.ChangeExtension(filename, ".dbf"), dbfEncoding))
                {
                    var dbfHeader = new DbaseFileHeader(dbfEncoding);
                    foreach (var field in fields)
                    {
                        dbfHeader.AddColumn(field.Name, field.DbaseType, field.Length, field.DecimalCount);
                    }
                    dbfWriter.Write(dbfHeader);

                    var numFeatures = 0;
                    foreach (var feature in features)
                    {
                        shpWriter.Write(feature.Geometry);
                        var values = new object[fields.Length];
                        for (var i = 0; i < fields.Length; i++)
                        {
                            values[i] = feature.Attributes[fields[i].Name];
                        }
                        dbfWriter.Write(values);
                        numFeatures++;
                    }

                    // set the number of records
                    dbfHeader.NumRecords = numFeatures;
                    // Update the header
                    dbfWriter.Write(dbfHeader);
                    // write the end of dbase file marker
                    dbfWriter.WriteEndOfDbf();
                    // close the dbase stream
                    dbfWriter.Close();
                }
            }
        }
 /// <summary>
 /// Initializes a new instance of the ColumnStructure class.
 /// </summary>
 /// <param name="dbaseField"></param>
 /// <param name="index"></param>
 public ColumnStructure(DbaseFieldDescriptor dbaseField, int index) : base(dbaseField.Name, null)
 {
     _dbaseField = dbaseField;
     _index      = index;
 }
Ejemplo n.º 21
0
        /// <summary>
        ///  Add a column to this DbaseFileHeader.
        /// </summary>
        /// <param name="fieldName">The name of the field to add.</param>
        /// <param name="fieldType">The type is one of (C N L or D) character, number, logical(true/false), or date.</param>
        /// <param name="fieldLength"> The Field length is the total length in bytes reserved for this column.</param>
        /// <param name="decimalCount">The decimal count only applies to numbers(N), and floating point values (F), and refers to the number of characters to reserve after the decimal point.</param>
        public void AddColumn(string fieldName, char fieldType, int fieldLength, int decimalCount)
        {
            if (fieldLength <= 0) fieldLength = 1;
            if (_fieldDescriptions == null) _fieldDescriptions = new DbaseFieldDescriptor[0];
            int tempLength = 1;  // the length is used for the offset, and there is a * for deleted as the first byte
            DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_fieldDescriptions.Length + 1];
            for (int i = 0; i < _fieldDescriptions.Length; i++)
            {
                _fieldDescriptions[i].DataAddress = tempLength;
                tempLength = tempLength + _fieldDescriptions[i].Length;
                tempFieldDescriptors[i] = _fieldDescriptions[i];
            }
            tempFieldDescriptors[_fieldDescriptions.Length] = new DbaseFieldDescriptor();
            tempFieldDescriptors[_fieldDescriptions.Length].Length = fieldLength;
            tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = decimalCount;
            tempFieldDescriptors[_fieldDescriptions.Length].DataAddress = tempLength;

            // set the field name
            string tempFieldName = fieldName;
            if (tempFieldName == null) tempFieldName = "NoName";
            if (tempFieldName.Length > FieldNameMaxLength)
            {
                string s = String.Format("FieldName {0} is longer than {1} characters", fieldName, FieldNameMaxLength);
                throw new ArgumentException(s);
            }
            tempFieldDescriptors[_fieldDescriptions.Length].Name = tempFieldName;

            // the field type
            if ((fieldType == 'C') || (fieldType == 'c'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'C';
                if (fieldLength > 254) Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Which is longer than 254, not consistent with dbase III");
            }
            else if ((fieldType == 'S') || (fieldType == 's'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'C';
                Trace.WriteLine("Field type for " + fieldName + " set to S which is flat out wrong people!, I am setting this to C, in the hopes you meant character.");
                if (fieldLength > 254) Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Which is longer than 254, not consistent with dbase III");
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 8;
            }
            else if ((fieldType == 'D') || (fieldType == 'd'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'D';
                if (fieldLength != 8) Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Setting to 8 digets YYYYMMDD");
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 8;
            }
            else if ((fieldType == 'F') || (fieldType == 'f'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'F';
                if (fieldLength > 20) Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Preserving length, but should be set to Max of 20 not valid for dbase IV, and UP specification, not present in dbaseIII.");
            }
            else if ((fieldType == 'N') || (fieldType == 'n'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'N';
                if (fieldLength > 18) Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Preserving length, but should be set to Max of 18 for dbase III specification.");
                if (decimalCount < 0)
                {
                    Trace.WriteLine("Field Decimal Position for " + fieldName + " set to " + decimalCount + " Setting to 0 no decimal data will be saved.");
                    tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = 0;
                }
                if (decimalCount > fieldLength - 1)
                {
                    Trace.WriteLine("Field Decimal Position for " + fieldName + " set to " + decimalCount + " Setting to " + (fieldLength - 1) + " no non decimal data will be saved.");
                    tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = fieldLength - 1;
                }
            }
            else if ((fieldType == 'L') || (fieldType == 'l'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'L';
                if (fieldLength != 1) Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Setting to length of 1 for logical fields.");
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 1;
            }
            else
            {
                throw new NotSupportedException("Unsupported field type " + fieldType + " For column " + fieldName);
            }
            // the length of a record
            tempLength = tempLength + tempFieldDescriptors[_fieldDescriptions.Length].Length;

            // set the new fields.
            _fieldDescriptions = tempFieldDescriptors;
            _headerLength = 33 + 32 * _fieldDescriptions.Length;
            _numFields = _fieldDescriptions.Length;
            _recordLength = tempLength;
        }
Ejemplo n.º 22
0
        /// <summary>
        /// Remove a column from this DbaseFileHeader.
        /// </summary>
        /// <param name="fieldName"></param>
        /// <returns>return index of the removed column, -1 if no found.</returns>
        public int RemoveColumn(string fieldName)
        {
            int retCol = -1;
            int tempLength = 1;
            DbaseFieldDescriptor[] tempFieldDescriptors =
                new DbaseFieldDescriptor[_fieldDescriptions.Length - 1];
            for (int i = 0, j = 0; i < _fieldDescriptions.Length; i++)
            {
                if (fieldName.ToLower() != (_fieldDescriptions[i].Name.Trim().ToLower()))
                {
                    // if this is the last field and we still haven't found the
                    // named field
                    if (i == j && i == _fieldDescriptions.Length - 1)
                        return retCol;
                    tempFieldDescriptors[j] = _fieldDescriptions[i];
                    tempFieldDescriptors[j].DataAddress = tempLength;
                    tempLength += tempFieldDescriptors[j].Length;
                    // only increment j on non-matching fields
                    j++;
                }
                else retCol = i;
            }

            // set the new fields.
            _fieldDescriptions = tempFieldDescriptors;
            _headerLength = 33 + 32 * _fieldDescriptions.Length;
            _numFields = _fieldDescriptions.Length;
            _recordLength = tempLength;

            return retCol;
        }
Ejemplo n.º 23
0
        /// <summary>
        ///  Add a column to this DbaseFileHeader.
        /// </summary>
        /// <param name="fieldName">The name of the field to add.</param>
        /// <param name="fieldType">The type is one of (C N L or D) character, number, logical(true/false), or date.</param>
        /// <param name="fieldLength"> The Field length is the total length in bytes reserved for this column.</param>
        /// <param name="decimalCount">The decimal count only applies to numbers(N), and floating point values (F), and refers to the number of characters to reserve after the decimal point.</param>
        public void AddColumn(string fieldName, char fieldType, int fieldLength, int decimalCount)
        {
            if (fieldLength <= 0)
            {
                fieldLength = 1;
            }
            if (_fieldDescriptions == null)
            {
                _fieldDescriptions = new DbaseFieldDescriptor[0];
            }
            int tempLength = 1;              // the length is used for the offset, and there is a * for deleted as the first byte

            DbaseFieldDescriptor[] tempFieldDescriptors = new DbaseFieldDescriptor[_fieldDescriptions.Length + 1];
            for (int i = 0; i < _fieldDescriptions.Length; i++)
            {
                _fieldDescriptions[i].DataAddress = tempLength;
                tempLength = tempLength + _fieldDescriptions[i].Length;
                tempFieldDescriptors[i] = _fieldDescriptions[i];
            }
            tempFieldDescriptors[_fieldDescriptions.Length]              = new DbaseFieldDescriptor();
            tempFieldDescriptors[_fieldDescriptions.Length].Length       = fieldLength;
            tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = decimalCount;
            tempFieldDescriptors[_fieldDescriptions.Length].DataAddress  = tempLength;

            // set the field name
            string tempFieldName = fieldName;

            if (tempFieldName == null)
            {
                tempFieldName = "NoName";
            }
            if (tempFieldName.Length > 11)
            {
                tempFieldName = tempFieldName.Substring(0, 11);
                Trace.WriteLine("FieldName " + fieldName + " is longer than 11 characters, truncating to " + tempFieldName);
            }
            tempFieldDescriptors[_fieldDescriptions.Length].Name = tempFieldName;

            // the field type
            if ((fieldType == 'C') || (fieldType == 'c'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'C';
                if (fieldLength > 254)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Which is longer than 254, not consistent with dbase III");
                }
            }
            else if ((fieldType == 'S') || (fieldType == 's'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'C';
                Trace.WriteLine("Field type for " + fieldName + " set to S which is flat out wrong people!, I am setting this to C, in the hopes you meant character.");
                if (fieldLength > 254)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Which is longer than 254, not consistent with dbase III");
                }
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 8;
            }
            else if ((fieldType == 'D') || (fieldType == 'd'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'D';
                if (fieldLength != 8)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Setting to 8 digets YYYYMMDD");
                }
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 8;
            }
            else if ((fieldType == 'F') || (fieldType == 'f'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'F';
                if (fieldLength > 20)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Preserving length, but should be set to Max of 20 not valid for dbase IV, and UP specification, not present in dbaseIII.");
                }
            }
            else if ((fieldType == 'N') || (fieldType == 'n'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'N';
                if (fieldLength > 18)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Preserving length, but should be set to Max of 18 for dbase III specification.");
                }
                if (decimalCount < 0)
                {
                    Trace.WriteLine("Field Decimal Position for " + fieldName + " set to " + decimalCount + " Setting to 0 no decimal data will be saved.");
                    tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = 0;
                }
                if (decimalCount > fieldLength - 1)
                {
                    Trace.WriteLine("Field Decimal Position for " + fieldName + " set to " + decimalCount + " Setting to " + (fieldLength - 1) + " no non decimal data will be saved.");
                    tempFieldDescriptors[_fieldDescriptions.Length].DecimalCount = fieldLength - 1;
                }
            }
            else if ((fieldType == 'L') || (fieldType == 'l'))
            {
                tempFieldDescriptors[_fieldDescriptions.Length].DbaseType = 'L';
                if (fieldLength != 1)
                {
                    Trace.WriteLine("Field Length for " + fieldName + " set to " + fieldLength + " Setting to length of 1 for logical fields.");
                }
                tempFieldDescriptors[_fieldDescriptions.Length].Length = 1;
            }
            else
            {
                throw new NotSupportedException("Unsupported field type " + fieldType + " For column " + fieldName);
            }
            // the length of a record
            tempLength = tempLength + tempFieldDescriptors[_fieldDescriptions.Length].Length;

            // set the new fields.
            _fieldDescriptions = tempFieldDescriptors;
            _headerLength      = 33 + 32 * _fieldDescriptions.Length;
            _numFields         = _fieldDescriptions.Length;
            _recordLength      = tempLength;
        }