GPS坐标系转换:点、区域序列化与反序列化、类型处理
This commit is contained in:
parent
992fcc6bcb
commit
4bef9ce778
@ -3,6 +3,8 @@ package com.cdzy.operations.config;
|
|||||||
import cn.hutool.core.date.DatePattern;
|
import cn.hutool.core.date.DatePattern;
|
||||||
import com.cdzy.operations.handler.PGpointDeserializer;
|
import com.cdzy.operations.handler.PGpointDeserializer;
|
||||||
import com.cdzy.operations.handler.PGpointSerializer;
|
import com.cdzy.operations.handler.PGpointSerializer;
|
||||||
|
import com.cdzy.operations.handler.PGpolygonDeserializer;
|
||||||
|
import com.cdzy.operations.handler.PGpolygonSerializer;
|
||||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
|
||||||
@ -12,6 +14,7 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
|
|||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
|
||||||
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
|
||||||
import org.postgresql.geometric.PGpoint;
|
import org.postgresql.geometric.PGpoint;
|
||||||
|
import org.postgresql.geometric.PGpolygon;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
@ -38,11 +41,13 @@ public class JacksonConfig {
|
|||||||
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DatePattern.NORM_DATE_FORMATTER));
|
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DatePattern.NORM_DATE_FORMATTER));
|
||||||
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER));
|
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DatePattern.NORM_DATETIME_FORMATTER));
|
||||||
javaTimeModule.addSerializer(PGpoint.class, new PGpointSerializer());
|
javaTimeModule.addSerializer(PGpoint.class, new PGpointSerializer());
|
||||||
|
javaTimeModule.addSerializer(PGpolygon.class, new PGpolygonSerializer());
|
||||||
|
|
||||||
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DatePattern.NORM_TIME_FORMATTER));
|
javaTimeModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DatePattern.NORM_TIME_FORMATTER));
|
||||||
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DatePattern.NORM_DATE_FORMATTER));
|
javaTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DatePattern.NORM_DATE_FORMATTER));
|
||||||
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER));
|
javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DatePattern.NORM_DATETIME_FORMATTER));
|
||||||
javaTimeModule.addDeserializer(PGpoint.class, new PGpointDeserializer());
|
javaTimeModule.addDeserializer(PGpoint.class, new PGpointDeserializer());
|
||||||
|
javaTimeModule.addDeserializer(PGpolygon.class, new PGpolygonDeserializer());
|
||||||
return javaTimeModule;
|
return javaTimeModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
package com.cdzy.operations.controller;
|
package com.cdzy.operations.controller;
|
||||||
|
|
||||||
import com.cdzy.common.model.response.JsonResult;
|
import com.cdzy.common.model.response.JsonResult;
|
||||||
|
import com.cdzy.operations.model.entity.EbikeBikeInfo;
|
||||||
import com.cdzy.operations.model.vo.EbikeBikeBindVo;
|
import com.cdzy.operations.model.vo.EbikeBikeBindVo;
|
||||||
import com.cdzy.operations.service.EbikeBikeInfoService;
|
import com.cdzy.operations.service.EbikeBikeInfoService;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import java.util.List;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 车辆基本信息 控制层。
|
* 车辆基本信息 控制层。
|
||||||
@ -35,4 +35,24 @@ public class EbikeBikeInfoController {
|
|||||||
return JsonResult.success();
|
return JsonResult.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 车辆列表
|
||||||
|
* @return 列表
|
||||||
|
*/
|
||||||
|
@GetMapping("list")
|
||||||
|
public JsonResult<?> list() {
|
||||||
|
List<EbikeBikeInfo> list = ebikeBikeInfoService.list();
|
||||||
|
return JsonResult.success(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成车辆
|
||||||
|
* @return 列表
|
||||||
|
*/
|
||||||
|
@PostMapping("save")
|
||||||
|
public JsonResult<?> save(@Validated @RequestBody EbikeBikeInfo ebikeBikeInfo) {
|
||||||
|
ebikeBikeInfoService.save(ebikeBikeInfo);
|
||||||
|
return JsonResult.success();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,11 +23,12 @@ public class PGpointDeserializer extends JsonDeserializer<PGpoint> {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 方式1: GeoJSON 格式
|
// 方式1: GeoJSON 格式
|
||||||
if (node.isObject() && node.has("type") && "Point".equals(node.get("type").asText())) {
|
if (node.isObject()) {
|
||||||
JsonNode coordinates = node.get("coordinates");
|
JsonNode longitude = node.get("longitude");
|
||||||
if (coordinates != null && coordinates.isArray() && coordinates.size() >= 2) {
|
JsonNode latitude = node.get("latitude");
|
||||||
double x = coordinates.get(0).asDouble();
|
if (longitude != null && latitude != null) {
|
||||||
double y = coordinates.get(1).asDouble();
|
double x = longitude.asDouble();
|
||||||
|
double y =latitude.asDouble();
|
||||||
return new PGpoint(x, y);
|
return new PGpoint(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,171 @@
|
|||||||
|
package com.cdzy.operations.handler;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonParser;
|
||||||
|
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||||
|
import com.fasterxml.jackson.databind.JsonDeserializer;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import org.postgresql.geometric.PGpoint;
|
||||||
|
import org.postgresql.geometric.PGpolygon;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGpolygon 反序列化器 - 将 JSON 反序列化为 PGpolygon
|
||||||
|
*/
|
||||||
|
public class PGpolygonDeserializer extends JsonDeserializer<PGpolygon> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PGpolygon deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
|
||||||
|
JsonNode node = p.getCodec().readTree(p);
|
||||||
|
|
||||||
|
if (node.isNull()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 支持多种 JSON 格式
|
||||||
|
|
||||||
|
// 格式1: 自定义格式 {"type": "polygon", "coordinates": [[x1,y1], [x2,y2], ...]}
|
||||||
|
if (node.isObject() && node.has("type") && "polygon".equals(node.get("type").asText())) {
|
||||||
|
return parseFromCustomFormat(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式2: GeoJSON 格式 {"type": "Polygon", "coordinates": [[[x1,y1], [x2,y2], ...]]}
|
||||||
|
if (node.isObject() && node.has("type") && "Polygon".equals(node.get("type").asText())) {
|
||||||
|
return parseFromGeoJSON(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式3: 直接坐标数组 [[x1,y1], [x2,y2], ...]
|
||||||
|
if (node.isArray()) {
|
||||||
|
return parseFromArray(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 格式4: 字符串格式 "((x1 y1, x2 y2, ...))"
|
||||||
|
if (node.isTextual()) {
|
||||||
|
return parseFromString(node.asText());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IOException("不支持的 PGpolygon JSON 格式");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("PGpolygon 反序列化失败: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<PGpolygon> handledType() {
|
||||||
|
return PGpolygon.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析自定义格式
|
||||||
|
*/
|
||||||
|
private PGpolygon parseFromCustomFormat(JsonNode node) throws IOException {
|
||||||
|
JsonNode coordinatesNode = node.get("coordinates");
|
||||||
|
if (coordinatesNode == null || !coordinatesNode.isArray()) {
|
||||||
|
throw new IOException("coordinates 字段缺失或格式错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PGpoint> points = new ArrayList<>();
|
||||||
|
for (JsonNode coordNode : coordinatesNode) {
|
||||||
|
if (coordNode.isArray() && coordNode.size() >= 2) {
|
||||||
|
double x = coordNode.get(0).asDouble();
|
||||||
|
double y = coordNode.get(1).asDouble();
|
||||||
|
points.add(new PGpoint(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPGpolygonFromPoints(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 GeoJSON 格式
|
||||||
|
*/
|
||||||
|
private PGpolygon parseFromGeoJSON(JsonNode node) throws IOException {
|
||||||
|
JsonNode coordinatesNode = node.get("coordinates");
|
||||||
|
if (coordinatesNode == null || !coordinatesNode.isArray() || coordinatesNode.isEmpty()) {
|
||||||
|
throw new IOException("coordinates 字段缺失或格式错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
// GeoJSON 格式: coordinates 是三维数组 [[[x1,y1], [x2,y2], ...]]
|
||||||
|
JsonNode ringNode = coordinatesNode.get(0);
|
||||||
|
if (!ringNode.isArray()) {
|
||||||
|
throw new IOException("GeoJSON coordinates 格式错误");
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PGpoint> points = new ArrayList<>();
|
||||||
|
for (JsonNode coordNode : ringNode) {
|
||||||
|
if (coordNode.isArray() && coordNode.size() >= 2) {
|
||||||
|
double x = coordNode.get(0).asDouble();
|
||||||
|
double y = coordNode.get(1).asDouble();
|
||||||
|
points.add(new PGpoint(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPGpolygonFromPoints(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析坐标数组格式
|
||||||
|
*/
|
||||||
|
private PGpolygon parseFromArray(JsonNode node) throws IOException {
|
||||||
|
List<PGpoint> points = new ArrayList<>();
|
||||||
|
for (JsonNode coordNode : node) {
|
||||||
|
if (coordNode.isArray() && coordNode.size() >= 2) {
|
||||||
|
double x = coordNode.get(0).asDouble();
|
||||||
|
double y = coordNode.get(1).asDouble();
|
||||||
|
points.add(new PGpoint(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return createPGpolygonFromPoints(points);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析字符串格式
|
||||||
|
*/
|
||||||
|
private PGpolygon parseFromString(String polygonString) throws IOException {
|
||||||
|
try {
|
||||||
|
return new PGpolygon(polygonString);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("PGpolygon 字符串格式解析失败: " + polygonString, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从点列表创建 PGpolygon
|
||||||
|
*/
|
||||||
|
private PGpolygon createPGpolygonFromPoints(List<PGpoint> points) throws IOException {
|
||||||
|
if (points == null || points.size() < 3) {
|
||||||
|
throw new IOException("多边形至少需要3个点");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建多边形字符串格式:((x1 y1, x2 y2, x3 y3, x1 y1))
|
||||||
|
StringBuilder sb = new StringBuilder("((");
|
||||||
|
for (int i = 0; i < points.size(); i++) {
|
||||||
|
PGpoint point = points.get(i);
|
||||||
|
sb.append(point.x).append(" ").append(point.y);
|
||||||
|
if (i < points.size() - 1) {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 确保多边形闭合(首尾点相同)
|
||||||
|
PGpoint firstPoint = points.get(0);
|
||||||
|
PGpoint lastPoint = points.get(points.size() - 1);
|
||||||
|
if (firstPoint.x != lastPoint.x || firstPoint.y != lastPoint.y) {
|
||||||
|
sb.append(", ").append(firstPoint.x).append(" ").append(firstPoint.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
sb.append("))");
|
||||||
|
|
||||||
|
return new PGpolygon(sb.toString());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new IOException("创建 PGpolygon 失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,70 @@
|
|||||||
|
package com.cdzy.operations.handler;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator;
|
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer;
|
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider;
|
||||||
|
import org.postgresql.geometric.PGpolygon;
|
||||||
|
import org.postgresql.geometric.PGpoint;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGpolygon 序列化器 - 将 PGpolygon 序列化为 JSON
|
||||||
|
*/
|
||||||
|
public class PGpolygonSerializer extends JsonSerializer<PGpolygon> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialize(PGpolygon polygon, JsonGenerator gen, SerializerProvider serializers) throws IOException {
|
||||||
|
if (polygon == null) {
|
||||||
|
gen.writeNull();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 方式1: 序列化为自定义格式
|
||||||
|
gen.writeStartObject();
|
||||||
|
gen.writeStringField("type", "polygon");
|
||||||
|
|
||||||
|
// 解析多边形字符串获取点坐标
|
||||||
|
PGpoint[] points = parsePointsFromPolygon(polygon);
|
||||||
|
gen.writeArrayFieldStart("coordinates");
|
||||||
|
for (PGpoint point : points) {
|
||||||
|
gen.writeStartArray();
|
||||||
|
gen.writeNumber(point.x);
|
||||||
|
gen.writeNumber(point.y);
|
||||||
|
gen.writeEndArray();
|
||||||
|
}
|
||||||
|
gen.writeEndArray();
|
||||||
|
gen.writeEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<PGpolygon> handledType() {
|
||||||
|
return PGpolygon.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从 PGpolygon 解析点坐标
|
||||||
|
*/
|
||||||
|
private PGpoint[] parsePointsFromPolygon(PGpolygon polygon) {
|
||||||
|
try {
|
||||||
|
String polygonString = polygon.toString();
|
||||||
|
// 解析格式:((x1 y1, x2 y2, x3 y3, x1 y1))
|
||||||
|
String pointsStr = polygonString.replaceAll("[()]", "").trim();
|
||||||
|
String[] pointPairs = pointsStr.split(",");
|
||||||
|
|
||||||
|
PGpoint[] points = new PGpoint[pointPairs.length];
|
||||||
|
for (int i = 0; i < pointPairs.length; i++) {
|
||||||
|
String pointPair = pointPairs[i].trim();
|
||||||
|
String[] coords = pointPair.split("\\s+");
|
||||||
|
if (coords.length >= 2) {
|
||||||
|
double x = Double.parseDouble(coords[0]);
|
||||||
|
double y = Double.parseDouble(coords[1]);
|
||||||
|
points[i] = new PGpoint(x, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return points;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to parse points from polygon", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,202 @@
|
|||||||
|
package com.cdzy.operations.handler;
|
||||||
|
|
||||||
|
import org.apache.ibatis.type.JdbcType;
|
||||||
|
import org.apache.ibatis.type.TypeHandler;
|
||||||
|
import org.postgresql.geometric.PGpolygon;
|
||||||
|
import org.postgresql.geometric.PGpoint;
|
||||||
|
import org.postgresql.util.PGobject;
|
||||||
|
import com.cdzy.common.utils.CoordinateUtil;
|
||||||
|
|
||||||
|
import java.sql.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PGpolygon 类型处理器 - 集成 CoordinateUtil 实现坐标转换
|
||||||
|
* 写入时:GCJ-02 → WGS-84
|
||||||
|
* 读取时:WGS-84 → GCJ-02
|
||||||
|
*/
|
||||||
|
public class PGpolygonTypeHandler implements TypeHandler<PGpolygon> {
|
||||||
|
|
||||||
|
// 正则表达式用于解析多边形字符串格式:((x1 y1, x2 y2, x3 y3, x1 y1))
|
||||||
|
private static final Pattern POLYGON_PATTERN = Pattern.compile("\\(\\s*\\(([^)]+)\\)\\s*\\)");
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setParameter(PreparedStatement ps, int i, PGpolygon parameter, JdbcType jdbcType) throws SQLException {
|
||||||
|
if (parameter == null) {
|
||||||
|
ps.setNull(i, Types.OTHER);
|
||||||
|
} else {
|
||||||
|
// 写入数据库时:GCJ-02 → WGS-84
|
||||||
|
PGpolygon wgs84Polygon = gcj02ToWgs84(parameter);
|
||||||
|
ps.setObject(i, wgs84Polygon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PGpolygon getResult(ResultSet rs, String columnName) throws SQLException {
|
||||||
|
Object object = rs.getObject(columnName);
|
||||||
|
PGpolygon wgs84Polygon = convertToPGpolygon(object);
|
||||||
|
// 读取时:WGS-84 → GCJ-02
|
||||||
|
return wgs84ToGcj02(wgs84Polygon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PGpolygon getResult(ResultSet rs, int columnIndex) throws SQLException {
|
||||||
|
Object object = rs.getObject(columnIndex);
|
||||||
|
PGpolygon wgs84Polygon = convertToPGpolygon(object);
|
||||||
|
// 读取时:WGS-84 → GCJ-02
|
||||||
|
return wgs84ToGcj02(wgs84Polygon);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PGpolygon getResult(CallableStatement cs, int columnIndex) throws SQLException {
|
||||||
|
Object object = cs.getObject(columnIndex);
|
||||||
|
PGpolygon wgs84Polygon = convertToPGpolygon(object);
|
||||||
|
// 读取时:WGS-84 → GCJ-02
|
||||||
|
return wgs84ToGcj02(wgs84Polygon);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将数据库对象转换为 PGpolygon
|
||||||
|
*/
|
||||||
|
private PGpolygon convertToPGpolygon(Object object) {
|
||||||
|
if (object == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (object instanceof PGpolygon) {
|
||||||
|
// 直接是 PGpolygon 类型
|
||||||
|
return (PGpolygon) object;
|
||||||
|
} else if (object instanceof String) {
|
||||||
|
// 字符串格式,如 "((x1 y1, x2 y2, x3 y3, x1 y1))"
|
||||||
|
return new PGpolygon((String) object);
|
||||||
|
} else if (object instanceof PGobject pgObject) {
|
||||||
|
// PGobject 类型,获取其字符串值
|
||||||
|
return new PGpolygon(pgObject.getValue());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to convert to PGpolygon: " + object, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GCJ-02 转 WGS-84(写入数据库时调用)
|
||||||
|
*/
|
||||||
|
private PGpolygon gcj02ToWgs84(PGpolygon gcj02Polygon) {
|
||||||
|
if (gcj02Polygon == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 通过字符串解析获取点坐标
|
||||||
|
String polygonString = gcj02Polygon.toString();
|
||||||
|
PGpoint[] points = parsePointsFromPolygonString(polygonString);
|
||||||
|
List<PGpoint> wgs84Points = new ArrayList<>();
|
||||||
|
|
||||||
|
// 对每个点进行坐标转换
|
||||||
|
for (PGpoint gcj02Point : points) {
|
||||||
|
double[] wgs84 = CoordinateUtil.GCJ02ToWGS84(gcj02Point.x, gcj02Point.y);
|
||||||
|
wgs84Points.add(new PGpoint(wgs84[0], wgs84[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的 WGS-84 多边形
|
||||||
|
return createPGpolygonFromPoints(wgs84Points);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("GCJ-02 转 WGS-84 区域转换错误", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WGS-84 转 GCJ-02(从数据库读取时调用)
|
||||||
|
*/
|
||||||
|
private PGpolygon wgs84ToGcj02(PGpolygon wgs84Polygon) {
|
||||||
|
if (wgs84Polygon == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 通过字符串解析获取点坐标
|
||||||
|
String polygonString = wgs84Polygon.toString();
|
||||||
|
PGpoint[] points = parsePointsFromPolygonString(polygonString);
|
||||||
|
List<PGpoint> gcj02Points = new ArrayList<>();
|
||||||
|
|
||||||
|
// 对每个点进行坐标转换
|
||||||
|
for (PGpoint wgs84Point : points) {
|
||||||
|
double[] gcj02 = CoordinateUtil.WGS84ToGCJ02(wgs84Point.x, wgs84Point.y);
|
||||||
|
gcj02Points.add(new PGpoint(gcj02[0], gcj02[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建新的 GCJ-02 多边形
|
||||||
|
return createPGpolygonFromPoints(gcj02Points);
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("GCJ-02 转 WGS-84 区域转换错误", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从多边形字符串中解析点坐标
|
||||||
|
*/
|
||||||
|
private PGpoint[] parsePointsFromPolygonString(String polygonString) {
|
||||||
|
List<PGpoint> points = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Matcher matcher = POLYGON_PATTERN.matcher(polygonString);
|
||||||
|
if (matcher.find()) {
|
||||||
|
String pointsStr = matcher.group(1);
|
||||||
|
// 分割点坐标:x1 y1, x2 y2, x3 y3
|
||||||
|
String[] pointPairs = pointsStr.split(",");
|
||||||
|
|
||||||
|
for (String pointPair : pointPairs) {
|
||||||
|
pointPair = pointPair.trim();
|
||||||
|
String[] coords = pointPair.split("\\s+");
|
||||||
|
if (coords.length >= 2) {
|
||||||
|
double x = Double.parseDouble(coords[0]);
|
||||||
|
double y = Double.parseDouble(coords[1]);
|
||||||
|
points.add(new PGpoint(x, y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Failed to parse points from polygon string: " + polygonString, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return points.toArray(new PGpoint[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从点列表创建 PGpolygon
|
||||||
|
*/
|
||||||
|
private PGpolygon createPGpolygonFromPoints(List<PGpoint> points) {
|
||||||
|
if (points.isEmpty()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 构建多边形字符串格式:((x1 y1, x2 y2, x3 y3, x1 y1))
|
||||||
|
StringBuilder sb = new StringBuilder("((");
|
||||||
|
for (int i = 0; i < points.size(); i++) {
|
||||||
|
PGpoint point = points.get(i);
|
||||||
|
sb.append(point.x).append(" ").append(point.y);
|
||||||
|
if (i < points.size() - 1) {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 确保多边形闭合(首尾点相同)
|
||||||
|
PGpoint firstPoint = points.get(0);
|
||||||
|
sb.append(", ").append(firstPoint.x).append(" ").append(firstPoint.y);
|
||||||
|
sb.append("))");
|
||||||
|
|
||||||
|
return new PGpolygon(sb.toString());
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("区域点列表创建错误", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user