2016-02-03 177 views
2

我需要上傳一個shapefile並將所有形狀存儲在數據庫中。我花了兩天的時間找到一個好的圖書館,但到目前爲止我沒有找到任何完整的解決方案。解析沒有shx和dbf文件的shapefile(shp文件)

我嘗試使用'Catfood.Shapefile'庫解析文件,但它需要除.shp文件之外的其他兩個文件,這是我沒有的。

我設法在Java中實現一個代碼,但現在我需要在C#中重新實現它。

請給我一些建議!

+0

這些文件*是*需要的。 shapefile不是獨立文件。它實際上是形狀,索引和元數據文件的組合。沒有它們,你只有一堆點沒有有意義的元數據。找到丟失的shapefile文件並將它們添加到相同的文件夾中,或者檢查是否可以強制庫在沒有它們的情況下工作。如果沒有元數據,您將如何將這些形狀與任何其他數據進行匹配並使用它們? –

+0

你在Java中知道我有這些行 \t prefs = new ValidationPreferences(); \t \t \t int avl = fis.available(); \t \t \t prefs.setMaxNumberOfPointsPerShape(16650); \t \t \t shapeFileReader = new ShapeFileReader(fis,prefs); 我確實有這兩個文件 – Mahdi

+0

那麼問題是什麼?你爲什麼不把這些文件與你的C#代碼一起使用呢? –

回答

0

好的,Shp文件是一個很好的設計文件,你可以看到描述here。 shx和dbf只會添加一些幫助來解析shp文件。我添加了一個名爲ShpParser的Catfood.Shapefile。這個類的輸入只是Shp文件。它不需要shx和dbf文件來提取文件中的形狀。

如果元數據爲空,這兩個類拋出異常,請確保您從下面的方法刪除元數據異常:

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

​​