在此介紹用sql對超圖的空間數據庫(sdx)進行空間查詢,優勢以下:html
1。超圖推薦的方式是用iobject,此方法要引入iobject前端
2。超圖另外一個推薦的方式是用iserver的REST接口,但web接口缺點在於性能通常,尤爲是返回數據比較多以及併發頻繁的狀況下性能很差java
超圖空間數據庫支持多種數據庫產品(DBMS),可這種方式只支持PostGIS,也便是下圖的web
PS:注意在超圖sdx的體系,Postgresql和PostGIS是兩種數據庫,而開源空間數據庫PostGIS依賴於postgresql,能夠說空間數據庫PostGIS也是postgresql,注意區別sql
PS:超圖idesktop部分版本不支持PostGIS,例如我只在idesktop 9D java 2019(9.1.0)能成功使用數據庫
當超圖PostGIS數據庫建好後,創建好jdbc鏈接(本文略,總之按postgresql建鏈接就行),而後就能夠用sql作空間查詢,以及輸出幾何對象api
sql中使用空間查詢的「接口」跟開源空間數據庫PostGIS是同樣的,原理是超圖PostGIS也兼容開源PostGIS的功能併發
開源PostGIS的空間查詢接口遵循OpenGIS標準,如下是開源PostGIS的官方文檔,有接口的詳細說明:https://postgis.net/docs/manual-dev/reference.htmlide
另外我的也能夠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); } }