1
votes

I was trying to deserialize a JSON string that contains a GeoJSON string.

point: {
    type: "Point",
    coordinates: [
        7.779259,
        52.21864
    ]
}

The object I want to create is of type

com.vividsolutions.jts.geom.Point

We use this class because of the use of an PostGis database for spatial data. Unfortunately the class does not have a non-arg constructor, which is needed. But somehow it also implements CoordinateSequence CoordinateSequence which neither has a non-arg constructor. Whenever I try to deserialize the incoming json string I get an error

java.lang.RuntimeException: Unable to invoke no-args constructor for 
interface com.vividsolutions.jts.geom.CoordinateSequence. 
Register an InstanceCreator with Gson for this type may fix this problem.

I tried to create an InstanceCreator for the interface of CoordinateSequence following the example here but did not succeed. Also subclassing Point did not bring the answer as the problem lies in the used interface of CoordinateSequence.

I would be thankful for any help or hints, that lead me to the solution.

3
Can you extend com.vividsolutions.jts.geom.Point class with your own with default constructor, and serialize/deserialize them? - Alexey Sviridov
Hi Alexey, thanks for your comment. I already tried extending Point. Please see my comment below. - Cliff Pereira

3 Answers

1
votes

We solved it using the Custom JsonDeserializer. Of course this is just a quick and dirty solution. One should check for other types and errors. But this should give an idea.

public class GeometryDeserializer implements JsonDeserializer<Geometry> {

@Override
public Geometry deserialize(JsonElement json, Type typeofT,
        JsonDeserializationContext context) throws JsonParseException {

    String type = json.getAsJsonObject().get("type").toString();

    JsonArray coordinates = json.getAsJsonObject().getAsJsonArray("coordinates");

    GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory(null);
    Coordinate coord = new Coordinate(coordinates.get(0).getAsDouble(), coordinates.get(1).getAsDouble());
    Geometry point = geometryFactory.createPoint(coord);


    return point;
}
}
0
votes

I assume the class is from a library that you cant change. Did you try subclassing the class and putting a no-arg constructor in your subclass just to assist the serialization process? I have done that before with some success.

// .... content I cant change.
public class LibraryPOJOClass {
  public LibraryPOJOClass(final int id) { 
    // ...
  }
}

public class MyLibraryPojoClass extends LibraryPOJOClass {
  MyLibraryPojoClass() {
    super(0); // I will change this later, with reflection if need be. 
  }
}
0
votes

Do it server side:

SELECT ST_GeomFromGeoJSON('{"type":"Point","coordinates":[7.779259,52.21864]}');

Note: the example provided in the question looks slightly different than The GeoJSON Format Specification.