Coder Social home page Coder Social logo

ancore / geojson-serializer Goto Github PK

View Code? Open in Web Editor NEW
6.0 1.0 0.0 168 KB

A library with a JsonSerializer and a set of annotations to serialize any PoJo as GeoJSON.

License: Apache License 2.0

Java 100.00%
geojson jackson-databind jts-topology-suite jackson-datatype-jts

geojson-serializer's Introduction

Java CI with Maven Maven Central

geojson-serializer

A library with a JsonSerializer and a set of annotations to serialize any PoJo as GeoJSON.

Supported so far is Feature and FeatureCollection, GeometryCollection.

A demo Spring Boot project is available: demo project

Procedure

The PoJo containing the data for the GeoJSON object is annotated with @GeoJson.

Whether the GeoJSON is a Feature, FeatureCollection or a GeometryCollection is specified by the annotation attribute type, for example GeoJson(type = GeoJsonType.FEATURE) .

PoJo annotations on fields or getters indicate the GeoJSON members (id, geometry, properties, features) depending on the type.

Dependencies

The serialization of Geometry objects from the JTS Technology Suite is handled by the graphopper implemenation of jackson-datatype-jts. The original jackson-datatype-jts project is not maintained anymore and uses an old version of the JTS Topology Suite, which can cause a naming conflict due to the different package name.

This library uses the org.locationtech.jts.geom classes.

Status

The status of this library is something like beta. Please let me know if you have any ideas for improvement.

TODO:

  • Caching by Type

Maven Dependency

Check for the current version: https://search.maven.org/artifact/ch.cordsen/geojson-serializer

<dependency>
   <groupId>ch.cordsen</groupId>
   <artifactId>geojson-serializer</artifactId>
   <version>X.X.X</version>
</dependency>

Example for Feature

The following PoJo (Attraction) is annotated to be serialized as a GeoJSON Feature. It has a field annotation to point out the Feature's id, two String properties and one geometry (Point).

import ch.cordsen.geojson.annotation.GeoJson;
import ch.cordsen.geojson.annotation.GeoJsonGeometry;
import ch.cordsen.geojson.annotation.GeoJsonId;
import ch.cordsen.geojson.annotation.GeoJsonProperty;
import ch.cordsen.geojson.serializer.GeoJsonSerializer;
import ch.cordsen.geojson.serializer.GeoJsonType;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import org.locationtech.jts.geom.Point;

import java.util.UUID;

@GeoJson(type = GeoJsonType.FEATURE)
@JsonSerialize(using = GeoJsonSerializer.class)
public class Attraction {

   @GeoJsonId private final UUID id;
   @GeoJsonProperty private final String name;
   @GeoJsonProperty private final String description;
   @GeoJsonGeometry private final Point location;

   public Attraction(UUID id, String name, String description, Point location) {
      this.id = id;
      this.name = name;
      this.description = description;
      this.location = location;
   }

   public UUID getId() {
      return id;
   }

   public String getName() {
      return name;
   }

   public String getDescription() {
      return description;
   }

   public Point getLocation() {
      return location;
   }
}

Programmatically calling the ObjectMapper to serialize:

import com.bedatadriven.jackson.datatype.jts.JtsModule;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.GeometryFactory;

import static java.util.UUID.randomUUID;

public class Test {

   public static void main(String... args) throws JsonProcessingException {

      ObjectMapper objectMapper = new ObjectMapper();
      objectMapper.registerModule(new JtsModule());

      GeometryFactory geometryFactory = new GeometryFactory();

      Attraction attraction = new Attraction(
         randomUUID(),
         "Eiffel Tower",
         "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France",
         geometryFactory.createPoint(new Coordinate(2.294527, 48.859092)));

      String geoJson = objectMapper
         .writerWithDefaultPrettyPrinter()
         .writeValueAsString(attraction);
   }
}

Output:

{
   "type": "Feature",
   "id": "2e38f4b1-d9ea-459a-ba52-6093b09b6dc0",
   "geometry": {
      "type": "Point",
      "coordinates": [
         2.294527,
         48.859092
      ]
   },
   "properties": {
      "name": "Eiffel Tower",
      "description": "Champ de Mars, 5 Avenue Anatole France, 75007 Paris, France"
   }
}

