Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions services-geojson/src/main/java/com/mapbox/geojson/Point.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,14 @@
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.reflect.TypeToken;
import com.mapbox.geojson.gson.BoundingBoxDeserializer;
import com.mapbox.geojson.gson.BoundingBoxSerializer;
import com.mapbox.geojson.gson.CoordinateTypeAdapter;
import com.mapbox.geojson.gson.GeoJsonAdapterFactory;
import com.mapbox.geojson.shifter.CoordinateShifterManager;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;

/**
Expand Down Expand Up @@ -72,6 +74,8 @@ public abstract class Point implements CoordinateContainer<List<Double>>, Serial
public static Point fromJson(@NonNull String json) {
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapterFactory(GeoJsonAdapterFactory.create());
gson.registerTypeAdapter(new TypeToken<List<Double>>(){}.getType(),
new CoordinateTypeAdapter());
gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxDeserializer());
return gson.create().fromJson(json, Point.class);
}
Expand All @@ -92,7 +96,9 @@ public static Point fromJson(@NonNull String json) {
public static Point fromLngLat(
@FloatRange(from = MIN_LONGITUDE, to = MAX_LONGITUDE) double longitude,
@FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latitude) {
List<Double> coordinates = Arrays.asList(longitude, latitude);

List<Double> coordinates =
CoordinateShifterManager.getCoordinateShifter().shiftLonLat(longitude, latitude);
return new AutoValue_Point(TYPE, null, coordinates);
}

Expand All @@ -115,7 +121,9 @@ public static Point fromLngLat(
@FloatRange(from = MIN_LONGITUDE, to = MAX_LONGITUDE) double longitude,
@FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latitude,
@Nullable BoundingBox bbox) {
List<Double> coordinates = Arrays.asList(longitude, latitude);

List<Double> coordinates =
CoordinateShifterManager.getCoordinateShifter().shiftLonLat(longitude, latitude);
return new AutoValue_Point(TYPE, bbox, coordinates);
}

Expand All @@ -139,9 +147,9 @@ public static Point fromLngLat(
@FloatRange(from = MIN_LONGITUDE, to = MAX_LONGITUDE) double longitude,
@FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latitude,
double altitude) {
List<Double> coordinates = Double.isNaN(altitude)
? Arrays.asList(longitude, latitude) :
Arrays.asList(longitude, latitude, altitude);

List<Double> coordinates =
CoordinateShifterManager.getCoordinateShifter().shiftLonLatAlt(longitude, latitude, altitude);
return new AutoValue_Point(TYPE, null, coordinates);
}

Expand All @@ -166,9 +174,9 @@ public static Point fromLngLat(
@FloatRange(from = MIN_LONGITUDE, to = MAX_LONGITUDE) double longitude,
@FloatRange(from = MIN_LATITUDE, to = MAX_LATITUDE) double latitude,
double altitude, @Nullable BoundingBox bbox) {
List<Double> coordinates = Double.isNaN(altitude)
? Arrays.asList(longitude, latitude) :
Arrays.asList(longitude, latitude, altitude);

List<Double> coordinates =
CoordinateShifterManager.getCoordinateShifter().shiftLonLatAlt(longitude, latitude, altitude);
return new AutoValue_Point(TYPE, bbox, coordinates);
}

Expand Down Expand Up @@ -284,6 +292,8 @@ public boolean hasAltitude() {
@Override
public String toJson() {
GsonBuilder gson = new GsonBuilder();
gson.registerTypeAdapter(new TypeToken<List<Double>>(){}.getType(),
new CoordinateTypeAdapter());
gson.registerTypeAdapter(BoundingBox.class, new BoundingBoxSerializer());
return gson.create().toJson(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.mapbox.geojson.gson;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import com.mapbox.geojson.shifter.CoordinateShifterManager;

import java.io.IOException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

/**
* Adapter to read and write coordinates for Point class.
*
* @since 4.1.0
*/
public class CoordinateTypeAdapter extends TypeAdapter<List<Double>> {
@Override
public void write(JsonWriter out, List<Double> value) throws IOException {

out.beginArray();

// Unshift coordinates
List<Double> unshiftedCoordinates =
CoordinateShifterManager.getCoordinateShifter().unshiftPoint(value);

BigDecimal lon = BigDecimal.valueOf(unshiftedCoordinates.get(0));
String lonString = lon.setScale(7, RoundingMode.HALF_UP)
.stripTrailingZeros().toPlainString();

BigDecimal lat = BigDecimal.valueOf(unshiftedCoordinates.get(1));
String latString = lat.setScale(7, RoundingMode.HALF_UP)
.stripTrailingZeros().toPlainString();

out.value(Double.valueOf(lonString));
out.value(Double.valueOf(latString));

// Includes altitude
if (value.size() > 2) {
out.value(unshiftedCoordinates.get(2));
}
out.endArray();
}

@Override
public List<Double> read(JsonReader in) throws IOException {
List<Double> coordinates = new ArrayList<Double>();
in.beginArray();
while (in.hasNext()) {
coordinates.add(in.nextDouble());
}
in.endArray();

if (coordinates.size() > 2) {
return CoordinateShifterManager.getCoordinateShifter()
.shiftLonLatAlt(coordinates.get(0), coordinates.get(1), coordinates.get(2));
}
return CoordinateShifterManager.getCoordinateShifter()
.shiftLonLat(coordinates.get(0), coordinates.get(1));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.mapbox.geojson.Point;
import com.mapbox.geojson.shifter.CoordinateShifterManager;

import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

/**
* Required to handle the special case where the altitude might be a Double.NaN, which isn't a valid
Expand Down Expand Up @@ -44,20 +46,24 @@ public PointSerializer() {
public JsonElement serialize(Point src, Type typeOfSrc, JsonSerializationContext context) {
JsonArray rawCoordinates = new JsonArray();

BigDecimal lat = BigDecimal.valueOf(src.latitude());
String latString = lat.setScale(7, RoundingMode.HALF_UP)
.stripTrailingZeros().toPlainString();
// Unshift coordinates
List<Double> unshiftedCoordinates =
CoordinateShifterManager.getCoordinateShifter().unshiftPoint(src);

BigDecimal lon = BigDecimal.valueOf(src.longitude());
BigDecimal lon = BigDecimal.valueOf(unshiftedCoordinates.get(0));
String lonString = lon.setScale(7, RoundingMode.HALF_UP)
.stripTrailingZeros().toPlainString();

BigDecimal lat = BigDecimal.valueOf(unshiftedCoordinates.get(1));
String latString = lat.setScale(7, RoundingMode.HALF_UP)
.stripTrailingZeros().toPlainString();

rawCoordinates.add(new JsonPrimitive(Double.valueOf(lonString)));
rawCoordinates.add(new JsonPrimitive(Double.valueOf(latString)));

// Includes altitude
if (src.hasAltitude()) {
rawCoordinates.add(new JsonPrimitive(src.altitude()));
rawCoordinates.add(new JsonPrimitive(unshiftedCoordinates.get(3)));
}

return rawCoordinates;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package com.mapbox.geojson.shifter;

import com.mapbox.geojson.Point;

import java.util.List;

/**
* ShifterManager allows to move all points according to some pluggable algorithm.
* Once set it will be applied to all Point object created through this method.
*
* @since 4.1.0
*/
public interface CoordinateShifter {

/**
* Shifted coordinate values according to its algorithm.
*
* @param lon unshifted longitude
* @param lat unshifted latitude
* @return shifted longitude, shifted latitude in the form of List of Double
* @since 4.1.0
*/
List<Double> shiftLonLat(double lon, double lat);

/**
* Shifted coordinate values according to its algorithm.
*
* @param lon unshifted longitude
* @param lat unshifted latitude
* @param altitude unshifted altitude
* @return shifted longitude, shifted latitude, shifted altitude in the form of List of Double
* @since 4.1.0
*/
List<Double> shiftLonLatAlt(double lon, double lat, double altitude);

/**
* Unshifted coordinate values according to its algorithm.
*
* @param shiftedPoint shifted point
* @return unshifted longitude, shifted latitude,
* and altitude (if present) in the form of List of Double
* @since 4.1.0
*/
List<Double> unshiftPoint(Point shiftedPoint);


/**
* Unshifted coordinate values according to its algorithm.
*
* @param shiftedCoordinates shifted point
* @return unshifted longitude, shifted latitude,
* and altitude (if present) in the form of List of Double
* @since 4.1.0
*/
List<Double> unshiftPoint(List<Double> shiftedCoordinates);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.mapbox.geojson.shifter;

import com.mapbox.geojson.Point;

import java.util.Arrays;
import java.util.List;

/**
* CoordinateShifterManager keeps track of currently set CoordinateShifter.
*
* @since 4.1.0
*/
public final class CoordinateShifterManager {

private static final CoordinateShifter DEFAULT = new CoordinateShifter() {
@Override
public List<Double> shiftLonLat(double lon, double lat) {
return Arrays.asList(lon, lat);
}

@Override
public List<Double> shiftLonLatAlt(double lon, double lat, double alt) {
return Double.isNaN(alt)
? Arrays.asList(lon, lat) :
Arrays.asList(lon, lat, alt);
}

@Override
public List<Double> unshiftPoint(Point point) {
return point.coordinates();
}

@Override
public List<Double> unshiftPoint(List<Double> coordinates) {
return coordinates;
}
};

private static volatile CoordinateShifter coordinateShifter = DEFAULT;

/**
* Currently set CoordinateShifterManager.
*
* @return Currently set CoordinateShifterManager
* @since 4.1.0
*/
public static CoordinateShifter getCoordinateShifter() {
return coordinateShifter;
}

/**
* Sets CoordinateShifterManager.
*
* @param coordinateShifter CoordinateShifterManager to be set
* @since 4.1.0
*/
public static void setCoordinateShifter(CoordinateShifter coordinateShifter) {
CoordinateShifterManager.coordinateShifter =
coordinateShifter == null ? DEFAULT : coordinateShifter;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/**
* Contains Utility for univerally applying shiftign algorithm to all Geometry.
*/
package com.mapbox.geojson.shifter;
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.mapbox.core.TestUtils;
import com.mapbox.core.exceptions.ServicesException;
import com.mapbox.geojson.Point;

import org.junit.Rule;
Expand All @@ -14,10 +13,9 @@
import java.lang.reflect.Type;
import java.util.List;

import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.startsWith;
import static org.junit.Assert.assertEquals;


public class PointDeserializerTest extends TestUtils {

@Rule
Expand Down
Loading