千家信息网

java如何操作gis geometry类型数据

发表于:2025-01-17 作者:千家信息网编辑
千家信息网最后更新 2025年01月17日,这篇文章主要介绍"java如何操作gis geometry类型数据",在日常操作中,相信很多人在java如何操作gis geometry类型数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作
千家信息网最后更新 2025年01月17日java如何操作gis geometry类型数据

这篇文章主要介绍"java如何操作gis geometry类型数据",在日常操作中,相信很多人在java如何操作gis geometry类型数据问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"java如何操作gis geometry类型数据"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

java操作gis geometry类型数据

现在做的gis方面的业务,所以需要操作postgis中的geometry对象,找了很多的库,比如geotools,但是莫名下载不下来。

还有就是jts,但是不好用,操作起来很复杂。找到了一个其他的类库--geolatte-geom 和geolatte-geojson。

用于操作geometry和String以及json的互相转化。而json和geojson个人理解就是输出格式不同。多了一些geometry特有的属性。

主要用于将String转geometry对象、wkt和wkb方便好用。

pom.xml文件如下

    org.geolatte    geolatte-geom    1.6.0     org.geolatte    geolatte-geojson    1.6.0
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读取数据库geometry

最近因为需要存一些经纬度块信息到数据库,所以用到了mysql中的Geometry属性(几何对象)。在网上搜集了很多资料,到真正用的时候还是各种问题,所以下面推荐一种可能有点笨但是实用的方法(我的使用环境springboot工具是sts),下面就举个例子来说明一下。

操作

先了解一下数据库中空间数据类型有哪些

类型说明简介例子
Geometry间数据任意一种空间类型
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空间数据集合集合类,可以包括多个点、线、多边形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)),((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))))'));

数据准备好了就准备开始准备读取操作。

在pom.xml添加操作Geometry等对象的依赖。

    com.vividsolutions    jts    1.13

本来先是想直接在实体类确定类型直接转对象,但是用了后发现不行,所以我就直接设置成Object,在mysql中存储Geometry使用的是二进制,所以下面直接把二进制通过jts转成Geometry对象。

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

完整使用例子,解析数据库中的geometry对象,得到我们需要的点位数据。

//返回一个区域集合  区域由若干个点组成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类型数据"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!

0