Works with Spring MVC:

@RestController
public class WebController {

   // ...

   @GetMapping("/api/attractions/{id}")
   public ResponseEntity<Attraction> findById(@PathVariable(value = "id") UUID id) {
      return repository.findById(id)
         .map(ResponseEntity::ok)
         .orElse(ResponseEntity.notFound().build());
   }
}

Please refer to the demo project for details.

Annotations

The library provides one type annotation @GeoJson and several annotations used on fields or methods. Methods are limited to getters ("Bean Property").

Additionally, the provided GeoJsonSerializer has to be used.

@GeoJson

This annotation declares a Java class as Feature, FeatureCollection or GeometryCollection by using the respective GeoJsonType:

  • @GeoJson(type=GeoJsonType.FEATURE)
  • @GeoJson(type=GeoJsonType.FEATURE_COLLECTION)
  • @GeoJson(type=GeoJsonType.GEOMETRY_COLLECTION)

The class furthermore contains fields or getters with annotations representing attributes of the specific type.

Example: The class 'Attraction' representing a Feature can be used in a class 'Attractions' representing a FeatureCollection.

@GeoJson(type = GeoJsonType.FEATURE)
@JsonSerialize(using = GeoJsonSerializer.class)
public class Attraction {

   @GeoJsonId private UUID id;
   @GeoJsonProperty private String name;
   @GeoJsonProperty private String description;
   @GeoJsonGeometry private Point location;

   // ...
}

@GeoJson(type = GeoJsonType.FEATURE_COLLECTION)
@JsonSerialize(using = GeoJsonSerializer.class)
public class Attractions {

   @GeoJsonFeatures private List<Attraction> attractions; // using 'Feature' Attraction

   // ...
}

@GeoJsonId

  • indicates the ID of a Feature
  • optional annotation, ID attribute is omitted if missing

Properties

There are two mutually exclusive annotations to indicate the Properties Object of a Feature. One is used for one Java object to represent the Properties Object, the other to collect all occurrences and combine them to one Properties Object. If no field is annotated with either of them, the Properties Object is set to null.

@GeoJsonProperties

  • indicates the Properties Object of a Feature
  • optional, but not more than once per class
  • mutually exclusive with @GeoJsonProperty
  • field or getter name is irrelevant
  • the field or getter value should serialize to a JSON object

@GeoJsonProperty

  • indicates one attribute of the Properties Object of a Feature
  • optional and unlimited
  • mutually exclusive with @GeoJsonProperties
  • field or getter name is used as attribute key, unless overwritten with @GeoJsonProperty#name()
  • the attribute value should be any serializable object

Geometries

As with Properties, two mutually exclusive annotations are available. A Feature may have one Geometry, a GeometryCollection has a Geometries Array. Missing annotations will lead to a null value for Feature or an empty Array for a GeometryCollection.

Every element is expected to be of type org.locationtech.jts.geom.Geometry or one of the standard subtypes like Point, Polygon and so on. The actual serialization is done by using com.graphhopper.external:jackson-datatype-jts.

@GeoJsonGeometries

  • indicates the Geometry Array of a GeometryCollection
  • optional, but not more than once per class
  • mutually exclusive with @GeoJsonGeometry
  • field or getter name is irrelevant
  • the field or getter value should serialize to a serializable collection containing Geometry elements

@GeoJsonGeometry

  • indicates the Geometry Object of a Feature or one element of the Geometries Array of a GeometryCollection
  • optional and unlimited
  • mutually exclusive with @GeoJsonGeometries
  • field or getter name is irrelevant

Features

Again, two mutually exclusive annotations are used. The values are excepted to be serializable as Feature, most likely using Java classes with annotations from this library. If no field is annotated with either of them, the Feature Array is empty.

@GeoJsonFeatures

  • indicates the Feature Array of a FeatureCollection
  • optional, but not more than once per class
  • mutually exclusive with @GeoJsonFeature

@GeoJsonFeature

  • indicates one Feature of the Feature Array of a FeatureCollection
  • optional and unlimited
  • mutually exclusive with @GeoJsonFeatures

Credits

Copyright (c) 2019 Andreas Cordsen

Please refer to the LICENSE file for details.

geojson-serializer's People

Contributors

dependabot[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.