Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature.id() can be String and Number #1033

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
80 changes: 67 additions & 13 deletions services-geojson/src/main/java/com/mapbox/geojson/Feature.java
Expand Up @@ -57,7 +57,7 @@ public final class Feature implements GeoJson {
@JsonAdapter(BoundingBoxTypeAdapter.class)
private final BoundingBox bbox;

private final String id;
private final Object id;

private final Geometry geometry;

Expand Down Expand Up @@ -158,11 +158,28 @@ public static Feature fromGeometry(@Nullable Geometry geometry, @Nullable JsonOb
* @param id common identifier of this feature
* @return {@link Feature}
* @since 1.0.0
* @deprecated since 5.0.0
*/
@Deprecated
public static Feature fromGeometry(@Nullable Geometry geometry, @Nullable JsonObject properties,
@Nullable String id) {
return fromGeometry(geometry, properties, (Object)id);
}

/**
* Create a new instance of this class by giving the feature a {@link Geometry}, optionally a
* set of properties, and a String which represents the objects id.
*
* @param geometry a single geometry which makes up this feature object
* @param properties a {@link JsonObject} containing the feature properties
* @param id common identifier of this feature
* @return {@link Feature}
* @since 5.0.0
*/
public static Feature fromGeometry(@Nullable Geometry geometry, @Nullable JsonObject properties,
@Nullable Object id) {
return new Feature(TYPE, null, id, geometry,
properties == null ? new JsonObject() : properties);
properties == null ? new JsonObject() : properties);
}

/**
Expand All @@ -175,14 +192,32 @@ public static Feature fromGeometry(@Nullable Geometry geometry, @Nullable JsonOb
* @param id common identifier of this feature
* @return {@link Feature}
* @since 1.0.0
* @deprecated since 4.9.0
*/
@Deprecated
public static Feature fromGeometry(@Nullable Geometry geometry, @NonNull JsonObject properties,
@Nullable String id, @Nullable BoundingBox bbox) {
return fromGeometry(geometry, properties, (Object)id, bbox);
}

/**
* Create a new instance of this class by giving the feature a {@link Geometry}, optionally a
* set of properties, and a String which represents the objects id.
*
* @param geometry a single geometry which makes up this feature object
* @param properties a {@link JsonObject} containing the feature properties
* @param bbox optionally include a bbox definition as a double array
* @param id common identifier of this feature
* @return {@link Feature}
* @since 4.9.0
*/
public static Feature fromGeometry(@Nullable Geometry geometry, @NonNull JsonObject properties,
@Nullable Object id, @Nullable BoundingBox bbox) {
return new Feature(TYPE, bbox, id, geometry,
properties == null ? new JsonObject() : properties);
}

Feature(String type, @Nullable BoundingBox bbox, @Nullable String id,
Feature(String type, @Nullable BoundingBox bbox, @Nullable Object id,
@Nullable Geometry geometry, @Nullable JsonObject properties) {
if (type == null) {
throw new NullPointerException("Null type");
Expand Down Expand Up @@ -229,13 +264,14 @@ public BoundingBox bbox() {
*
* @return a String containing this features unique identification or null if one wasn't given
* during creation.
* @since 1.0.0
* @since 5.0.0
*/
@Nullable
public String id() {
public Object id() {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be great to include as idAsString and idAsNumber facility methods (if the type doesn't match throw an exception).

return id;
}


/**
* The geometry which makes up this feature. A Geometry object represents points, curves, and
* surfaces in coordinate space. One of the seven geometries provided inside this library can be
Expand Down Expand Up @@ -499,6 +535,7 @@ static final class GsonTypeAdapter extends TypeAdapter<Feature> {
private volatile TypeAdapter<BoundingBox> boundingBoxTypeAdapter;
private volatile TypeAdapter<Geometry> geometryTypeAdapter;
private volatile TypeAdapter<JsonObject> jsonObjectTypeAdapter;
private volatile TypeAdapter<Double> doubleAdapter;
private final Gson gson;

GsonTypeAdapter(Gson gson) {
Expand Down Expand Up @@ -537,13 +574,20 @@ public void write(JsonWriter jsonWriter, Feature object) throws IOException {
jsonWriter.name("id");
if (object.id() == null) {
jsonWriter.nullValue();
} else {
} else if (object.id() instanceof String) {
TypeAdapter<String> stringTypeAdapter = this.stringTypeAdapter;
if (stringTypeAdapter == null) {
stringTypeAdapter = gson.getAdapter(String.class);
this.stringTypeAdapter = stringTypeAdapter;
}
stringTypeAdapter.write(jsonWriter, object.id());
stringTypeAdapter.write(jsonWriter, (String)object.id());
} else if (object.id instanceof Double) {
TypeAdapter<Double> doubleAdapter = this.doubleAdapter;
if (doubleAdapter == null) {
doubleAdapter = gson.getAdapter(Double.class);
this.doubleAdapter = doubleAdapter;
}
doubleAdapter.write(jsonWriter, (Double)object.id());
}
jsonWriter.name("geometry");
if (object.geometry() == null) {
Expand Down Expand Up @@ -579,7 +623,7 @@ public Feature read(JsonReader jsonReader) throws IOException {
jsonReader.beginObject();
String type = null;
BoundingBox bbox = null;
String id = null;
Object id = null;
Geometry geometry = null;
JsonObject properties = null;
while (jsonReader.hasNext()) {
Expand Down Expand Up @@ -608,12 +652,22 @@ public Feature read(JsonReader jsonReader) throws IOException {
break;

case "id":
strTypeAdapter = this.stringTypeAdapter;
if (strTypeAdapter == null) {
strTypeAdapter = gson.getAdapter(String.class);
this.stringTypeAdapter = strTypeAdapter;

if (jsonReader.peek() == JsonToken.STRING) {
strTypeAdapter = this.stringTypeAdapter;
if (strTypeAdapter == null) {
strTypeAdapter = gson.getAdapter(String.class);
this.stringTypeAdapter = strTypeAdapter;
}
id = strTypeAdapter.read(jsonReader);
} else {
TypeAdapter<Double> doubleAdapter = this.doubleAdapter;
if (doubleAdapter == null) {
doubleAdapter = gson.getAdapter(Double.class);
this.doubleAdapter = doubleAdapter;
}
id = doubleAdapter.read(jsonReader);
}
id = strTypeAdapter.read(jsonReader);
break;

case "geometry":
Expand Down
38 changes: 38 additions & 0 deletions services-geojson/src/test/java/com/mapbox/geojson/FeatureTest.java
Expand Up @@ -219,6 +219,44 @@ public void pointFeature_fromJson_toJson() throws IOException {
compareJson(jsonString, jsonStringFromFeature);
}

@Test
public void pointFeatureWithNumberId_fromJson_toJson() throws IOException {
final String jsonString =
"{\"id\" : 5," +
" \"bbox\": [-120.0, -60.0, 120.0, 60.0]," +
" \"geometry\": {" +
" \"bbox\": [-110.0, -50.0, 110.0, 50.0]," +
" \"coordinates\": [ 100.0, 0.0], " +
" \"type\": \"Point\"}," +
"\"type\": \"Feature\"," +
"\"properties\": {\"prop0\": \"value0\", \"prop1\": \"value1\"}" +
"}";


Feature featureFromJson = Feature.fromJson(jsonString);
String jsonStringFromFeature = featureFromJson.toJson();

compareJson(jsonString, jsonStringFromFeature);
}

@Test
public void id_number() throws IOException {
final String jsonString =
"{\"id\" : 5," +
" \"bbox\": [-120.0, -60.0, 120.0, 60.0]," +
" \"geometry\": {" +
" \"bbox\": [-110.0, -50.0, 110.0, 50.0]," +
" \"coordinates\": [ 100.0, 0.0], " +
" \"type\": \"Point\"}," +
"\"type\": \"Feature\"," +
"\"properties\": {\"prop0\": \"value0\", \"prop1\": \"value1\"}" +
"}";


Feature featureFromJson = Feature.fromJson(jsonString);
assertTrue(featureFromJson.id() instanceof Double);
}

@Test
public void feature_getProperty_empty_property() throws IOException {
final String jsonString =
Expand Down