使用SQL生成网格线坐标

发布于 2025-02-07 04:51:46 字数 2028 浏览 2 评论 0 原文

Oracle 18c:

使用SQL查询,我想生成构成a 正方网格图

“在此处输入图像说明”

STARTPOINT_X STARTPOINT_Y ENDPOINT_X ENDPOINT_Y
------------ ------------ ---------- ----------
           0            0          1          0 --horizontal lines
           1            0          2          0
           2            0          3          0
           3            0          4          0
           4            0          5          0
           5            0          6          0

         ...

           0            0          0          1 --vertical lines
           0            1          0          2
           0            2          0          3
           0            3          0          4
           0            4          0          5
           0            5          0          6

         ...

[220 rows selected]

详细信息:

  1. 在每个交叉路口将行分开。因此,在上图中,有220行。每行都由两个顶点组成。
  2. 理想情况下,我可以选择在查询中指定整体网格尺寸是什么。例如,在SQL中的某个地方指定此内容: dimensions = 10 x 10 (或 dimensions = 100 x 100 等)。
  3. 为了保持简单,我们可以假设网格的整体形状始终是正方形(长度=宽度)。我们可以使单元大小 1单位
  4. I've supplied sample data in this db<>fiddle< /a>。我使用Excel创建了该数据。
    • 提示:垂直网格线从第111行开始。

我要生成此数据的原因是:

我希望在测试Oracle空间查询时使用示例线数据。有时我需要几百行。其他时候,我需要数千条线。

另外,如果线路在网格中,那么我的结果中是否缺少任何行(通过查看映射软件中的数据并发现差距),这将是显而易见的。


如何使用SQL生成这些网格线坐标?

相关:的线路功能

Oracle 18c:

Using an SQL query, I want to generate a list of coordinates that make up the line segments of a square grid graph:

enter image description here

STARTPOINT_X STARTPOINT_Y ENDPOINT_X ENDPOINT_Y
------------ ------------ ---------- ----------
           0            0          1          0 --horizontal lines
           1            0          2          0
           2            0          3          0
           3            0          4          0
           4            0          5          0
           5            0          6          0

         ...

           0            0          0          1 --vertical lines
           0            1          0          2
           0            2          0          3
           0            3          0          4
           0            4          0          5
           0            5          0          6

         ...

[220 rows selected]

Details:

  1. The lines would be split at each intersection. So, in the image above, there are 220 lines. Each line is composed of two vertices.
  2. Ideally, I would have the option of specifying in the query what the overall grid dimensions would be. For example, specify this somewhere in the SQL: DIMENSIONS = 10 x 10 (or DIMENSIONS = 100 x 100, etc.).
  3. To keep things simple, we can assume the grid's overall shape will always be a square (length = width). And we can make the cell size 1 unit.
  4. I've supplied sample data in this db<>fiddle. I created that data using Excel.
    • Hint: The vertical grid lines start at row 111.

The reason I want to generate this data is:

I want sample line data to work with when testing Oracle Spatial queries. Sometimes I need a few hundred lines. Other times, I need thousands of lines.

Also, if the lines are in a grid, then it will be obvious if any lines are missing in my results (by looking at the data in mapping software and spotting gaps).


How can I generate those grid line coordinates using SQL?

Related: Generate grid line features using SQL

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

一生独一 2025-02-14 04:51:46

您可以使用:

WITH range (v) AS (
  SELECT LEVEL - 1 FROM DUAL CONNECT BY LEVEL <= 11
)
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v + 1 AS endpoint_x,
       y.v AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  x.v <= 9
UNION ALL
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v AS endpoint_x,
       y.v + 1 AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  y.v <= 9

或更普遍地:

WITH range (v) AS (
  SELECT LEVEL - 1 FROM DUAL CONNECT BY LEVEL - 1 <= GREATEST(:max_x, :max_y)
)
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v + 1 AS endpoint_x,
       y.v AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  x.v <  :max_x
AND    y.v <= :max_y
UNION ALL
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v AS endpoint_x,
       y.v + 1 AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  x.v <= :max_x
AND    y.v <  :max_y

db&lt;&gt; fiddle

You can use:

WITH range (v) AS (
  SELECT LEVEL - 1 FROM DUAL CONNECT BY LEVEL <= 11
)
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v + 1 AS endpoint_x,
       y.v AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  x.v <= 9
UNION ALL
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v AS endpoint_x,
       y.v + 1 AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  y.v <= 9

