首页 文章

解析没有shx和dbf文件的shapefile(shp文件)

提问于
浏览
2

我需要上传一个shapefile并将所有形状存储在数据库中 . 我花了两天时间找到一个好的图书馆,但到目前为止我找不到任何完整的解决方案 .

我尝试使用'Catfood.Shapefile'库解析文件,但是除了.shp文件之外还需要另外两个文件,我没有 .

我设法用Java实现代码,但现在我需要在c#中重新实现它 .

请给我一些建议!

1 回答

  • 0

    好的,Shp文件是一个很好的设计文件,你可以看到描述here . shx和dbf只添加一些帮助来解析shp文件 . 我在Catfood.Shapefile中添加了一个类,它的名字是ShpParser . 此类的输入仅为Shp文件 . 它不需要shx和dbf文件来提取文件中的形状 .

    如果元数据为null,则抛出两个类异常,请确保从以下方法中删除元数据异常:

    1-形状构造函数2- ShapeFactory.ParseShape

    这里是ShpParser的代码

    using System;
     using System.Collections;
     using System.Collections.Generic;
     using System.Data.OleDb;
     using System.IO;
     using System.Text;
    
     namespace Catfood.Shapefile
     { 
    /// <summary>
    /// 
    /// </summary>
    public class ShpParser : IDisposable, IEnumerator<Shape>, IEnumerable<Shape>
    {
        private bool _disposed;
        private bool _opened;
        private int _currentIndex;
        private int _count;
        private RectangleD _boundingBox;
        private ShapeType _type;
        private int _currentPosition;
        private FileStream _mainStream;
        private Header _mainHeader;
    
        /// <summary>
        /// 
        /// </summary>
        public ShpParser()
        {
            _currentIndex = -1;
            _currentPosition = 0;
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        public ShpParser(string path)
            : this()
        {
            Open(path);
        }
    
        /// <summary>
        /// 
        /// </summary>
        /// <param name="path"></param>
        private void Open(string path)
        {
            if (_disposed)
            {
                throw new ObjectDisposedException("ShpParser");
            }
    
            if (string.IsNullOrEmpty(path))
            {
                throw new ArgumentNullException("path");
            }
    
            if (!File.Exists(path))
            {
                throw new FileNotFoundException("shp file not found", path);
            }
    
            _mainStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read);
    
            if (_mainStream.Length < Header.HeaderLength)
            {
                throw new InvalidOperationException("Shapefile main file does not contain a valid header");
            }
    
            // read in and parse the headers
            var headerBytes = new byte[Header.HeaderLength];
            _mainStream.Read(headerBytes, 0, Header.HeaderLength);
            _mainHeader = new Header(headerBytes);
            _type = _mainHeader.ShapeType;
            _boundingBox = new RectangleD(_mainHeader.XMin, _mainHeader.YMin, _mainHeader.XMax, _mainHeader.YMax);
    
            _currentPosition = Header.HeaderLength;
    
            _count = _mainHeader.FileLength * 2; // FileLength return the size of file in words (16 bytes)
            _opened = true;
    
        }
        #region IDisposable Members
        /// <summary>
        /// Close the Shapefile. Equivalent to calling Dispose().
        /// </summary>
        public void Close()
        {
            Dispose();
        }
    
    
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        private void Dispose(bool canDisposeManagedResources)
        {
            if (!_disposed)
            {
                if (canDisposeManagedResources)
                {
                    if (_mainStream != null)
                    {
                        _mainStream.Close();
                        _mainStream = null;
                    }
                }
                _disposed = true;
                _opened = false;
            }
        }
        #endregion
    
        public bool MoveNext()
        {
            if (_disposed) throw new ObjectDisposedException("ShpParser");
            if (!_opened) throw new InvalidOperationException("ShpParser not open.");
    
            if (_currentPosition < (_count - 1))
            {
                // try to read the next database record
               return true;
            }
            else
            {
                // reached the last shape
                return false;
            }
        }
    
        public void Reset()
        {
            if (_disposed) throw new ObjectDisposedException("ShpParser");
            if (!_opened) throw new InvalidOperationException("ShpParser not open.");
    
            _currentIndex = -1;
        }
    
        public Shape Current
        {
            get
            {
                if (_disposed) throw new ObjectDisposedException("ShpParser");
                if (!_opened) throw new InvalidOperationException("ShpParser not open.");
    
    
                //get recordheader;
                var recordheader = new byte[8];
    
    
                _mainStream.Read(recordheader, 0, recordheader.Length);
    
    
                int contentOffsetInWords = EndianBitConverter.ToInt32(recordheader, 0, ProvidedOrder.Big);
                int contentLengthInWords = EndianBitConverter.ToInt32(recordheader, 4, ProvidedOrder.Big);
    
    
                _mainStream.Seek(_currentPosition , SeekOrigin.Begin); // back to header of record 
                int bytesToRead = (contentLengthInWords * 2) + 8;
                byte[] shapeData = new byte[bytesToRead];
                _currentPosition += bytesToRead;
                _mainStream.Read(shapeData, 0, bytesToRead);
                return ShapeFactory.ParseShape(shapeData , null);
             //  return null;
            }
        }
    
        object IEnumerator.Current
        {
            get
            {
                if (_disposed) throw new ObjectDisposedException("ShpParser");
                if (!_opened) throw new InvalidOperationException("ShpParser not open.");
    
                return this.Current;
            }
        }
    
        public IEnumerator<Shape> GetEnumerator()
        {
            return (IEnumerator<Shape>)this;
        }
    
        IEnumerator IEnumerable.GetEnumerator()
        {
            return (System.Collections.IEnumerator)this;
        }
    }
    

    }

    如何使用ShpParser

    using (var shapefile = new ShpParser("my.shp")
    {
       foreach (Shape shape in shapefile)
       {
           Console.WriteLine("ShapeType: {0}", shape.Type);
       }
    }
    

相关问题