Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
8c69ad4
Use primitive array in Point instead of List
jush Jan 23, 2026
16a474d
Use flat structure for LineString data
jush Jan 25, 2026
03133c4
Use class to store flatten list of points
jush Jan 25, 2026
8cd1b9c
Rename PrimitiveCoordinateContainer to FlattenedCoordinateContainer
jush Jan 25, 2026
c182c29
Minor refactor FlattenListOfPoints
jush Jan 25, 2026
b2754df
Add missing Keep to FlattenedCoordinateContainer
jush Jan 25, 2026
b107ac9
Convert MultiPoint to use flatten structure
jush Jan 25, 2026
c5cdda7
Remove unused ListOfPointCoordinatesTypeAdapter.java
jush Jan 25, 2026
981ea48
Minor rename and fix empty list of points
jush Jan 25, 2026
a6e7feb
Small javadoc fixes
jush Jan 26, 2026
a715c38
Fix code style
jush Jan 26, 2026
cfa95b9
Better names when reading point from JSON
jush Jan 26, 2026
8db98e8
Fix order of lng,lat in various names and improved tests
jush Jan 26, 2026
eb96721
Improve reading list of points from JSON
jush Jan 26, 2026
63fc157
Expose LineString constructor with FlattenListOfPoints
jush Jan 26, 2026
6d564fb
Added encode/decode to PolylineUtils
jush Jan 26, 2026
b0fb8f7
Build LineString.toString using the FlattenListOfPoints
jush Jan 26, 2026
c3d7bab
Code style fixes
jush Jan 27, 2026
e264d6f
Use flattenListOfPoints for the `toString`
jush Jan 27, 2026
e375321
Update services-geojson/src/main/java/com/mapbox/geojson/FlattenListO…
jush Jan 27, 2026
aa51c39
PolylineUtils#decodeToFlattenListOfPoints returns double[]
jush Jan 29, 2026
9c85c7d
Fixed TurfMiscTest tests
jush Jan 29, 2026
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
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package com.mapbox.geojson;

import androidx.annotation.Keep;
import androidx.annotation.NonNull;

