From ce8b93b3617ca9e7ac755f56f15f23ae1c2f9b20 Mon Sep 17 00:00:00 2001 From: Dzina Dybouskaya Date: Wed, 19 Oct 2022 11:54:04 +0300 Subject: [PATCH] NAVAND-713: publicly expose unrecognized properties --- CHANGELOG.md | 4 + .../v5/models/DirectionsJsonObject.java | 37 +- .../v5/utils/UnrecognizedPropertiesUtils.java | 54 + .../v5/models/DirectionsResponseTest.java | 53 +- .../v5/models/LegAnnotationTest.java | 11 + .../UnrecognizedPropertiesUtilsTest.java | 75 + .../models/DirectionsRefreshJsonObject.java | 50 +- .../v1/models/DirectionsRefreshResponse.java | 2 +- .../v1/models/DirectionsRouteRefresh.java | 2 +- .../v1/models/RouteLegRefresh.java | 2 +- .../DirectionsRefreshResponseTest.java | 66 +- .../directions_refresh_v1_waypoints.json | 3065 +++++++++++++++++ 12 files changed, 3404 insertions(+), 17 deletions(-) create mode 100644 services-directions-models/src/main/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtils.java create mode 100644 services-directions-models/src/test/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtilsTest.java create mode 100644 services-directions-refresh-models/src/test/resources/directions_refresh_v1_waypoints.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 0890601a3..d42d1c740 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,10 @@ Mapbox welcomes participation and contributions from everyone. ### main +- Added `getUnrecognizedJsonProperties()` method to `DirectionsRefreshJsonObject` so that unrecognized properties can be received from refresh response. +- Added `DirectionsRefreshJsonObject.Builder#unrecognizedJsonProperties`. [#1500](https://github.com/mapbox/mapbox-java/pull/1500) +- Added `getUnrecognizedJsonProperties()` method to `DirectionsJsonObject` so that a map of unrecognized properties can be received from route response. +- Added `DirectionsJsonObject.Builder#unrecognizedJsonProperties`. [#1500](https://github.com/mapbox/mapbox-java/pull/1500) ### v6.8.0 - September 29, 2022 - Replaced `TurfSimplify#simplify` with `TurfTransformation#simplify`. [#1496](https://github.com/mapbox/mapbox-java/pull/1496) diff --git a/services-directions-models/src/main/java/com/mapbox/api/directions/v5/models/DirectionsJsonObject.java b/services-directions-models/src/main/java/com/mapbox/api/directions/v5/models/DirectionsJsonObject.java index 09c8f987e..dbfe69bd5 100644 --- a/services-directions-models/src/main/java/com/mapbox/api/directions/v5/models/DirectionsJsonObject.java +++ b/services-directions-models/src/main/java/com/mapbox/api/directions/v5/models/DirectionsJsonObject.java @@ -5,10 +5,11 @@ import com.google.gson.GsonBuilder; import com.google.gson.JsonElement; import com.mapbox.api.directions.v5.DirectionsAdapterFactory; -import com.mapbox.geojson.Point; -import com.mapbox.geojson.PointAsCoordinatesTypeAdapter; +import com.mapbox.api.directions.v5.utils.UnrecognizedPropertiesUtils; import com.mapbox.auto.value.gson.SerializableJsonElement; import com.mapbox.auto.value.gson.UnrecognizedJsonProperties; +import com.mapbox.geojson.Point; +import com.mapbox.geojson.PointAsCoordinatesTypeAdapter; import java.io.Serializable; import java.util.Collections; @@ -89,6 +90,24 @@ public final Set getUnrecognizedPropertiesNames() { return result; } + /** + * Use this method to get JSON properties that weren't recognized during JSON + * serialization by the model. This may be useful to access experimental API properties. + * When an experimental API property becomes stable, + * it will eventually have static field in a model introduced + * and it won't be available via this dynamic method anymore. + * + * See + * Directions API documentation + * for available experimental fields. + * + * @return unrecognized JSON properties + */ + @Nullable + public final Map getUnrecognizedJsonProperties() { + return UnrecognizedPropertiesUtils.fromSerializableProperties(unrecognized()); + } + @Nullable @UnrecognizedJsonProperties abstract Map unrecognized(); @@ -96,5 +115,19 @@ public final Set getUnrecognizedPropertiesNames() { abstract static class Builder { @NonNull abstract T unrecognized(@Nullable Map value); + + /** + * Use this method to add parameters which are not present in the model yet but are supported + * on the Directions API side in the response. + * Use it for experimental parameters. + * + * @param unrecognizedProperties parameters to add to request + */ + @NonNull + public T unrecognizedJsonProperties(@Nullable Map unrecognizedProperties) { + return unrecognized( + UnrecognizedPropertiesUtils.toSerializableProperties(unrecognizedProperties) + ); + } } } diff --git a/services-directions-models/src/main/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtils.java b/services-directions-models/src/main/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtils.java new file mode 100644 index 000000000..d0bda3cb2 --- /dev/null +++ b/services-directions-models/src/main/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtils.java @@ -0,0 +1,54 @@ +package com.mapbox.api.directions.v5.utils; + +import androidx.annotation.Nullable; +import com.google.gson.JsonElement; +import com.mapbox.auto.value.gson.SerializableJsonElement; + +import java.util.HashMap; +import java.util.Map; + +/** + * Provides utility methods to work with unrecognized properties. + */ +public final class UnrecognizedPropertiesUtils { + + /** + * Converts unrecognized properties in form of Map<String, SerializableJsonElement< + * to unrecognized properties in form of Map<String, JsonElement<. + * @param unrecognizedProperties original map + * @return converted map + */ + @Nullable + public static Map fromSerializableProperties( + @Nullable Map unrecognizedProperties + ) { + if (unrecognizedProperties != null) { + Map result = new HashMap<>(); + for (String key : unrecognizedProperties.keySet()) { + result.put(key, unrecognizedProperties.get(key).getElement()); + } + return result; + } + return null; + } + + /** + * Converts unrecognized properties in form of Map<String, JsonElement<. + * to unrecognized properties in form of Map<String, SerializableJsonElement<. + * @param unrecognizedProperties original map + * @return converted map + */ + @Nullable + public static Map toSerializableProperties( + @Nullable Map unrecognizedProperties + ) { + if (unrecognizedProperties != null) { + Map result = new HashMap<>(); + for (Map.Entry entry : unrecognizedProperties.entrySet()) { + result.put(entry.getKey(), new SerializableJsonElement(entry.getValue())); + } + return result; + } + return null; + } +} diff --git a/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/DirectionsResponseTest.java b/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/DirectionsResponseTest.java index 93f300920..80d8dd304 100644 --- a/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/DirectionsResponseTest.java +++ b/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/DirectionsResponseTest.java @@ -10,11 +10,15 @@ import com.mapbox.geojson.Point; import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; import java.util.List; import org.junit.Test; import java.util.ArrayList; +import java.util.Map; import java.util.Set; import static com.mapbox.api.directions.v5.utils.MutateJsonUtil.mutateJson; @@ -34,11 +38,41 @@ public class DirectionsResponseTest extends TestUtils { @Test public void sanity() throws Exception { + Metadata metadata = Metadata.builder().infoMap(Collections.singletonMap("aaa", "bbb")).build(); + List waypoints = Arrays.asList( + DirectionsWaypoint + .builder() + .rawLocation(new double[0]) + .distance(9.8) + .name("aaa") + .build() + ); + List routes = Arrays.asList( + DirectionsRoute + .builder() + .distance(1.2) + .duration(7.8) + .build() + ); + Map unrecognizedProperties = Collections.singletonMap("ccc", new JsonPrimitive("ddd")); DirectionsResponse response = DirectionsResponse.builder() .code("100") - .routes(new ArrayList()) + .routes(routes) + .message("Message") + .metadata(metadata) + .uuid("uuid") + .waypoints(waypoints) + .unrecognizedJsonProperties(unrecognizedProperties) .build(); + assertNotNull(response); + assertEquals("100", response.code()); + assertEquals("Message", response.message()); + assertEquals(1, response.routes().size()); + assertEquals(metadata, response.metadata()); + assertEquals("uuid", response.uuid()); + assertEquals(waypoints, response.waypoints()); + assertEquals(unrecognizedProperties, response.getUnrecognizedJsonProperties()); } @Test @@ -88,6 +122,21 @@ public void accessUnrecognizedProperties() throws Exception { assertNull(notExistingProperty); } + @Test + public void accessUnrecognizedJsonProperties() throws Exception { + JsonObject directionsResponseJson = readJsonObject(DIRECTIONS_V5_PRECISION6_FIXTURE_ARTIFICIAL_FIELDS); + String unrecognizedPropertyName = "testUnrecognizedProperty"; + String unrecognizedPropertyValue = "test"; + directionsResponseJson.add(unrecognizedPropertyName, new JsonPrimitive(unrecognizedPropertyValue)); + Map expected = new HashMap<>(); + expected.put(unrecognizedPropertyName, new JsonPrimitive(unrecognizedPropertyValue)); + DirectionsResponse response = DirectionsResponse.fromJson(directionsResponseJson.toString()); + + Map actual = response.getUnrecognizedJsonProperties(); + + assertEquals(expected, actual); + } + @Test public void noUnrecognizedProperties() throws Exception { JsonObject directionsResponseJson = readJsonObject(DIRECTIONS_V5_PRECISION6_FIXTURE_ARTIFICIAL_FIELDS); @@ -95,9 +144,11 @@ public void noUnrecognizedProperties() throws Exception { JsonElement value = response.getUnrecognizedProperty(""); Set propertiesNames = response.getUnrecognizedPropertiesNames(); + Map jsonProperties = response.getUnrecognizedJsonProperties(); assertNull(value); assertEquals(0, propertiesNames.size()); + assertNull(jsonProperties); } @Test diff --git a/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/LegAnnotationTest.java b/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/LegAnnotationTest.java index 400ad3e45..ce2daf864 100644 --- a/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/LegAnnotationTest.java +++ b/services-directions-models/src/test/java/com/mapbox/api/directions/v5/models/LegAnnotationTest.java @@ -3,12 +3,16 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import com.google.gson.JsonElement; +import com.google.gson.JsonPrimitive; import com.mapbox.core.TestUtils; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; public class LegAnnotationTest extends TestUtils { @@ -20,12 +24,15 @@ public void sanity() throws Exception { .distance(new ArrayList()) .duration(new ArrayList()) .speed(new ArrayList()) + .unrecognizedJsonProperties(new HashMap<>()) .build(); assertNotNull(annotation); } @Test public void testSerializable() throws Exception { + Map unrecognizedProperties = new HashMap<>(); + unrecognizedProperties.put("aaa", new JsonPrimitive("bbb")); List distance = new ArrayList<>(); distance.add(20d); distance.add(40d); @@ -36,6 +43,7 @@ public void testSerializable() throws Exception { .distance(distance) .duration(new ArrayList()) .speed(new ArrayList()) + .unrecognizedJsonProperties(unrecognizedProperties) .build(); byte[] serialized = TestUtils.serialize(annotation); assertEquals(annotation, deserialize(serialized, LegAnnotation.class)); @@ -43,6 +51,8 @@ public void testSerializable() throws Exception { @Test public void testToFromJson1() { + Map unrecognizedProperties = new HashMap<>(); + unrecognizedProperties.put("aaa", new JsonPrimitive("bbb")); List distanceList = Arrays.asList( 4.294596842089401, @@ -101,6 +111,7 @@ public void testToFromJson1() { .duration(durationList) .speed(speedList) .congestion(congestionList) + .unrecognizedJsonProperties(unrecognizedProperties) .build(); diff --git a/services-directions-models/src/test/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtilsTest.java b/services-directions-models/src/test/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtilsTest.java new file mode 100644 index 000000000..87a94bd5a --- /dev/null +++ b/services-directions-models/src/test/java/com/mapbox/api/directions/v5/utils/UnrecognizedPropertiesUtilsTest.java @@ -0,0 +1,75 @@ +package com.mapbox.api.directions.v5.utils; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; +import com.mapbox.auto.value.gson.SerializableJsonElement; +import org.junit.Assert; +import org.junit.Test; + +import java.util.HashMap; +import java.util.Map; + +public class UnrecognizedPropertiesUtilsTest { + + @Test + public void fromSerializableProperties_nullProperties() { + Map actual = UnrecognizedPropertiesUtils.fromSerializableProperties(null); + Assert.assertNull(actual); + } + + @Test + public void fromSerializableProperties_emptyProperties() { + Map actual = UnrecognizedPropertiesUtils.fromSerializableProperties( + new HashMap<>() + ); + Assert.assertEquals(0, actual.size()); + } + + @Test + public void fromSerializableProperties_hasProperties() { + final JsonObject propertyValue = new JsonObject(); + propertyValue.add("key", new JsonPrimitive("value")); + final Map properties = new HashMap<>(); + properties.put("aaa", new SerializableJsonElement(propertyValue)); + properties.put("bbb", new SerializableJsonElement(new JsonObject())); + Map expected = new HashMap<>(); + expected.put("aaa", propertyValue); + expected.put("bbb", new JsonObject()); + final Map actual = UnrecognizedPropertiesUtils.fromSerializableProperties( + properties + ); + Assert.assertEquals(expected, actual); + } + + @Test + public void toSerializableProperties_nullProperties() { + Map actual = UnrecognizedPropertiesUtils.toSerializableProperties(null); + Assert.assertNull(actual); + } + + @Test + public void toSerializableProperties_emptyProperties() { + Map actual = UnrecognizedPropertiesUtils.toSerializableProperties( + new HashMap<>() + ); + Assert.assertEquals(0, actual.size()); + } + + @Test + public void toSerializableProperties_hasProperties() { + final JsonObject propertyValue = new JsonObject(); + propertyValue.add("key", new JsonPrimitive("value")); + final Map properties = new HashMap<>(); + properties.put("aaa", propertyValue); + properties.put("bbb", new JsonObject()); + Map expected = new HashMap<>(); + expected.put("aaa", new SerializableJsonElement(propertyValue)); + expected.put("bbb", new SerializableJsonElement(new JsonObject())); + final Map actual = UnrecognizedPropertiesUtils.toSerializableProperties( + properties + ); + Assert.assertEquals(expected, actual); + } + +} \ No newline at end of file diff --git a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshJsonObject.java b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshJsonObject.java index 03c33ae14..d747b31f7 100644 --- a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshJsonObject.java +++ b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshJsonObject.java @@ -1,16 +1,23 @@ package com.mapbox.api.directionsrefresh.v1.models; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; import com.mapbox.api.directions.v5.DirectionsAdapterFactory; +import com.mapbox.api.directions.v5.utils.UnrecognizedPropertiesUtils; import com.mapbox.api.directionsrefresh.v1.DirectionsRefreshAdapterFactory; +import com.mapbox.auto.value.gson.SerializableJsonElement; +import com.mapbox.auto.value.gson.UnrecognizedJsonProperties; import com.mapbox.geojson.Point; import com.mapbox.geojson.PointAsCoordinatesTypeAdapter; import java.io.Serializable; +import java.util.Map; /** * Provides a base class for Directions model classes. */ -public class DirectionsRefreshJsonObject implements Serializable { +public abstract class DirectionsRefreshJsonObject implements Serializable { /** * This takes the currently defined values found inside this instance and converts it to a json @@ -25,4 +32,45 @@ public String toJson() { gson.registerTypeAdapterFactory(DirectionsRefreshAdapterFactory.create()); return gson.create().toJson(this); } + + /** + * Use this method to get JSON properties that weren't recognized during JSON + * serialization by the model. This may be useful to access experimental API properties. + * When an experimental API property becomes stable, + * it will eventually have static field in a model introduced + * and it won't be available via this dynamic method anymore. + * + * See + * Directions API documentation + * for available experimental fields. + * + * @return unrecognized JSON properties + */ + @Nullable + public final Map getUnrecognizedJsonProperties() { + return UnrecognizedPropertiesUtils.fromSerializableProperties(unrecognized()); + } + + @Nullable + @UnrecognizedJsonProperties + abstract Map unrecognized(); + + abstract static class Builder { + @NonNull + abstract T unrecognized(@Nullable Map value); + + /** + * Use this method to add parameters which are not present in the model yet but are supported + * on the Directions API side in the response. + * Use it for experimental parameters. + * + * @param unrecognizedProperties parameters to add to request + */ + @NonNull + public T unrecognizedJsonProperties(@Nullable Map unrecognizedProperties) { + return unrecognized( + UnrecognizedPropertiesUtils.toSerializableProperties(unrecognizedProperties) + ); + } + } } diff --git a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshResponse.java b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshResponse.java index e18131777..f59ae24fe 100644 --- a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshResponse.java +++ b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRefreshResponse.java @@ -99,7 +99,7 @@ public static DirectionsRefreshResponse fromJson(String json) { * @since 4.4.0 */ @AutoValue.Builder - public abstract static class Builder { + public abstract static class Builder extends DirectionsRefreshJsonObject.Builder { /** * String indicating the state of the response. This is a separate code than the HTTP status diff --git a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRouteRefresh.java b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRouteRefresh.java index 0388cfc85..9d6eb4780 100644 --- a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRouteRefresh.java +++ b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/DirectionsRouteRefresh.java @@ -71,7 +71,7 @@ public static DirectionsRouteRefresh fromJson(String json) { * This builder can be used to set the values describing the {@link DirectionsRouteRefresh}. */ @AutoValue.Builder - public abstract static class Builder { + public abstract static class Builder extends DirectionsRefreshJsonObject.Builder { /** * A Leg Refresh is an object contain refresh data between only two {@link DirectionsWaypoint}. diff --git a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/RouteLegRefresh.java b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/RouteLegRefresh.java index 6e2b78932..711dc3f02 100644 --- a/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/RouteLegRefresh.java +++ b/services-directions-refresh-models/src/main/java/com/mapbox/api/directionsrefresh/v1/models/RouteLegRefresh.java @@ -96,7 +96,7 @@ public static RouteLegRefresh fromJson(String json) { * This builder can be used to set the values describing the {@link RouteLegRefresh}. */ @AutoValue.Builder - public abstract static class Builder { + public abstract static class Builder extends DirectionsRefreshJsonObject.Builder { /** * A list of incidents that occur on this leg. diff --git a/services-directions-refresh-models/src/test/java/com.mapbox.api.directionsrefresh.v1.models/DirectionsRefreshResponseTest.java b/services-directions-refresh-models/src/test/java/com.mapbox.api.directionsrefresh.v1.models/DirectionsRefreshResponseTest.java index 979db942d..dfa6475f9 100644 --- a/services-directions-refresh-models/src/test/java/com.mapbox.api.directionsrefresh.v1.models/DirectionsRefreshResponseTest.java +++ b/services-directions-refresh-models/src/test/java/com.mapbox.api.directionsrefresh.v1.models/DirectionsRefreshResponseTest.java @@ -1,35 +1,52 @@ package com.mapbox.api.directionsrefresh.v1.models; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import com.mapbox.core.TestUtils; +import org.junit.Test; + import java.io.IOException; import java.util.Collections; -import org.junit.Test; +import java.util.HashMap; +import java.util.Map; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class DirectionsRefreshResponseTest extends TestUtils { private static final String DIRECTIONS_REFRESH_V1 = "directions_refresh_v1.json"; + private static final String DIRECTIONS_REFRESH_V1_WAYPOINTS = "directions_refresh_v1_waypoints.json"; @Test public void sanity() { - DirectionsRefreshResponse.builder() + DirectionsRouteRefresh route = DirectionsRouteRefresh.builder() + .legs(Collections.emptyList()) + .build(); + Map unrecognizedProperties = Collections + .singletonMap("key1", new JsonPrimitive("value1")); + DirectionsRefreshResponse response = DirectionsRefreshResponse.builder() .code("200") .message("Message") - .route( - DirectionsRouteRefresh.builder() - .legs(Collections.emptyList()) - .build() - ) + .route(route) + .unrecognizedJsonProperties(unrecognizedProperties) .build(); + + assertEquals("200", response.code()); + assertEquals("Message", response.message()); + assertEquals(route, response.route()); + assertEquals(unrecognizedProperties, response.getUnrecognizedJsonProperties()); } @Test public void testSerialization() throws IOException { DirectionsRefreshResponse directionsRefreshResponse = - DirectionsRefreshResponse.fromJson(loadJsonFixture(DIRECTIONS_REFRESH_V1)); + DirectionsRefreshResponse.fromJson(loadJsonFixture(DIRECTIONS_REFRESH_V1_WAYPOINTS)); assertEquals(directionsRefreshResponse.code(), "Ok"); assertNotNull(directionsRefreshResponse.route()); @@ -41,10 +58,9 @@ public void testSerialization() throws IOException { assertTrue(directionsRefreshResponse.route().legs().get(0).incidents().size() > 0); assertTrue(directionsRefreshResponse.route().legs().get(0).closures().size() > 0); } - @Test public void testSerializationDeserialization() throws IOException { - String json = loadJsonFixture(DIRECTIONS_REFRESH_V1); + String json = loadJsonFixture(DIRECTIONS_REFRESH_V1_WAYPOINTS); DirectionsRefreshResponse fromJson1 = DirectionsRefreshResponse.fromJson(json); String jsonFromObj = fromJson1.toJson(); @@ -52,4 +68,34 @@ public void testSerializationDeserialization() throws IOException { assertEquals(fromJson1, fromJson2); } + + @Test + public void accessUnrecognizedProperties() throws Exception { + Map expected = new HashMap<>(); + JsonObject directionsRefreshResponseJson = readJsonObject(DIRECTIONS_REFRESH_V1); + String unrecognizedPropertyName = "testUnrecognizedProperty"; + String unrecognizedPropertyValue = "test"; + directionsRefreshResponseJson.add(unrecognizedPropertyName, new JsonPrimitive(unrecognizedPropertyValue)); + expected.put(unrecognizedPropertyName, new JsonPrimitive(unrecognizedPropertyValue)); + DirectionsRefreshResponse response = DirectionsRefreshResponse.fromJson(directionsRefreshResponseJson.toString()); + + Map actual = response.getUnrecognizedJsonProperties(); + + assertEquals(expected, actual); + } + + @Test + public void noUnrecognizedProperties() throws Exception { + JsonObject directionsRefreshResponseJson = readJsonObject(DIRECTIONS_REFRESH_V1); + DirectionsRefreshResponse response = DirectionsRefreshResponse.fromJson(directionsRefreshResponseJson.toString()); + + Map actual = response.getUnrecognizedJsonProperties(); + + assertNull(actual); + } + + private JsonObject readJsonObject(String file) throws IOException { + Gson gson = new GsonBuilder().create(); + return gson.fromJson(loadJsonFixture(file), JsonObject.class); + } } diff --git a/services-directions-refresh-models/src/test/resources/directions_refresh_v1_waypoints.json b/services-directions-refresh-models/src/test/resources/directions_refresh_v1_waypoints.json new file mode 100644 index 000000000..ed8f2e562 --- /dev/null +++ b/services-directions-refresh-models/src/test/resources/directions_refresh_v1_waypoints.json @@ -0,0 +1,3065 @@ +{ + "code": "Ok", + "route": { + "legs": [ + { + "closures": [ + { + "geometry_index_end": 21, + "geometry_index_start": 13 + } + ], + "incidents": [ + { + "length": 288, + "affected_road_names": [ + "Möllendorffstraße" + ], + "id": "14158569638505033", + "type": "lane_restriction", + "congestion": { + "value": 101 + }, + "description": "Möllendorffstrasse: Bauarbeiten zwischen Storkower Strasse und Scheffelstrasse", + "long_description": "Fahrbahnverengung von auf eine Fahrspur wegen Bauarbeiten auf der Möllendorffstrasse in Richtung Süden zwischen Storkower Strasse und Scheffelstrasse.", + "impact": "low", + "alertc_codes": [ + 743 + ], + "geometry_index_start": 453, + "geometry_index_end": 466, + "creation_time": "2022-05-11T14:10:36Z", + "start_time": "2022-04-19T05:00:00Z", + "end_time": "2022-06-30T21:59:00Z", + "iso_3166_1_alpha2": "DE", + "iso_3166_1_alpha3": "DEU", + "lanes_blocked": [] + }, + { + "length": 314, + "affected_road_names": [ + "Köpenicker Chaussee", + "Rummelsburger Landstraße" + ], + "id": "10682743105318298", + "type": "lane_restriction", + "congestion": { + "value": 101 + }, + "description": "Poggendorffweg: Bauarbeiten um Rummelsburger Landstrasse", + "long_description": "Fahrbahnverengung von auf eine Fahrspur wegen Bauarbeiten auf der Poggendorffweg in beiden Richtungen zwischen Köpenicker Chaussee und Rummelsburger Landstrasse.", + "impact": "low", + "alertc_codes": [ + 743 + ], + "geometry_index_start": 656, + "geometry_index_end": 665, + "creation_time": "2022-05-11T14:10:36Z", + "start_time": "2022-04-12T16:59:23Z", + "end_time": "2022-05-28T21:59:00Z", + "iso_3166_1_alpha2": "DE", + "iso_3166_1_alpha3": "DEU", + "lanes_blocked": [] + }, + { + "length": 369, + "affected_road_names": [ + "Rummelsburger Landstraße" + ], + "id": "11589180127444257", + "type": "lane_restriction", + "congestion": { + "value": 101 + }, + "description": "Rummelsburger Landstrasse: Bauarbeiten um Fritz-König-Weg", + "long_description": "Fahrbahnverengung von auf eine Fahrspur wegen Bauarbeiten auf der Rummelsburger Landstrasse in Richtung Süden zwischen Rummelsburger Landstrasse und Fritz-König-Weg.", + "impact": "low", + "alertc_codes": [ + 743 + ], + "geometry_index_start": 672, + "geometry_index_end": 680, + "creation_time": "2022-05-11T14:10:36Z", + "start_time": "2022-04-29T13:08:25Z", + "end_time": "2022-05-30T21:59:00Z", + "iso_3166_1_alpha2": "DE", + "iso_3166_1_alpha3": "DEU", + "lanes_blocked": [] + } + ], + "annotation": { + "traffic_tendency": [ + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 5, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 1, + 0, + 1, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 3, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 1, + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 5 + ], + "duration": [ + 4.3, + 1.4, + 1.6, + 1.1, + 1.1, + 2, + 1.5, + 2.9, + 2.2, + 3.9, + 2.5, + 1.7, + 1.8, + 0.4, + 2.4, + 4.6, + 1.1, + 4.1, + 0.7, + 1.1, + 5.4, + 4.8, + 2.6, + 3.5, + 2.8, + 1.4, + 1.2, + 0.2, + 3.5, + 0.2, + 0.4, + 1.2, + 0.7, + 0.7, + 0.6, + 0.7, + 0.8, + 0.5, + 0.8, + 0.7, + 0.6, + 0.9, + 0.8, + 0.8, + 0.8, + 0.4, + 1.4, + 2, + 1.9, + 2.6, + 2.9, + 2.9, + 2.6, + 2.3, + 2.4, + 3.1, + 2.4, + 3, + 2.7, + 1.1, + 2.4, + 2, + 0.6, + 0.2, + 1.9, + 2.1, + 1.3, + 0.9, + 0.6, + 0.9, + 6.4, + 2.7, + 2.6, + 2.2, + 0.6, + 0.7, + 0.9, + 0.5, + 0.5, + 0.6, + 1.7, + 2.1, + 1.9, + 1.1, + 2, + 1.6, + 0.4, + 3.5, + 1, + 1.1, + 1.6, + 1.7, + 1.3, + 1, + 3.8, + 3.1, + 1.4, + 1.3, + 2.4, + 1.8, + 1.4, + 1.3, + 1.3, + 1.6, + 2.4, + 2.3, + 3.1, + 1.8, + 1.7, + 1.7, + 2.1, + 1.9, + 2.2, + 2.1, + 2.6, + 7.7, + 2.5, + 2.1, + 0.8, + 1, + 0.6, + 2.1, + 2, + 2.1, + 1.7, + 1.2, + 5.3, + 2.2, + 3.2, + 3.9, + 3.4, + 2.5, + 2, + 2, + 1.9, + 2.4, + 1.8, + 1.4, + 1.6, + 1.4, + 1.1, + 1.5, + 1.5, + 3.4, + 2.2, + 3.3, + 1, + 0.9, + 1.9, + 79.6, + 11, + 2.1, + 0.8, + 1.6, + 2.4, + 2.1, + 9.9, + 12.6, + 12.8, + 5.2, + 2.8, + 3.2, + 1.7, + 2.5, + 3.1, + 2.1, + 0.7, + 17.2, + 1.1, + 0.4, + 0.1, + 1, + 0.6, + 0.2, + 1.2, + 1, + 1.1, + 5.2, + 3.7, + 7.7, + 1.6, + 9.9, + 5, + 1, + 0.7, + 2.8, + 14.2, + 7.4, + 4.6, + 2.5, + 2.3, + 3.6, + 3.7, + 3.6, + 12.5, + 1.1, + 0.9, + 1.2, + 1.7, + 2.5, + 1.9, + 0.8, + 1.8, + 2, + 0.6, + 0.8, + 1.9, + 1.4, + 3.2, + 1.8, + 2.1, + 0.9, + 0.7, + 0.5, + 0.3, + 2.5, + 2, + 0.6, + 0.8, + 1, + 2.3, + 1, + 2, + 2.3, + 2.1, + 1.3, + 1.2, + 2.4, + 0.9, + 1.7, + 1.8, + 0.3, + 1.1, + 2.5, + 0.3, + 0.5, + 0.4, + 0.4, + 0.2, + 0.1, + 0.6, + 0.6, + 0.9, + 0.7, + 0.5, + 0.7, + 0.5, + 0.2, + 0.2, + 0.3, + 0.2, + 0.5, + 0.7, + 0.5, + 0.2, + 0.3, + 0.5, + 0.3, + 0.3, + 0.3, + 0.3, + 0.3, + 0.2, + 0.2, + 0.4, + 0.6, + 0.6, + 2.3, + 0.9, + 0.7, + 0.2, + 0.4, + 0.3, + 0.4, + 0.7, + 0.3, + 0.3, + 0.2, + 0.2, + 0.3, + 0.2, + 0.6, + 0.2, + 0.4, + 0.3, + 0.4, + 0.3, + 0.5, + 0.6, + 0.3, + 1.1, + 0.3, + 0.3, + 0.4, + 0.2, + 0.3, + 0.3, + 0.2, + 0.3, + 0.1, + 0.4, + 0.4, + 0.2, + 0.4, + 0.2, + 1, + 1, + 1.2, + 0.8, + 1.4, + 1.7, + 2.2, + 2.8, + 2.2, + 3.8, + 1.5, + 1.3, + 1.5, + 0.9, + 1.1, + 0.9, + 1.2, + 0.6, + 1.6, + 3.6, + 2.2, + 2.1, + 2.2, + 3, + 2.1, + 1.9, + 1.3, + 1.5, + 1, + 1.2, + 0.8, + 0.7, + 0.7, + 1.1, + 1.4, + 1, + 0.6, + 0.9, + 0.9, + 1.6, + 0.9, + 0.3, + 0.3, + 0.5, + 0.5, + 0.6, + 0.8, + 0.6, + 0.6, + 0.7, + 0.9, + 1.5, + 0.6, + 1.5, + 0.5, + 0.7, + 0.5, + 0.6, + 0.7, + 1.5, + 1.6, + 1, + 0.2, + 0.4, + 0.6, + 0.4, + 0.2, + 0.2, + 0.4, + 0.4, + 0.4, + 0.3, + 1.2, + 0.5, + 0.5, + 0.5, + 0.3, + 0.5, + 1.1, + 0.3, + 0.3, + 0.3, + 0.5, + 0.9, + 1.5, + 1.4, + 1.9, + 1.3, + 1.4, + 1.2, + 0.9, + 0.8, + 1.2, + 1.3, + 1.8, + 0.8, + 0.8, + 1.9, + 1.6, + 1.5, + 2.1, + 1.1, + 0.6, + 1.7, + 1.3, + 1.6, + 0.9, + 0.3, + 0.6, + 0.3, + 0.3, + 0.6, + 0.6, + 0.6, + 0.6, + 0.6, + 1.8, + 0.6, + 0.6, + 0.4, + 0.8, + 0.4, + 0.8, + 0.8, + 1.3, + 1, + 1, + 1, + 1, + 0.5, + 0.5, + 1.6, + 1.1, + 0.7, + 0.5, + 0.5, + 0.5, + 0.5, + 0.5, + 5.3, + 2.4, + 10.9, + 2.4, + 5.7, + 16.2, + 7.7, + 6.7 + ], + "congestion": [ + "severe", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "low", + "low", + "low", + "heavy", + "heavy", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "heavy", + "heavy", + "heavy", + "low", + "low", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "heavy", + "low", + "low", + "low", + "low", + "low", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "moderate", + "unknown", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "moderate", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "moderate", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low", + "low" + ], + "maxspeed": [ + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 30, + "unit": "mph" + }, + { + "speed": 30, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "speed": 35, + "unit": "mph" + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "unknown": true + }, + { + "speed": 30, + "unit": "mph" + } + ] + } + } + ], + "waypoints": [ + { + "name": "", + "location": [-122.416686,37.783425], + "distance": 0 + }, + { + "name": "", + "location": [-122.801453,38.971143], + "distance": 106, + "metadata": { + "type": "charging-station", + "name": "", + "charge_time": 111, + "charge_to": 1111, + "charge_at_arrival": 1111, + "plug_type": "tesla", + "current_type": "dc", + "power_kw": 111, + "station_id": "" + } + } + ] + } +} \ No newline at end of file