您好,登錄后才能下訂單哦!
這篇文章主要介紹“java如何操作gis geometry類型數據”,在日常操作中,相信很多人在java如何操作gis geometry類型數據問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java如何操作gis geometry類型數據”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
現在做的gis方面的業務,所以需要操作postgis中的geometry對象,找了很多的庫,比如geotools,但是莫名下載不下來。
還有就是jts,但是不好用,操作起來很復雜。找到了一個其他的類庫--geolatte-geom 和geolatte-geojson。
用于操作geometry和String以及json的互相轉化。而json和geojson個人理解就是輸出格式不同。多了一些geometry特有的屬性。
主要用于將String轉geometry對象、wkt和wkb方便好用。
<!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-geom --> <dependency> <groupId>org.geolatte</groupId> <artifactId>geolatte-geom</artifactId> <version>1.6.0</version> </dependency> <!-- https://mvnrepository.com/artifact/org.geolatte/geolatte-geojson --> <dependency> <groupId>org.geolatte</groupId> <artifactId>geolatte-geojson</artifactId> <version>1.6.0</version> </dependency>
public static void main(String[] args) { // 模擬數據庫中直接取出的geometry對象值(他是二進制的) // WKT 是字符串形式,類似"POINT(1 2)"的形式 // 所以WKT轉 geometry,相當于是字符串轉geometry // WKB轉 geometry,相當于是字節轉geometry String s="01020000800200000097E5880801845C404D064F3AF4AE36400000000000000000290A915F01845C40DC90B1A051AE36400000000000000000"; Geometry geo = Wkb.fromWkb(ByteBuffer.from(s)); // geometry對象和WKT輸出一致 // Geometry geometry1 = Wkt.fromWkt(wkt); System.out.println("-----Geometry------"+geo.getPositionN(1)); System.out.println("-----wkt------"+ Wkt.toWkt(geo)); System.out.println("-----wkb------"+Wkb.toWkb(geo)); }
最近因為需要存一些經緯度塊信息到數據庫,所以用到了mysql中的Geometry屬性(幾何對象)。在網上搜集了很多資料,到真正用的時候還是各種問題,所以下面推薦一種可能有點笨但是實用的方法(我的使用環境springboot工具是sts),下面就舉個例子來說明一下。
先了解一下數據庫中空間數據類型有哪些
類型 | 說明 | 簡介 | 例子 |
Geometry | 間數據 | 任意一種空間類型 | |
Point | 點 | 坐標值 | POINT(104.00924 30.46872) |
LineString | 線 | 線,由一系列點連接而成 | LINESTRING(1 1, 1 1, 1 1) |
Polygon | 多邊形 | 由多條線組成 | POLYGON((1 1, 2 2, 3 3, 4 4, 5 5)) |
MultiPoint | 點集合 | 集合類,包含多個點 | MULTIPOINT(1 1, 2 2, 1 1) |
MultiLineString | 線集合 | 集合類,包含多條線 | MULTILINESTRING((1 1, 2 2), (1 1, 1 1)) |
MultiPolygon | 多邊形集合 | 集合類,包含多個多邊形 | MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)), ((1 1, 1 1, 1 1, 1 1, 1 1))) |
GeometryCollection | 空間數據集合 | 集合類,可以包括多個點、線、多邊形 | GEOMETRYCOLLECTION(POINT(1 1), POINT(3 3), LINESTRING(1 1, 2 2)) |
接著往數據庫插入一個測試數據,插入的是一個空間數據集合里面包含多個多邊形集合。
INSERT INTO `geometry`(`geome`) VALUES(GeomFromText('GEOMETRYCOLLECTION(MULTIPOLYGON(((104.009241 30.468972,104.009229 30.468961,104.009225 30.468997)),((104.009241 30.468972,104.009229 30.468961,104.009225 30.468997))),MULTIPOLYGON(((104.009241 30.468972,104.009229 30.468961,104.009225 30.468997))))'));
數據準備好了就準備開始準備讀取操作。
在pom.xml添加操作Geometry等對象的依賴。
<dependency> <groupId>com.vividsolutions</groupId> <artifactId>jts</artifactId> <version>1.13</version> </dependency>
本來先是想直接在實體類確定類型直接轉對象,但是用了后發現不行,所以我就直接設置成Object,在mysql中存儲Geometry使用的是二進制,所以下面直接把二進制通過jts轉成Geometry對象。
//private Geometry geom; 不可行 private Object geomAsBytes; //可行 最終得到的是一個byte數組 //直接把數據庫中的byte[]轉Geometry對象 public static Geometry getGeometryByBytes( byte[] geometryAsBytes) throws Exception { Geometry dbGeometry = null; // 字節數組小于5,說明geometry有問題 if (geometryAsBytes.length < 5) { return null; } //這里是取字節數組的前4個來解析srid byte[] sridBytes = new byte[4]; System.arraycopy(geometryAsBytes, 0, sridBytes, 0, 4); boolean bigEndian = (geometryAsBytes[4] == 0x00); // 解析srid int srid = 0; if (bigEndian) { for (int i = 0; i < sridBytes.length; i++) { srid = (srid << 8) + (sridBytes[i] & 0xff); } } else { for (int i = 0; i < sridBytes.length; i++) { srid += (sridBytes[i] & 0xff) << (8 * i); } } //use the JTS WKBReader for WKB parsing WKBReader wkbReader = new WKBReader(); // 使用geotool的WKBReader 把字節數組轉成geometry對象。 byte[] wkb = new byte[geometryAsBytes.length - 4]; System.arraycopy(geometryAsBytes, 4, wkb, 0, wkb.length); dbGeometry = wkbReader.read(wkb); dbGeometry.setSRID(srid); return dbGeometry; }
完整使用例子,解析數據庫中的geometry對象,得到我們需要的點位數據。
//返回一個區域集合 區域由若干個點組成 public List < Area > geometryCollection2PressAreas(byte[] data) { List < Area > areas= new ArrayList < > (); try { //解析出空間集合層 GeometryCollection geometryCollection = (GeometryCollection) GeometryUtil.getGeometryByBytes(data); int geometrySize = geometryCollection.getNumGeometries(); for (int i1 = 0; i1 < geometrySize; i1++) { try { //解析出多邊形集合層 MultiPolygon multiPolygon = (MultiPolygon) geometryCollection.getGeometryN(i1); int size = (int) multiPolygon.getNumPoints(); for (int i = 0; i < size; i++) { try { //解析出多邊形 Polygon polygon = (Polygon) multiPolygon.getGeometryN(i); //解析出多邊形中的多個點位 Coordinate[] coordinates2 = polygon.getCoordinates(); int size2 = coordinates2.length; Area area = new Area(); area.area_pts = new ArrayList < > (); for (int j = 0; j < size2; j++) { //點位對象 就一個x,一個y數據 Point point = new Point(); point.x = coordinates2[j].x; point.y = coordinates2[j].y; //點位集合 area.area_pts.add(point); } areas.add(area); } catch (Exception e) { break; } } } catch (Exception e) { break; } } } catch (Exception e) { e.printStackTrace(); } return areas; }
到此,關于“java如何操作gis geometry類型數據”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。