【GIS】Hibernate-Spatial

1.简介

在本文中,我们将了解Hibernate的空间扩展,hibernate-spatial。Hibernate Spatial提供了用于处理地理数据的标准接口。

2.Hibernate Spatial的背景

地理数据包括诸如Point,Line,Polygon(多边形)等实体的表示。此类数据类型不是JDBC规范的一部分,因此JTS(JTS拓扑套件)已成为表示空间数据类型的标准。

除了JTS之外,Hibernate空间还支持Geolatte-geom,这是一个最新的库,具有一些JTS中不可用的功能。

这两个库都已包含在休眠空间项目中。使用一个库而不是另一个库仅仅是我们要从哪个jar导入数据类型的问题。

尽管Hibernate空间支持Oracle,MySQL,PostgreSQLql / PostGIS和其他一些不同的数据库,但对数据库特定功能的支持并不统一。

最好参考最新的Hibernate文档,以检查hibernate为给定数据库提供支持的功能列表。

在本文中,我们将使用内存中的Mariadb4j –它维护MySQL的全部功能。

Mariadb4j和MySql的配置相似,即使mysql-connector库也适用于这两个数据库。

3. Maven依赖

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-entitymanager</artifactId>
    <version>5.2.12.Final</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-spatial</artifactId>
    <version>5.2.12.Final</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>6.0.6</version>
</dependency>
<dependency>
    <groupId>ch.vorburger.mariaDB4j</groupId>
    <artifactId>mariaDB4j</artifactId>
    <version>2.2.3</version>
</dependency>

4.配置

新建一个hibernate.properties文件

hibernate.dialect=org.hibernate.spatial.dialect.postgis.PostgisDialect

5.了解Geometry类型

Geometry是JTS中所有空间类型的基本类型。这意味着Point,Polygon等其他类型也从Geometry扩展而来。Java中的Geometry类型也与MySql中的GEOMETRY类型相对应。

通过解析String类型,我们获得了Geometry的实例。JTS提供的实用程序类WKTReader可用于将任何众所周知的文本表示形式转换为Geometry类型:

public Geometry wktToGeometry(String wellKnownText) 
  throws ParseException {
  
    return new WKTReader().read(wellKnownText);
}

现在,让我们看看这个方法的实际作用:

@Test
public void shouldConvertWktToGeometry() {
    Geometry geometry = wktToGeometry("POINT (2 5)");
  
    assertEquals("Point", geometry.getGeometryType());
    assertTrue(geometry instanceof Point);
}

如我们所见,即使方法的返回类型为read()方法为Geometry,实际的实例还是Point的实例。

6.在数据库中存储一个Point

现在,我们对什么是Geometry类型以及如何从String中获取Point有了一个很好的了解,让我们看一下PointEntity:

@Entity
public class PointEntity {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private Point point;
 
    // standard getters and setters
}

请注意,实体PointEntity包含空间类型Point。如前所述,一个点由两个坐标表示:

public void insertPoint(String point) {
    PointEntity entity = new PointEntity();
    entity.setPoint((Point) wktToGeometry(point));
    session.persist(entity);
}

方法insertPoint()接受Point的熟知文本(WKT)表示形式,将其转换为Point实例,然后保存在DB中。

提醒一下,该会话不是特定于hibernamte-spatial的,而是以类似于另一个hibernate项目的方式创建的。

我们可以在这里注意到,一旦创建了Point的实例,存储PointEntity的过程便与任何常规实体相似。
让我们看一些测试:

@Test
public void shouldInsertAndSelectPoints() {
    PointEntity entity = new PointEntity();
    entity.setPoint((Point) wktToGeometry("POINT (1 1)"));
 
    session.persist(entity);
    PointEntity fromDb = session
      .find(PointEntity.class, entity.getId());
  
    assertEquals("POINT (1 1)", fromDb.getPoint().toString());
    assertTrue(geometry instanceof Point);
}

在一个Point上调用的toString()返回的WKT表示此Point。这是因为Geometry类覆盖的toString()方法和内部使用WKTWriter,免费类WKTReader我们前面看到的。

一旦运行此测试,hibernate将为我们创建PointEntity表。

让我们看一下该表:

desc PointEntity;
Field    Type          Null    Key
id       bigint(20)    NO      PRI
point    geometry      YES

正如预期的那样,该Point的类型是Geometry。因此,在使用我们的SQL编辑器(例如MySql工作台)获取数据时,我们需要将此GEOMETRY类型转换为人类可读的文本:

select id, astext(point) from PointEntity;
 
id      astext(point)
1       POINT(2 4)

不过,当我们在Geometry或其任何子类上调用toString()方法时,hibernate已经返回了WKT表示形式,因此我们无需为这种转换而烦恼。

7.使用空间功能

7.1 ST_WITHIN()示例

现在,我们将研究与空间数据类型一起使用的数据库功能的用法。

