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

GIS编程

开发平台:

C#

  1. // Copyright 2006 - Ricardo Stuven (rstuven@gmail.com)
  2. // Copyright 2006 - Morten Nielsen (www.iter.dk)
  3. //
  4. // MsSqlSpatial provider by Ricardo Stuven.
  5. // Based on PostGIS provider by Morten Nielsen.
  6. //
  7. // This file is part of SharpMap.
  8. // SharpMap is free software; you can redistribute it and/or modify
  9. // it under the terms of the GNU Lesser General Public License as published by
  10. // the Free Software Foundation; either version 2 of the License, or
  11. // (at your option) any later version.
  12. // 
  13. // SharpMap is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. // GNU Lesser General Public License for more details.
  17. // You should have received a copy of the GNU Lesser General Public License
  18. // along with SharpMap; if not, write to the Free Software
  19. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Collections.ObjectModel;
  23. using System.Text;
  24. using System.Data.SqlClient;
  25. namespace SharpMap.Data.Providers
  26. {
  27. /// <summary>
  28. /// Microsoft SQL Server 2005 / MsSqlSpatial dataprovider
  29. /// </summary>
  30. /// <example>
  31. /// Adding a datasource to a layer:
  32. /// <code lang="C#">
  33. /// SharpMap.Layers.VectorLayer myLayer = new SharpMap.Layers.VectorLayer("My layer");
  34. /// string ConnStr = @"Data Source=localhostsqlexpress;Initial Catalog=myGisDb;Integrated Security=SSPI;";
  35. /// myLayer.DataSource = new SharpMap.Data.Providers.MsSqlSpatial(ConnStr, "myTable", "myId");
  36. /// </code>
  37. /// </example>
  38. [Serializable]
  39. public class MsSqlSpatial : SharpMap.Data.Providers.IProvider, IDisposable
  40. {
  41. /// <summary>
  42. /// Initializes a new connection to MsSqlSpatial
  43. /// </summary>
  44. /// <param name="ConnectionStr">Connectionstring</param>
  45. /// <param name="tablename">Name of data table</param>
  46. /// <param name="geometryColumnName">Name of geometry column</param>
  47. /// /// <param name="OID_ColumnName">Name of column with unique identifier</param>
  48. public MsSqlSpatial(string ConnectionStr, string tablename, string geometryColumnName, string OID_ColumnName)
  49. {
  50. this.ConnectionString = ConnectionStr;
  51. this.Table = tablename;
  52. this.GeometryColumn = geometryColumnName;
  53. this.ObjectIdColumn = OID_ColumnName;
  54. }
  55. /// <summary>
  56. /// Initializes a new connection to MsSqlSpatial
  57. /// </summary>
  58. /// <param name="ConnectionStr">Connectionstring</param>
  59. /// <param name="tablename">Name of data table</param>
  60. /// <param name="OID_ColumnName">Name of column with unique identifier</param>
  61. public MsSqlSpatial(string ConnectionStr, string tablename, string OID_ColumnName) : this(ConnectionStr,tablename,"",OID_ColumnName)
  62. {
  63. this.GeometryColumn = this.GetGeometryColumn();
  64. }
  65. private bool _IsOpen;
  66. /// <summary>
  67. /// Returns true if the datasource is currently open
  68. /// </summary>
  69. public bool IsOpen
  70. {
  71. get { return _IsOpen; }
  72. }
  73. /// <summary>
  74. /// Opens the datasource
  75. /// </summary>
  76. public void Open()
  77. {
  78. //Don't really do anything. SqlClient's ConnectionPooling takes over here
  79. _IsOpen = true;
  80. }
  81. /// <summary>
  82. /// Closes the datasource
  83. /// </summary>
  84. public void Close()
  85. {
  86. //Don't really do anything. SqlClient's ConnectionPooling takes over here
  87. _IsOpen = false;
  88. }
  89. #region Disposers and finalizers
  90. private bool disposed = false;
  91. /// <summary>
  92. /// Disposes the object
  93. /// </summary>
  94. public void Dispose()
  95. {
  96. Dispose(true);
  97. GC.SuppressFinalize(this);
  98. }
  99. internal void Dispose(bool disposing)
  100. {
  101. if (!disposed)
  102. {
  103. if (disposing)
  104. {
  105. //Close();
  106. }
  107. disposed = true;
  108. }
  109. }
  110. /// <summary>
  111. /// Finalizer
  112. /// </summary>
  113. ~MsSqlSpatial()
  114. {
  115. Dispose();
  116. }
  117. #endregion
  118. private string _ConnectionString;
  119. /// <summary>
  120. /// Connectionstring
  121. /// </summary>
  122. public string ConnectionString
  123. {
  124. get { return _ConnectionString; }
  125. set { _ConnectionString = value; }
  126. }
  127. private string _Table;
  128. /// <summary>
  129. /// Data table name
  130. /// </summary>
  131. public string Table
  132. {
  133. get { return _Table; }
  134. set { _Table = value; }
  135. }
  136. private string _GeometryColumn;
  137. /// <summary>
  138. /// Name of geometry column
  139. /// </summary>
  140. public string GeometryColumn
  141. {
  142. get { return _GeometryColumn; }
  143. set { _GeometryColumn = value; }
  144. }
  145. private string _GeometryExpression = "{0}";
  146. /// <summary>
  147. /// Expression template for geometry column evaluation.
  148. /// </summary>
  149. /// <example>
  150. /// You could, for instance, simplify your geometries before they're displayed.
  151. /// Simplification helps to speed the rendering of big geometries.
  152. /// Here's a sample code to simplify geometries using 100 meters of threshold.
  153. /// <code>
  154. /// datasource.GeometryExpression = "ST.Simplify({0}, 100)";
  155. /// </code>
  156. /// Also you could draw a 20 meters buffer around those little points:
  157. /// <code>
  158. /// datasource.GeometryExpression = "ST.Buffer({0}, 20)";
  159. /// </code>
  160. /// </example>
  161. public string GeometryExpression
  162. {
  163. get { return _GeometryExpression; }
  164. set { _GeometryExpression = value; }
  165. }
  166. private string _ObjectIdColumn;
  167. /// <summary>
  168. /// Name of column that contains the Object ID
  169. /// </summary>
  170. public string ObjectIdColumn
  171. {
  172. get { return _ObjectIdColumn; }
  173. set { _ObjectIdColumn = value; }
  174. }
  175. /// <summary>
  176. /// Returns geometries within the specified bounding box
  177. /// </summary>
  178. /// <param name="bbox"></param>
  179. /// <returns></returns>
  180. public Collection<Geometries.Geometry> GetGeometriesInView(SharpMap.Geometries.BoundingBox bbox)
  181. {
  182. Collection<Geometries.Geometry> features = new Collection<SharpMap.Geometries.Geometry>();
  183. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  184. {
  185. string strSQL = "SELECT ST.AsBinary(" + this.BuildGeometryExpression() + ") ";
  186. strSQL += "FROM ST.FilterQuery" + this.BuildSpatialQuerySuffix() + "(" + this.BuildEnvelope(bbox) + ")";
  187. if (!String.IsNullOrEmpty(_definitionQuery))
  188. strSQL += " WHERE " + this.DefinitionQuery;
  189. using (SqlCommand command = new SqlCommand(strSQL, conn))
  190. {
  191. conn.Open();
  192. using (SqlDataReader dr = command.ExecuteReader())
  193. {
  194. while (dr.Read())
  195. {
  196. if (dr[0] != DBNull.Value)
  197. {
  198. SharpMap.Geometries.Geometry geom = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])dr[0]);
  199. if(geom!=null)
  200. features.Add(geom);
  201. }
  202. }
  203. }
  204. conn.Close();
  205. }
  206. }
  207. return features;
  208. }
  209. /// <summary>
  210. /// Returns the geometry corresponding to the Object ID
  211. /// </summary>
  212. /// <param name="oid">Object ID</param>
  213. /// <returns>geometry</returns>
  214. public SharpMap.Geometries.Geometry GetGeometryByID(uint oid)
  215. {
  216. SharpMap.Geometries.Geometry geom = null;
  217. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  218. {
  219. string strSQL = "SELECT ST.AsBinary(" + this.BuildGeometryExpression() + ") AS Geom FROM " + this.Table + " WHERE " + this.ObjectIdColumn + "='" + oid.ToString() + "'";
  220. conn.Open();
  221. using (SqlCommand command = new SqlCommand(strSQL, conn))
  222. {
  223. using (SqlDataReader dr = command.ExecuteReader())
  224. {
  225. while (dr.Read())
  226. {
  227. if (dr[0] != DBNull.Value)
  228. geom = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])dr[0]);
  229. }
  230. }
  231. }
  232. conn.Close();
  233. }
  234. return geom;
  235. }
  236. /// <summary>
  237. /// Returns geometry Object IDs whose bounding box intersects 'bbox'
  238. /// </summary>
  239. /// <param name="bbox"></param>
  240. /// <returns></returns>
  241. public Collection<uint> GetObjectIDsInView(SharpMap.Geometries.BoundingBox bbox)
  242. {
  243. Collection<uint> objectlist = new Collection<uint>();
  244. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  245. {
  246. string strSQL = "SELECT * FROM ST.FilterQuery('" + this.Table + "', '" + this.GeometryColumn + "', " + this.BuildEnvelope(bbox) + ")";
  247. if (!String.IsNullOrEmpty(_definitionQuery))
  248. strSQL += " WHERE " + this.DefinitionQuery;
  249. using (SqlCommand command = new SqlCommand(strSQL, conn))
  250. {
  251. conn.Open();
  252. using (SqlDataReader dr = command.ExecuteReader())
  253. {
  254. while (dr.Read())
  255. {
  256. if (dr[0] != DBNull.Value)
  257. {
  258. uint ID = (uint)(int)dr[0];
  259. objectlist.Add(ID);
  260. }
  261. }
  262. }
  263. conn.Close();
  264. }
  265. }
  266. return objectlist;
  267. }
  268. /// <summary>
  269. /// Returns all objects within a distance of a geometry
  270. /// </summary>
  271. /// <param name="geom"></param>
  272. /// <param name="distance"></param>
  273. /// <returns></returns>
  274. [Obsolete("Use ExecuteIntersectionQuery instead")]
  275. public SharpMap.Data.FeatureDataTable QueryFeatures(SharpMap.Geometries.Geometry geom, double distance)
  276. {
  277. //List<Geometries.Geometry> features = new List<SharpMap.Geometries.Geometry>();
  278. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  279. {
  280. string strGeom = "ST.GeomFromText('" + geom.AsText() + "', " + this.SRID.ToString() + ")";
  281. string strSQL = "SELECT *, ST.AsBinary(" + this.BuildGeometryExpression() + ") As sharpmap_tempgeometry ";
  282. strSQL += "FROM ST.IsWithinDistanceQuery" + this.BuildSpatialQuerySuffix() + "(" + strGeom + ", " + distance.ToString(Map.numberFormat_EnUS) + ")";
  283. if (!String.IsNullOrEmpty(_definitionQuery))
  284. strSQL += " WHERE " + this.DefinitionQuery;
  285. using (SqlDataAdapter adapter = new SqlDataAdapter(strSQL, conn))
  286. {
  287. System.Data.DataSet ds = new System.Data.DataSet();
  288. conn.Open();
  289. adapter.Fill(ds);
  290. conn.Close();
  291. if (ds.Tables.Count > 0)
  292. {
  293. FeatureDataTable fdt = new FeatureDataTable(ds.Tables[0]);
  294. foreach (System.Data.DataColumn col in ds.Tables[0].Columns)
  295. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  296. fdt.Columns.Add(col.ColumnName,col.DataType,col.Expression);
  297. foreach (System.Data.DataRow dr in ds.Tables[0].Rows)
  298. {
  299. SharpMap.Data.FeatureDataRow fdr = fdt.NewRow();
  300. foreach(System.Data.DataColumn col in ds.Tables[0].Columns)
  301. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  302. fdr[col.ColumnName] = dr[col];
  303. if (dr["sharpmap_tempgeometry"] != DBNull.Value)
  304. fdr.Geometry = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])dr["sharpmap_tempgeometry"]);
  305. fdt.AddRow(fdr);
  306. }
  307. return fdt;
  308. }
  309. else return null;
  310. }
  311. }
  312. }
  313. /// <summary>
  314. /// Returns the features that intersects with 'geom'
  315. /// </summary>
  316. /// <param name="geom"></param>
  317. /// <param name="ds">FeatureDataSet to fill data into</param>
  318. public void ExecuteIntersectionQuery(SharpMap.Geometries.Geometry geom, FeatureDataSet ds)
  319. {
  320. List<Geometries.Geometry> features = new List<SharpMap.Geometries.Geometry>();
  321. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  322. {
  323. string strGeom = "ST.GeomFromText('" + geom.AsText() + "', " + this.SRID.ToString() + ")";
  324. string strSQL = "SELECT *, ST.AsBinary(" + this.BuildGeometryExpression() + ") As sharpmap_tempgeometry ";
  325. strSQL += "FROM ST.RelateQuery" + this.BuildSpatialQuerySuffix() + "(" + strGeom + ", 'intersects')";
  326. if (!String.IsNullOrEmpty(_definitionQuery))
  327. strSQL += " WHERE " + this.DefinitionQuery;
  328. using (SqlDataAdapter adapter = new SqlDataAdapter(strSQL, conn))
  329. {
  330. conn.Open();
  331. adapter.Fill(ds);
  332. conn.Close();
  333. if (ds.Tables.Count > 0)
  334. {
  335. FeatureDataTable fdt = new FeatureDataTable(ds.Tables[0]);
  336. foreach (System.Data.DataColumn col in ds.Tables[0].Columns)
  337. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  338. fdt.Columns.Add(col.ColumnName, col.DataType, col.Expression);
  339. foreach (System.Data.DataRow dr in ds.Tables[0].Rows)
  340. {
  341. SharpMap.Data.FeatureDataRow fdr = fdt.NewRow();
  342. foreach (System.Data.DataColumn col in ds.Tables[0].Columns)
  343. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  344. fdr[col.ColumnName] = dr[col];
  345. if (dr["sharpmap_tempgeometry"] != DBNull.Value)
  346. fdr.Geometry = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])dr["sharpmap_tempgeometry"]);
  347. fdt.AddRow(fdr);
  348. }
  349. ds.Tables.Add(fdt);
  350. }
  351. }
  352. }
  353. }
  354. /// <summary>
  355. /// Convert WellKnownText to linestrings
  356. /// </summary>
  357. /// <param name="WKT"></param>
  358. /// <returns></returns>
  359. private SharpMap.Geometries.LineString WktToLineString(string WKT)
  360. {
  361. SharpMap.Geometries.LineString line = new SharpMap.Geometries.LineString();
  362. WKT = WKT.Substring(WKT.LastIndexOf('(') + 1).Split(')')[0];
  363. string[] strPoints = WKT.Split(',');
  364. foreach (string strPoint in strPoints)
  365. {
  366. string[] coord = strPoint.Split(' ');
  367. line.Vertices.Add(new SharpMap.Geometries.Point(double.Parse(coord[0], SharpMap.Map.numberFormat_EnUS), double.Parse(coord[1], SharpMap.Map.numberFormat_EnUS)));
  368. }
  369. return line;
  370. }
  371. /// <summary>
  372. /// Returns the number of features in the dataset
  373. /// </summary>
  374. /// <returns>number of features</returns>
  375. public int GetFeatureCount()
  376. {
  377. int count = 0;
  378. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  379. {
  380. string strSQL = "SELECT COUNT(*) FROM " + this.Table;
  381. if (!String.IsNullOrEmpty(_definitionQuery))
  382. strSQL += " WHERE " + this.DefinitionQuery;
  383. using (SqlCommand command = new SqlCommand(strSQL, conn))
  384. {
  385. conn.Open();
  386. count = (int)command.ExecuteScalar();
  387. conn.Close();
  388. }
  389. }
  390. return count;
  391. }
  392. #region IProvider Members
  393. private string _definitionQuery;
  394. /// <summary>
  395. /// Definition query used for limiting dataset
  396. /// </summary>
  397. public string DefinitionQuery
  398. {
  399. get { return _definitionQuery; }
  400. set { _definitionQuery = value; }
  401. }
  402. /// <summary>
  403. /// Gets a collection of columns in the dataset
  404. /// </summary>
  405. public System.Data.DataColumnCollection Columns
  406. {
  407. get {
  408. throw new NotImplementedException();
  409. //using (SqlConnection conn = new SqlConnection(this.ConnectionString))
  410. //{
  411. //    System.Data.DataColumnCollection columns = new System.Data.DataColumnCollection();
  412. //    string strSQL = "SELECT column_name, udt_name FROM information_schema.columns WHERE table_name='" + this.Table + "' ORDER BY ordinal_position";
  413. //    using (SqlCommand command = new SqlCommand(strSQL, conn))
  414. //    {
  415. //        conn.Open();
  416. //        using (SqlDataReader dr = command.ExecuteReader())
  417. //        {
  418. //            while (dr.Read())
  419. //            {
  420. //                System.Data.DataColumn col = new System.Data.DataColumn((string)dr["column_name"]);
  421. //                switch((string)dr["udt_name"])
  422. //                {
  423. //                    case "int4":
  424. //                        col.DataType = typeof(Int32);
  425. //                        break;
  426. //                    case "int8":
  427. //                        col.DataType = typeof(Int64);
  428. //                        break;
  429. //                    case "varchar":
  430. //                        col.DataType = typeof(string);
  431. //                        break;
  432. //                    case "text":
  433. //                        col.DataType = typeof(string);
  434. //                        break;
  435. //                    case "bool":
  436. //                        col.DataType = typeof(bool);
  437. //                        break;
  438. //                    case "geometry":
  439. //                        col.DataType = typeof(SharpMap.Geometries.Geometry);
  440. //                        break;
  441. //                    default:
  442. //                        col.DataType = typeof(object);
  443. //                        break;
  444. //                }
  445. //                columns.Add(col);
  446. //            }
  447. //        }
  448. //    }
  449. //    return columns;
  450. //}
  451. }
  452. }
  453. private int _srid=-2;
  454. /// <summary>
  455. /// Spacial Reference ID
  456. /// </summary>
  457. public int SRID
  458. {
  459. get {
  460. if (_srid == -2)
  461. {
  462. int dotPos = this.Table.IndexOf(".");
  463. string strSQL = "";
  464. if (dotPos == -1)
  465. strSQL = "select SRID from ST.GEOMETRY_COLUMNS WHERE F_TABLE_NAME='" + this.Table + "'";
  466. else
  467. {
  468. string schema = this.Table.Substring(0, dotPos);
  469. string table = this.Table.Substring(dotPos + 1);
  470. strSQL = "select SRID from ST.GEOMETRY_COLUMNS WHERE F_TABLE_SCHEMA='" + schema + "' AND F_TABLE_NAME='" + table + "'";
  471. }
  472. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  473. {
  474. using (SqlCommand command = new SqlCommand(strSQL, conn))
  475. {
  476. try
  477. {
  478. conn.Open();
  479. _srid = (int)command.ExecuteScalar();
  480. conn.Close();
  481. }
  482. catch
  483. {
  484. _srid = -1;
  485. }
  486. }
  487. }
  488. }
  489. return _srid;
  490. }
  491. set
  492. {
  493. // SRID can be set in order to support views.
  494. _srid = value;
  495. }
  496. }
  497. /// <summary>
  498. /// Queries the MsSqlSpatial database to get the name of the Geometry Column. This is used if the columnname isn't specified in the constructor
  499. /// </summary>
  500. /// <remarks></remarks>
  501. /// <returns>Name of column containing geometry</returns>
  502. private string GetGeometryColumn()
  503. {
  504. string strSQL = "select F_GEOMETRY_COLUMN from ST.GEOMETRY_COLUMNS WHERE F_TABLE_NAME='" + this.Table + "'";
  505. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  506. using (SqlCommand command = new SqlCommand(strSQL, conn))
  507. {
  508. conn.Open();
  509. object columnname = command.ExecuteScalar();
  510. conn.Close();
  511. if (columnname == System.DBNull.Value)
  512. throw new ApplicationException("Table '" + this.Table + "' does not contain a geometry column");
  513. return (string)columnname;
  514. }
  515. }
  516. /// <summary>
  517. /// Returns a datarow based on a RowID
  518. /// </summary>
  519. /// <param name="RowID"></param>
  520. /// <returns>datarow</returns>
  521. public SharpMap.Data.FeatureDataRow GetFeature(uint RowID)
  522. {
  523. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  524. {
  525. string strSQL = "select * , ST.AsBinary(" + this.BuildGeometryExpression() + ") As sharpmap_tempgeometry from " + this.Table + " WHERE " + this.ObjectIdColumn + "='" + RowID.ToString() + "'";
  526. using (SqlDataAdapter adapter = new SqlDataAdapter(strSQL, conn))
  527. {
  528. FeatureDataSet ds = new FeatureDataSet();
  529. conn.Open();
  530. adapter.Fill(ds);
  531. conn.Close();
  532. if (ds.Tables.Count > 0)
  533. {
  534. FeatureDataTable fdt = new FeatureDataTable(ds.Tables[0]);
  535. foreach (System.Data.DataColumn col in ds.Tables[0].Columns)
  536. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  537. fdt.Columns.Add(col.ColumnName, col.DataType, col.Expression);
  538. if(ds.Tables[0].Rows.Count>0)
  539. {
  540. System.Data.DataRow dr = ds.Tables[0].Rows[0];
  541. SharpMap.Data.FeatureDataRow fdr = fdt.NewRow();
  542. foreach (System.Data.DataColumn col in ds.Tables[0].Columns)
  543. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  544. fdr[col.ColumnName] = dr[col];
  545. if (dr["sharpmap_tempgeometry"] != DBNull.Value)
  546. fdr.Geometry = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])dr["sharpmap_tempgeometry"]);
  547. return fdr;
  548. }
  549. else
  550. return null;
  551. }
  552. else 
  553. return null;
  554. }
  555. }
  556. }
  557. /// <summary>
  558. /// Boundingbox of dataset
  559. /// </summary>
  560. /// <returns>boundingbox</returns>
  561. public SharpMap.Geometries.BoundingBox GetExtents()
  562. {
  563. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  564. {
  565. string strSQL = string.Format("SELECT ST.AsBinary(ST.EnvelopeQueryWhere('{0}', '{1}', '{2}'))", this.Table, this.GeometryColumn, this.DefinitionQuery.Replace("'", "''"));
  566. using (SqlCommand command = new SqlCommand(strSQL, conn))
  567. {
  568. conn.Open();
  569. object result = command.ExecuteScalar();
  570. conn.Close();
  571. if (result == System.DBNull.Value)
  572. return null;
  573. SharpMap.Geometries.BoundingBox bbox = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])result).GetBoundingBox();
  574. return bbox;
  575. }
  576. }
  577. }
  578. /// <summary>
  579. /// Gets the connection ID of the datasource
  580. /// </summary>
  581. public string ConnectionID
  582. {
  583. get { return _ConnectionString; }
  584. }
  585. #endregion
  586. #region IProvider Members
  587. /// <summary>
  588. /// Returns all features with the view box
  589. /// </summary>
  590. /// <param name="bbox">view box</param>
  591. /// <param name="ds">FeatureDataSet to fill data into</param>
  592. [Obsolete("Use ExecuteIntersectionQuery")]
  593. public void GetFeaturesInView(SharpMap.Geometries.BoundingBox bbox, SharpMap.Data.FeatureDataSet ds)
  594. {
  595. ExecuteIntersectionQuery(bbox, ds);
  596. }
  597. /// <summary>
  598. /// Returns all features with the view box
  599. /// </summary>
  600. /// <param name="bbox">view box</param>
  601. /// <param name="ds">FeatureDataSet to fill data into</param>
  602. public void ExecuteIntersectionQuery(SharpMap.Geometries.BoundingBox bbox, SharpMap.Data.FeatureDataSet ds)
  603. {
  604. List<Geometries.Geometry> features = new List<SharpMap.Geometries.Geometry>();
  605. using (SqlConnection conn = new SqlConnection(_ConnectionString))
  606. {
  607. string strSQL = "SELECT *, ST.AsBinary(" + this.BuildGeometryExpression() + ") AS sharpmap_tempgeometry ";
  608. strSQL += "FROM ST.FilterQuery" + this.BuildSpatialQuerySuffix() + "(" + this.BuildEnvelope(bbox) + ")";
  609. if (!String.IsNullOrEmpty(_definitionQuery))
  610. strSQL += " WHERE " + this.DefinitionQuery;
  611. using (SqlDataAdapter adapter = new SqlDataAdapter(strSQL, conn))
  612. {
  613. conn.Open();
  614. System.Data.DataSet ds2 = new System.Data.DataSet();
  615. adapter.Fill(ds2);
  616. conn.Close();
  617. if (ds2.Tables.Count > 0)
  618. {
  619. FeatureDataTable fdt = new FeatureDataTable(ds2.Tables[0]);
  620. foreach (System.Data.DataColumn col in ds2.Tables[0].Columns)
  621. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  622. fdt.Columns.Add(col.ColumnName,col.DataType,col.Expression);
  623. foreach (System.Data.DataRow dr in ds2.Tables[0].Rows)
  624. {
  625. SharpMap.Data.FeatureDataRow fdr = fdt.NewRow();
  626. foreach(System.Data.DataColumn col in ds2.Tables[0].Columns)
  627. if (col.ColumnName != this.GeometryColumn && !col.ColumnName.StartsWith(this.GeometryColumn + "_Envelope_") && col.ColumnName != "sharpmap_tempgeometry")
  628. fdr[col.ColumnName] = dr[col];
  629. if (dr["sharpmap_tempgeometry"] != DBNull.Value)
  630. fdr.Geometry = SharpMap.Converters.WellKnownBinary.GeometryFromWKB.Parse((byte[])dr["sharpmap_tempgeometry"]);
  631. fdt.AddRow(fdr);
  632. }
  633. ds.Tables.Add(fdt);
  634. }
  635. }
  636. }
  637. }
  638. #endregion
  639. private string BuildSpatialQuerySuffix()
  640. {
  641. string schema;
  642. string table = this.Table;
  643. int dotPosition = table.IndexOf('.');
  644. if (dotPosition == -1)
  645. {
  646. schema = "dbo";
  647. }
  648. else
  649. {
  650. schema = table.Substring(0, dotPosition);
  651. table = table.Substring(dotPosition + 1);
  652. }
  653. return "#" + schema + "#" + table + "#" + this.GeometryColumn;
  654. }
  655. private string BuildGeometryExpression()
  656. {
  657. return string.Format(this.GeometryExpression, this.GeometryColumn);
  658. }
  659. private string BuildEnvelope(SharpMap.Geometries.BoundingBox bbox)
  660. {
  661. return string.Format(SharpMap.Map.numberFormat_EnUS,
  662. "ST.MakeEnvelope({0},{1},{2},{3},{4})",
  663. bbox.Min.X,
  664. bbox.Min.Y,
  665. bbox.Max.X,
  666. bbox.Max.Y,
  667. this.SRID);
  668. }
  669. }
  670. }