diff --git a/build.gradle b/build.gradle index 3d8296ed..f55ce79c 100644 --- a/build.gradle +++ b/build.gradle @@ -36,6 +36,7 @@ dependencies { //geometry implementation 'com.fasterxml.jackson.core:jackson-databind' implementation 'org.locationtech.jts.io:jts-io-common:1.20.0' + implementation 'org.locationtech.jts:jts-core:1.19.0' // QueryDSL JPA implementation 'com.querydsl:querydsl-jpa:5.0.0:jakarta' diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java new file mode 100644 index 00000000..f6eecdb2 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometryDeserializer.java @@ -0,0 +1,37 @@ +package com.kamco.cd.kamcoback.common.utils.geometry; + +import com.fasterxml.jackson.core.JacksonException; +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.deser.std.StdDeserializer; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.geojson.GeoJsonReader; +import org.springframework.util.StringUtils; + +import java.io.IOException; + +public class GeometryDeserializer extends StdDeserializer { + + public GeometryDeserializer(Class targetType) { + super(targetType); + } + + // TODO: test code + @SuppressWarnings("unchecked") + @Override + public T deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) + throws IOException, JacksonException { + String json = jsonParser.readValueAsTree().toString(); + + if (!StringUtils.hasText(json)) { + return null; + } + + try { + GeoJsonReader reader = new GeoJsonReader(); + return (T) reader.read(json); + } catch (Exception e) { + throw new IllegalArgumentException("Failed to deserialize GeoJSON into Geometry", e); + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java new file mode 100644 index 00000000..b5433da6 --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/common/utils/geometry/GeometrySerializer.java @@ -0,0 +1,31 @@ +package com.kamco.cd.kamcoback.common.utils.geometry; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.io.geojson.GeoJsonWriter; + +import java.io.IOException; +import java.util.Objects; + +public class GeometrySerializer extends StdSerializer { + + // TODO: test code + public GeometrySerializer(Class targetType) { + super(targetType); + } + + @Override + public void serialize(T geometry, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) + throws IOException { + if (Objects.nonNull(geometry)) { + // default: 8자리 강제로 반올림시킴. 16자리로 늘려줌 + GeoJsonWriter writer = new GeoJsonWriter(16); + String json = writer.write(geometry); + jsonGenerator.writeRawValue(json); + } else { + jsonGenerator.writeNull(); + } + } +} diff --git a/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java b/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java new file mode 100644 index 00000000..6671faba --- /dev/null +++ b/src/main/java/com/kamco/cd/kamcoback/config/WebConfig.java @@ -0,0 +1,33 @@ +package com.kamco.cd.kamcoback.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; +import com.kamco.cd.kamcoback.common.utils.geometry.GeometryDeserializer; +import com.kamco.cd.kamcoback.common.utils.geometry.GeometrySerializer; +import org.locationtech.jts.geom.Geometry; +import org.locationtech.jts.geom.Point; +import org.locationtech.jts.geom.Polygon; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; + +@Configuration +public class WebConfig { + + @Bean + public ObjectMapper objectMapper() { + SimpleModule module = new SimpleModule(); + module.addSerializer(Geometry.class, new GeometrySerializer<>(Geometry.class)); + module.addDeserializer(Geometry.class, new GeometryDeserializer<>(Geometry.class)); + + module.addSerializer(Polygon.class, new GeometrySerializer<>(Polygon.class)); + module.addDeserializer(Polygon.class, new GeometryDeserializer<>(Polygon.class)); + + module.addSerializer(Point.class, new GeometrySerializer<>(Point.class)); + module.addDeserializer(Point.class, new GeometryDeserializer<>(Point.class)); + + return Jackson2ObjectMapperBuilder.json() + .modulesToInstall(module) + .build(); + } +}