Home  >  Article  >  Java  >  How to operate GIS Geometry type data in Java?

How to operate GIS Geometry type data in Java?

王林
王林forward
2023-04-22 23:10:061764browse

java operates gis geometry type data

I am currently doing gis business, so I need to operate the geometry object in postgis. I have found a lot of libraries, such as geotools, but I can't download it for some reason.

There is also jts, but it is not easy to use and very complicated to operate. Found another class library--geolatte-geom and geolatte-geojson.

Used to operate the conversion between geometry, String and json. My personal understanding of json and geojson is that the output formats are different. There are some more geometry-specific properties.

Mainly used to convert String into geometry objects, wkt and wkb are convenient and easy to use.

The pom.xml file is as follows

<!-- 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));
    }

java reads database geometry

Recently, because I need to save some longitude and latitude block information to the database, I used the Geometry attribute (geometry) in mysql object). I have collected a lot of information on the Internet, but there are still various problems when I actually use it, so I recommend a method that may be a bit stupid but practical (my usage environment springboot tool is sts). Here is an example to illustrate.

Operation

First understand what spatial data types are in the database

##GeometrySpace dataAny space typePointPointCoordinate valuePOINT(104.00924 30.46872)##LineString PolygonMultiPointMultiLineStringMultiPolygonGeometryCollection#Then insert a test data into the database. What is inserted is a spatial data collection containing multiple polygon collections.
Type Description Introduction Example
Line Line is formed by connecting a series of points LINESTRING(1 1, 1 1, 1 1)
Polygon is composed of multiple lines POLYGON((1 1, 2 2, 3 3, 4 4, 5 5))
Point collection Collection class, containing multiple points MULTIPOINT(1 1, 2 2, 1 1)
Line collection Collection class, containing multiple lines MULTILINESTRING((1 1, 2 2), (1 1, 1 1))
Polygon collection Collection class, containing multiple polygons MULTIPOLYGON(((0 0 , 1 0, 1 1, 0 1, 0 0)), ((1 1, 1 1, 1 1, 1 1, 1 1)))
Spatial data collection Collection class, which can include multiple points, lines, and polygons 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)),((1 04.009241 30.468972,104.009229 30.468961,104.009225 30.468997))),MULTIPOLYGON(((104.009241 30.468972,104.009229 30.468961,104.009225 30.468997)))'));

When the data is ready, start preparing for the read operation.

Add dependencies for operating objects such as Geometry in pom.xml.

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

Originally, I wanted to directly determine the type in the entity class and convert it directly to the object, but after using it, I found that it didn’t work, so I directly set it to Object. Binary is used to store Geometry in mysql, so I directly convert the binary Convert to Geometry object through jts.

//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;
       }

Complete usage example, parse the geometry object in the database and get the point data we need.

//返回一个区域集合  区域由若干个点组成
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;
}

The above is the detailed content of How to operate GIS Geometry type data in Java?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete