简体   繁体   中英

How to convert data from PostGIS database into GeoJSON in Java

I have a PostgreSQL/PostGIS database and I want to convert my data table from database into GeoJSON format.

My purpose is to use this GeoJSON for creating a map with JavaScript. I am using Java and JDBC in Spring MVC. What is the best way to convert data?

This can be done in the query that pulls the data out of the database. You can use the postgis function ST_AsGeoJSON() . Here is a link to the documentation for it.

http://postgis.org/docs/ST_AsGeoJSON.html

One thing to note is that the result of ST_AsGeoJSON() only returns the geometry portion of the data. If you need to get a geojson feature, then you will have to create the feature object and add the geometry to it.

An example of the result that you should expect when using ST_AsGeoJSON() would be {"type": "Point", "coordinates": [12, 15]} .

If you wanted to create a feature out of the geometry object, that would look something like {"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [12, 15]}} .

ogr2ogr is your friend. Steve Bennett gives an excellent example with custom properties/columns selection here , along the lines of this:

ogr2ogr -f GeoJSON out.json "PG:host=localhost dbname=mydb user=myuser password=mypw" -sql "SELECT column1, column2, column3 FROM mytable"

The most obvious answer is to use ST_AsGeoJSON to convert the geometry into a string on the database. However, this pushes some application logic into the database and, perhaps more importantly, it results in far more data being transferred over the network as the GeoJSON text representation is far less compact than the extended Well Known Binary (EWKB) that Postgres uses otherwise. It also means that you are unable to do anything useful in your MVC controllers with the geometry without deserialising it back to something like a JTS geometry.

A richer, and potentially faster (if there is networking involved), solution is to use spatial extensions for your JPA provider (eg Hibernate supports this out of the box in version 5, and had Hibernate-Spatial for version 4) to pull the geometry directly into your entity as a JTS (or similar) geometry. Most implementations will use WKB (Well Known Binary) as a compact representation over the wire, then deserialise into the appropriate Java type, rather than converting every 64bit (8 bytes) binary double into some huge structure! With Hibernate one can do the following (adjust definition as required for SRID and geometry type etc):

@Column(columnDefinition = "geometry(MultiPolygon,4326)")
private Geometry geom;

Then tell Spring that you are using the PostGIS dialect in application.properties (or other config source):

spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect

Your Spring data repositories will now return entities with geometries (it's also possible to write JPQL queries on the repository interface methods to support spatial queries, eg bounding box intersection etc).

Having got an entity with a populated geometry you can easily convert this to GeoJSON with Jackson on your endpoints by including converters for the JTS types in your build, eg https://github.com/bedatadriven/jackson-datatype-jts :

<dependency>
  <groupId>com.bedatadriven</groupId>
  <artifactId>jackson-datatype-jts</artifactId>
  <version>2.2</version>
</dependency>

and then adding it to the Jackson ObjectMappers created by Spring by creating a suitable bean in one of your application configuration classes, eg:

    @Bean
    public Jackson2ObjectMapperBuilder objectMapperBuilder() {
            Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
            builder.modulesToInstall(new JtsModule());
            return builder;
    }

You may need more configuration of Jackson than this for other things (null handling, indentation, etc) but it's a good start.

Now, when you return a JTS geometry on an object from your Spring MVC controllers they will automatically be converted to GeoJSON geometries. You will have to either replicate GeoJSON Feature / FeatureCollection structures as classes if you want to use those, or return something (eg your Entity) that can be easily mapped in JavaScript into such a structure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM