【问题标题】:Selecting overlapping rectangles from a database table从数据库表中选择重叠的矩形
【发布时间】:2021-02-17 09:41:41
【问题描述】:

我有一个存储矩形的数据库表(postgres),由左下角和右上角的网格坐标(X 和 Y)定义。表是这样定义的......

CREATE TABLE tableA (
  minX             NUMERIC, 
  minY             NUMERIC, 
  maxX             NUMERIC,
  maxY             NUMERIC 
);

其中minXminY 是左下角的坐标,maxXmaxY 是右上角的坐标。

我正在尝试提出一个 SQL 查询,该查询将拉回与目标矩形重叠的任何矩形的记录,该目标矩形也由左下角和右上角定义 - minX_TminY_TmaxX_T , maxY_T.

这就是我目前所想出的......

SELECT * FROM tableA  
WHERE 
( 
  ( 
    (minY <=minY_T AND maxY >= minY_T) 
    AND 
    (minX <=minX_T AND maxX >= minX_T) 
  ) 
  OR 
  ( 
    (minY <=maxY_T AND maxY >= maxY_T) 
    AND 
    (minX <=maxX_T AND maxX >= maxX_T) 
  ) 
  OR 
  ( 
    (minY <=maxY_T AND maxY >= maxY_T) 
    AND 
    (minX <=minX_T AND maxX >= minX_T) 
  ) 
  OR 
  ( 
    (minY <=minY_T AND maxY >= minY_T) 
    AND 
    (minX <=maxX_T AND maxX >= maxX_T) 
  )
)

这(部分)有效,它从数据库中选择矩形角落在目标范围内的任何记录,但是它不会找到所有变体,而且它是一个非常混乱的 SQL。乍一看,这是一个非常简单的问题,但我已经为此绞尽脑汁好几个小时了 - 每次我认为我有一个解决方案时,我都会发现它行不通的场景为!

有什么想法吗? (顺便说一句 - 这仅适用于边为水平或垂直的矩形)


好的,再过几个小时,这个更简单的版本似乎可以解决问题

SELECT * FROM tableA
WHERE 
( 
 minX_T < maxX 
  AND 
 maxX_T > minX 
  AND 
 minY_T < maxY 
  AND 
 maxY_T > minY 
) 

【问题讨论】:

  • 通常我会直接转到完全包含的对象并以两种方式检查它(即翻转您正在检查的对象与您正在检查的对象/翻转_T 与非@987654333 @)。我相信这就是您在更新中发现并修复的。我认为从准确性的角度来看你很好,但我不能谈优化。

标签: postgresql geometry trigonometry


【解决方案1】:

不要重新发明轮子(或者在这种情况下是盒子)。 Postgres 提供了geometric data types(在这种情况下为点和框)和必要的geometric functions,正是你想要的。
以下 sql 函数将从您的表中返回任何重叠的“框”:

create or replace 
function overlaps_rectangle( rectangle_in box) 
 returns setof tablea
 language sql
 as $$
    select * 
      from tablea 
     where box( point(maxx,maxy),point(minx,miny)) && rectangle_in ;
$$;

example here:

该函数实际上不需要,sql语句本身可以作为脚本运行。我只是发现将参数传递给函数比修改脚本更容易。更进一步,根据其他用途,您实际上可以将值存储为点甚至框。样品包括在上述参考中。注意:作为一个盒子

可以在输入中提供任何两个对角,但值将 根据需要重新排序以存储右上和左下 角,按此顺序。

【讨论】:

    猜你喜欢
    • 2015-10-07
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 1970-01-01
    • 2014-08-26
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多