java 操作gis geometry類型數(shù)據(jù)方式
java操作gis geometry類型數(shù)據(jù)
現(xiàn)在做的gis方面的業(yè)務,所以需要操作postgis中的geometry對象,找了很多的庫,比如geotools,但是莫名下載不下來。
還有就是jts,但是不好用,操作起來很復雜。找到了一個其他的類庫--geolatte-geom 和geolatte-geojson。
用于操作geometry和String以及json的互相轉化。而json和geojson個人理解就是輸出格式不同。多了一些geometry特有的屬性。
主要用于將String轉geometry對象、wkt和wkb方便好用。
pom.xml文件如下
<!-- 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) { ? ? ? ? // 模擬數(shù)據(jù)庫中直接取出的geometry對象值(他是二進制的) ? ? ? ? // WKT 是字符串形式,類似"POINT(1 2)"的形式 ? ? ? ? // 所以WKT轉 ?geometry,相當于是字符串轉geometry ? ? ? ? // WKB轉 ?geometry,相當于是字節(jié)轉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)); ? ? }
java讀取數(shù)據(jù)庫geometry
最近因為需要存一些經(jīng)緯度塊信息到數(shù)據(jù)庫,所以用到了mysql中的Geometry屬性(幾何對象)。在網(wǎng)上搜集了很多資料,到真正用的時候還是各種問題,所以下面推薦一種可能有點笨但是實用的方法(我的使用環(huán)境springboot工具是sts),下面就舉個例子來說明一下。
操作
先了解一下數(shù)據(jù)庫中空間數(shù)據(jù)類型有哪些
類型 | 說明 | 簡介 | 例子 |
Geometry | 間數(shù)據(jù) | 任意一種空間類型 | |
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 | 空間數(shù)據(jù)集合 | 集合類,可以包括多個點、線、多邊形 | GEOMETRYCOLLECTION(POINT(1 1), POINT(3 3), LINESTRING(1 1, 2 2)) |
接著往數(shù)據(jù)庫插入一個測試數(shù)據(jù),插入的是一個空間數(shù)據(jù)集合里面包含多個多邊形集合。
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))))'));
數(shù)據(jù)準備好了就準備開始準備讀取操作。
在pom.xml添加操作Geometry等對象的依賴。
<dependency> ? ? <groupId>com.vividsolutions</groupId> ? ? <artifactId>jts</artifactId> ? ? <version>1.13</version> </dependency>
本來先是想直接在實體類確定類型直接轉對象,但是用了后發(fā)現(xiàn)不行,所以我就直接設置成Object,在mysql中存儲Geometry使用的是二進制,所以下面直接把二進制通過jts轉成Geometry對象。
//private Geometry geom; 不可行 private Object geomAsBytes; //可行 ?最終得到的是一個byte數(shù)組 ?? ? //直接把數(shù)據(jù)庫中的byte[]轉Geometry對象 ? public static Geometry getGeometryByBytes( byte[] ?geometryAsBytes) throws Exception { ? ? ? ? ? ?Geometry dbGeometry = null; ? ? ? ? ? ? ? ?// 字節(jié)數(shù)組小于5,說明geometry有問題 ? ? ? ? ? ? ? ?if (geometryAsBytes.length < 5) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return null; ? ? ? ? ? ? ? ?} ? ? ? ? ? ? ? ? ?//這里是取字節(jié)數(shù)組的前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 把字節(jié)數(shù)組轉成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; ? ? ? ?}
完整使用例子,解析數(shù)據(jù)庫中的geometry對象,得到我們需要的點位數(shù)據(jù)。
//返回一個區(qū)域集合 ?區(qū)域由若干個點組成 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數(shù)據(jù) ?? ??? ??? ??? ??? ??? ??? ?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; }
小結一下
其實以前存地理信息都是用的自己組裝的json字符串,占用空間太大。最近才發(fā)現(xiàn)mysql還有地理空間數(shù)據(jù)這個好東(發(fā)現(xiàn)新大陸~),空間節(jié)省了,讀取也快了。不過讀取數(shù)據(jù)庫中數(shù)據(jù)不知道還有沒有更好的方法,這篇介紹的都是自己手動轉的對象,不過暫時先能用就好。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
springboot?整合?dubbo?的實現(xiàn)組聚合詳情
這篇文章主要介紹了springboot整合dubbo的實現(xiàn)組聚合詳情,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-07-07spring boot使用RabbitMQ實現(xiàn)topic 主題
本篇文章主要介紹了spring boot使用RabbitMQ實現(xiàn)topic 主題,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-03-03SpringBoot項目docker容器部署實現(xiàn)
本文主要介紹了SpringBoot項目docker容器部署實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-03-03