java 操作gis geometry类型数据方式

目录
  • java操作gisgeometry类型数据
    • pom.xml文件如下
  • java读取数据库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文件如下

<!-- 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读取数据库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等对象的依赖。

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

本来先是想直接在实体类确定类型直接转对象,但是用了后发现不行,所以我就直接设置成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;
}

小结一下

其实以前存地理信息都是用的自己组装的json字符串,占用空间太大。最近才发现mysql还有地理空间数据这个好东(发现新大陆~),空间节省了,读取也快了。不过读取数据库中数据不知道还有没有更好的方法,这篇介绍的都是自己手动转的对象,不过暂时先能用就好。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • java中ResultSet遍历数据操作

    1.查找数据库中表的列名 <pre name="code" class="html">String sql = "select *from tblmetadatainfo"; ResultSet rs = MySqlHelper.executeQuery(sql, null); String str=""; try { ResultSetMetaData rsmd = rs.getMetaData(); for (

  • Java流操作之数据流实例代码

    实例1: package dataInputStreamAndPrintStreamDemo; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.PrintStream; //示范如何自键

  • JAVA如何使用Math类操作数据

    Math 类位于 java.lang 包中,包含用于执行基本数学运算的方法, Math 类的所有方法都是静态方法,所以使用该类中的方法时,可以直接使用类名.方法名,如: Math.round(); 常用的方法: 通过案例我们来认识一下他们的使用吧!! 运行结果: PS: Math 类还提供了许多其他方法,各位小伙伴们可以注意关注 wiki ,查阅更多信息 示例: 定义一个包含 10 个元素的整型数组,通过随机产生 10 以内的随机数,给数组中的每个元素赋值,并输出结果 输出: 6 0 6 3 2

  • Java 8 Stream操作类型及peek示例解析

    简介 java 8 stream作为流式操作有两种操作类型,中间操作和终止操作.这两种有什么区别呢? 我们看一个peek的例子: Stream<String> stream = Stream.of("one", "two", "three","four"); stream.peek(System.out::println); 上面的例子中,我们的本意是打印出Stream的值,但实际上没有任何输出. 为什么呢? 中间

  • java 操作gis geometry类型数据方式

    目录 java操作gisgeometry类型数据 pom.xml文件如下 java读取数据库geometry 操作 小结一下 java操作gis geometry类型数据 现在做的gis方面的业务,所以需要操作postgis中的geometry对象,找了很多的库,比如geotools,但是莫名下载不下来. 还有就是jts,但是不好用,操作起来很复杂.找到了一个其他的类库--geolatte-geom 和geolatte-geojson. 用于操作geometry和String以及json的互相转

  • Java操作Mongodb数据库实现数据的增删查改功能示例

    本文实例讲述了Java操作Mongodb数据库实现数据的增删查改功能.分享给大家供大家参考,具体如下: 首先,我们在windows下安装mongodb数据库,安装教程可查看前面一篇文章:http://www.jb51.net/article/85605.htm 代码如下: package io.mogo; import java.util.Map; import org.apache.commons.lang3.StringUtils; import com.mongodb.BasicDBObj

  • C#使用System.Buffer以字节数组Byte[]操作基元类型数据

    1. Buffer.ByteLength:计算基元类型数组累计有多少字节组成. 该方法结果等于"基元类型字节长度 * 数组长度" var bytes = new byte[] { 1, 2, 3 }; var shorts = new short[] { 1, 2, 3 }; var ints = new int[] { 1, 2, 3 }; Console.WriteLine(Buffer.ByteLength(bytes)); // 1 byte * 3 elements = 3

  • Mysql字段和java实体类属性类型匹配方式

    Mysql字段和java实体类属性类型匹配 参见下图: 数据库字段转实体类字段 DROP FUNCTION IF EXISTS f_spiltStr; CREATE FUNCTION `f_spiltStr`(DATA1 varchar(50)) RETURNS varchar(1000) CHARSET utf8 BEGIN SET @length = LENGTH(DATA1) - LENGTH(REPLACE(DATA1,'_','')); SET @i = 1; set @result

  • Java 多层嵌套JSON类型数据全面解析

    目录 多层嵌套JSON类型数据解析 以下举例数据结构 解析代码 json解析多层嵌套并转为对应类(List) Json(随便扒的格式,将就看~) 关键依赖 JAVABEAN转JSONObject 多层嵌套JSON类型数据解析 简单来说: “key”:“value” --> 此时value为String“key":0 --> 此时value为int“key”:{“k1”:“v1”} --> 此时value为JSONObject“key”:[v] --> 此时value为JS

  • 如何使用Java操作Zookeeper

    简介 Java操作Zookeeper有很多种方式,如zookeeper.zkclient.curator等等,下面介绍下使用zkclient的方式操作Zookeeper. Maven依赖: <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.11</version> </dependency&g

  • SpringMVC接收java.util.Date类型数据的2种方式小结

    SpringMVC接收java.util.Date类型数据 在Controller中如下定义方法 public PassQueryRequest trade(@ModelAttribute PassQueryRequest tradeRequest, @RequestParam(value="startDate", required=true)Date startDate, @RequestParam(value="endDate", required=true)D

  • java long 类型数据的赋值方式

    目录 java long类型数据的赋值 问题 解决 把null赋值给long产生的奇怪问题 问题产生的原因 java long类型数据的赋值 问题 当程序出现较大的数值的时候(超过int类型:-2^31 到 2^31 - 1间),就需要将类型变成Long类型. long l = 1507772738542; Long l1 = (long)1507772738542; 以上的写法,在编译的时候会报错, 大概的意思就是数据太长,超过了int类型的值. 解决 Long l = 15077727385

  • Java Spring MVC获取请求数据详解操作

    目录 1. 获得请求参数 2. 获得基本类型参数 3. 获得POJO类型参数 4. 获得数组类型参数 5. 获得集合类型参数 6. 请求数据乱码问题 7. 参数绑定注解 @requestParam 8. 获得Restful风格的参数 9. 自定义类型转换器 1.定义转换器类实现Converter接口 2.在配置文件中声明转换器 3.在<annotation-driven>中引用转换器 10. 获得Servlet相关API 11. 获得请求头 11.1 @RequestHeader 11.2 @

  • Java操作Jenkins操作凭证(Credential)信息方式

    jenkins-client包的api中大部分的操作是支持的,但有一些特殊操作,比如需要操作jenkins的Credential凭据信息,或是希望使用java修改Jenkins的系统配置,类似这样的操作在api中是没有的. 但依然可以通过rest的方式完成这些操作 当新增一条凭据信息时可以通过浏览器的网络监控看到他的请求内容 可以看到操作凭证的请求地址.请求参数列表,这里的参数列表的参数非常的多,但实际上在源码中读取的只有红框中的json的这一段.用postman来模拟调用一下 调用后会发现是失

随机推荐