📄 shapefile.cs
字号:
ds.Tables.Add(dt);
}
/// <summary>
/// Returns geometry Object IDs whose bounding box intersects 'bbox'
/// </summary>
/// <param name="bbox"></param>
/// <returns></returns>
public Collection<uint> GetObjectIDsInView(SharpMap.Geometries.BoundingBox bbox)
{
if (!this.IsOpen)
throw (new ApplicationException("An attempt was made to read from a closed datasource"));
//Use the spatial index to get a list of features whose boundingbox intersects bbox
return tree.Search(bbox);
}
/// <summary>
/// Returns the geometry corresponding to the Object ID
/// </summary>
/// <param name="oid">Object ID</param>
/// <returns>geometry</returns>
public SharpMap.Geometries.Geometry GetGeometryByID(uint oid)
{
if (FilterDelegate != null) //Apply filtering
{
FeatureDataRow fdr = GetFeature(oid);
if (fdr!=null)
return fdr.Geometry;
else
return null;
}
else return ReadGeometry(oid);
}
/// <summary>
/// Reads and parses the geometry with ID 'oid' from the ShapeFile
/// </summary>
/// <remarks><see cref="FilterDelegate">Filtering</see> is not applied to this method</remarks>
/// <param name="oid">Object ID</param>
/// <returns>geometry</returns>
private SharpMap.Geometries.Geometry ReadGeometry(uint oid)
{
brShapeFile.BaseStream.Seek(GetShapeIndex(oid) + 8, 0); //Skip record number and content length
ShapeType type = (ShapeType)brShapeFile.ReadInt32(); //Shape type
if (type == ShapeType.Null)
return null;
if (_ShapeType == ShapeType.Point || _ShapeType==ShapeType.PointM || _ShapeType==ShapeType.PointZ)
{
SharpMap.Geometries.Point tempFeature = new SharpMap.Geometries.Point();
return new SharpMap.Geometries.Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble());
}
else if (_ShapeType == ShapeType.Multipoint || _ShapeType == ShapeType.MultiPointM || _ShapeType == ShapeType.MultiPointZ)
{
brShapeFile.BaseStream.Seek(32 + brShapeFile.BaseStream.Position, 0); //skip min/max box
SharpMap.Geometries.MultiPoint feature = new SharpMap.Geometries.MultiPoint();
int nPoints = brShapeFile.ReadInt32(); // get the number of points
if (nPoints == 0)
return null;
for (int i = 0; i < nPoints; i++)
feature.Points.Add(new SharpMap.Geometries.Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
return feature;
}
else if ( _ShapeType == ShapeType.PolyLine || _ShapeType == ShapeType.Polygon ||
_ShapeType == ShapeType.PolyLineM || _ShapeType == ShapeType.PolygonM ||
_ShapeType == ShapeType.PolyLineZ || _ShapeType == ShapeType.PolygonZ)
{
brShapeFile.BaseStream.Seek(32 + brShapeFile.BaseStream.Position, 0); //skip min/max box
int nParts = brShapeFile.ReadInt32(); // get number of parts (segments)
if (nParts == 0)
return null;
int nPoints = brShapeFile.ReadInt32(); // get number of points
int[] segments = new int[nParts + 1];
//Read in the segment indexes
for (int b = 0; b < nParts; b++)
segments[b] = brShapeFile.ReadInt32();
//add end point
segments[nParts] = nPoints;
if ((int)_ShapeType%10 == 3)
{
SharpMap.Geometries.MultiLineString mline = new SharpMap.Geometries.MultiLineString();
for (int LineID = 0; LineID < nParts; LineID++)
{
SharpMap.Geometries.LineString line = new SharpMap.Geometries.LineString();
for (int i = segments[LineID]; i < segments[LineID + 1]; i++)
line.Vertices.Add(new SharpMap.Geometries.Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
mline.LineStrings.Add(line);
}
if (mline.LineStrings.Count == 1)
return mline[0];
return mline;
}
else //(_ShapeType == ShapeType.Polygon etc...)
{
//First read all the rings
List<SharpMap.Geometries.LinearRing> rings = new List<SharpMap.Geometries.LinearRing>();
for (int RingID = 0; RingID < nParts; RingID++)
{
SharpMap.Geometries.LinearRing ring = new SharpMap.Geometries.LinearRing();
for (int i = segments[RingID]; i < segments[RingID + 1]; i++)
ring.Vertices.Add(new SharpMap.Geometries.Point(brShapeFile.ReadDouble(), brShapeFile.ReadDouble()));
rings.Add(ring);
}
bool[] IsCounterClockWise = new bool[rings.Count];
int PolygonCount = 0;
for (int i = 0; i < rings.Count;i++)
{
IsCounterClockWise[i] = rings[i].IsCCW();
if (!IsCounterClockWise[i])
PolygonCount++;
}
if (PolygonCount == 1) //We only have one polygon
{
SharpMap.Geometries.Polygon poly = new SharpMap.Geometries.Polygon();
poly.ExteriorRing = rings[0];
if (rings.Count > 1)
for (int i = 1; i < rings.Count; i++)
poly.InteriorRings.Add(rings[i]);
return poly;
}
else
{
SharpMap.Geometries.MultiPolygon mpoly = new SharpMap.Geometries.MultiPolygon();
SharpMap.Geometries.Polygon poly = new SharpMap.Geometries.Polygon();
poly.ExteriorRing = rings[0];
for (int i = 1; i < rings.Count;i++)
{
if (!IsCounterClockWise[i])
{
mpoly.Polygons.Add(poly);
poly = new SharpMap.Geometries.Polygon(rings[i]);
}
else
poly.InteriorRings.Add(rings[i]);
}
mpoly.Polygons.Add(poly);
return mpoly;
}
}
}
else
throw (new ApplicationException("Shapefile type " + _ShapeType.ToString() + " not supported"));
}
/// <summary>
/// Returns the data associated with all the geometries that are intersected by 'geom'.
/// Please note that the ShapeFile provider currently doesn't fully support geometryintersection
/// and thus only BoundingBox/BoundingBox querying are performed. The results are NOT
/// guaranteed to lie withing 'geom'.
/// </summary>
/// <param name="geom"></param>
/// <param name="ds">FeatureDataSet to fill data into</param>
public void ExecuteIntersectionQuery(SharpMap.Geometries.Geometry geom, FeatureDataSet ds)
{
SharpMap.Data.FeatureDataTable dt = (SharpMap.Data.FeatureDataTable)dbaseFile.NewTable;
SharpMap.Geometries.BoundingBox bbox = geom.GetBoundingBox();
//Get candidates by intersecting the spatial index tree
Collection<uint> objectlist = tree.Search(bbox);
if (objectlist.Count == 0)
return;
for (int j = 0; j < objectlist.Count; j++)
{
for (uint i = (uint)dt.Rows.Count - 1; i >= 0; i--)
{
FeatureDataRow fdr = GetFeature(objectlist[j],dt);
if (fdr.Geometry != null)
if (fdr.Geometry.GetBoundingBox().Intersects(bbox))
//replace above line with this: if(fdr.Geometry.Intersects(bbox)) when relation model is complete
if (FilterDelegate == null || FilterDelegate(fdr))
dt.AddRow(fdr);
}
}
ds.Tables.Add(dt);
}
/// <summary>
/// Returns the total number of features in the datasource (without any filter applied)
/// </summary>
/// <returns></returns>
public int GetFeatureCount()
{
return _FeatureCount;
}
/// <summary>
/// Filter Delegate Method
/// </summary>
/// <remarks>
/// The FilterMethod delegate is used for applying a method that filters data from the dataset.
/// The method should return 'true' if the feature should be included and false if not.
/// <para>See the <see cref="FilterDelegate"/> property for more info</para>
/// </remarks>
/// <seealso cref="FilterDelegate"/>
/// <param name="dr"><see cref="SharpMap.Data.FeatureDataRow"/> to test on</param>
/// <returns>true if this feature should be included, false if it should be filtered</returns>
public delegate bool FilterMethod(SharpMap.Data.FeatureDataRow dr);
private FilterMethod _FilterDelegate;
/// <summary>
/// Filter Delegate Method for limiting the datasource
/// </summary>
/// <remarks>
/// <example>
/// Using an anonymous method for filtering all features where the NAME column starts with S:
/// <code lang="C#">
/// myShapeDataSource.FilterDelegate = new SharpMap.Data.Providers.ShapeFile.FilterMethod(delegate(SharpMap.Data.FeatureDataRow row) { return (!row["NAME"].ToString().StartsWith("S")); });
/// </code>
/// </example>
/// <example>
/// Declaring a delegate method for filtering (multi)polygon-features whose area is larger than 5.
/// <code>
/// myShapeDataSource.FilterDelegate = CountryFilter;
/// [...]
/// public static bool CountryFilter(SharpMap.Data.FeatureDataRow row)
/// {
/// if(row.Geometry.GetType()==typeof(SharpMap.Geometries.Polygon))
/// return ((row.Geometry as SharpMap.Geometries.Polygon).Area>5);
/// if (row.Geometry.GetType() == typeof(SharpMap.Geometries.MultiPolygon))
/// return ((row.Geometry as SharpMap.Geometries.MultiPolygon).Area > 5);
/// else return true;
/// }
/// </code>
/// </example>
/// </remarks>
/// <seealso cref="FilterMethod"/>
public FilterMethod FilterDelegate
{
get
{
return _FilterDelegate;
}
set
{
_FilterDelegate = value;
}
}
/*
/// <summary>
/// Returns a colleciton of columns from the datasource [NOT IMPLEMENTED]
/// </summary>
public System.Data.DataColumnCollection Columns
{
get {
if (dbaseFile != null)
{
System.Data.DataTable dt = dbaseFile.DataTable;
return dt.Columns;
}
else
throw (new ApplicationException("An attempt was made to read DBase data from a shapefile without a valid .DBF file"));
}
}*/
/// <summary>
/// Gets a datarow from the datasource at the specified index
/// </summary>
/// <param name="RowID"></param>
/// <returns></returns>
public SharpMap.Data.FeatureDataRow GetFeature(uint RowID)
{
return GetFeature(RowID, null);
}
/// <summary>
/// Gets a datarow from the datasource at the specified index belonging to the specified datatable
/// </summary>
/// <param name="RowID"></param>
/// <param name="dt">Datatable to feature should belong to.</param>
/// <returns></returns>
public SharpMap.Data.FeatureDataRow GetFeature(uint RowID, FeatureDataTable dt)
{
if (dbaseFile != null)
{
SharpMap.Data.FeatureDataRow dr = (SharpMap.Data.FeatureDataRow)dbaseFile.GetFeature(RowID, (dt==null)?dbaseFile.NewTable:dt);
dr.Geometry = ReadGeometry(RowID);
if (FilterDelegate == null || FilterDelegate(dr))
return dr;
else
return null;
}
else
throw (new ApplicationException("An attempt was made to read DBase data from a shapefile without a valid .DBF file"));
}
/// <summary>
/// Returns the extents of the datasource
/// </summary>
/// <returns></returns>
public SharpMap.Geometries.BoundingBox GetExtents()
{
if (tree == null)
throw new ApplicationException("File hasn't been spatially indexed. Try opening the datasource before retriving extents");
return tree.Box;
}
/// <summary>
/// Gets the connection ID of the datasource
/// </summary>
/// <remarks>
/// The connection ID of a shapefile is its filename
/// </remarks>
public string ConnectionID
{
get { return this._Filename; }
}
private int _SRID = -1;
/// <summary>
/// Gets or sets the spatial reference ID (CRS)
/// </summary>
public int SRID
{
get { return _SRID; }
set { _SRID = value; }
}
#endregion
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -