这篇博客将介绍Geometry几何二进制流及wkt及Geometry的互转,有俩种方式;
方法1、 st_astext 将二进制geom转为wkt,st_geomfromtext 将wkt转为二进制geom;
方法2、Java程序转,第一种比较简单,这篇博客将重点介绍方法2;
方法一效果图如下:
select point_geom,st_astext(point_geom) as point,
polygon_geom,st_astext(polygon_geom) as polygon,
line_geom,st_astext(line_geom) as line from
(select st_geomfromtext('Point(121.344239 31.292094 40.54)',4326) as point_geom,
ST_GeomFromText('MULTIPOLYGON(((116.25853747 39.97870959,116.2585059 39.97869392,116.25845554 39.97875528,116.25848712 39.97877096,116.25853747 39.97870959)))') as multipoly_Geom,
st_geomfromtext('LINESTRING(121.344239 31.292094, 121.345239 31.293094)',4326) as line_geom,
st_geomfromtext('POLYGON ((121.3450796849 31.29321148221, 121.34539831471 31.29297651758, 121.34439831415 31.29197651879, 121.34407968546 31.292211481, 121.3450796849 31.29321148221))')
as polygon_geom) t
报错一:org.locationtech.jts.io.ParseException: Unknown WKB type 104
org.vividsolutions.jts.io.ParseException: Unknown WKB type 48
报错二:geotoolsError: Unknown WKB type 48
vividsolutionsError: Unknown WKB type 48
locationtechError: Unknown WKB type 592
主要是读取到的bytes有问题,解决:使用 org.geotools.data.postgis.WKBReader 将16进制转正确的二进制流
// **不能少了这一句
byte[] bytes = org.geotools.data.postgis.WKBReader.hexToBytes(geomBytes);
// 下边转用org.geotools.data.postgis.WKBReader、com.vividsolutions.jts.io.WKBReader、org.locationtech.jts.io.WKBReader转都可以
org.geotools.data.postgis.WKBReader wkbReader = new org.geotools.data.postgis.WKBReader();
Geometry geo = null;
try {
geo = wkbReader.read(bytes);
} catch (ParseException e) {
throw new RuntimeException(e);
}
<dependency>
<groupId>com.vividsolutions</groupId>
<artifactId>jts</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>org.locationtech.jts</groupId>
<artifactId>jts-core</artifactId>
<version>1.18.1</version>
</dependency>
<dependency>
<groupId>org.geotools.jdbc</groupId>
<artifactId>gt-jdbc-postgis</artifactId>
<version>17.1</version>
</dependency>
import com.vividsolutions.jts.geom.Point;
import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.util.GeometricShapeFactory;
import java.util.List;
/*************************************
*Class Name: JtsUtils
*Description: 增加
*@author: Seminar
*@create: 2023/3/31
*@since 1.0.0
*************************************/
public class JtsUtils {
static GeometryFactory factory = new GeometryFactory(new PrecisionModel(PrecisionModel.FLOATING), 4326);
public static Point createPoint(Coordinate pt) {
return factory.createPoint(pt);
}
public static double distance(Point p1, Point p2) {
return distance(p1.getCoordinate(), p2.getCoordinate());
}
public static double distance(Coordinate p1, Coordinate p2) {
double lat1 = Math.toRadians(p1.y);
double lon1 = Math.toRadians(p1.x);
double lat2 = Math.toRadians(p2.y);
double lon2 = Math.toRadians(p2.x);
double vLon = Math.abs(lon1 - lon2);
double vLat = Math.abs(lat1 - lat2);
double h = haverSin(vLat) + Math.cos(lat1) * Math.cos(lat2) * haverSin(vLon);
double distance = 1.2756274E7 * Math.asin(Math.sqrt(h));
return distance;
}
private static double haverSin(double theta) {
double v = Math.sin(theta / 2.0);
return v * v;
}
public static double distance(LineString line) {
Coordinate[] coors = line.getCoordinates();
return distance(coors);
}
public static double distance(Coordinate[] coors) {
double lineDist = 0.0;
for (int i = 1; i < coors.length; ++i) {
Coordinate coor1 = coors[i - 1];
Coordinate coor2 = coors[i];
if (coor1.x == coor2.x && coor1.y == coor2.y) {
lineDist += 0.0;
} else {
lineDist += distance(coor1, coor2);
}
}
return lineDist;
}
public static double distance(List<Coordinate> coors) {
double lineDist = 0.0;
for (int i = 1; i < coors.size(); ++i) {
Coordinate coor1 = (Coordinate) coors.get(i - 1);
Coordinate coor2 = (Coordinate) coors.get(i);
if (coor1.x == coor2.x && coor1.y == coor2.y) {
lineDist += 0.0;
} else {
lineDist += distance(coor1, coor2);
}
}
return lineDist;
}
public static Geometry createGeometryByWKT(String wkt) throws ParseException {
WKTReader reader = new WKTReader(factory);
Geometry geometry = reader.read(wkt);
return geometry;
}
public static LineString createLineStringByWKT(String wkt) throws ParseException {
WKTReader reader = new WKTReader(factory);
LineString line = (LineString) reader.read(wkt);
return line;
}
public static Point createPointByWKT(String pointWkt) {
WKTReader reader = new WKTReader(factory);
Point point = null;
try {
point = (Point) reader.read(pointWkt);
} catch (ParseException var4) {
var4.printStackTrace();
}
return point;
}
public static Polygon createPolygonByWKT(String polygonWkt) {
WKTReader reader = new WKTReader(factory);
Polygon polygon = null;
try {
polygon = (Polygon) reader.read(polygonWkt);
} catch (ParseException var4) {
var4.printStackTrace();
}
return polygon;
}
public static Geometry createCircle(double x, double y, double radius) {
GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
shapeFactory.setNumPoints(128);
shapeFactory.setCentre(new Coordinate(x, y));
shapeFactory.setSize(radius * 2.0);
return shapeFactory.createCircle();
}
/**
* 二进制GeometryBytes 转Geometry
*
* @param geomBytes
* @return
*/
private static Geometry bytesToGeometry(String geomBytes) {
// 不能少了这一句
byte[] bytes = org.geotools.data.postgis.WKBReader.hexToBytes(geomBytes);
// 下边转用org.geotools.data.postgis.WKBReader、com.vividsolutions.jts.io.WKBReader、org.locationtech.jts.io.WKBReader转都可以
Geometry geo = null;
try {
org.geotools.data.postgis.WKBReader wkbReader = new org.geotools.data.postgis.WKBReader();
geo = wkbReader.read(bytes);
System.out.println("geotools: " + geo.getCoordinates().length);
} catch (ParseException e) {
System.err.println("geotoolsError: " + e.getMessage());
}
try {
com.vividsolutions.jts.io.WKBReader wkbReader1 = new com.vividsolutions.jts.io.WKBReader();
Geometry geometry = wkbReader1.read(bytes);
System.out.println("vividsolutions: " + geometry.getCoordinates().length);
} catch (ParseException e) {
System.err.println("vividsolutionsError: " + e.getMessage());
}
try {
org.locationtech.jts.io.WKBReader wkbReader2 = new org.locationtech.jts.io.WKBReader();
org.locationtech.jts.geom.Geometry geometry = wkbReader2.read(bytes);
System.out.println("locationtech: " + geometry.getCoordinates().length);
} catch (org.locationtech.jts.io.ParseException e) {
System.err.println("locationtechError: " + e.getMessage());
}
return geo;
}
private static Geometry bytesToGeometryError(String pointBytes) {
byte[] bytes = pointBytes.getBytes();
Geometry geo = null;
try {
org.geotools.data.postgis.WKBReader wkbReader = new org.geotools.data.postgis.WKBReader();
geo = wkbReader.read(bytes);
System.out.println("geotools: " + geo.getCoordinates().length);
} catch (ParseException e) {
System.err.println("geotoolsError: " + e.getMessage());
}
try {
com.vividsolutions.jts.io.WKBReader wkbReader1 = new com.vividsolutions.jts.io.WKBReader();
Geometry geometry = wkbReader1.read(bytes);
System.out.println("vividsolutions: " + geometry.getCoordinates().length);
} catch (ParseException e) {
System.err.println("vividsolutionsError: " + e.getMessage());
}
try {
org.locationtech.jts.io.WKBReader wkbReader2 = new org.locationtech.jts.io.WKBReader();
org.locationtech.jts.geom.Geometry geometry = wkbReader2.read(bytes);
System.out.println("locationtech: " + geometry.getCoordinates().length);
} catch (org.locationtech.jts.io.ParseException e) {
System.err.println("locationtechError: " + e.getMessage());
e.printStackTrace();
}
return geo;
}
public static void main(String[] args) throws ParseException {
String lineString = "LINESTRING(118.810687877626 31.9125455099001,118.809488683078 31.9106356486321)";
// 纬度lat,经度lng,纬度,经度
//coordinate.y对应纬度
System.out.println("dis: " + distance(createLineStringByWKT(lineString)) + "m");
String pointBytes = "01010000A0E61000007FC0030308565E409A5B21ACC64A3F4085EB51B81E454440";
String multiBytes = "01030000000100000005000000354A1AC915565E4055E75EE80F4B3F40787188011B565E4088805182004B3F4098043A9F0A565E402A671FF9BE4A3F403211CD6605565E402569225FCE4A3F40354A1AC915565E4055E75EE80F4B3F40";
String polyBytes = "0103000020E61000000100000005000000354A1AC915565E4055E75EE80F4B3F40787188011B565E4088805182004B3F4098043A9F0A565E402A671FF9BE4A3F403211CD6605565E402569225FCE4A3F40354A1AC915565E4055E75EE80F4B3F40";
String lineBytes = "0102000020E6100000020000007FC0030308565E409A5B21ACC64A3F407193516518565E4061A75835084B3F40";
// 报错复现
Geometry geom = bytesToGeometryError(pointBytes);
Geometry pointGeom = bytesToGeometry(pointBytes);
Geometry multiPolyGeom = bytesToGeometry(multiBytes);
Geometry lineGeom = bytesToGeometry(lineBytes);
Geometry polyGeom = bytesToGeometry(polyBytes);
System.out.println("pointGeom: " + pointGeom.toText());
System.out.println("multipolyGeom: " + multiPolyGeom.toText());
System.out.println("lineGeom: " + lineGeom.toText());
System.out.println("polyGeom: " + polyGeom.toText());
}
}