首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何获取oracle多边形集合的一小部分

如何获取oracle多边形集合的一小部分
EN

Stack Overflow用户
提问于 2011-06-06 15:27:08
回答 1查看 1.9K关注 0票数 2

我有一个SDO_GEOMETRY列,其中包含相当大的多多边形,定义如下:

代码语言:javascript
复制
INSERT INTO t1 (i, d, g)
VALUES (
  25,
  'Multipolygon - multi-touch',
  sdo_geometry (2007, null, null, sdo_elem_info_array (1,1003,1, 17,1003,1), 
  sdo_ordinate_array (50,95, 55,95, 53,96, 55,97, 53,98, 55,99, 50,99, 50,95, 55,100, 55,95, 60,95, 60,100, 55,100))
);

与上面示例中的两个多边形不同,一列包含>100个多边形。

我想过滤这个列,这样它就只返回一个相关的子集(使用bbox?),如下所示:

代码语言:javascript
复制
  SELECT filter(Geometry, bbox) from Table Where Id = 1
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-06-08 14:16:05

对蛮力解决方案的第一次尝试可能如下所示:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION FILTER_MULTI_POLYGONS
(
    udtGeometry IN SDO_GEOMETRY,
    udtMask IN SDO_GEOMETRY,
    dTolerance IN NUMBER
)
RETURN SDO_GEOMETRY
AS
    iElements INTEGER;
    udtElement SDO_GEOMETRY;
    udtResult SDO_GEOMETRY := NULL;
    iCount INTEGER;
BEGIN
    IF udtGeometry IS NOT NULL THEN
        iElements := SDO_UTIL.GETNUMELEM(udtGeometry);
        FOR iElement IN 1..iElements
        LOOP
            udtElement := SDO_UTIL.EXTRACT(udtGeometry, iElement);
            IF SDO_GEOM.SDO_DISTANCE(udtElement, udtMask, dTolerance) <= dTolerance THEN
                IF udtResult IS NULL THEN
                    udtResult := udtElement;
                ELSE
                    udtResult := SDO_UTIL.APPEND(udtResult, udtElement);
                END IF;
            END IF;
        END LOOP;
    END IF;
    RETURN udtResult;
END;

我说暴力是因为:

  1. 单独的子多边形没有索引,所以这个解决方案不利用空间索引。如果性能足够重要,那么可能值得将多个多边形分解为它们组成的子多边形(每个子多边形在源表中有一行),这样您就可以使用利用空间索引的不同解决方案。您可以提前(通过更改源表的设计)或幕后(可能使用基于原始表的物化视图)来实现这一点。
  2. 看起来像是在Oracle上,因此仅限于Oracle

1和2的Locator子集,这意味着您在确定哪个子多边形与掩码交互的唯一内置选择似乎是通过SDO_GEOM.SDO_DISTANCE进行的。这将是资源密集型的(因为它将对每个子多边形进行调用),并且只给您一种类型的交互,而使用内置的空间运算符(依赖于空间indexing).

  1. SDO_UTIL.APPEND的空间运算符可能不是最具表现力的(或正确的,特别是如果您的多多边形不是不相交的)构建“过滤”多多边形结果的方法,但是它说明了这个概念。

不管怎么说,这是我得到的,你的样本几何学对一些样本面具。您应该确保该函数返回真实几何图形的预期结果。

代码语言:javascript
复制
SQL> REM Example mask that overlaps first polygon only
SQL> SELECT 
  2      FILTER_MULTI_POLYGONS
  3      (
  4          T1.G, 
  5          SDO_GEOMETRY
  6          (
  7              2003, 
  8              NULL, 
  9              NULL, 
 10              SDO_ELEM_INFO_ARRAY(1, 1003, 3),
 11              SDO_ORDINATE_ARRAY(0, 0, 53, 96)
 12          ),
 13          0.1
 14      ) AS RESULT
 15  FROM T1;

RESULT(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
--------------------------------------------------------------------------------
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARR
AY(50, 95, 55, 95, 53, 96, 55, 97, 53, 98, 55, 99, 50, 99, 50, 95))


SQL> REM Example mask that overlaps second polygon only
SQL> SELECT 
  2      FILTER_MULTI_POLYGONS
  3      (
  4          T1.G, 
  5          SDO_GEOMETRY
  6          (
  7              2003, 
  8              NULL, 
  9              NULL, 
 10              SDO_ELEM_INFO_ARRAY(1, 1003, 3),
 11              SDO_ORDINATE_ARRAY(56, 0, 60, 96)
 12          ),
 13          0.1
 14      ) AS RESULT
 15  FROM T1;

RESULT(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
--------------------------------------------------------------------------------
SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1), SDO_ORDINATE_ARR
AY(55, 100, 55, 95, 60, 95, 60, 100, 55, 100))


SQL> REM Example mask that overlaps both polygons
SQL> SELECT 
  2      FILTER_MULTI_POLYGONS
  3      (
  4          T1.G, 
  5          SDO_GEOMETRY
  6          (
  7              2003, 
  8              NULL, 
  9              NULL, 
 10              SDO_ELEM_INFO_ARRAY(1, 1003, 3),
 11              SDO_ORDINATE_ARRAY(0, 0, 100, 100)
 12          ),
 13          0.1
 14      ) AS RESULT
 15  FROM T1;

RESULT(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
--------------------------------------------------------------------------------
SDO_GEOMETRY(2007, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 1, 17, 1003, 1), SDO
_ORDINATE_ARRAY(50, 95, 55, 95, 53, 96, 55, 97, 53, 98, 55, 99, 50, 99, 50, 95,
55, 100, 55, 95, 60, 95, 60, 100, 55, 100))


SQL> REM Example mask that overlaps neither polygon
SQL> SELECT 
  2      FILTER_MULTI_POLYGONS
  3      (
  4          T1.G, 
  5          SDO_GEOMETRY
  6          (
  7              2003, 
  8              NULL, 
  9              NULL, 
 10              SDO_ELEM_INFO_ARRAY(1, 1003, 3),
 11              SDO_ORDINATE_ARRAY(0, 0, 10, 10)
 12          ),
 13          0.1
 14      ) AS RESULT
 15  FROM T1;

RESULT(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
--------------------------------------------------------------------------------

希望这能有所帮助。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6254312

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档