最明显的答案是使用 ST_AsGeoJSON 将几何图形转换为数据库中的字符串。但是,这会将一些应用程序逻辑推送到数据库中,并且可能更重要的是,它会导致更多的数据通过网络传输,因为 GeoJSON 文本表示远不如 Postgres 使用的扩展的 Well Known Binary (EWKB) 紧凑。这也意味着如果不将其反序列化回 JTS 几何体之类的东西,您将无法在 MVC 控制器中使用几何体做任何有用的事情。
一个更丰富且可能更快(如果涉及网络)的解决方案是为您的 JPA 提供程序使用空间扩展(例如,Hibernate 在版本 5 中开箱即用地支持此功能,并且在版本 4 中具有 Hibernate-Spatial)来将几何图形作为 JTS(或类似)几何图形直接拉入您的实体。大多数实现将使用 WKB(众所周知的二进制)作为网络上的紧凑表示,然后反序列化为适当的 Java 类型,而不是将每个 64 位(8 字节)二进制 double 转换为一些巨大的结构!使用 Hibernate 可以执行以下操作(根据 SRID 和几何类型等的需要调整定义):
@Column(columnDefinition = "geometry(MultiPolygon,4326)")
private Geometry geom;
然后告诉 Spring 你在 application.properties(或其他配置源)中使用 PostGIS 方言:
spring.jpa.database-platform=org.hibernate.spatial.dialect.postgis.PostgisDialect
您的 Spring 数据存储库现在将返回具有几何形状的实体(也可以在存储库接口方法上编写 JPQL 查询以支持空间查询,例如边界框相交等)。
拥有一个具有填充几何的实体,您可以通过在您的构建中包含 JTS 类型的转换器,轻松地将其转换为 GeoJSON,并在您的端点上使用 Jackson,例如 https://github.com/bedatadriven/jackson-datatype-jts:
<dependency>
<groupId>com.bedatadriven</groupId>
<artifactId>jackson-datatype-jts</artifactId>
<version>2.2</version>
</dependency>
然后通过在您的应用程序配置类之一中创建合适的 bean,将其添加到 Spring 创建的 Jackson ObjectMappers,例如:
@Bean
public Jackson2ObjectMapperBuilder objectMapperBuilder() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.modulesToInstall(new JtsModule());
return builder;
}
对于其他事情(空处理、缩进等),您可能需要对 Jackson 进行更多配置,但这是一个好的开始。
现在,当您从 Spring MVC 控制器返回对象上的 JTS 几何图形时,它们将自动转换为 GeoJSON 几何图形。如果您想使用 GeoJSON Feature / FeatureCollection 结构作为类,您必须将它们复制为类,或者返回可以在 JavaScript 中轻松映射到此类结构中的某些内容(例如您的实体)。