超圖supermap sdx資料庫用sql實現空間查詢
阿新 • • 發佈:2018-11-29
在此介紹用sql對超圖的空間資料庫(sdx)進行空間查詢,優點如下:
1。超圖推薦的方式是用iobject,此方法要引入iobject
2。超圖另一個推薦的方式是用iserver的REST介面,但web介面缺點在於效能一般,尤其是返回資料比較多以及併發頻繁的情況下效能不好
超圖空間資料庫支援多種資料庫產品(DBMS),可這種方式只支援PostGIS,也即是下圖的
PS:注意在超圖sdx的體系,Postgresql和PostGIS是兩種資料庫,而開源空間資料庫PostGIS依賴於postgresql,可以說空間資料庫PostGIS也是postgresql,注意區別
PS:超圖idesktop部分版本不支援PostGIS,例如我只在idesktop 9D java 2019(9.1.0)能成功使用
當超圖PostGIS資料庫建好後,建立好jdbc連線(本文略,總之按postgresql建連線就行),然後就可以用sql做空間查詢,以及輸出幾何物件
sql中使用空間查詢的“介面”跟開源空間資料庫PostGIS是一樣的,原理是超圖PostGIS也相容開源PostGIS的功能
開源PostGIS的空間查詢介面遵循OpenGIS標準,以下是開源PostGIS的官方文件,有介面的詳細說明:https://postgis.net/docs/manual-dev/reference.html
另外個人也可以baidu關鍵詞:postgis查詢,來找到相關文章
以下貼一些程式碼
/** * 屬性查詢 * * @throws Exception */ private void attrQuery() throws Exception { //屬性查詢 //例子:查詢名稱為f1的欄位,值等於 面1 的要素(資料/行) //圖層名 //sde資料庫帶空間屬性的表叫圖層,因此圖層跟表類似 String layerName = "polygon1"; //獲取預設資料庫連線 Connection conn = JdbcConnConfigUtil.getDefaultConn(); //查詢使用的是sql,就是普通的sql //select至from之間是輸出的欄位,其中ST_AsText(smgeometry)是輸出幾何物件並轉成wkt格式,smgeometry代表幾何物件,ST_AsText是一個函式可以把幾何物件轉成wkt格式的字串 //ST_開頭的函式屬於開源空間資料庫PostGIS的功能,可以理解為寫在sql語句裡的一些函式,詳細api在這https://postgis.net/docs/manual-dev/reference.html String sql = "select f1,ST_AsText(smgeometry) as wkt" + " from " + layerName + " t " + //查詢條件,本demo是屬性查詢因此跟一般sql一樣 "where t.f1='面1'"; //查詢程式碼,跟jdbc一樣的用法 PreparedStatement pst = null; ResultSet rs = null; try { pst = conn.prepareStatement(sql); //執行查詢 rs = pst.executeQuery(); //while迴圈變數查詢結果 while (rs.next()) { //通過欄位索引獲取欄位值,注意:索引從1開始!!!! //獲取幾何物件,wkt格式 //wkt格式既可以構建幾何物件(如何構建後面有說),也可以輸出到前端供前端使用 String wkt = rs.getString(2); //獲取普通欄位的值 Long f1 = DataConvertUtil.strToLong(rs.getString(1)); } } finally { //關閉連線,清除各種物件 DbUtils.closeQuietly(conn, pst, rs); } }
/**
* 空間查詢,點查詢面圖層
*
* @throws Exception
*/
private void pointQueryPolygonLayer() throws Exception {
//空間查詢,點查詢面圖層
//圖層名
//sde資料庫帶空間屬性的表叫圖層,因此圖層跟表類似
String layerName = "polygon1";
//點以座標形式存在
double x = 38794.80;
double y = 25327.295;
//獲取預設資料庫連線
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//獲取圖層的srid
//srid代表圖層的空間參考(也可以說是座標系),sr=spatial reference
String srid = SdxUtil.getSridByTableName(conn, layerName, JdbcConnConfigUtil.getDefaultMapProperties());
conn = JdbcConnConfigUtil.getDefaultConn();
//查詢使用的是sql,就是普通的sql
//因為是普通sql,所以在navicat也能執行,除錯sql可以直接在navicat中除錯
String sql = "select ST_AsText(smgeometry) as wkt" +
" from " + layerName + " t " +
//查詢條件,以下寫法意思是查詢面圖層中與點(點座標值就是x,y變數)相交的面
//其中ST_Intersects是相交的判斷函式,引數是兩個幾何物件,第一個t.smgeometry代表本表的幾何物件
//第二個ST_PointFromText('POINT(" + x + " " + y + ")', " + srid + "),這裡使用了ST_PointFromText函式通過xy座標值構建點的幾何物件,其中srid是直接使用了圖層的srid
//關於srid:所以空間物件,例如圖層和幾何物件,都有座標系(也可叫做空間參考),srid就代表座標系
//在空間查詢,一般來說,被查詢的圖層和作為查詢條件的幾何物件的座標系要統一,否則很可能出錯或造成查詢結果不對
//ST_Intersects的詳細描述請看api
"where ST_Intersects(t.smgeometry,ST_PointFromText('POINT(" + x + " " + y + ")', " + srid + ")) = true";
//查詢程式碼,跟jdbc一樣的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//執行查詢
rs = pst.executeQuery();
//while迴圈變數查詢結果
while (rs.next()) {
//通過欄位索引獲取欄位值,注意:索引從1開始!!!!
//獲取幾何物件,wkt格式
//wkt格式既可以構建幾何物件(如何構建後面有說),也可以輸出到前端供前端使用
String wkt = rs.getString(1);
}
} finally {
//關閉連線,清除各種物件
DbUtils.closeQuietly(conn, pst, rs);
}
}
/**
* 空間查詢,點緩衝區查詢面圖層
*
* @throws Exception
*/
private void pointBufferQueryPolygonLayer() throws Exception {
//空間查詢,點緩衝區查詢面圖層
//圖層名
//sde資料庫帶空間屬性的表叫圖層,因此圖層跟表類似
String layerName = "polygon1";
//點以座標形式存在
double x = 38821.471;
double y = 25274.206;
//緩衝半徑
double bufferDistance = 100.0;
//獲取預設資料庫連線
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//獲取圖層的srid
//srid代表圖層的空間參考(也可以說是座標系),sr=spatial reference
String srid = SdxUtil.getSridByTableName(conn, layerName, JdbcConnConfigUtil.getDefaultMapProperties());
conn = JdbcConnConfigUtil.getDefaultConn();
//查詢使用的是sql,就是普通的sql
String sql = "select ST_AsText(smgeometry) as wkt" +
" from " + layerName + " t " +
//查詢條件,以下寫法意思是查詢面圖層中與點的緩衝區相交的面
//此方法常用於點選地圖查詢點和線,因為點選通常很難絕對點中點和線,所有要加一個小小的緩衝範圍
//ST_Buffer是構建緩衝區的意思,在此例中是對點物件建立半徑為xx(值在變數bufferDistance)的緩衝區,引數1是幾何物件,引數2是緩衝半徑
//ST_Buffer外部有select sde.ST_Buffer.... ,大家可能會覺得加這一步多餘(實際上也不會影響查詢結果)
//ST_Buffer的詳細描述請看api
"where st_intersects(t.smgeometry,(select ST_Buffer(ST_PointFromText('POINT(" + x + " " + y + ")', " + srid + ")," + bufferDistance + "))) = true";
//查詢程式碼,跟jdbc一樣的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//執行查詢
rs = pst.executeQuery();
//while迴圈變數查詢結果
while (rs.next()) {
//通過欄位索引獲取欄位值,注意:索引從1開始!!!!
//獲取幾何物件,wkt格式
//wkt格式既可以構建幾何物件(如何構建後面有說),也可以輸出到前端供前端使用
String wkt = rs.getString(1);
}
} finally {
//關閉連線,清除各種物件
DbUtils.closeQuietly(conn, pst, rs);
}
}
/**
* 空間查詢,線查詢面圖層,也包括使用引數查詢
*
* @throws Exception
*/
private void lineQueryPolygonLayer() throws Exception {
//空間查詢,線查詢面圖層
//此demo中查詢條件的線的格式是wkt,因此此demo同樣適用於wkt格式的點線面作為查詢條件
//圖層名
//sde資料庫帶空間屬性的表叫圖層,因此圖層跟表類似
String layerName = "polygon1";
//作為查詢條件的線,wkt格式
String queryConditionWkt = "LINESTRING (38778.80641398 25400.74843392, 38829.229274779995 25320.265790719997, 38787.53344758 25269.35809472)";
//獲取預設資料庫連線
Connection conn = JdbcConnConfigUtil.getDefaultConn();
//獲取圖層的srid
//srid代表圖層的空間參考(也可以說是座標系),sr=spatial reference
String srid = SdxUtil.getSridByTableName(conn, layerName, JdbcConnConfigUtil.getDefaultMapProperties());
conn = JdbcConnConfigUtil.getDefaultConn();
//查詢使用的是sql,就是普通的sql
String sql = "select st_astext(t.smgeometry) as wkt,t.f1" +
" from " + layerName + " t " +
//查詢條件,以下寫法意思是查詢面圖層中與線(不止線,同樣可用於點和麵)相交的面
//ST_GeomFromText是傳入的值生成幾何物件,此demo的值是wkt格式,實際不止支援wkt,詳細可看api
//ST_GeomFromText第一個引數是問號(?)而不是具體的值,問號意思是引數化查詢,把值用引數傳入(如何傳入引數下面有寫),引數查詢是jdbc的特性
//為何要用引數查詢(而不是直接把值內容拼成string)?因為wkt的長度通常都很長,以本demo為例,一個點的字串長度就有31,假設一條線有1000個點字元長度就是310000,sql語句會超長
//構建幾何物件的函式還有ST_GeomFromWKB,ST_Polygon,ST_PolygonFromText等等,具體請看api
" where st_intersects(t.smgeometry,(select ST_GeomFromText(?," + srid + "))) = true" +
//字元型欄位的引數查詢例子(字元,整形,浮點型的引數化使用都比較簡單,而且類似)
" and t.f1=?";
//查詢程式碼,跟jdbc一樣的用法
PreparedStatement pst = null;
ResultSet rs = null;
try {
pst = conn.prepareStatement(sql);
//wkt字元欄位引數查詢例子
pst.setString(1, queryConditionWkt);
//字元欄位引數查詢例子
pst.setString(2, "面2");
//執行查詢
rs = pst.executeQuery();
//while迴圈變數查詢結果
while (rs.next()) {
//通過欄位索引獲取欄位值,注意:索引從1開始!!!!
//獲取幾何物件,wkt格式
//wkt格式既可以構建幾何物件(如何構建後面有說),也可以輸出到前端供前端使用
String wkt = rs.getString(1);
String f1 = rs.getString(2);
}
} finally {
//關閉連線,清除各種物件
DbUtils.closeQuietly(conn, pst, rs);
}
}