or, more generally:

WITH range (v) AS (
  SELECT LEVEL - 1 FROM DUAL CONNECT BY LEVEL - 1 <= GREATEST(:max_x, :max_y)
)
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v + 1 AS endpoint_x,
       y.v AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  x.v <  :max_x
AND    y.v <= :max_y
UNION ALL
SELECT x.v AS startpoint_x,
       y.v AS startpoint_y,
       x.v AS endpoint_x,
       y.v + 1 AS endpoint_y
FROM   range x CROSS JOIN range y
WHERE  x.v <= :max_x
AND    y.v <  :max_y

db<>fiddle here

倾城°AllureLove 2025-02-14 04:51:46

有几种方法可以在Oracle中生成行。注意:这种特殊的(递归)方式可能对非常大的网格可能不是最佳的,因为您可能需要交叉2行,但是,这种方式更适合为您的尺寸注入变量。

从魔术 dual 表中选择表通常返回1行,但您可以使用递归通过使用魔术 level 值来确定您多少行想。它不会返回0级,所以我对此进行了硬编码。

看着您的正方形,它是由单个单位向量组成的镜像。所有水平向量均垂直重复,因此只能生成一半。请注意,在最终查询中,所有联合只是返回相同的数据,但交换x和y点。

它交叉加入Dimension CTE 3次。前两个是获得开始&amp;结束,只有第三个,因为对于所有EG水平向量,我们只希望垂直坐标对于启动和结尾都相同。它过滤了开始&amp;结束与零长度向量相等,而不需要的向量以及使用的长度1的零,其中 b.point -a.point = 1

with dimension as (
    select 0 as point from dual
      union all 
    select level
    from dual
    connect by level <= 10
), points as (
    select 
      a.point as startpoint, 
      b.point as endpoint,
      c.point as fixed
    from dimension a
    cross join dimension b
    cross join dimension c
    where b.point - a.point = 1
)
select
  startpoint as startpoint_x,
  fixed as startpoint_y,
  endpoint as endpoint_x,
  fixed as endpoint_y
from points
  union all
select
  fixed as startpoint_x,
  startpoint as startpoint_y,
  fixed as endpoint_x,
  endpoint as endpoint_y
from points
order by startpoint_y, endpoint_y, startpoint_x, endpoint_x

您将在第6行上注入变量的地方,用您想要的任何网格大小通过Level&lt; = 10 替换10个。

在SQL*Plus脚本中,您可以这样做

define dimension = 10;
with ...[ rest of the query blah blah ] 
connect by level <= &dimension

There's a few ways to generate rows in Oracle. Note: This particular (recursive) way might not be optimal for very large grids, for that you might want to cross join 2 rows a bunch of times, however, this way is more amenable to injecting a variable for your dimension.

Selecting from the magic dual table usually returns 1 row but you can use the recursive connect by with the magic level value to determine how many rows you want. It doesn't return a 0-level so I hard-coded that in.

Looking at your square, its a mirror image made up of single unit vectors; all the horizontal vectors are repeated vertically, so only half have to be generated. Note the union all in the final query just returns the same data but swaps the x and y points.

It cross joins dimension CTE 3 times. The first 2 are to get the start & end and only a 3rd because for all the e.g. horizontal vectors we just want the vertical coordinates to be the same for both start and end. It filters out where start & end are equal as those are zero-length vectors which are not needed as well as those longer than length 1 using where b.point - a.point = 1 .

with dimension as (
    select 0 as point from dual
      union all 
    select level
    from dual
    connect by level <= 10
), points as (
    select 
      a.point as startpoint, 
      b.point as endpoint,
      c.point as fixed
    from dimension a
    cross join dimension b
    cross join dimension c
    where b.point - a.point = 1
)
select
  startpoint as startpoint_x,
  fixed as startpoint_y,
  endpoint as endpoint_x,
  fixed as endpoint_y
from points
  union all
select
  fixed as startpoint_x,
  startpoint as startpoint_y,
  fixed as endpoint_x,
  endpoint as endpoint_y
from points
order by startpoint_y, endpoint_y, startpoint_x, endpoint_x

The place where you would inject the variable is on line 6, replacing that 10 with whatever grid size you want connect by level <= 10.

In a SQL*Plus script you could do that like

define dimension = 10;
with ...[ rest of the query blah blah ] 
connect by level <= &dimension
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文