吉安感知网项目-后端
linwei
2026-02-09 4c4a505ba4c0f10cededf701fc170c0c7b76fc5e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package org.sxkj.gd.config;
 
 
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryFactory;
import org.locationtech.jts.geom.PrecisionModel;
import org.locationtech.jts.io.*;
 
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
 
@MappedTypes({String.class})
@MappedJdbcTypes({JdbcType.OTHER})
public class GeometryTypeHandler extends BaseTypeHandler<String> {
 
 
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, String s, JdbcType jdbcType) throws SQLException {
        if (s == null || s.isEmpty()) {
            preparedStatement.setNull(i, jdbcType.TYPE_CODE);
            return;
        }
 
        Geometry geo = null;
        try {
            // String转Geometry
            geo = new WKTReader(new GeometryFactory(new PrecisionModel())).read(s);
            if (geo == null) {
                preparedStatement.setNull(i, jdbcType.TYPE_CODE);
                return;
            }
            // 设置SRID为WGS84 (4326)
            geo.setSRID(4326);
            // Geometry转WKB,使用大端序(PostgreSQL 期望的格式),并包含SRID信息(EWKB格式)
            byte[] wkb = new WKBWriter(2, ByteOrderValues.BIG_ENDIAN, true).write(geo);
            preparedStatement.setBytes(i, wkb);
        } catch (ParseException e) {
            // 解析失败时设置为null
            preparedStatement.setNull(i, jdbcType.TYPE_CODE);
        }
    }
 
 
    @Override
    public String getNullableResult(ResultSet resultSet, String s) {
        try (InputStream inputStream = resultSet.getBinaryStream(s)) {
            Geometry geo = getGeometryFromInputStream(inputStream);
            if (geo != null) {
                return geo.toString();
            }
        } catch (Exception e) {
 
        }
        return null;
    }
 
    @Override
    public String getNullableResult(ResultSet resultSet, int i) {
        try (InputStream inputStream = resultSet.getBinaryStream(i)) {
            Geometry geo = getGeometryFromInputStream(inputStream);
            if (geo != null) {
                return geo.toString();
            }
        } catch (Exception e) {
 
        }
        return null;
    }
 
    @Override
    public String getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        try {
            // 使用 getBlob 方法获取 Blob 对象
            java.sql.Blob blob = callableStatement.getBlob(i);
            if (blob != null) {
                try (InputStream inputStream = blob.getBinaryStream()) {
                    Geometry geo = getGeometryFromInputStream(inputStream);
                    if (geo != null) {
                        return geo.toString();
                    }
                }
            }
        } catch (Exception e) {
            // 处理异常
        }
        return null;
    }
 
    /**
     * 流 转 geometry
     */
    private Geometry getGeometryFromInputStream(InputStream inputStream) throws Exception {
 
        Geometry dbGeometry = null;
 
        if (inputStream != null) {
            // 二进制流转成字节数组
            byte[] buffer = new byte[255];
 
            int bytesRead = 0;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            while ((bytesRead = inputStream.read(buffer)) != -1) {
                baos.write(buffer, 0, bytesRead);
            }
            // 得到字节数组
            byte[] geometryAsBytes = baos.toByteArray();
            // 字节数组小于5 异常
            if (geometryAsBytes.length < 5) {
 
            }
 
            // 字节数组前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);
                }
            }
 
            WKBReader wkbReader = new WKBReader();
            // 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;
    }
}