Java postgis Geometry几何二进制流byte[]转wkt,转Geometry

Java postgis Geometry几何二进制流byte[]转wkt,wkt转Geometry

这篇博客将介绍Geometry几何二进制流及wkt及Geometry的互转,有俩种方式;

方法1、 st_astext 将二进制geom转为wkt,st_geomfromtext 将wkt转为二进制geom;
方法2、Java程序转,第一种比较简单,这篇博客将重点介绍方法2;

1. 效果图

方法一效果图如下:

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

在这里插入图片描述

方法二效果图如下:
在这里插入图片描述

2. 报错解决

报错一: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);
	}

3. 源码

		<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: <jtsutils工具类>  增加<Java转换byte[]为Geometery>
 *@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());
    }
}

参考

猜你喜欢

转载自blog.csdn.net/qq_40985985/article/details/131803657