Skip to content

Commit c15a62f

Browse files
authored
BoundingBox deserialization (#891)
1 parent d54fe4c commit c15a62f

13 files changed

Lines changed: 227 additions & 30 deletions

services-geojson/src/main/java/com/mapbox/geojson/Point.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,9 @@ public static Point fromLngLat(
139139
@FloatRange(from = MIN_LONGITUDE, to = MAX_LONGITUDE) double longitude,
140140
@FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latitude,
141141
double altitude) {
142-
List<Double> coordinates = Arrays.asList(longitude, latitude, altitude);
142+
List<Double> coordinates = Double.isNaN(altitude)
143+
? Arrays.asList(longitude, latitude) :
144+
Arrays.asList(longitude, latitude, altitude);
143145
return new AutoValue_Point(TYPE, null, coordinates);
144146
}
145147

@@ -164,7 +166,9 @@ public static Point fromLngLat(
164166
@FloatRange(from = MIN_LONGITUDE, to = MAX_LONGITUDE) double longitude,
165167
@FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latitude,
166168
double altitude, @Nullable BoundingBox bbox) {
167-
List<Double> coordinates = Arrays.asList(longitude, latitude, altitude);
169+
List<Double> coordinates = Double.isNaN(altitude)
170+
? Arrays.asList(longitude, latitude) :
171+
Arrays.asList(longitude, latitude, altitude);
168172
return new AutoValue_Point(TYPE, bbox, coordinates);
169173
}
170174

services-geojson/src/main/java/com/mapbox/geojson/gson/GeometryDeserializer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public Geometry deserialize(JsonElement json, Type typeOfT, JsonDeserializationC
5151

5252
try {
5353
// Use the current context to deserialize it
54-
Type classType = Class.forName("com.mapbox.geojson." + geometryType);
54+
Type classType = Class.forName("com.mapbox.geojson.AutoValue_" + geometryType);
5555
return context.deserialize(json, classType);
5656
} catch (ClassNotFoundException classNotFoundException) {
5757
// Unknown geometry

services-geojson/src/main/java/com/mapbox/geojson/gson/GeometryGeoJson.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@
33
import android.support.annotation.NonNull;
44

55
import com.google.gson.GsonBuilder;
6+
import com.mapbox.geojson.BoundingBox;
67
import com.mapbox.geojson.Geometry;
78
import com.mapbox.geojson.Point;
89

910
/**
1011
* This is a utility class that helps create a Geometry instance from a JSON string.
11-
* @since 3.5.0
12+
* @since 4.0.0
1213
*/
1314
public class GeometryGeoJson {
1415

@@ -18,12 +19,13 @@ public class GeometryGeoJson {
1819
* @param json a formatted valid JSON string defining a GeoJson Geometry
1920
* @return a new instance of Geometry class defined by the values passed inside
2021
* this static factory method
21-
* @since 3.5.0
22+
* @since 4.0.0
2223
*/
2324
public static Geometry fromJson(@NonNull String json) {
2425
GsonBuilder gson = new GsonBuilder();
2526
gson.registerTypeAdapterFactory(GeoJsonAdapterFactory.create());
2627
gson.registerTypeAdapter(Point.class, new PointDeserializer());
28+
gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxDeserializer());
2729
gson.registerTypeAdapter(Geometry.class, new GeometryDeserializer());
2830
return gson.create().fromJson(json, Geometry.class);
2931
}

services-geojson/src/main/java/com/mapbox/geojson/gson/PointDeserializer.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,7 @@ public PointDeserializer() {
4141
*/
4242
@Override
4343
public Point deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) {
44-
JsonArray rawCoordinates;
45-
46-
if (json.isJsonObject()) {
47-
rawCoordinates = json.getAsJsonObject().getAsJsonArray("coordinates");
48-
} else {
49-
rawCoordinates = json.getAsJsonArray();
50-
}
44+
JsonArray rawCoordinates = json.getAsJsonArray();
5145

5246
double longitude = rawCoordinates.get(0).getAsDouble();
5347
double latitude = rawCoordinates.get(1).getAsDouble();

services-geojson/src/test/java/com/mapbox/geojson/FeatureCollectionTest.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
public class FeatureCollectionTest extends TestUtils {
1616

1717
private static final String SAMPLE_FEATURECOLLECTION = "sample-featurecollection.json";
18+
private static final String SAMPLE_FEATURECOLLECTION_BBOX = "sample-feature-collection-with-bbox.json";
1819

1920
@Test
2021
public void sanity() throws Exception {
@@ -116,7 +117,7 @@ public void fromJson() throws IOException {
116117

117118
@Test
118119
public void toJson() throws IOException {
119-
final String json = loadJsonFixture(SAMPLE_FEATURECOLLECTION);
120+
final String json = loadJsonFixture(SAMPLE_FEATURECOLLECTION_BBOX);
120121
FeatureCollection geo = FeatureCollection.fromJson(json);
121122
compareJson(json, geo.toJson());
122123
}

services-geojson/src/test/java/com/mapbox/geojson/FeatureTest.java

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import static org.junit.Assert.assertNull;
77
import static org.junit.Assert.assertTrue;
88

9+
import com.google.gson.JsonElement;
910
import com.google.gson.JsonObject;
1011
import com.mapbox.core.TestUtils;
1112

@@ -18,6 +19,7 @@
1819
public class FeatureTest extends TestUtils {
1920

2021
private static final String SAMPLE_FEATURE = "sample-feature.json";
22+
private static final String SAMPLE_FEATURE_POINT = "sample-feature-point-all.json";
2123

2224
@Test
2325
public void sanity() throws Exception {
@@ -76,25 +78,56 @@ public void bbox_doesSerializeWhenPresent() throws Exception {
7678

7779
BoundingBox bbox = BoundingBox.fromLngLats(1.0, 2.0, 3.0, 4.0);
7880
Feature feature = Feature.fromGeometry(lineString, bbox);
81+
String featureJsonString = feature.toJson();
7982
compareJson("{\"type\":\"Feature\",\"bbox\":[1.0,2.0,3.0,4.0],\"geometry\":"
8083
+ "{\"type\":\"LineString\",\"coordinates\":[[1,2],[2,3]]}}",
8184
feature.toJson());
8285
}
8386

8487
@Test
85-
public void fromJson() throws IOException {
86-
final String json = loadJsonFixture(SAMPLE_FEATURE);
88+
public void test_point_feature_fromJson() throws IOException {
89+
final String json = "{ \"type\": \"Feature\"," +
90+
"\"geometry\": { \"type\": \"Point\", \"coordinates\": [ 125.6, 10.1] }," +
91+
"\"properties\": {\"name\": \"Dinagat Islands\" }}";
8792
Feature geo = Feature.fromJson(json);
8893
assertEquals(geo.type(), "Feature");
8994
assertEquals(geo.geometry().type(), "Point");
95+
assertEquals(((Point)geo.geometry()).longitude(), 125.6, DELTA);
96+
assertEquals(((Point)geo.geometry()).latitude(), 10.1, DELTA);
9097
assertEquals(geo.properties().get("name").getAsString(), "Dinagat Islands");
9198
}
9299

93100
@Test
94-
public void toJson() throws IOException {
95-
final String json = loadJsonFixture(SAMPLE_FEATURE);
101+
public void test_linestring_feature_fromJson() throws IOException {
102+
final String json = "{ \"type\": \"Feature\"," +
103+
"\"geometry\": { \"type\": \"LineString\", "+
104+
" \"coordinates\": [[ 102.0, 20],[103.0, 3.0],[104.0, 4.0], [105.0, 5.0]]}," +
105+
"\"properties\": {\"name\": \"line name\" }}";
96106
Feature geo = Feature.fromJson(json);
97-
compareJson(json, geo.toJson());
107+
assertEquals(geo.type(), "Feature");
108+
assertEquals(geo.geometry().type(), "LineString");
109+
assertNotNull(geo.geometry());
110+
List<Point> coordinates = ((LineString) geo.geometry()).coordinates();
111+
assertNotNull(coordinates);
112+
assertEquals(4, coordinates.size());
113+
assertEquals(105.0,coordinates.get(3).longitude(), DELTA);
114+
assertEquals(5.0,coordinates.get(3).latitude(), DELTA);
115+
assertEquals("line name", geo.properties().get("name").getAsString());
116+
}
117+
118+
@Test
119+
public void test_point_feature_toJson() throws IOException {
120+
JsonObject properties = new JsonObject();
121+
properties.addProperty("name", "Dinagat Islands");
122+
Feature geo = Feature.fromGeometry(Point.fromLngLat(125.6, 10.1),
123+
properties);
124+
String geoJsonString = geo.toJson();
125+
126+
String expectedJson = "{ \"type\": \"Feature\"," +
127+
"\"geometry\": { \"type\": \"Point\", \"coordinates\": [ 125.6, 10.1] }," +
128+
"\"properties\": {\"name\": \"Dinagat Islands\" }}";
129+
130+
compareJson(expectedJson, geoJsonString);
98131
}
99132

100133
@Test
@@ -138,4 +171,14 @@ public void testNullPropertiesJson() {
138171
String fromFeatureJsonString = feature.toJson();
139172
assertEquals(fromFeatureJsonString, jsonString);
140173
}
174+
175+
176+
@Test
177+
public void test_fromJson_toJson() throws IOException {
178+
final String jsonString = loadJsonFixture(SAMPLE_FEATURE_POINT);
179+
Feature featureFromJson = Feature.fromJson(jsonString);
180+
String jsonStringFromFeature = featureFromJson.toJson();
181+
182+
compareJson(jsonString, jsonStringFromFeature);
183+
}
141184
}
Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,97 @@
11
package com.mapbox.geojson.gson;
22

33
import com.google.gson.GsonBuilder;
4+
import com.google.gson.JsonSyntaxException;
5+
import com.google.gson.reflect.TypeToken;
46
import com.mapbox.core.TestUtils;
7+
import com.mapbox.core.exceptions.ServicesException;
58
import com.mapbox.geojson.Point;
69

10+
import org.junit.Rule;
711
import org.junit.Test;
12+
import org.junit.rules.ExpectedException;
13+
14+
import java.lang.reflect.Type;
15+
import java.util.List;
16+
17+
import static org.hamcrest.Matchers.containsString;
18+
import static org.hamcrest.Matchers.startsWith;
19+
import static org.junit.Assert.assertEquals;
820

921
public class PointDeserializerTest extends TestUtils {
1022

11-
private static final String POINT_FIXTURE = "sample-point.json";
12-
private static final String POINT_WITH_BBOX_FIXTURE = "sample-point-with-bbox.json";
23+
@Rule
24+
public ExpectedException thrown = ExpectedException.none();
1325

1426
@Test
1527
public void deserialize_sanity() throws Exception {
16-
String fixtureJson = loadJsonFixture(POINT_FIXTURE);
28+
String jsonString = "[100.0, 0.0]";
29+
GsonBuilder gsonBuilder = new GsonBuilder()
30+
.registerTypeAdapter(Point.class, new PointDeserializer());
31+
Point point = gsonBuilder.create().fromJson(jsonString, Point.class);
32+
33+
assertEquals(100, point.longitude(), DELTA);
34+
assertEquals(0, point.latitude(), DELTA);
35+
}
36+
37+
@Test
38+
public void point_doesNotDeserializeObject() throws Exception {
39+
thrown.expect(JsonSyntaxException.class);
40+
41+
String jsonString = "{ \"coordinates\": [100.0, 0.0, 200.0]}";
1742
GsonBuilder gsonBuilder = new GsonBuilder()
1843
.registerTypeAdapter(Point.class, new PointDeserializer());
19-
Point point = gsonBuilder.create().fromJson(fixtureJson, Point.class);
20-
compareJson(point.toJson(), fixtureJson);
44+
gsonBuilder.create().fromJson(jsonString, Point.class);
2145
}
2246

2347
@Test
24-
public void point_doesHaveAltitude() throws Exception {
25-
String fixtureJson = loadJsonFixture(POINT_WITH_BBOX_FIXTURE);
48+
public void point_deserializeArray() throws Exception {
49+
String jsonString = "[100.0, 0.0, 200.0]";
2650
GsonBuilder gsonBuilder = new GsonBuilder()
2751
.registerTypeAdapter(Point.class, new PointDeserializer());
28-
Point point = gsonBuilder.create().fromJson(fixtureJson, Point.class);
29-
compareJson(point.toJson(), fixtureJson);
52+
Point point = gsonBuilder.create().fromJson(jsonString, Point.class);
53+
54+
assertEquals(100, point.longitude(), DELTA);
55+
assertEquals(0, point.latitude(), DELTA);
56+
assertEquals(200, point.altitude(), DELTA);
57+
}
58+
59+
@Test
60+
public void point_deserializeArrayOfArrays() throws Exception {
61+
String jsonString = "[[50.0, 50.0, 100.0], [100.0, 100.0, 200.0]]";
62+
GsonBuilder gsonBuilder = new GsonBuilder()
63+
.registerTypeAdapter(Point.class, new PointDeserializer());
64+
List<Point> points = gsonBuilder.create().fromJson(jsonString,
65+
new TypeToken<List<Point>>() {}.getType());
66+
67+
assertEquals(50, points.get(0).longitude(), DELTA);
68+
assertEquals(50, points.get(0).latitude(), DELTA);
69+
assertEquals(100, points.get(0).altitude(), DELTA);
70+
71+
72+
assertEquals(100, points.get(1).longitude(), DELTA);
73+
assertEquals(100, points.get(1).latitude(), DELTA);
74+
assertEquals(200, points.get(1).altitude(), DELTA);
75+
}
76+
77+
@Test
78+
public void point_deserializeArrayOfArraysOfArrays() throws Exception {
79+
String jsonString = "[[[50.0, 50.0, 100.0], [100.0, 100.0, 200.0]]]";
80+
GsonBuilder gsonBuilder = new GsonBuilder()
81+
.registerTypeAdapter(Point.class, new PointDeserializer());
82+
83+
Type type =
84+
new TypeToken<List<List<Point>>>() {}.getType();
85+
List<List<Point>> points = gsonBuilder.create().fromJson(jsonString,
86+
type);
87+
88+
assertEquals(50, points.get(0).get(0).longitude(), DELTA);
89+
assertEquals(50, points.get(0).get(0).latitude(), DELTA);
90+
assertEquals(100, points.get(0).get(0).altitude(), DELTA);
91+
92+
93+
assertEquals(100, points.get(0).get(1).longitude(), DELTA);
94+
assertEquals(100, points.get(0).get(1).latitude(), DELTA);
95+
assertEquals(200, points.get(0).get(1).altitude(), DELTA);
3096
}
3197
}
Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,36 @@
11
package com.mapbox.geojson.gson;
22

3+
34
import com.mapbox.core.TestUtils;
5+
import com.mapbox.geojson.BoundingBox;
46
import com.mapbox.geojson.Point;
57
import org.junit.Test;
68

79
public class PointSerializerTest extends TestUtils {
810

11+
private static final String POINT_FIXTURE = "sample-point.json";
912
private static final String POINT_WITH_BBOX_FIXTURE = "sample-point-with-bbox.json";
13+
private static final String POINT_WITH_ALTITUDE_FIXTURE = "sample-point-with-altitude.json";
1014

1115
@Test
1216
public void point_hasAltitudeValue() throws Exception {
13-
Point point = Point.fromLngLat(100, 0, 200);
17+
Point point = Point.fromLngLat(100, 0, 200,
18+
BoundingBox.fromLngLats(-100, -10, 100, 100, 10, 200));
19+
compareJson(loadJsonFixture(POINT_WITH_ALTITUDE_FIXTURE), point.toJson());
20+
}
21+
22+
@Test
23+
public void point_hasBboxValue() throws Exception {
24+
Point point = Point.fromLngLat(100, 0,
25+
BoundingBox.fromLngLats(-100, -10, 100, 10));
1426
compareJson(loadJsonFixture(POINT_WITH_BBOX_FIXTURE), point.toJson());
1527
}
28+
29+
@Test
30+
public void point_hasAltitudeAsNan() throws Exception {
31+
Point point = Point.fromLngLat(100, 0, Double.NaN);
32+
String expectedString = loadJsonFixture(POINT_FIXTURE);
33+
String jsonString = point.toJson();
34+
compareJson(expectedString, jsonString);
35+
}
1636
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
{
2+
"type": "FeatureCollection",
3+
"bbox": [100, 0, 105, 1],
4+
"features": [
5+
{
6+
"type": "Feature",
7+
"id": "id0",
8+
"bbox": [102, 0, 105, 1],
9+
"geometry": {
10+
"type": "LineString",
11+
"coordinates": [
12+
[102.0, 0.0], [103.0, 1.0], [104.0, 0.0], [105.0, 1.0]
13+
]
14+
},
15+
"properties": {
16+
"prop0": "value0",
17+
"prop1": "value1"
18+
}
19+
},
20+
{
21+
"type": "Feature",
22+
"id": "id1",
23+
"bbox": [100, 0, 101, 1],
24+
"geometry": {
25+
"type": "Polygon",
26+
"coordinates": [
27+
[
28+
[100.0, 0.0], [101.0, 0.0], [101.0, 1.0], [100.0, 1.0], [100.0, 0.0]
29+
]
30+
]
31+
},
32+
"properties": {
33+
"prop0": "value0",
34+
"prop1": "value1"
35+
}
36+
}
37+
]
38+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
{
2+
"id" : "id0",
3+
"bbox": [-120.0, -60.0, 120.0, 60.0],
4+
"geometry": {
5+
"bbox": [-110.0, -50.0, 110.0, 50.0],
6+
"coordinates": [
7+
100.0,
8+
0.0
9+
],
10+
"type": "Point"
11+
},
12+
"type": "Feature",
13+
"properties": {
14+
"prop0": "value0",
15+
"prop1": "value1"
16+
}
17+
}

0 commit comments

Comments
 (0)