NtsProvider.cs
上传用户:sex100000
上传日期:2013-11-09
资源大小:1377k
文件大小:20k
源码类别:

GIS编程

开发平台:

C#

  1. // Copyright 2006 - Diego Guidi
  2. //
  3. // This file is part of NtsProvider.
  4. // NtsProvider is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU Lesser General Public License as published by
  6. // the Free Software Foundation; either version 2 of the License, or
  7. // (at your option) any later version.
  8. // 
  9. // SharpMap is distributed in the hope that it will be useful,
  10. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. // GNU Lesser General Public License for more details.
  13. // You should have received a copy of the GNU Lesser General Public License
  14. // along with NtsProvider; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  16. using System;
  17. using System.Collections.Generic;
  18. using System.Collections.ObjectModel;
  19. using System.Data;
  20. using System.Diagnostics;
  21. using System.Globalization;
  22. using System.Text;
  23. using SharpMap.Converters.NTS;
  24. namespace SharpMap.Data.Providers
  25. {
  26.     /// <summary>
  27. /// The NtsProvider enables you to feed any SharpMap datasource through the <a href="http://sourceforge.net/projects/nts">NetTopologySuite</a>
  28. /// geometry using any NTS operation.
  29.     /// </summary>
  30. /// <remarks>
  31. /// The following example shows how to apply buffers to a shapefile-based river-dataset:
  32. /// <code lang="C#">
  33. /// public void InitializeMap(SharpMap.Map map)
  34. /// {
  35. /// //Create Shapefile datasource
  36. /// SharpMap.Data.Providers.ShapeFile shp = new SharpMap.Data.Providers.ShapeFile("rivers.shp", true);
  37. /// //Create NTS Datasource that gets its data from 'shp' and calls 'NtsOperation' that defines a geoprocessing method
  38. /// SharpMap.Data.Providers.NtsProvider nts = new SharpMap.Data.Providers.NtsProvider(shp,new SharpMap.Data.Providers.NtsProvider.GeometryOperationDelegate(NtsOperation));
  39. /// //Create the layer for rendering
  40. /// SharpMap.Layers.VectorLayer layRivers = new SharpMap.Layers.VectorLayer("Rivers");
  41. /// layRivers.DataSource = nts;
  42. /// layRivers.Style.Fill = Brushes.Blue;
  43. /// map.Layers.Add(layRivers);
  44. /// }
  45. /// //Define geoprocessing delegate that buffers all geometries with a distance of 0.5 mapunits
  46. /// public static void NtsOperation(List<GisSharpBlog.NetTopologySuite.Features.Feature> geoms)
  47. /// {
  48. /// foreach (GisSharpBlog.NetTopologySuite.Features.Feature f in geoms)
  49. ///  f.Geometry = f.Geometry.Buffer(0.5);
  50. /// }
  51. /// </code>
  52. /// </remarks>
  53.     public class NtsProvider : IProvider
  54.     {
  55. /// <summary>
  56. /// Defines a geometry operation that will be applied to all geometries in <see cref="NtsProvider"/>.
  57. /// </summary>
  58. /// <param name="features"></param>
  59. public delegate void GeometryOperationDelegate(List<GisSharpBlog.NetTopologySuite.Features.Feature> features);
  60.         
  61.         #region Fields
  62.         // Factory for NTS features
  63.         private GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory geometryFactory = null;
  64.         // NTS features
  65.         private List<GisSharpBlog.NetTopologySuite.Features.Feature> features = null;
  66.         #endregion
  67.         #region Constructor
  68.         /// <summary>
  69.         /// Initializes a new instance of the <see cref="T:NtsProvider"/> class
  70.         /// using a default <see cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel"/> 
  71.         /// with Floating precision.
  72.         /// </summary>        
  73.         protected internal NtsProvider() : this(new GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel()) { }
  74.         /// <summary>
  75. /// Initializes a new instance of the <see cref="T:NtsProvider"/> class
  76.         /// using the given <paramref name="precisionModel"/>.
  77.         /// </summary>
  78.         /// <param name="precisionModel">
  79.         /// The <see cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel"/>  
  80.         /// to use for define the precision of the geometry operations.
  81.         /// </param>
  82.         /// <seealso cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModels"/>
  83.         /// <seealso cref="GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory"/>
  84.         protected internal NtsProvider(GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel precisionModel)
  85.         {
  86.             geometryFactory = new GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory(precisionModel);
  87.         }
  88.         /// <summary>
  89. /// Initializes a new instance of the <see cref="T:NtsProvider"/> class 
  90.         /// from another <see cref="SharpMap.Data.Providers.IProvider" />.
  91.         /// </summary>
  92.         /// <param name="provider">
  93.         /// The base <see cref="SharpMap.Data.Providers.IProvider"/> 
  94. /// from witch initialize the <see cref="NtsProvider"/> instance.
  95.         /// </param>
  96.         public NtsProvider(SharpMap.Data.Providers.IProvider provider) : this()
  97.         {                        
  98.             BuildFromProvider(provider);            
  99.         }
  100.         /// <summary>
  101. /// Initializes a new instance of the <see cref="T:NtsProvider"/> class
  102.         /// from another <see cref="SharpMap.Data.Providers.IProvider" />.
  103.         /// </summary>
  104.         /// <param name="provider">
  105.         /// The base <see cref="SharpMap.Data.Providers.IProvider"/> 
  106. /// from witch initialize the <see cref="NtsProvider"/> instance.
  107.         /// </param>
  108.         /// <param name="precisionModel">
  109.         /// The <see cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel"/>  
  110.         /// to use for define the precision of the geometry operations.
  111.         /// </param>
  112.         /// <seealso cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModels"/>     
  113.         /// <seealso cref="GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory"/>
  114.         public NtsProvider(SharpMap.Data.Providers.IProvider provider, 
  115.             GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel precisionModel) : this(precisionModel)
  116.         {                       
  117.             BuildFromProvider(provider);            
  118.         }
  119.         /// <summary>
  120. /// Initializes a new instance of the <see cref="T:NtsProvider"/> class
  121.         /// from another <see cref="SharpMap.Data.Providers.IProvider" />.
  122.         /// </summary>
  123.         /// <param name="provider">
  124.         /// The base <see cref="SharpMap.Data.Providers.IProvider"/> 
  125. /// from witch initialize the <see cref="NtsProvider"/> instance.
  126.         /// </param>
  127.         /// <param name="operation">
  128.         /// The <see cref="GeometryOperationDelegate"/> to apply 
  129.         /// to all geometry elements in the <paramref name="provider"/>.
  130.         /// </param>  
  131.         public NtsProvider(SharpMap.Data.Providers.IProvider provider, GeometryOperationDelegate operation) : this(provider)
  132.         {            
  133.             operation(features);
  134.          }
  135.         /// <summary>
  136.  /// Initializes a new instance of the <see cref="T:NtsProvider"/> class
  137.         /// from another <see cref="SharpMap.Data.Providers.IProvider" />.
  138.         /// </summary>
  139.         /// <param name="provider">
  140.         /// The base <see cref="SharpMap.Data.Providers.IProvider"/> 
  141.  /// from witch initialize the <see cref="NtsProvider"/> instance.
  142.         /// </param>
  143.         /// <param name="operation">
  144.         /// The <see cref="GeometryOperationDelegate"/> to apply 
  145.         /// to all geometry elements in the <paramref name="provider"/>.
  146.         /// </param>         
  147.         /// <param name="precisionModel">
  148.         /// The <see cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel"/>  
  149.         /// to use for define the precision of the geometry operations.
  150.         /// </param>
  151.         /// <seealso cref="GisSharpBlog.NetTopologySuite.Geometries.PrecisionModels"/> 
  152.         /// <seealso cref="GisSharpBlog.NetTopologySuite.Geometries.GeometryFactory"/>
  153.         public NtsProvider(SharpMap.Data.Providers.IProvider provider, GeometryOperationDelegate operation,
  154.             GisSharpBlog.NetTopologySuite.Geometries.PrecisionModel precisionModel) : this(provider, precisionModel)
  155.         {            
  156.             operation(features);         
  157.         }
  158.         /// <summary>
  159.         /// Builds from the given provider.
  160.         /// </summary>
  161.         /// <param name="provider">
  162.         /// The base <see cref="SharpMap.Data.Providers.IProvider"/> 
  163. /// from witch initialize the <see cref="NtsProvider"/> instance.
  164.         /// </param>
  165.         private void BuildFromProvider(SharpMap.Data.Providers.IProvider provider)
  166.         {            
  167.             // Features list initialization
  168.             features = new List<GisSharpBlog.NetTopologySuite.Features.Feature>(provider.GetFeatureCount());
  169.             try
  170.             {
  171.                 // Load all features from the given provider
  172.                 provider.Open();                
  173.                 Collection<uint> ids = provider.GetObjectIDsInView(provider.GetExtents());             
  174.                 foreach (uint id in ids)
  175.                 {
  176.                     SharpMap.Data.FeatureDataRow dataRow = provider.GetFeature(id);
  177.                     GisSharpBlog.NetTopologySuite.Geometries.Geometry geometry = GeometryConverter.ToNTSGeometry(dataRow.Geometry, geometryFactory);
  178.                     GisSharpBlog.NetTopologySuite.Features.AttributesTable attributes = new GisSharpBlog.NetTopologySuite.Features.AttributesTable();
  179.                     foreach (DataColumn column in dataRow.Table.Columns)
  180.                     {                        
  181.                         if (dataRow[column] == null || dataRow[column].GetType() == typeof(System.DBNull))
  182.                             throw new ApplicationException("Null values not supported");
  183.                         attributes.AddAttribute(column.ColumnName, dataRow[column]);
  184.                     }
  185.                     features.Add(new GisSharpBlog.NetTopologySuite.Features.Feature(geometry, attributes));
  186.                 }
  187.             }
  188.             finally
  189.             {
  190.                 if (provider.IsOpen)
  191.                     provider.Close();
  192.             }
  193.         }
  194.         #endregion
  195.         #region IProvider Members
  196.         /// <summary>
  197.         /// Returns the data associated with all the geometries that is within 'distance' of 'geom'
  198.         /// </summary>
  199.         /// <param name="geom"></param>
  200.         /// <param name="distance"></param>
  201.         /// <returns></returns>
  202. [Obsolete("Use ExecuteIntersectionQuery instead")]
  203. public SharpMap.Data.FeatureDataTable QueryFeatures(SharpMap.Geometries.Geometry geom, double distance)
  204.         {
  205. throw new NotImplementedException("QueryFeatures is obsolete. Use ExecuteIntersectionQuery.");
  206.         }
  207.         /// <summary>
  208.         /// Creates a new row in the given <see cref="SharpMap.Data.FeatureDataTable"/> <paramref name="dataTable"/>
  209.         /// using data in <see cref="GisSharpBlog.NetTopologySuite.Features.Feature"/> <paramref name="feature"/>.
  210.         /// </summary>
  211.         /// <param name="dataTable">The <see cref="SharpMap.Data.FeatureDataTable"/> to fill.</param>
  212.         /// <param name="feature">Data to insert in the <see cref="SharpMap.Data.FeatureDataTable"/>.</param>
  213.         private void CreateNewRow(SharpMap.Data.FeatureDataTable dataTable, GisSharpBlog.NetTopologySuite.Features.Feature feature)
  214.         {
  215.             SharpMap.Data.FeatureDataRow dataRow = dataTable.NewRow();
  216.             dataRow.Geometry = GeometryConverter.ToSharpMapGeometry(feature.Geometry);
  217.             foreach (string columnName in feature.Attributes.GetNames())
  218.                 dataRow[columnName] = feature.Attributes[columnName];
  219. dataTable.AddRow(dataRow);
  220.         }
  221.         /// <summary>
  222.         /// Creates a <see cref="SharpMap.Data.FeatureDataTable"/> using a stub feature (feature[0]).
  223.         /// </summary>
  224.         /// <returns><see cref="SharpMap.Data.FeatureDataTable"/></returns>
  225.         private SharpMap.Data.FeatureDataTable CreateFeatureDataTable()
  226.         {            
  227.             SharpMap.Data.FeatureDataTable dataTable = new SharpMap.Data.FeatureDataTable();
  228.             foreach (string columnName in features[0].Attributes.GetNames())
  229.                 dataTable.Columns.Add(new DataColumn(columnName, features[0].Attributes.GetType(columnName)));
  230.             return dataTable;
  231.         }
  232.         /// <summary>
  233.         /// Gets the connection ID.
  234.         /// </summary>
  235.         /// <value>The connection ID.</value>
  236.         [Obsolete("Does nothing at all")]
  237.         public string ConnectionID
  238.         {
  239.             get 
  240.             {
  241.                 return String.Empty;
  242.             }
  243.         }
  244.         /// <summary>
  245.         /// Gets the features in view.
  246.         /// </summary>
  247.         /// <param name="bbox">The bbox.</param>
  248.         /// <param name="ds">The ds.</param>
  249.         public void GetFeaturesInView(SharpMap.Geometries.BoundingBox bbox, SharpMap.Data.FeatureDataSet ds)
  250.         {
  251. ExecuteIntersectionQuery(bbox, ds);
  252.         }
  253.         /// <summary>
  254.         /// Returns the BoundingBox of the dataset.
  255.         /// </summary>
  256.         /// <returns>BoundingBox</returns>
  257.         public SharpMap.Geometries.BoundingBox GetExtents()
  258.         {            
  259.             GisSharpBlog.NetTopologySuite.Geometries.Envelope envelope = new GisSharpBlog.NetTopologySuite.Geometries.Envelope();
  260.             foreach (GisSharpBlog.NetTopologySuite.Features.Feature feature in features)
  261.                 envelope.ExpandToInclude(feature.Geometry.EnvelopeInternal);
  262.             return GeometryConverter.ToSharpMapBoundingBox(envelope);
  263.         }
  264.         /// <summary>
  265.         /// Gets the feature identified from the given <paramref name="rowID" />.
  266.         /// </summary>
  267.         /// <param name="rowID">The row ID.</param>
  268.         /// <returns></returns>
  269.         public SharpMap.Data.FeatureDataRow GetFeature(uint rowID)
  270.         {
  271.             GisSharpBlog.NetTopologySuite.Features.Feature feature = features[Convert.ToInt32(rowID)];            
  272.             SharpMap.Data.FeatureDataTable dataTable = new SharpMap.Data.FeatureDataTable();            
  273.             foreach (string columnName in feature.Attributes.GetNames())
  274.                 dataTable.Columns.Add(new DataColumn(columnName, feature.Attributes.GetType(columnName)));            
  275.             
  276.             SharpMap.Data.FeatureDataRow dataRow = dataTable.NewRow();
  277.             dataRow.Geometry = GeometryConverter.ToSharpMapGeometry(feature.Geometry);
  278.             foreach (string columnName in feature.Attributes.GetNames())
  279.                 dataRow[columnName] = feature.Attributes[columnName];
  280.             return dataRow;
  281.         }
  282.         /// <summary>
  283.         /// Returns the number of features in the dataset.
  284.         /// </summary>
  285.         /// <returns>number of features</returns>
  286.         public int GetFeatureCount()
  287.         {
  288.             return features.Count;
  289.         }
  290.         /// <summary>
  291.         /// Returns features within the specified bounding box.
  292.         /// </summary>
  293.         /// <param name="bbox"></param>
  294.         /// <returns></returns>
  295.         public Collection<SharpMap.Geometries.Geometry> GetGeometriesInView(SharpMap.Geometries.BoundingBox bbox)
  296.         {
  297.             // Identifies all the features within the given BoundingBox
  298.             GisSharpBlog.NetTopologySuite.Geometries.Envelope envelope = GeometryConverter.ToNTSEnvelope(bbox);
  299.             Collection<SharpMap.Geometries.Geometry> geoms = new Collection<SharpMap.Geometries.Geometry>();
  300.             foreach (GisSharpBlog.NetTopologySuite.Features.Feature feature in features)
  301.                 if (envelope.Intersects(feature.Geometry.EnvelopeInternal))
  302.                     geoms.Add(GeometryConverter.ToSharpMapGeometry(feature.Geometry));  
  303.             return geoms;        
  304.         }
  305.         /// <summary>
  306.         /// 
  307.         /// </summary>
  308.         /// <param name="box"></param>
  309.         /// <param name="ds"></param>
  310. public void ExecuteIntersectionQuery(SharpMap.Geometries.BoundingBox box, FeatureDataSet ds)
  311. {
  312. // Identifies all the features within the given BoundingBox
  313. GisSharpBlog.NetTopologySuite.Geometries.Envelope envelope = GeometryConverter.ToNTSEnvelope(box);
  314. List<GisSharpBlog.NetTopologySuite.Features.Feature> results = new List<GisSharpBlog.NetTopologySuite.Features.Feature>(features.Count);
  315. foreach (GisSharpBlog.NetTopologySuite.Features.Feature feature in features)
  316. if (envelope.Intersects(feature.Geometry.EnvelopeInternal))
  317. results.Add(feature);
  318. // Fill DataSet
  319. SharpMap.Data.FeatureDataTable dataTable = CreateFeatureDataTable();
  320. foreach (GisSharpBlog.NetTopologySuite.Features.Feature feature in results)
  321. CreateNewRow(dataTable, feature);
  322. ds.Tables.Add(dataTable);
  323. }
  324.         /// <summary>
  325.         /// 
  326.         /// </summary>
  327.         /// <param name="geom"></param>
  328.         /// <param name="ds"></param>
  329.         public void ExecuteIntersectionQuery(SharpMap.Geometries.Geometry geom, FeatureDataSet ds)
  330. {
  331. GisSharpBlog.NetTopologySuite.Geometries.Geometry geometry = GeometryConverter.ToNTSGeometry(geom, geometryFactory);
  332. SharpMap.Data.FeatureDataTable dataTable = CreateFeatureDataTable();
  333. foreach (GisSharpBlog.NetTopologySuite.Features.Feature feature in features)
  334. if (feature.Geometry.Intersects(geometry))
  335. CreateNewRow(dataTable, feature);
  336. ds.Tables.Add(dataTable);
  337. }
  338.         /// <summary>
  339.         /// Gets the geometry by ID.
  340.         /// </summary>
  341.         /// <param name="oid">The oid.</param>
  342.         /// <returns></returns>
  343.         public SharpMap.Geometries.Geometry GetGeometryByID(uint oid)
  344.         {
  345.             GisSharpBlog.NetTopologySuite.Features.Feature feature = features[Convert.ToInt32(oid)];
  346.             return GeometryConverter.ToSharpMapGeometry(feature.Geometry);
  347.         }
  348.         /// <summary>
  349.         /// Gets the object IDs in the view.
  350.         /// </summary>
  351.         /// <param name="bbox">The bbox.</param>
  352.         /// <returns></returns>
  353.         public Collection<uint> GetObjectIDsInView(SharpMap.Geometries.BoundingBox bbox)
  354.         {
  355.             // Identifies all the features within the given BoundingBox
  356.             GisSharpBlog.NetTopologySuite.Geometries.Envelope envelope = GeometryConverter.ToNTSEnvelope(bbox);
  357.             Collection<uint> geoms = new Collection<uint>();
  358.             for(int i = 0; i < features.Count; i++)            
  359.                 if (envelope.Intersects(features[i].Geometry.EnvelopeInternal))
  360.                     geoms.Add(Convert.ToUInt32(i));
  361.             return geoms;                   
  362.         }
  363.         /// <summary>
  364.         /// Opens this instance.
  365.         /// </summary>
  366.         [Obsolete("Does nothing at all")]
  367.         public void Open() { }
  368.         /// <summary>
  369.         /// Gets a value indicating whether this instance is open.
  370.         /// </summary>
  371.         /// <value><c>true</c> if this instance is open; otherwise, <c>false</c>.</value>
  372.         public bool IsOpen
  373.         {
  374.             get
  375.             {
  376.                 return features.Count > 0;
  377.             }
  378.         }
  379.         /// <summary>
  380.         /// Closes this instance.
  381.         /// </summary>
  382.         [Obsolete("Does nothing at all")]
  383.         public void Close() { }
  384. private int _SRID = -1;
  385. /// <summary>
  386. /// The spatial reference ID (CRS)
  387. /// </summary>
  388. public int SRID
  389. {
  390. get { return _SRID; }
  391. set { _SRID = value; }
  392. }
  393.         #endregion
  394.         #region IDisposable Members
  395.         /// <summary>
  396.         /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
  397.         /// </summary>
  398.         public void Dispose() { }
  399.         #endregion
  400. }
  401. }