import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonToken;
import com.google.gson.stream.JsonWriter;
import com.mapbox.geojson.exception.GeoJsonException;
import com.mapbox.geojson.shifter.CoordinateShifterManager;
import com.mapbox.geojson.utils.GeoJsonUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* Base class for converting {@code T} instance of coordinates to JSON and
* JSON to instance of {@code T}.
* Base class for converting {@code T} instance of coordinates to JSON and
* JSON to instance of {@code T}.
*
* @param <T> Type of coordinates
* @since 4.6.0
Expand All @@ -25,25 +23,19 @@
abstract class BaseCoordinatesTypeAdapter<T> extends TypeAdapter<T> {


protected void writePoint(JsonWriter out, Point point) throws IOException {
protected void writePoint(JsonWriter out, Point point) throws IOException {
if (point == null) {
return;
}
writePointList(out, point.coordinates());
writePointList(out, point.flattenCoordinates());
}

protected Point readPoint(JsonReader in) throws IOException {

List<Double> coordinates = readPointList(in);
if (coordinates != null && coordinates.size() > 1) {
return new Point("Point",null, coordinates);
}

throw new GeoJsonException(" Point coordinates should be non-null double array");
return new Point("Point", null, readPointList(in));
}


protected void writePointList(JsonWriter out, List<Double> value) throws IOException {
protected void writePointList(JsonWriter out, double[] value) throws IOException {

if (value == null) {
return;
Expand All @@ -52,38 +44,52 @@ protected void writePointList(JsonWriter out, List<Double> value) throws IOExcep
out.beginArray();

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

out.value(GeoJsonUtils.trim(unshiftedCoordinates.get(0)));
out.value(GeoJsonUtils.trim(unshiftedCoordinates.get(1)));
out.value(GeoJsonUtils.trim(unshiftedCoordinates[0]));
out.value(GeoJsonUtils.trim(unshiftedCoordinates[1]));

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

protected List<Double> readPointList(JsonReader in) throws IOException {

@NonNull
protected double[] readPointList(JsonReader in) throws IOException {
if (in.peek() == JsonToken.NULL) {
throw new NullPointerException();
}

List<Double> coordinates = new ArrayList<Double>(3);
double lon;
double lat;
double altitude;
in.beginArray();
while (in.hasNext()) {
coordinates.add(in.nextDouble());
if (in.hasNext()) {
lon = in.nextDouble();
} else {
throw new IndexOutOfBoundsException("Point coordinates should contain at least two values");
}
in.endArray();

if (coordinates.size() > 2) {
return CoordinateShifterManager.getCoordinateShifter()
.shiftLonLatAlt(coordinates.get(0), coordinates.get(1), coordinates.get(2));
if (in.hasNext()) {
lat = in.nextDouble();
} else {
throw new IndexOutOfBoundsException("Point coordinates should contain at least two values");
}
if (in.hasNext()) {
altitude = in.nextDouble();
// Consume any extra value but don't store it
while (in.hasNext()) {
in.skipValue();
}
in.endArray();
return CoordinateShifterManager.getCoordinateShifter().shift(lon, lat, altitude);
} else {
in.endArray();
return CoordinateShifterManager.getCoordinateShifter().shift(lon, lat);
}
return CoordinateShifterManager.getCoordinateShifter()
.shiftLonLat(coordinates.get(0), coordinates.get(1));

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,26 +21,66 @@
* @since 4.6.0
*/
@Keep
abstract class BaseGeometryTypeAdapter<G, T> extends TypeAdapter<G> {
abstract class BaseGeometryTypeAdapter<G, T, A> extends TypeAdapter<G> {

private volatile TypeAdapter<String> stringAdapter;
private volatile TypeAdapter<BoundingBox> boundingBoxAdapter;
private volatile TypeAdapter<T> coordinatesAdapter;
private volatile TypeAdapter<A> coordinatesAdapter;

private final Gson gson;

BaseGeometryTypeAdapter(Gson gson, TypeAdapter<T> coordinatesAdapter) {
BaseGeometryTypeAdapter(Gson gson, TypeAdapter<A> coordinatesAdapter) {
this.gson = gson;
this.coordinatesAdapter = coordinatesAdapter;
this.boundingBoxAdapter = new BoundingBoxTypeAdapter();
}

public void writeCoordinateContainer(JsonWriter jsonWriter, CoordinateContainer<T> object)
public void writeCoordinateContainerPrimitive(
JsonWriter jsonWriter,
FlattenedCoordinateContainer<T, A> object
) throws IOException {
if (object == null) {
jsonWriter.nullValue();
return;
}
writeCommon(jsonWriter, object);
jsonWriter.name("coordinates");
if (object.coordinates() == null) {
jsonWriter.nullValue();
} else {
TypeAdapter<A> coordinatesAdapter = this.coordinatesAdapter;
if (coordinatesAdapter == null) {
throw new GeoJsonException("Coordinates type adapter is null");
}
coordinatesAdapter.write(jsonWriter, object.flattenCoordinates());
}
jsonWriter.endObject();
}

public void writeCoordinateContainer(JsonWriter jsonWriter, CoordinateContainer<A> object)
throws IOException {
if (object == null) {
jsonWriter.nullValue();
return;
}

writeCommon(jsonWriter, object);

jsonWriter.name("coordinates");
if (object.coordinates() == null) {
jsonWriter.nullValue();
} else {
TypeAdapter<A> coordinatesAdapter = this.coordinatesAdapter;
if (coordinatesAdapter == null) {
throw new GeoJsonException("Coordinates type adapter is null");
}
coordinatesAdapter.write(jsonWriter, object.coordinates());
}

jsonWriter.endObject();
}

private void writeCommon(JsonWriter jsonWriter, CoordinateContainer object) throws IOException {
jsonWriter.beginObject();
jsonWriter.name("type");
if (object.type() == null) {
Expand All @@ -64,17 +104,6 @@ public void writeCoordinateContainer(JsonWriter jsonWriter, CoordinateContainer<
}
boundingBoxAdapter.write(jsonWriter, object.bbox());
}
jsonWriter.name("coordinates");
if (object.coordinates() == null) {
jsonWriter.nullValue();
} else {
TypeAdapter<T> coordinatesAdapter = this.coordinatesAdapter;
if (coordinatesAdapter == null) {
throw new GeoJsonException("Coordinates type adapter is null");
}
coordinatesAdapter.write(jsonWriter, object.coordinates());
}
jsonWriter.endObject();
}

public CoordinateContainer<T> readCoordinateContainer(JsonReader jsonReader) throws IOException {
Expand All @@ -86,7 +115,7 @@ public CoordinateContainer<T> readCoordinateContainer(JsonReader jsonReader) thr
jsonReader.beginObject();
String type = null;
BoundingBox bbox = null;
T coordinates = null;
A coordinates = null;

while (jsonReader.hasNext()) {
String name = jsonReader.nextName();
Expand Down Expand Up @@ -114,7 +143,7 @@ public CoordinateContainer<T> readCoordinateContainer(JsonReader jsonReader) thr
break;

case "coordinates":
TypeAdapter<T> coordinatesAdapter = this.coordinatesAdapter;
TypeAdapter<A> coordinatesAdapter = this.coordinatesAdapter;
if (coordinatesAdapter == null) {
throw new GeoJsonException("Coordinates type adapter is null");
}
Expand All @@ -133,5 +162,5 @@ public CoordinateContainer<T> readCoordinateContainer(JsonReader jsonReader) thr

abstract CoordinateContainer<T> createCoordinateContainer(String type,
BoundingBox bbox,
T coordinates);
A coordinates);
}
Loading