MySQL中的此类函数之一就是ST_WITHIN(),它告诉一个Geometry是否在另一个Geometry中。一个很好的例子是找出给定半径内的所有点。

让我们从如何创建一个圆开始:

public Geometry createCircle(double x, double y, double radius) {
    GeometricShapeFactory shapeFactory = new GeometricShapeFactory();
    shapeFactory.setNumPoints(32);
    shapeFactory.setCentre(new Coordinate(x, y));
    shapeFactory.setSize(radius * 2);
    return shapeFactory.createCircle();
}

一个圆由setNumPoints()方法指定的一组有限点表示。在调用setSize()方法之前,半径已加倍,因为我们需要在两个方向上围绕中心绘制圆。

现在,让我们继续前进,看看如何获​​取给定半径内的点:

@Test
public void shouldSelectAllPointsWithinRadius() throws ParseException {
    insertPoint("POINT (1 1)");
    insertPoint("POINT (1 2)");
    insertPoint("POINT (3 4)");
    insertPoint("POINT (5 6)");
 
    Query query = session.createQuery("select p from PointEntity p where 
      within(p.point, :circle) = true", PointEntity.class);
    query.setParameter("circle", createCircle(0.0, 0.0, 5));
 
    assertThat(query.getResultList().stream()
      .map(p -> ((PointEntity) p).getPoint().toString()))
      .containsOnly("POINT (1 1)", "POINT (1 2)");
    }

Hibernate的映射其within()函数对应ST_WITHIN()的MySQL的功能。

有趣的观察是,点(3,4)恰好落在圆上。不过,查询不会返回这一点。这是因为只有当给定的几何形状完全是另一几何内within()函数才会返回true。

7.2.ST_TOUCHES()示例

这里,我们将呈现一个示例,插入一组多边形在数据库中,然后Select一个多边形与给定的多边形相邻。让我们快速看一下PolygonEntity类:

@Entity
public class PolygonEntity {
 
    @Id
    @GeneratedValue
    private Long id;
 
    private Polygon polygon;
 
    // standard getters and setters
}

与以前的PointEntity唯一不同的是,我们使用的是Polygon类型而不是Point。

现在让我们进行测试:

@Test
public void shouldSelectAdjacentPolygons() throws ParseException {
    insertPolygon("POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))");
    insertPolygon("POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))");
    insertPolygon("POLYGON ((2 2, 3 1, 2 5, 4 3, 3 3, 2 2))");
 
    Query query = session.createQuery("select p from PolygonEntity p 
      where touches(p.polygon, :polygon) = true", PolygonEntity.class);
    query.setParameter("polygon", wktToGeometry("POLYGON ((5 5, 5 10, 10 10, 10 5, 5 5))"));
    assertThat(query.getResultList().stream()
      .map(p -> ((PolygonEntity) p).getPolygon().toString())).containsOnly(
      "POLYGON ((0 0, 0 5, 5 5, 5 0, 0 0))", "POLYGON ((3 0, 3 5, 8 5, 8 0, 3 0))");
}

该insertPolygon()方法类似于在insertPoint()方法,我们前面看到的。源包含此方法的完整实现。

我们使用的touches()函数来找到多边形小号相邻给定的多边形。显然,第三个多边形没有返回结果,因为没有边缘接触所给的多边形。

8.结论

在本文中,我们已经看到,休眠空间使处理空间数据类型变得更加简单,因为它处理了底层细节。

即使本文使用Mariadb4j,我们也可以将其替换为MySql,而无需修改任何配置。

与往常一样,可以在GitHub上找到本文的完整源代码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
explicit spectral-to-spatial convolution for pansharpening是一种用于全色融合的显式光谱到空间卷积方法。全色融合是将高分辨率的全色(黑白)图像与低分辨率的多光谱(彩色)图像融合,以提高图像质量和细节。传统的融合方法常常使用高通滤波器进行频域操作,而explicit spectral-to-spatial convolution for pansharpening则使用基于卷积的空间域方法。 该方法基于以下原理:在全色图像中,光谱分辨率高,但空间分辨率较低;而在多光谱图像中,光谱分辨率较低,但空间分辨率较高。因此,通过将全色图像的光谱信息传递给多光谱图像,可以提高多光谱图像的空间分辨率。 explicit spectral-to-spatial convolution for pansharpening方法通过使用卷积核,将全色图像的光谱信息转换为空间域的高频细节。这个卷积核是根据光谱和空间信息之间的关系而设计的。通过将这个卷积核应用于低分辨率的多光谱图像,可以增强其空间细节,使其接近高分辨率的全色图像。 这种方法的优势在于显式地将光谱信息转换为空间域的细节,能够更好地保留图像的光谱特征和空间细节。与传统的频域方法相比,显式光谱到空间卷积方法更容易实现,并且能够更好地适应各种图像场景。 总之,explicit spectral-to-spatial convolution for pansharpening是一种通过卷积将全色图像的光谱信息转换为多光谱图像的空间细节的方法,以实现全色融合,提高图像质量和细节。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值