java 操作gis geometry類型數(shù)據(jù)方式
java操作gis geometry類型數(shù)據(jù)
現(xiàn)在做的gis方面的業(yè)務(wù),所以需要操作postgis中的geometry對象,找了很多的庫,比如geotools,但是莫名下載不下來。
還有就是jts,但是不好用,操作起來很復(fù)雜。找到了一個(gè)其他的類庫--geolatte-geom 和geolatte-geojson。
用于操作geometry和String以及json的互相轉(zhuǎn)化。而json和geojson個(gè)人理解就是輸出格式不同。多了一些geometry特有的屬性。
主要用于將String轉(zhuǎn)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對象值(他是二進(jìn)制的) ? ? ? ? // WKT 是字符串形式,類似"POINT(1 2)"的形式 ? ? ? ? // 所以WKT轉(zhuǎn) ?geometry,相當(dāng)于是字符串轉(zhuǎn)geometry ? ? ? ? // WKB轉(zhuǎn) ?geometry,相當(dāng)于是字節(jié)轉(zhuǎn)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
最近因?yàn)樾枰嬉恍┙?jīng)緯度塊信息到數(shù)據(jù)庫,所以用到了mysql中的Geometry屬性(幾何對象)。在網(wǎng)上搜集了很多資料,到真正用的時(shí)候還是各種問題,所以下面推薦一種可能有點(diǎn)笨但是實(shí)用的方法(我的使用環(huán)境springboot工具是sts),下面就舉個(gè)例子來說明一下。
操作
先了解一下數(shù)據(jù)庫中空間數(shù)據(jù)類型有哪些
類型 | 說明 | 簡介 | 例子 |
Geometry | 間數(shù)據(jù) | 任意一種空間類型 | |
Point | 點(diǎn) | 坐標(biāo)值 | POINT(104.00924 30.46872) |
LineString | 線 | 線,由一系列點(diǎn)連接而成 | LINESTRING(1 1, 1 1, 1 1) |
Polygon | 多邊形 | 由多條線組成 | POLYGON((1 1, 2 2, 3 3, 4 4, 5 5)) |
MultiPoint | 點(diǎn)集合 | 集合類,包含多個(gè)點(diǎn) | MULTIPOINT(1 1, 2 2, 1 1) |
MultiLineString | 線集合 | 集合類,包含多條線 | MULTILINESTRING((1 1, 2 2), (1 1, 1 1)) |
MultiPolygon | 多邊形集合 | 集合類,包含多個(gè)多邊形 | MULTIPOLYGON(((0 0, 1 0, 1 1, 0 1, 0 0)), ((1 1, 1 1, 1 1, 1 1, 1 1))) |
GeometryCollection | 空間數(shù)據(jù)集合 | 集合類,可以包括多個(gè)點(diǎn)、線、多邊形 | GEOMETRYCOLLECTION(POINT(1 1), POINT(3 3), LINESTRING(1 1, 2 2)) |
接著往數(shù)據(jù)庫插入一個(gè)測試數(shù)據(jù),插入的是一個(gè)空間數(shù)據(jù)集合里面包含多個(gè)多邊形集合。
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ù)準(zhǔn)備好了就準(zhǔn)備開始準(zhǔn)備讀取操作。
在pom.xml添加操作Geometry等對象的依賴。
<dependency> ? ? <groupId>com.vividsolutions</groupId> ? ? <artifactId>jts</artifactId> ? ? <version>1.13</version> </dependency>
本來先是想直接在實(shí)體類確定類型直接轉(zhuǎn)對象,但是用了后發(fā)現(xiàn)不行,所以我就直接設(shè)置成Object,在mysql中存儲Geometry使用的是二進(jìn)制,所以下面直接把二進(jìn)制通過jts轉(zhuǎn)成Geometry對象。
//private Geometry geom; 不可行 private Object geomAsBytes; //可行 ?最終得到的是一個(gè)byte數(shù)組 ?? ? //直接把數(shù)據(jù)庫中的byte[]轉(zhuǎn)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個(gè)來解析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ù)組轉(zhuǎn)成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對象,得到我們需要的點(diǎn)位數(shù)據(jù)。
//返回一個(gè)區(qū)域集合 ?區(qū)域由若干個(gè)點(diǎn)組成 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); ? ? ? ? ? ? ? ? ? ? ? ? //解析出多邊形中的多個(gè)點(diǎn)位 ?? ??? ??? ??? ??? ??? ?Coordinate[] coordinates2 = polygon.getCoordinates(); ?? ??? ??? ??? ??? ??? ?int size2 = coordinates2.length; ?? ??? ??? ??? ??? ??? ?Area area = new Area(); ?? ??? ??? ??? ??? ??? ?area.area_pts = new ArrayList < > (); ?? ??? ??? ??? ??? ??? ?for (int j = 0; j < size2; j++) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? //點(diǎn)位對象 就一個(gè)x,一個(gè)y數(shù)據(jù) ?? ??? ??? ??? ??? ??? ??? ?Point point = new Point(); ?? ??? ??? ??? ??? ??? ??? ?point.x = coordinates2[j].x; ?? ??? ??? ??? ??? ??? ??? ?point.y = coordinates2[j].y; ? ? ? ? ? ? ? ? ? ? ? ? ? ? //點(diǎn)位集合 ?? ??? ??? ??? ??? ??? ??? ?area.area_pts.add(point); ?? ??? ??? ??? ??? ??? ?} ?? ??? ??? ??? ??? ??? ?areas.add(area); ?? ??? ??? ??? ??? ?} catch (Exception e) { ?? ??? ??? ??? ??? ??? ?break; ?? ??? ??? ??? ??? ?} ?? ??? ??? ??? ?} ?? ??? ??? ?} catch (Exception e) { ?? ??? ??? ??? ?break; ?? ??? ??? ?} ?? ??? ?} ?? ?} catch (Exception e) { ?? ??? ?e.printStackTrace(); ?? ?} ?? ?return areas; }
小結(jié)一下
其實(shí)以前存地理信息都是用的自己組裝的json字符串,占用空間太大。最近才發(fā)現(xiàn)mysql還有地理空間數(shù)據(jù)這個(gè)好東(發(fā)現(xiàn)新大陸~),空間節(jié)省了,讀取也快了。不過讀取數(shù)據(jù)庫中數(shù)據(jù)不知道還有沒有更好的方法,這篇介紹的都是自己手動轉(zhuǎn)的對象,不過暫時(shí)先能用就好。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot項(xiàng)目如何使用切面記錄用戶操作日志
這篇文章主要介紹了springboot項(xiàng)目如何使用切面記錄用戶操作日志,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-10-10springboot?整合?dubbo?的實(shí)現(xiàn)組聚合詳情
這篇文章主要介紹了springboot整合dubbo的實(shí)現(xiàn)組聚合詳情,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-07-07Java優(yōu)先隊(duì)列?priority?queue
本文主要介紹了Java優(yōu)先隊(duì)列?priority?queue,優(yōu)先隊(duì)列是一種特殊的數(shù)據(jù)結(jié)構(gòu)隊(duì)列中每一個(gè)元素都被分配到一個(gè)優(yōu)先權(quán)值,出隊(duì)順序按照優(yōu)先權(quán)值來劃分。一般有兩種出隊(duì)順序高優(yōu)先權(quán)出隊(duì)或低優(yōu)先權(quán)出隊(duì),想了解具體內(nèi)容的小伙伴可以參考下文內(nèi)容,希望對你有所幫助2021-12-12通過實(shí)例學(xué)習(xí)JAVA對象轉(zhuǎn)成XML輸出
這篇文章主要介紹了通過實(shí)例學(xué)習(xí)JAVA對象轉(zhuǎn)成XML輸出,做流程圖的項(xiàng)目時(shí),新的流程定義為xml的,需要對xml與java對象進(jìn)行互轉(zhuǎn),下面我們來深入學(xué)習(xí),需要的朋友可以參考下2019-06-06IDEA在一個(gè)項(xiàng)目空間下管理多個(gè)項(xiàng)目的操作方法
這篇文章主要介紹了IDEA如何在一個(gè)項(xiàng)目空間下管理多個(gè)項(xiàng)目,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-04-04spring boot使用RabbitMQ實(shí)現(xiàn)topic 主題
本篇文章主要介紹了spring boot使用RabbitMQ實(shí)現(xiàn)topic 主題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03SpringBoot項(xiàng)目docker容器部署實(shí)現(xiàn)
本文主要介紹了SpringBoot項(xiàng)目docker容器部署實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03