SpatialDB Advisor
set timing on
set linesize 120
set pagesize 1000
set serveroutput on size 1000000
DROP SEQUENCE my_points_seq;
CREATE SEQUENCE my_points_seq;
DROP TABLE my_points;
Prompt Create a table to hold our point data maximising its use of database blocks so it uses as little space as possible
CREATE TABLE my_points (
point_id Integer primary key,
window_id Integer,
geometry mdsys.sdo_geometry
) PCTUSED 99;
Accept minx number default 100000 prompt 'Enter minimum X coordinate of whole area for which points are needed (100000): '
Accept miny number default 5000000 prompt 'Enter minimum Y coordinate of whole area for which points are needed (5000000): '
Accept maxx number default 400000 prompt 'Enter Maximum X coordinate of whole area for which points are needed (4000000): '
Accept maxy number default 6000000 prompt 'Enter Maximum Y coordinate of whole area for which points are needed (6000000): '
Accept InternalWindows number default 5 prompt 'Enter number of internal windows (5): '
Accept PointsPerWindow number default 5000 prompt 'Enter possible maximum number of points per window (5000): '
Accept minWidth number default 500 prompt 'Enter Minimum width of an internal window (500): '
Accept maxWidth number default 100000 prompt 'Enter Maximum width of an internal window (100000): '
Accept minHeight number default 500 prompt 'Enter Minimum Height of an internal window (500): '
Accept maxHeight number default 100000 prompt 'Enter Maximum Height of an internal window (100000): '
Accept sdoTolerance number default 0.05 prompt 'Enter SDO_TOLERANCE metadata (0.05): '
Prompt Generate &InternalWindows. random Windows within our area each having a random window size
DECLARE
v_round_factor NUMBER;
BEGIN
v_round_factor := ROUND(log(10,1/&sdotolerance.))+1;
<<window_generation_loop>>
-- First let's create and process a list of windows defined from randomly created centre points with random extents
-- We'll include a sprinkling of points across the whole area and not just within particular windows
For rec In ( SELECT rownum As WindowID, X, Y, WinHeight, WinWidth, PointCount
FROM ( SELECT ( &minx. + &maxx. ) / 2 as X,
( &miny. + &maxy. ) / 2 as y,
( &maxy. - &miny. ) as WinHeight,
( &maxx. - &minx. ) as WinWidth,
trunc(dbms_random.value(1,&PointsPerWindow.),0) as PointCount
FROM DUAL
UNION ALL
SELECT dbms_random.value(&minx.,&maxx.) as X,
dbms_random.value(&miny.,&maxy.) as Y,
dbms_random.value(&minHeight.,&maxHeight.) as WinHeight,
dbms_random.value(&minWidth.,&maxWidth.) as WinWidth,
trunc(dbms_random.value(1,&PointsPerWindow.),0) as PointCount
FROM dual
CONNECT BY LEVEL <= &InternalWindows.
)
) LOOP
dbms_output.put_line('Generating ' || rec.PointCount || ' Points for Window ' || rec.WindowId || ' of size ('|| rec.WinWidth||','||rec.WinHeight||')');
-- Now for each window create a random number of points within its extent ...
INSERT INTO my_points
SELECT my_points_seq.nextval,
rec.WindowId,
mdsys.sdo_geometry(2001,NULL,
MDSYS.SDO_POINT_TYPE(
ROUND(dbms_random.value(rec.x - ( rec.WinWidth / 2 ),
rec.x + ( rec.WinWidth / 2 )),v_round_factor),
ROUND(dbms_random.value(rec.y - ( rec.WinHeight / 2 ),
rec.y + ( rec.WinHeight / 2 ) ),v_round_factor),
NULL),
NULL,NULL)
FROM DUAL
CONNECT BY LEVEL <= rec.PointCount;
COMMIT;
End Loop window_generation_loop;
END;
/
SHOW ERRORS
Prompt Let's sample some of the created data...
SELECT myp.geometry.sdo_point.x,
myp.geometry.sdo_point.y,
window_id
FROM my_points sample (2) myp;
Prompt Let's summary what was inserted into the table...
SELECT 'For Window ' || window_id || ' ' || count(*) || ' points were stored' As Result
FROM my_points
GROUP BY window_id;
Prompt Create Oracle Metadata Entry...
DELETE FROM user_sdo_geom_metadata WHERE table_name = 'MY_POINTS';
COMMIT;
INSERT INTO user_sdo_geom_metadata
SELECT 'MY_POINTS','GEOMETRY',
MDSYS.SDO_DIM_ARRAY(
MDSYS.SDO_DIM_ELEMENT('X', minx, maxx, &sdoTolerance.),
MDSYS.SDO_DIM_ELEMENT('Y', miny, maxy, &sdoTolerance.)), NULL
FROM ( SELECT TRUNC( MIN( a.geometry.sdo_point.x ) - 1,0) as minx,
ROUND( MAX( a.geometry.sdo_point.x ) + 1,0) as maxx,
TRUNC( MIN( a.geometry.sdo_point.y ) - 1,0) as miny,
ROUND( MAX( a.geometry.sdo_point.y ) + 1,0) as maxy
FROM my_points a);
Prompt Create RTree index on point data ...
DROP INDEX my_points_geometry;
CREATE INDEX my_points_geometry ON my_points(geometry)
INDEXTYPE IS MDSYS.SPATIAL_INDEX
PARAMETERS('sdo_indx_dims=2, layer_gtype=point');

<<Oracle's SQL/MM Compliant Types >>Tip #2: layer_gtypes for spatial indexes