最近看到有些程序員研究在手機上或者平板上研究基於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);
}
}