2 changed files with 307 additions and 0 deletions
@ -0,0 +1,156 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2015-2021 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.geo; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.JsonGenerator; |
||||||
|
import com.fasterxml.jackson.core.JsonProcessingException; |
||||||
|
import com.fasterxml.jackson.databind.JsonSerializer; |
||||||
|
import com.fasterxml.jackson.databind.Module; |
||||||
|
import com.fasterxml.jackson.databind.SerializerProvider; |
||||||
|
import com.fasterxml.jackson.databind.module.SimpleModule; |
||||||
|
import org.springframework.data.geo.Point; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* A Jackson {@link Module} to register custom {@link JsonSerializer}s for GeoJSON types. |
||||||
|
* |
||||||
|
* @author Bjorn Harvold |
||||||
|
* @since |
||||||
|
*/ |
||||||
|
public class GeoJsonSerializersModule extends SimpleModule { |
||||||
|
|
||||||
|
private static final long serialVersionUID = 1340494654898895610L; |
||||||
|
|
||||||
|
public GeoJsonSerializersModule() { |
||||||
|
addSerializer(GeoJsonPoint.class, new GeoJsonPointSerializer()); |
||||||
|
addSerializer(GeoJsonMultiPoint.class, new GeoJsonMultiPointSerializer()); |
||||||
|
addSerializer(GeoJsonLineString.class, new GeoJsonLineStringSerializer()); |
||||||
|
addSerializer(GeoJsonMultiLineString.class, new GeoJsonMultiLineStringSerializer()); |
||||||
|
addSerializer(GeoJsonPolygon.class, new GeoJsonPolygonSerializer()); |
||||||
|
addSerializer(GeoJsonMultiPolygon.class, new GeoJsonMultiPolygonSerializer()); |
||||||
|
} |
||||||
|
|
||||||
|
public static class GeoJsonPointSerializer extends JsonSerializer<GeoJsonPoint> { |
||||||
|
@Override |
||||||
|
public void serialize(GeoJsonPoint value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { |
||||||
|
gen.writeStartObject(); |
||||||
|
gen.writeStringField("type", value.getType()); |
||||||
|
gen.writeObjectField("coordinates", value.getCoordinates()); |
||||||
|
gen.writeEndObject(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
public static class GeoJsonLineStringSerializer extends JsonSerializer<GeoJsonLineString> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void serialize(GeoJsonLineString value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { |
||||||
|
gen.writeStartObject(); |
||||||
|
gen.writeStringField("type", value.getType()); |
||||||
|
gen.writeArrayFieldStart("coordinates"); |
||||||
|
for (Point p : value.getCoordinates()) { |
||||||
|
gen.writeObject(new double[]{p.getX(), p.getY()}); |
||||||
|
} |
||||||
|
gen.writeEndArray(); |
||||||
|
gen.writeEndObject(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class GeoJsonMultiPointSerializer extends JsonSerializer<GeoJsonMultiPoint> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void serialize(GeoJsonMultiPoint value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { |
||||||
|
gen.writeStartObject(); |
||||||
|
gen.writeStringField("type", value.getType()); |
||||||
|
gen.writeArrayFieldStart("coordinates"); |
||||||
|
for (Point p : value.getCoordinates()) { |
||||||
|
gen.writeObject(new double[]{p.getX(), p.getY()}); |
||||||
|
} |
||||||
|
gen.writeEndArray(); |
||||||
|
gen.writeEndObject(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class GeoJsonMultiLineStringSerializer extends JsonSerializer<GeoJsonMultiLineString> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void serialize(GeoJsonMultiLineString value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { |
||||||
|
gen.writeStartObject(); |
||||||
|
gen.writeStringField("type", value.getType()); |
||||||
|
gen.writeArrayFieldStart("coordinates"); |
||||||
|
for (GeoJsonLineString lineString : value.getCoordinates()) { |
||||||
|
List<double[]> arrayList = new ArrayList<>(); |
||||||
|
for (Point p : lineString.getCoordinates()) { |
||||||
|
arrayList.add(new double[]{p.getX(), p.getY()}); |
||||||
|
} |
||||||
|
double[][] doubles = arrayList.toArray(new double[0][0]); |
||||||
|
gen.writeObject(doubles); |
||||||
|
} |
||||||
|
gen.writeEndArray(); |
||||||
|
gen.writeEndObject(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class GeoJsonPolygonSerializer extends JsonSerializer<GeoJsonPolygon> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void serialize(GeoJsonPolygon value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { |
||||||
|
gen.writeStartObject(); |
||||||
|
gen.writeStringField("type", value.getType()); |
||||||
|
gen.writeArrayFieldStart("coordinates"); |
||||||
|
for (GeoJsonLineString ls : value.getCoordinates()) { |
||||||
|
gen.writeStartArray(); |
||||||
|
for (Point p : ls.getCoordinates()) { |
||||||
|
gen.writeObject(new double[]{p.getX(), p.getY()}); |
||||||
|
} |
||||||
|
gen.writeEndArray(); |
||||||
|
} |
||||||
|
gen.writeEndArray(); |
||||||
|
gen.writeEndObject(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static class GeoJsonMultiPolygonSerializer extends JsonSerializer<GeoJsonMultiPolygon> { |
||||||
|
|
||||||
|
@Override |
||||||
|
public void serialize(GeoJsonMultiPolygon value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException { |
||||||
|
gen.writeStartObject(); |
||||||
|
gen.writeStringField("type", value.getType()); |
||||||
|
gen.writeArrayFieldStart("coordinates"); |
||||||
|
for (GeoJsonPolygon polygon : value.getCoordinates()) { |
||||||
|
|
||||||
|
gen.writeStartArray(); |
||||||
|
|
||||||
|
gen.writeStartArray(); |
||||||
|
for (GeoJsonLineString lineString : polygon.getCoordinates()) { |
||||||
|
|
||||||
|
for (Point p : lineString.getCoordinates()) { |
||||||
|
gen.writeObject(new double[]{p.getX(), p.getY()}); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
gen.writeEndArray(); |
||||||
|
gen.writeEndArray(); |
||||||
|
} |
||||||
|
gen.writeEndArray(); |
||||||
|
gen.writeEndObject(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
@ -0,0 +1,151 @@ |
|||||||
|
/* |
||||||
|
* Copyright 2015-2021 the original author or authors. |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
*/ |
||||||
|
package org.springframework.data.mongodb.core.geo; |
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper; |
||||||
|
import org.junit.jupiter.api.BeforeEach; |
||||||
|
import org.junit.jupiter.api.Test; |
||||||
|
import org.springframework.data.geo.Point; |
||||||
|
|
||||||
|
import java.io.IOException; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Bjorn Harvold |
||||||
|
*/ |
||||||
|
public class GeoJsonModuleRoundTripUnitTests { |
||||||
|
|
||||||
|
ObjectMapper mapper; |
||||||
|
|
||||||
|
@BeforeEach |
||||||
|
public void setUp() { |
||||||
|
|
||||||
|
mapper = new ObjectMapper(); |
||||||
|
mapper.registerModule(new GeoJsonModule()); |
||||||
|
mapper.registerModule(new GeoJsonSerializersModule()); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void shouldMarshalJsonPointCorrectly() throws IOException { |
||||||
|
|
||||||
|
String json = "{\"type\":\"Point\",\"coordinates\":[10.0,20.0]}"; |
||||||
|
GeoJsonPoint point = new GeoJsonPoint(10D, 20D); |
||||||
|
|
||||||
|
assertThat(mapper.readValue(json, GeoJsonPoint.class)).isEqualTo(point); |
||||||
|
|
||||||
|
String backToJSON = mapper.writeValueAsString(point); |
||||||
|
|
||||||
|
assertThat(backToJSON).isEqualTo(json); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void shouldMarshalGeoJsonLineStringCorrectly() |
||||||
|
throws IOException { |
||||||
|
|
||||||
|
String json = "{\"type\":\"LineString\",\"coordinates\":[[10.0,20.0],[30.0,40.0],[50.0,60.0]]}"; |
||||||
|
|
||||||
|
GeoJsonLineString lineString = new GeoJsonLineString(Arrays.asList(new Point(10, 20), new Point(30, 40), new Point(50, 60))); |
||||||
|
|
||||||
|
assertThat(mapper.readValue(json, GeoJsonLineString.class)).isEqualTo(lineString); |
||||||
|
|
||||||
|
String backToJSON = mapper.writeValueAsString(lineString); |
||||||
|
|
||||||
|
assertThat(backToJSON).isEqualTo(json); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void shouldMarshalGeoJsonMultiPointCorrectly() throws IOException { |
||||||
|
|
||||||
|
String json = "{\"type\":\"MultiPoint\",\"coordinates\":[[10.0,20.0],[30.0,40.0],[50.0,60.0]]}"; |
||||||
|
GeoJsonMultiPoint multiPoint = new GeoJsonMultiPoint(Arrays.asList(new Point(10, 20), new Point(30, 40), new Point(50, 60))); |
||||||
|
|
||||||
|
assertThat(mapper.readValue(json, GeoJsonMultiPoint.class)).isEqualTo(multiPoint); |
||||||
|
|
||||||
|
String backToJSON = mapper.writeValueAsString(multiPoint); |
||||||
|
|
||||||
|
assertThat(backToJSON).isEqualTo(json); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
@SuppressWarnings("unchecked") |
||||||
|
public void shouldMarshalGeoJsonMultiLineStringCorrectly() throws IOException { |
||||||
|
|
||||||
|
String json = "{\"type\":\"MultiLineString\",\"coordinates\":[[[10.0,20.0],[30.0,40.0]],[[50.0,60.0],[70.0,80.0]]]}"; |
||||||
|
GeoJsonMultiLineString multiLineString = new GeoJsonMultiLineString(Arrays.asList(new Point(10, 20), new Point(30, 40)), Arrays.asList(new Point(50, 60), new Point(70, 80))); |
||||||
|
|
||||||
|
assertThat(mapper.readValue(json, GeoJsonMultiLineString.class)).isEqualTo(multiLineString); |
||||||
|
|
||||||
|
String backToJSON = mapper.writeValueAsString(multiLineString); |
||||||
|
|
||||||
|
assertThat(backToJSON).isEqualTo(json); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void shouldMarshalGeoJsonPolygonCorrectly() throws IOException { |
||||||
|
String json = "{\"type\":\"Polygon\",\"coordinates\":[[[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]]]}"; |
||||||
|
|
||||||
|
List<Point> points = Arrays.asList(new Point(100, 0), new Point(101, 0), new Point(101, 1), new Point(100, 1), new Point(100, 0)); |
||||||
|
GeoJsonPolygon polygon = new GeoJsonPolygon(points); |
||||||
|
|
||||||
|
assertThat(mapper.readValue(json, GeoJsonPolygon.class)).isEqualTo(polygon); |
||||||
|
|
||||||
|
String backToJSON = mapper.writeValueAsString(polygon); |
||||||
|
|
||||||
|
assertThat(backToJSON).isEqualTo(json); |
||||||
|
} |
||||||
|
|
||||||
|
@Test |
||||||
|
public void shouldMarshalGeoJsonMultiPolygonCorrectly() |
||||||
|
throws IOException { |
||||||
|
|
||||||
|
String json = "{\"type\":\"MultiPolygon\",\"coordinates\":[" |
||||||
|
+ "[" |
||||||
|
+ "[" |
||||||
|
+ "[102.0,2.0],[103.0,2.0],[103.0,3.0],[102.0,3.0],[102.0,2.0]" |
||||||
|
+ "]" |
||||||
|
+ "]," |
||||||
|
+ "[" |
||||||
|
+ "[" |
||||||
|
+ "[100.0,0.0],[101.0,0.0],[101.0,1.0],[100.0,1.0],[100.0,0.0]" |
||||||
|
+ "]" |
||||||
|
+ "]," |
||||||
|
+ "[" |
||||||
|
+ "[" |
||||||
|
+ "[100.2,0.2],[100.8,0.2],[100.8,0.8],[100.2,0.8],[100.2,0.2]" |
||||||
|
+ "]" |
||||||
|
+ "]" |
||||||
|
+ "]" |
||||||
|
+ "}"; |
||||||
|
|
||||||
|
GeoJsonMultiPolygon multiPolygon = new GeoJsonMultiPolygon(Arrays.asList( |
||||||
|
new GeoJsonPolygon(Arrays.asList(new Point(102, 2), new Point(103, 2), new Point(103, 3), new Point(102, 3), |
||||||
|
new Point(102, 2))), |
||||||
|
new GeoJsonPolygon(Arrays.asList(new Point(100, 0), new Point(101, 0), new Point(101, 1), new Point(100, 1), |
||||||
|
new Point(100, 0))), |
||||||
|
new GeoJsonPolygon(Arrays.asList(new Point(100.2, 0.2), new Point(100.8, 0.2), new Point(100.8, 0.8), |
||||||
|
new Point(100.2, 0.8), new Point(100.2, 0.2))))); |
||||||
|
|
||||||
|
assertThat(mapper.readValue(json, GeoJsonMultiPolygon.class)).isEqualTo(multiPolygon); |
||||||
|
|
||||||
|
String backToJSON = mapper.writeValueAsString(multiPolygon); |
||||||
|
|
||||||
|
assertThat(backToJSON).isEqualTo(json); |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue