My Brain on Code

A GeoPoint Converter for GSON

I’ve been working with the Google Maps library for an Android app I have been working on. The app uses an external api I created that sends back GPS coordinates (longitude and latitude) in JSON form. I needed to be able to serialize and deserialize this data to/from the GeoPoint class that the Maps library uses.

In order to do that I created this GeoPointConverter class:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import com.google.android.maps.GeoPoint;

import com.google.gson.JsonElement;
import com.google.gson.JsonArray;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonParseException;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;

import java.lang.reflect.Type;

/**
* Serializes and deserializes a GeoPoint
*
* It gets serialized to [lon, lat] (e.g. [-67.834062, 46.141129] )
*
* It also expects this format when deserializing.
* */
public class GeoPointConverter implements JsonSerializer<GeoPoint>,
    JsonDeserializer<GeoPoint> {

    @Override
    public JsonElement serialize(GeoPoint src, Type srcType,
        JsonSerializationContext context) {

        JsonArray array = new JsonArray();

        array.add(
            context.serialize(src.getLongitudeE6() / 1E6, Double.class));
        array.add(
            context.serialize(src.getLatitudeE6() / 1E6, Double.class));

        return array;
    }

    @Override
    public GeoPoint deserialize(JsonElement json, Type type,
        JsonDeserializationContext context)
        throws JsonParseException {

        final JsonArray array = json.getAsJsonArray();
        final JsonElement lonElement = array.get(0);
        final JsonElement latElement = array.get(1);
        final Double lon = lonElement.getAsDouble();
        final Double lat = latElement.getAsDouble();

        return new GeoPoint((int)(lat * 1E6), (int)(lon * 1E6));
    }
}

This will serialize a GeoPoint into a JSON array like so: [longitude, latitude]

And expects it in that format when deserializing back to a GeoPoint.

The reason I chose longitude first is due to my requirements (the JSON is used with mongodb which expects longitude first). However, it is trivial to change the order if you really need to.

To use this with GSON, you simply register it:

1
2
3
Gson gson = new GsonBuilder()
    .registerTypeAdapter(GeoPoint.class, new GeoPointConverter())
    .create();

Now whenever that gson instance comes across a GeoPoint it needs to serialize/deserialize, it will use the GeoPointConverter class to do it.