吉安感知网项目-后端
linwei
2026-04-07 fa1e221e3db35b55eddcd4459f533ca650b59a38
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
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 {
 
 
        Geometry geo = null;
        try {
            // String转Geometry
            geo = new WKTReader(new GeometryFactory(new PrecisionModel())).read(s);
 
            // 解析SRID(如果字符串包含SRID=4326;前缀)
            int srid = 4326; // 默认使用WGS84坐标系
            String wktString = s;
            if (s != null && s.toUpperCase().startsWith("SRID=")) {
                int semicolonIndex = s.indexOf(';');
                if (semicolonIndex > 0) {
                    try {
                        srid = Integer.parseInt(s.substring(5, semicolonIndex));
                        wktString = s.substring(semicolonIndex + 1);
                    } catch (NumberFormatException e) {
                        // 如果解析失败,使用默认SRID 4326
                    }
                }
            }
 
            // 设置Geometry的SRID
            geo.setSRID(srid);
 
            // Geometry转WKB
            byte[] geometryBytes = new WKBWriter(2, ByteOrderValues.LITTLE_ENDIAN, true).write(geo);
            preparedStatement.setBytes(i, geometryBytes);
        } catch (ParseException e) {
            throw new SQLException("Failed to parse geometry WKT: " + s, e);
        }
    }
 
 
    @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 {
        return "";
    }
 
    /**
     * 流 转 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;
    }
}