溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

java如何操作gis?geometry類型數(shù)據(jù)

發(fā)布時(shí)間:2022-03-11 16:24:48 來源:億速云 閱讀:990 作者:iii 欄目:開發(fā)技術(shù)

這篇文章主要介紹“java如何操作gis geometry類型數(shù)據(jù)”,在日常操作中,相信很多人在java如何操作gis geometry類型數(shù)據(jù)問題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”java如何操作gis geometry類型數(shù)據(jù)”的疑惑有所幫助!接下來,請(qǐng)跟著小編一起來學(xué)習(xí)吧!

java操作gis geometry類型數(shù)據(jù)

現(xiàn)在做的gis方面的業(yè)務(wù),所以需要操作postgis中的geometry對(duì)象,找了很多的庫,比如geotools,但是莫名下載不下來。

還有就是jts,但是不好用,操作起來很復(fù)雜。找到了一個(gè)其他的類庫--geolatte-geom 和geolatte-geojson。

用于操作geometry和String以及json的互相轉(zhuǎn)化。而json和geojson個(gè)人理解就是輸出格式不同。多了一些geometry特有的屬性。

主要用于將String轉(zhuǎn)geometry對(duì)象、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對(duì)象值(他是二進(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對(duì)象和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屬性(幾何對(duì)象)。在網(wǎng)上搜集了很多資料,到真正用的時(shí)候還是各種問題,所以下面推薦一種可能有點(diǎn)笨但是實(shí)用的方法(我的使用環(huán)境springboot工具是sts),下面就舉個(gè)例子來說明一下。

操作

先了解一下數(shù)據(jù)庫中空間數(shù)據(jù)類型有哪些

類型說明簡(jiǎn)介例子
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è)測(cè)試數(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等對(duì)象的依賴。

<dependency>
    <groupId>com.vividsolutions</groupId>
    <artifactId>jts</artifactId>
    <version>1.13</version>
</dependency>

本來先是想直接在實(shí)體類確定類型直接轉(zhuǎn)對(duì)象,但是用了后發(fā)現(xiàn)不行,所以我就直接設(shè)置成Object,在mysql中存儲(chǔ)Geometry使用的是二進(jìn)制,所以下面直接把二進(jìn)制通過jts轉(zhuǎn)成Geometry對(duì)象。

//private Geometry geom; 不可行
private Object geomAsBytes; //可行  最終得到的是一個(gè)byte數(shù)組
     //直接把數(shù)據(jù)庫中的byte[]轉(zhuǎn)Geometry對(duì)象
  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對(duì)象。
               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對(duì)象,得到我們需要的點(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)位對(duì)象 就一個(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;
}

到此,關(guān)于“java如何操作gis geometry類型數(shù)據(jù)”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)砀鄬?shí)用的文章!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI