简体   繁体   English

从数据库表中选择重叠的矩形

[英]Selecting overlapping rectangles from a database table

I have a database table (postgres) that stores rectangles, defined by the grid co-ordinates (X and Y) of the bottom left and top right hand corners.我有一个存储矩形的数据库表 (postgres),由左下角和右上角的网格坐标(X 和 Y)定义。 The table is defined something like this......该表定义如下......

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

Where minX and minY are the co-ordinates of the bottom left corner, and maxX and maxY the co-ordinates of the top right.其中minXminY是左下角的坐标, maxXmaxY是右上角的坐标。

I'm trying to come up with a SQL query that will pull back the records of any rectangle that overlaps a target rectangle also defined by the bottom left and top right corners - minX_T , minY_T , maxX_T , maxY_T .我正在尝试提出一个 SQL 查询,该查询将拉回与目标矩形重叠的任何矩形的记录,该目标矩形也由左下角和右上角 - minX_TminY_TmaxX_TmaxY_T

This is what I've come up with so far...到目前为止,这就是我想出的...

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) 
  )
)

This works (partially) it selects any records from the database where a corner of the rectangle falls within the target, however it wont find all variations and it's a really messy bit of SQL. At first glance this is a really simple problem, but I've been racking my brains on this for hours now - each time a I think I have a solution I discover a scenario that it won't work for!这(部分)有效它从数据库中选择矩形的一角落在目标内的任何记录,但是它不会找到所有变化并且它是 SQL 的一个非常混乱的位。乍一看这是一个非常简单的问题,但我我已经为此绞尽脑汁好几个小时了——每次我认为我有一个解决方案时,我都会发现一个它不起作用的场景!

Any ideas?有任何想法吗? (BTW - this only for rectangles with sides either horizontal, or vertical) (顺便说一句 - 这仅适用于边长为水平或垂直的矩形)


ok, after another few hours, this simpler version seems to do the trick好的,又过了几个小时,这个更简单的版本似乎可以解决问题

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

Do not reinvent the wheel (or in this case the box).不要重新发明轮子(或者在这种情况下是盒子)。 Postgres provides geometric data types (in this case point and box) and the necessary geometric functions for exactly what you want. Postgres 提供了几何数据类型(在本例中为点和框)和所需的几何函数
The following sql function will return any overlapping 'box' from your table:以下 sql function 将从您的表格中返回任何重叠的“框”:

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 ;
$$;

See example here :请参阅此处的示例

The function is not actually needed, the sql statement itself can run as is as a script. function其实并不需要,sql语句本身可以作为脚本运行。 I just find passing parameters to a function easier than modifying a script.我只是发现将参数传递给 function 比修改脚本更容易。 Going a step further and depending on other uses you could actually store the values as Points or even Boxes.更进一步,根据其他用途,您实际上可以将值存储为 Points 甚至 Boxes。 Samples include in above reference.示例包含在上述参考中。 Note: as a Box注意:作为一个盒子

Any two opposite corners can be supplied on input, but the values will be reordered as needed to store the upper right and lower left corners, in that order.可以在输入中提供任意两个对角,但值将根据需要重新排序以按该顺序存储右上角和左下角。

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

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