2
我需要上傳一個shapefile並將所有形狀存儲在數據庫中。我花了兩天的時間找到一個好的圖書館,但到目前爲止我沒有找到任何完整的解決方案。解析沒有shx和dbf文件的shapefile(shp文件)
我嘗試使用'Catfood.Shapefile'庫解析文件,但它需要除.shp文件之外的其他兩個文件,這是我沒有的。
我設法在Java中實現一個代碼,但現在我需要在C#中重新實現它。
請給我一些建議!
我需要上傳一個shapefile並將所有形狀存儲在數據庫中。我花了兩天的時間找到一個好的圖書館,但到目前爲止我沒有找到任何完整的解決方案。解析沒有shx和dbf文件的shapefile(shp文件)
我嘗試使用'Catfood.Shapefile'庫解析文件,但它需要除.shp文件之外的其他兩個文件,這是我沒有的。
我設法在Java中實現一個代碼,但現在我需要在C#中重新實現它。
請給我一些建議!
好的,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
這些文件*是*需要的。 shapefile不是獨立文件。它實際上是形狀,索引和元數據文件的組合。沒有它們,你只有一堆點沒有有意義的元數據。找到丟失的shapefile文件並將它們添加到相同的文件夾中,或者檢查是否可以強制庫在沒有它們的情況下工作。如果沒有元數據,您將如何將這些形狀與任何其他數據進行匹配並使用它們? –
你在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
那麼問題是什麼?你爲什麼不把這些文件與你的C#代碼一起使用呢? –