Python 官方文档:入门教程 => 点击学习
目录java操作GISgeometry类型数据pom.xml文件如下java读取数据库geometry操作小结一下java操作gis geometry类型数据 现在做的gis方面的业
现在做的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),下面就举个例子来说明一下。
先了解一下数据库中空间数据类型有哪些
类型 | 说明 | 简介 | 例子 |
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还有地理空间数据这个好东(发现新大陆~),空间节省了,读取也快了。不过读取数据库中数据不知道还有没有更好的方法,这篇介绍的都是自己手动转的对象,不过暂时先能用就好。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。
--结束END--
本文标题: java操作gisgeometry类型数据方式
本文链接: https://www.lsjlt.com/news/142206.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0