Oracle Spatial Geometry covered by the most

时间:2015-06-30 13:33:50

标签: sql oracle oracle-spatial

I have a table which contains a number of geometries. I am attempting to extract the one which is most covered by another geometry.

This is best explained with pictures and code.

Currently I am doing this simple spatial query to get any rows that spatially interact with a passed in WKT Geometry

SELECT ID, NAME FROM MY_TABLE WHERE 
sdo_anyinteract(geom, 
sdo_geometry('POLYGON((400969 95600,402385 95957,402446 95579,400905 95353,400969 95600))',27700)) = 'TRUE';

Works great, returns a bunch of rows that interact in any way with my passed in geometry.

What I preferably want though is to find which one is covered most by my passed in geometry. Consider this image.

Polygon selection example

The coloured blocks represent 'MY_TABLE'. The black polygon over the top represents my passed in geometry I am searching with. The result I want returned from this is Polygon 2, as this is the one that is most covered by my polygon. Is this possible? Is there something I can use to pull the cover percentage in and order by that or a way of doing it that simply returns just that one result?

--EDIT--

Just to supplement the accepted answer (which you should go down and give an upvote as it is the entire basis for this) this is what I ended up with.

SELECT name, MI_PRINX, 
SDO_GEOM.SDO_AREA(
  SDO_GEOM.SDO_INTERSECTION(
    GEOM, 
    sdo_geometry('POLYGON((400969.48717156524 95600.59583240788,402385.9445972018 95957.22742049221,402446.64806962677 95579.91508788493,400905.95874489535 95353.03765349534,400969.48717156524 95600.59583240788))',27700)
    ,0.005
  )
,0.005) AS intersect_area 
FROM LIFE_HEATHLAND WHERE sdo_anyinteract(geom, sdo_geometry('POLYGON((400969.48717156524 95600.59583240788,402385.9445972018 95957.22742049221,402446.64806962677 95579.91508788493,400905.95874489535 95353.03765349534,400969.48717156524 95600.59583240788))',27700)) = 'TRUE'
ORDER BY INTERSECT_AREA DESC;

This returns me all the results that intersect my query polygon with a new column called INTERSECT_AREA, which provides the area. I can then sort this and pick up the highest number.

1 个答案:

答案 0 :(得分:2)

只计算每个返回的几何与查询窗口之间的交集(使用SDO_GEOM.SDO_INTERSECTION()),计算每个此类交集的区域(使用SDO_GEOM.SDO_AREA())并返回最大区域的行(按计算区域的降序排列结果,只保留第一行。

例如,以下计算黄石国家公园在其覆盖的每个州占据多少空间。结果按区域排序(降序)。

SELECT s.state,
       sdo_geom.sdo_area (
         sdo_geom.sdo_intersection (
           s.geom, p.geom, 0.5),
         0.5, 'unit=sq_km') area
  FROM us_states s, us_parks p
 WHERE SDO_ANYINTERACT (s.geom, p.geom) = 'TRUE'
   AND p.name = 'Yellowstone NP'
 ORDER by area desc;

返回:

STATE                                AREA
------------------------------ ----------
Wyoming                        8100.64988
Montana                        640.277886
Idaho                          154.657145

3 rows selected.

仅保留具有最大交点的行:

SELECT * FROM (
  SELECT s.state,
         sdo_geom.sdo_area (
           sdo_geom.sdo_intersection (
             s.geom, p.geom, 0.5),
           0.5, 'unit=sq_km') area
    FROM us_states s, us_parks p
   WHERE SDO_ANYINTERACT (s.geom, p.geom) = 'TRUE'
     AND p.name = 'Yellowstone NP'
   ORDER by area desc
)
WHERE rownum = 1;     

,并提供:

STATE                                AREA
------------------------------ ----------
Wyoming                        8100.64988

1 row selected.

以下变体还返回每个交叉状态下公园表面的百分比:

WITH p AS (
  SELECT s.state,
         sdo_geom.sdo_area (
           sdo_geom.sdo_intersection (
             s.geom, p.geom, 0.5),
           0.5, 'unit=sq_km') area
    FROM us_states s, us_parks p
   WHERE SDO_ANYINTERACT (s.geom, p.geom) = 'TRUE'
     AND p.name = 'Yellowstone NP'
)
SELECT state, area,
       RATIO_TO_REPORT(area) OVER () * 100 AS pct
FROM p
ORDER BY pct DESC;

如果要返回交叉点的几何图形,只需将其包含在结果集中即可。