現在做的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),下面就舉個例子來說明一下。
先了解資料庫中空間資料型別有哪些
類型 | ##說明簡介 | 範例 | |
#間資料 | 任一空間類型 | ||
點 | #座標值 | #POINT(104.00924 30.46872) | |
線 | 線,由一系列點連接而成 | LINESTRING(1 1, 1 1, 1 1) | |
多邊形 | 由多條線組成 | POLYGON((1 1, 2 2, 3 3, 4 4, 5 5)) | |
點集合 | 集合類,包含多個點 | MULTIPOINT(1 1, 2 2, 1 1) | |
線集合 | 集合類,包含多條線 | MULTILINESTRING((1 1, 2 2), (1 1, 1 1)) | |
多邊形集合 | 集合類,包含多個多邊形 | MULTIPOLYGON(((0 0 , 1 0, 1 1, 0 1, 0 0)), ((1 1, 1 1, 1 1, 1 1, 1 1))) | |
空間資料集合 | 集合類,可以包含多個點、線、多邊形 | 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.468496950. 4.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>
//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; }
//返回一个区域集合 区域由若干个点组成 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類型資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!