C#开发SQLServer的Geometry和Geography存储
原文:C#开发SQLServer的Geometry和Geography存储
SQL Server2008推出后最大的变化就是提供了支持空间数据存储的Geometry和Geography,这个也是如果将ArcSDE和SQLServer数据库相结合后可以供用户选择的一种数据存储模式,因为SQLServer2008前的数据库版本都是BLOB来存储空间数据对象的,目前没有测试来判断哪个性能更优,但是个人倾向于Geometry和Geography。
使用这两种存储,一个优点就是,使用SQL Server数据库也可以像使用Oracle、PostgreSQL一样,使用SQL来进行操作。
在以前的文章中我们也介绍了关于SQL的操作,但是都是在SQl Server的manger studio里面进行的
相关参考:ArcSDE for SQLServer的SQL操作
本文介绍的如何使用编程的方式C#来对SQL Server空间数据存储的Geometry和Geography来进行操作。
首先我们需要引用一个Microsoft.SqlServer.Types.dll,
该文件根据32Bit和64Bit的不同分布情况不同
32Bit:C:\Program Files \Microsoft SQL Server\100\SDK\Assemblies
64Bit:C:\Program Files (x86)\Microsoft SQL Server\100\SDK\Assemblies
注意如果你的SQL Server是2008和2012也是有相关区别的。
引用相关dll我们就可以进行开发了
以下代码环境:VS2010,引用dll版本SQL Server2012
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.SqlServer.Types;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Configuration; namespace SQL
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent(); object s= GetSRID("sde101", "sde", "CHINACITYTABLE");
}
//连接串
string connstring = "Data Source=192.168.100.111;Initial Catalog=sde101;Persist Security Info=True;User ID=sde;Password=sde";
//获得数据连接
public SqlConnection GetSQLConnection()
{
try
{
return new SqlConnection(connstring);
}
catch (Exception)
{
return null;
}
} //将Geometry对象转换为WKT串
public void QuerytoWKT()
{
string sql = "select shape from xzq where objectid=45";
SqlGeometry g = GetGeometry(sql);
if (g != null)
{
//以WKT输出
Console.WriteLine(g);
}
}
//获得Geometry对象
/// <summary>
/// 直接使用SQL语句获得SQLGeometry对象
/// </summary>
/// <param name="sql"></param>
/// <returns></returns>
public SqlGeometry GetGeometry(string sql)
{
try
{ SqlCommand cmd = GetCommand(sql);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
SqlBytes sb = reader.GetSqlBytes(0);
//Deserialize方法只有引用SQLServer2012的dll才能使用,2008不支持
SqlGeometry g = SqlGeometry.Deserialize(sb);
return g;
}
return null;
} catch (Exception e)
{ return null; }
}
/// <summary>
/// 根据WKT串获得SQLGeometry对象
/// </summary>
/// <param name="sWKT"></param>
/// <param name="sSRID"></param>
/// <returns></returns>
public SqlGeometry GetGeometry(string sWKT, int sSRID)
{
// var sql = "POLYGON((509827.650 3848402.022,509763.336 3847282.564,509268.926 3847640.308,509827.650 3848402.022))"; SqlChars polyText = new SqlChars(sWKT);
return SqlGeometry.STGeomFromText(polyText, sSRID);
}
public SqlCommand GetCommand(string sql)
{
SqlConnection conn = GetSQLConnection();
conn.Open();
SqlCommand cmd = new SqlCommand(sql, conn);
return cmd;
}
//增删改直接写上不同的SQL语句即可
public void EditData()
{
try
{
string sWKT = "POLYGON((513132.704 3847868.592,513860.309 3846638.277,512682.911 3846598.589,513132.704 3847868.592))";
string sql = "insert xzq (objectid,shape) values(11111,'"+sWKT+"')";
SqlCommand cmd = GetCommand(sql);
cmd.ExecuteNonQuery();
}
catch (Exception e)
{ }
}
//获得相交数据
/// <summary>
/// Unable to load DLL 'SqlServerSpatial110.dll': 找不到指定的模块。 (Exception from HRESULT: 0x8007007E)
/// </summary>
public void GetIntersections()
{
try
{
string sql1 = "select shape from xzq where objectid=86";
string sql2 = "select shape from xzq where objectid=71";
SqlGeometry g1 = GetGeometry(sql1);
SqlGeometry g2 = GetGeometry(sql2); //获得相交的图形
SqlGeometry g3 = g1.STIntersection(g2);
if (g3 != null)
{
//以WKT输出
Console.WriteLine(g3);
}
}
catch (Exception e)
{ }
}
//获得两点距离
public string GetDistance(SqlGeometry p1, SqlGeometry p2)
{
return p1.STDistance(p2).ToString();
} /// <summary>
/// //根据表名获得SRID
/// 主要是直接进入GDB_ITEMS表里面获得制定表对象的SRID值
/// GDB_ITEMS表是安装了ArcSDE后才有的表
/// select shape from [sde101].[sde].[CHINACITYTABLE]
/// </summary>
/// <param name="sTableName"></param>
/// <param name="sDatabasename"></param>
/// <param name="sUser"></param>
/// <returns></returns>
public object GetSRID(string sDatabasename,string sUser,string sTableName)
{
//如果找不到,返回0
object SRID = null;
//如果熟悉ArcSDE的库的表结构,只要是解析相关的XML文件,来获得SRID
string sql = "SELECT Definition.value('(/DEFeatureClassInfo/SpatialReference/LatestWKID)[1]','nvarchar(max)') FROM "+
sDatabasename+"."+sUser+".[GDB_ITEMS] WHERE Name='"+sDatabasename+"."+sUser+"."+sTableName+"'";
SqlCommand cmd = GetCommand(sql);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
SRID= reader.GetSqlValue(0);
}
return SRID;
}
}
}
以上代码有几个需要说明
1:在使用Geometry对象解析过程中,使用Deserialize,该方法只有SQL Server2012有,如果你使用SQL Server2008没有该方法
2:Geometry和Geography的区别在于你所使用的投影是平面坐标和地理坐标
3:在使用空间关系中,系统会提示
Unable to load DLL 'SqlServerSpatial110.dll': 找不到指定的模块。 (Exception from HRESULT: 0x8007007E)
这是因为,Microsoft.SqlServer.Types.dll文件需要使用操作系统C:\Windows\System32\SqlServerSpatial110.dll(同样安装了SQL Server不同版本,在该路径下的版本号不一样,110代表2012版本),该dll不是加载的,是需要存储放在系统路径下的,注意两者的版本一致。
4:获得SRID,我是直接从ArcSDE的Schema的XML来获得的。
最后强调一下,因为这是Mircosoft提供的空间存储对象,所以相关帮助查看微软帮助即可。
http://technet.microsoft.com/zh-cn/library/ee642046(v=sql.105).aspx
更深一步,如果对该方面的内容非常感兴趣,建议看看
版权所有,文章允许转载,但必须以链接方式注明源地址,否则追究法律责任!
------------------------------------------------------------------------------------------------------
版权声明:本文为博主原创文章,未经博主允许不得转载。
C#开发SQLServer的Geometry和Geography存储的更多相关文章
- SqlServer之geometry格式数据的添加和修改
SqlServer之geometry格式数据的添加和修改 SqlServer中geometry是一种存储空间数据的格式,其数据主要有点线面等几种格式: POINT( ) //点 LINESTRING ...
- 使用.NET 6开发TodoList应用(4)——引入数据存储
需求 作为后端CRUD程序员(bushi,数据存储是开发后端服务一个非常重要的组件.对我们的TodoList项目来说,自然也需要配置数据存储.目前的需求很简单: 需要能持久化TodoList对象并对其 ...
- iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...
- iOS开发UI篇—ios应用数据存储方式(偏好设置)
iOS开发UI篇—ios应用数据存储方式(偏好设置) 一.简单介绍 很多iOS应用都支持偏好设置,比如保存用户名.密码.字体大小等设置,iOS提供了一套标准的解决方案来为应用加入偏好设置功能 每个应用 ...
- iOS开发UI篇—ios应用数据存储方式(归档)
iOS开发UI篇—ios应用数据存储方式(归档) 一.简单说明 在使用plist进行数据存储和读取,只适用于系统自带的一些常用类型才能用,且必须先获取路径相对麻烦: 偏好设置(将所有的东西都保存在同 ...
- (转)HTML5开发学习(2):本地存储之localStorage 、sessionStorage、globalStorage
原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(2):本地存储之localStorage ...
- (转)HTML5开发学习(3):本地存储之Web Sql Database
原文:http://www.cnblogs.com/xumingxiang/archive/2012/03/25/2416386.html HTML5开发学习(3):本地存储之Web Sql Data ...
- Windows Phone开发(29):隔离存储C
原文:Windows Phone开发(29):隔离存储C 本文是隔离存储的第三节,大家先喝杯咖啡放松,今天的内容也是非常简单,我们就聊一件东东--用户设置. 当然了,可能翻译为应用程序设置合适一些,不 ...
- Windows Phone开发(28):隔离存储B
原文:Windows Phone开发(28):隔离存储B 上一节我们聊了目录的操作,这一节我们继续来看看如何读写文件. 首先说一下题外话,许多朋友都在摇摆不定,三心二意,其实这样的学习态度是很不好的, ...
随机推荐
- python中的继承原则
继承是面向对象的重要特征之一,继承是两个类或者多个类之间的父子关系,子进程继承了父进程的所有公有实例变量和方法.继承实现了代码的重用.重用已经存在的数据和行为,减少代码的重新编写,python在类名 ...
- smarty模板执行原理
为了实现程序的业务逻辑和内容表现页面的分离从而提高开发速度,php 引入了模板引擎的概念,php 模板引擎里面最流行的可以说是smarty了,smarty因其功能强大而且速度快而被广大php web开 ...
- Sum Root to Leaf Numbers 解答
Question Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent ...
- obiz
ofbiz 安装 1. 由 binary 安装: 由 binary 安装非常简单, 以下是安装方法: 下载ofbiz-2.0-beta1-complete.tar.gz, 注意不是ofbiz-2.0- ...
- ubuntu下php安装xdebug
1.安装 sudo apt-get install php5-xdebug 2.配置 修改 php .ini 路径: /etc/php5/apache2/php.ini (这里可能有不同,不同的u ...
- handsontable的核心方法
1.为handsontable添加钩子方法 addHook(key,callback):key为钩子方法名 <span style="font-size:18px;"> ...
- C语言获取系统当前时间转化成时间字符串
因为保存的文件须要加上保存的时间,所以须要一个函数来将系统当前时间获取出来,同一时候转换成时间字符串.详细的时间代码例如以下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ...
- 基于RSA的加密/解密示例C#代码
using System;using System.Security.Cryptography;using System.Text; class RSACSPSample{ static void M ...
- Codeforces 67C Sequence of Balls 编辑距离 dp
题目链接:点击打开链接 有一个交换操作比較特殊,所以记录每一个点距离自己近期的那个字符的位置 然后交换就相当于把第一行要交换的2个字符 之间的字符都删掉 把第二行要交换的2个字符 之间的字符都插入第一 ...
- 已解决 C# 调用 MySQLDriverCS 类库 报 vshost32-clr2.exe 已停止工作
这几天修改一个项目是用C# 通过调用 MySQLDriverCS.dll 类库来操作 MySql数据库, 调试的会发生以上错误(直接运行是正常的),刚开始以为是兼容性问题,吧此错误百度上一粘贴有的人说 ...