简体   繁体   English

如何在 Java 中将 PostGIS 数据库中的数据转换为 GeoJSON

[英]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.我有一个 PostgreSQL/PostGIS 数据库,我想将我的数据表从数据库转换为 GeoJSON 格式。

My purpose is to use this GeoJSON for creating a map with JavaScript.我的目的是使用这个 GeoJSON 通过 JavaScript 创建地图。 I am using Java and JDBC in Spring MVC.我在 Spring MVC 中使用 Java 和 JDBC。 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() .您可以使用 postgis 函数ST_AsGeoJSON() Here is a link to the documentation for it.这是它的文档链接。

http://postgis.org/docs/ST_AsGeoJSON.html 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.需要注意的一件事是ST_AsGeoJSON()的结果只返回数据的几何部分。 If you need to get a geojson feature, then you will have to create the feature object and add the geometry to it.如果您需要获取 geojson 特征,则必须创建特征对象并向其添加几何图形。

An example of the result that you should expect when using ST_AsGeoJSON() would be {"type": "Point", "coordinates": [12, 15]} .使用ST_AsGeoJSON()时您应该期望的结果示例是{"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]}} .如果你想从几何对象中创建一个特征,它看起来像{"type": "Feature", "properties": {}, "geometry": {"type": "Point", "coordinates": [12, 15]}}

ogr2ogr is your friend. ogr2ogr 是你的朋友。 Steve Bennett gives an excellent example with custom properties/columns selection here , along the lines of this: Steve Bennett 给出了一个很好的例子, 这里有自定义属性/列选择,大致如下:

ogr2ogr -f GeoJSON out.json "PG:host=localhost dbname=mydb user=myuser password=mypw" -sql "SELECT column1, column2, column3 FROM mytable" 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.最明显的答案是使用 ST_AsGeoJSON 将几何图形转换为数据库中的字符串。 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.然而,这会将一些应用程序逻辑推入数据库中,也许更重要的是,它导致更多的数据通过网络传输,因为 GeoJSON 文本表示远不如 Postgres 使用的扩展众所周知的二进制 (EWKB) 紧凑。 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.这也意味着您无法在 MVC 控制器中使用几何体做任何有用的事情,除非将其反序列化为 JTS 几何体之类的东西。

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.一个更丰富、可能更快(如果涉及网络)的解决方案是为您的 JPA 提供者使用空间扩展(例如,Hibernate 在第 5 版中支持开箱即用,并且在第 4 版中有 Hibernate-Spatial)来拉几何直接作为 JTS(或类似)几何图形进入您的实体。 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!大多数实现将使用 WKB(众所周知的二进制)作为在线上的紧凑表示,然后反序列化为适当的 Java 类型,而不是将每个 64 位(8 字节)二进制双精度转换为某种巨大的结构! With Hibernate one can do the following (adjust definition as required for SRID and geometry type etc):使用 Hibernate 可以执行以下操作(根据 SRID 和几何类型等的需要调整定义):

@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 您正在 application.properties(或其他配置源)中使用 PostGIS 方言:

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).您的 Spring 数据存储库现在将返回具有几何图形的实体(也可以在存储库接口方法上编写 JPQL 查询以支持空间查询,例如边界框交集等)。

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 :获得具有填充几何图形的实体后,您可以通过在构建中包含 JTS 类型的转换器,轻松将其转换为端点上的带有 Jackson 的 GeoJSON,例如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 将其添加到 Spring 创建的 Jackson ObjectMappers,例如:

    @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.对于其他事情(空处理、缩进等),您可能需要比这更多的 Jackson 配置,但这是一个好的开始。

Now, when you return a JTS geometry on an object from your Spring MVC controllers they will automatically be converted to GeoJSON geometries.现在,当您从 Spring MVC 控制器返回对象上的 JTS 几何图形时,它们将自动转换为 GeoJSON 几何图形。 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.如果您想使用它们,您必须将 GeoJSON Feature / FeatureCollection 结构复制为类,或者返回可以在 JavaScript 中轻松映射到此类结构的某些内容(例如您的实体)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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