最近看到有些程序员研究在手机上或者平板上研究基于spatialite的矢量数据处理,或者称之为离线数据绘制或者编辑的一种实现。
由于我也在学习研究android的开发,所以就对基于sqlite数据库的这个spatialite学习了一番。
spatialite,如果需要对其详细了解请进下面网站
http://www.gaia-gis.it/gaia-sins/ (就是spatialite项目的站点了)
spatialite是sqlite的一个扩展,使用相对来说并不复杂,按照网站上的Cook book,如下操作建立支持空间数据的sqlite库
1、创建表,这个没什么说的。就是sqlite创表了。
CREATE TABLE test_geom (
id INTEGER NOT NULL
PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
measured_value DOUBLE NOT NULL);
2、给表增加Geometry列,就是一个BLOB类型的图形数据列。
SELECT AddGeometryColumn('test_geom', 'the_geom',
4326, 'POINT', 'XY', 1);
参数简单解释一下AddGeometrt(
'表名'
'要加的图形列的列名'
坐标SRID对应的数字
'图形类型',
'XY' 这一列是标示二维三维等 如果是三维就是写'XYZ'
数字1标示该列不为null相反0则可为null
其中图形类型可以分为POINT LINESTRING POLYGON MULTIPOINT MULTILINESTRING MULTIPOLYGON GEOMETRYCOLLECTION GEOMETRY
图形类型常用的就是前三种了。
3、删除图形列,删除后可以用RecoverGeometryColumn恢复
SELECT DiscardGeometryColumn('test_geom', 'the_geom');
SELECT RecoverGeometryColumn('test_geom', 'the_geom',
4326, 'POINT', 'XY');
4、空间索引,spatialite默认是RTree空间索引,建完表以后使用下面语句建立空间索引。
SELECT CreateSpatialIndex('表名','图形列名');
以上简单介绍了Spatialite库的创建。下面可以使用.net 开发语言看如果调用这些sql 或者进行Spatialite二次开发
首先需要下载Spatialite的dll库,Spatialite需要在Linux环境c++编译,有其他人编译好的dll或者也可以自己按照说明编译
代码下载地址 https://www.gaia-gis.it/fossil/libspatialite/index 网站也提供了已经编译后的库 http://www.gaia-gis.it/spatialite-3.0.0-BETA/binaries.html
http://download.csdn.net/detail/rex0y/7904053
以c#为例调用过程如下
//注意引用 sqlite的数据库驱动System.Data.SQLite.dll
static bool ExecuteSql(string sql)
{
SQLiteCommand cmdinsert = new SQLiteCommand(sql, conn);
int r = cmdinsert.ExecuteNonQuery();
if (r > 0)
return true;
else
return false;
}
private void InitDb()
{
SQLiteConnection conn = null;
/* 打开连接 如果没有数据库文件自动创建*/
string dbpath = "Data Source=" + Application.StartupPath + "\\db.sqlite";
conn = new SQLiteConnection(dbpath);
conn.Open();
/* 加载sqlite扩展库 spatialite */
string sql = "SELECT load_extension('libspatialite-4.dll');";
bool bRet = ExecuteSql(sql, conn);
/* 初始化空间数据库描述的一些表 */
sql = "SELECT InitSpatialMetaData()";
bRet = ExecuteSql(sql, conn);
/* */
sql = "CREATE TABLE test_geom (id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,name TEXT NOT NULL,measured_value DOUBLE NOT NULL)";
bRet = ExecuteSql(sql, conn);
/* 添加图形列 */
sql = "SELECT AddGeometryColumn('test_geom', 'the_geom',4326, 'POINT', 'XY')";
bRet = ExecuteSql(sql, conn);
/* 添加空间索引 */
sql = "SELECT CreateSpatialIndex('test_geom', 'the_geom')";
bRet = ExecuteSql(sql, conn);
/* 通过OGC标准的WTK 文件描述格式插入一个点记录*/
sql = "INSERT INTO test_geom(id, name, measured_value, the_geom) VALUES (NULL, 'first point', 1.23456,GeomFromText('POINT(1.01 2.02)', 4326))";
bRet = ExecuteSql(sql, conn);
/* 通过OGC标准的WTK 文件描述格式插入一个点记录*/
sql = "INSERT INTO test_geom(the_geom, measured_value, name, id)VALUES (GeomFromText('POINT(11.01 11.02)', 4326),11.123456789, 'eleventh point', NULL)";
bRet = ExecuteSql(sql, conn);
conn.Close();
}
对于建立好的这个spatialite库可以使用工具 spatialite_gui.exe 打开查询一下
可以看到一些metadata的表,是由spatialite自动建立的,而Spatial Index分组下是空间索引。当然也可以用一般的sqlite工具打开。但可能会有一些警告。因为空间索引是虚表。
5、空间数据如果导入spatialite呢,以我们常见的arcgis数据转移到spatial为例,可以将arcgis的图形读取并转换为WKT (文本) 或者WKB (二进制)
过程简单实现如下:
AppendGeometryTaggedText(IGeometry geometry, StringWriter writer)
{
if (geometry == null)
{
throw new NullReferenceException("Geometry为空,无法转写WKT");
}
if (geometry is IPoint)
{
IPoint point = geometry as IPoint;
AppendPointTaggedText(point, writer);
}
if (geometry is IPolyline)
{
IPolyline polyline=geometry as IPolyline;
AppendPolylineTaggedText(polyline, writer);
}
if (geometry is IPolygon&&!ableMULTI)
{
IPolygon polygon = geometry as IPolygon;
AppendPolygonTaggedText(polygon, writer);
}
if (geometry is IPolygon && ableMULTI)
{
IPolygon polygon = geometry as IPolygon;
AppendMultiPolygonTaggedText(polygon, writer);
}
}