Difference between revisions of "Points"

From Wikivyuka
Jump to: navigation, search
m
m (Vytvoření prostorového indexu)
 
(46 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
Příklad využívá podklady z Oracle dokumentace zaměřené na práci s [http://docs.oracle.com/cd/B25329_01/doc/appdev.102/b28004/xe_locator.htm modulem Locator].
 
Příklad využívá podklady z Oracle dokumentace zaměřené na práci s [http://docs.oracle.com/cd/B25329_01/doc/appdev.102/b28004/xe_locator.htm modulem Locator].
  
 +
=====Příprava tabulek CUSTOMERS a STORES=====
 
Uvedený příklad vychází z předpokladu, kdy obchodní společnost má několik maloobchodních prodejen. Aby prodejny mohly zákazníky, kteří jsou v blízkosti daného obchodu, informovat o nových reklamních akcích, je nutné uložit a uchovávat lokalizační údaje jak pro zákazníky, tak obchody. Pak je teprve možné najít odpovídající zákazníky a provádět analýzy využívající znalost polohy obchodu i zákazníků.  
 
Uvedený příklad vychází z předpokladu, kdy obchodní společnost má několik maloobchodních prodejen. Aby prodejny mohly zákazníky, kteří jsou v blízkosti daného obchodu, informovat o nových reklamních akcích, je nutné uložit a uchovávat lokalizační údaje jak pro zákazníky, tak obchody. Pak je teprve možné najít odpovídající zákazníky a provádět analýzy využívající znalost polohy obchodu i zákazníků.  
  
Data o ''Zákaznících'' budou uloženy v tabulce CUSTOMERS, která již má strukturu definovanou a je možné ji vytvořit pomocí následujícícho příkazu CREATE:
+
Data o ''Zákaznících'' budou uloženy v tabulce CUSTOMERS, která má takto definovanou strukturu:
  
CREATE TABLE customers (
+
  CUSTOMERS(
 
   customer_id NUMBER,
 
   customer_id NUMBER,
 
   last_name VARCHAR2(30),
 
   last_name VARCHAR2(30),
Line 13: Line 14:
 
   state_province_code VARCHAR2(2),
 
   state_province_code VARCHAR2(2),
 
   postal_code VARCHAR2(9),
 
   postal_code VARCHAR2(9),
   cust_geo_location SDO_GEOMETRY);
+
   cust_geo_location SDO_GEOMETRY)
  
Data o obchodech jsou definovány a vytvořeny podobně, v tabulce STORES:
+
Data o obchodech budou mít strukturu definovánou v tabulce STORES:
  
CREATE TABLE stores (
+
  STORES(
 
   store_id NUMBER,
 
   store_id NUMBER,
 
   description VARCHAR2(100),
 
   description VARCHAR2(100),
Line 24: Line 25:
 
   state_province_code VARCHAR2(2),
 
   state_province_code VARCHAR2(2),
 
   postal_code VARCHAR2(9),
 
   postal_code VARCHAR2(9),
   store_geo_location SDO_GEOMETRY);
+
   store_geo_location SDO_GEOMETRY)
 +
 
 +
Než tabulky vytvoříme, je vhodné "vyčistit" databázi pro případ, že by tam už tabulky stejného jména existovaly. (Zejména v případě, že budeme akce opakovat:-)). Příkaz DROP vymaže z databáze tabulku nebo index daného jména, příkaz DELETE vymaže záznam, který je dán podmínkou za klíčovým slovem WHERE.
  
-- Clean up from any previous running of this procedure.
+
  DROP TABLE customers;
   
+
DROP TABLE stores;
DROP TABLE customers;
+
DROP INDEX customers_sidx;
DROP TABLE stores;
+
DROP INDEX stores_sidx;
DROP INDEX customers_sidx;
+
DELETE FROM USER_SDO_GEOM_METADATA  
DROP INDEX stores_sidx;
 
DELETE FROM USER_SDO_GEOM_METADATA  
 
 
   WHERE TABLE_NAME = 'CUSTOMERS' AND COLUMN_NAME = 'CUST_GEO_LOCATION';
 
   WHERE TABLE_NAME = 'CUSTOMERS' AND COLUMN_NAME = 'CUST_GEO_LOCATION';
DELETE FROM USER_SDO_GEOM_METADATA  
+
DELETE FROM USER_SDO_GEOM_METADATA  
 
   WHERE TABLE_NAME = 'STORES' AND COLUMN_NAME = 'STORE_GEO_LOCATION';
 
   WHERE TABLE_NAME = 'STORES' AND COLUMN_NAME = 'STORE_GEO_LOCATION';
 
   
 
   
-- Create table for customer information.
+
Nyní je možné vytvořit pomocí příkazů CREATE obě tabulky:
 
   
 
   
CREATE TABLE customers (
+
CREATE TABLE customers (
 
   customer_id NUMBER,
 
   customer_id NUMBER,
 
   last_name VARCHAR2(30),
 
   last_name VARCHAR2(30),
Line 49: Line 50:
 
   cust_geo_location SDO_GEOMETRY);
 
   cust_geo_location SDO_GEOMETRY);
 
   
 
   
-- Create table for store information.
+
  CREATE TABLE stores (
   
 
CREATE TABLE stores (
 
 
   store_id NUMBER,
 
   store_id NUMBER,
 
   description VARCHAR2(100),
 
   description VARCHAR2(100),
Line 59: Line 58:
 
   postal_code VARCHAR2(9),
 
   postal_code VARCHAR2(9),
 
   store_geo_location SDO_GEOMETRY);
 
   store_geo_location SDO_GEOMETRY);
 +
 +
=====Vkládání dat s bodovou geometrií=====
 
   
 
   
-- Insert customer data.
+
Pomocí příkazů INSERT začneme vkládat data do tabulek. Hodnoty vkládané do atributů ''cust_geo_location'' a ''store_geo_location'' jsou typu POINT (hodnota 2001 na pozici SDO_GTYPE), jsou vztaženy k souřadnicovému systému s kódem 8307 (atribut SDO_SRID), dále jsou uváděny souřadnice bodu (atribut SDO_POINT), zbývající atibuty SDO_ELEM_INFO a SDO_ORDINATES mají hodnoty NULL. Při vkládání souřadnic je nutné dát pozor na následující pravidlo: Oracle Locator vyžaduje, aby hodnota hodnotu zeměpisné délky byla umístěna před hodnotou zeměpisné šířky.
 +
 
 +
Vkládání dat o zákaznících:
 
   
 
   
INSERT INTO customers VALUES
+
INSERT INTO customers VALUES
 
   (1001,'Nichols', 'Alexandra',  
 
   (1001,'Nichols', 'Alexandra',  
 
   '17 Maple Drive', 'Nashua', 'NH','03062',
 
   '17 Maple Drive', 'Nashua', 'NH','03062',
Line 68: Line 71:
 
     SDO_POINT_TYPE (-71.48923,42.72347,NULL), NULL, NULL));
 
     SDO_POINT_TYPE (-71.48923,42.72347,NULL), NULL, NULL));
 
   
 
   
INSERT INTO customers VALUES
+
INSERT INTO customers VALUES
 
   (1002,'Harris', 'Melvin',  
 
   (1002,'Harris', 'Melvin',  
 
   '5543 Harrison Blvd', 'Reston', 'VA', '20190',
 
   '5543 Harrison Blvd', 'Reston', 'VA', '20190',
Line 74: Line 77:
 
     SDO_POINT_TYPE(-70.120133,44.795766,NULL), NULL, NULL));
 
     SDO_POINT_TYPE(-70.120133,44.795766,NULL), NULL, NULL));
 
   
 
   
INSERT INTO customers VALUES
+
INSERT INTO customers VALUES
 
   (1003,'Chang', 'Marian',  
 
   (1003,'Chang', 'Marian',  
 
   '294 Main St', 'Concord', 'MA','01742',
 
   '294 Main St', 'Concord', 'MA','01742',
Line 80: Line 83:
 
     SDO_POINT_TYPE (-71.351,42.4598,NULL), NULL, NULL));
 
     SDO_POINT_TYPE (-71.351,42.4598,NULL), NULL, NULL));
 
   
 
   
INSERT INTO customers VALUES
+
INSERT INTO customers VALUES
 
   (1004,'Williams', 'Thomas',  
 
   (1004,'Williams', 'Thomas',  
 
   '84 Hayward Rd', 'Acton', 'MA','01720',
 
   '84 Hayward Rd', 'Acton', 'MA','01720',
Line 86: Line 89:
 
     SDO_POINT_TYPE (-71.4559,42.4748,NULL), NULL, NULL));
 
     SDO_POINT_TYPE (-71.4559,42.4748,NULL), NULL, NULL));
 
   
 
   
INSERT INTO customers VALUES
+
INSERT INTO customers VALUES
 
   (1005,'Rodriguez', 'Carla',  
 
   (1005,'Rodriguez', 'Carla',  
 
   '9876 Pine Lane', 'Sudbury', 'MA','01776',
 
   '9876 Pine Lane', 'Sudbury', 'MA','01776',
Line 92: Line 95:
 
     SDO_POINT_TYPE (-71.4242,42.3826,NULL), NULL, NULL));
 
     SDO_POINT_TYPE (-71.4242,42.3826,NULL), NULL, NULL));
 
   
 
   
INSERT INTO customers VALUES
+
INSERT INTO customers VALUES
 
   (1006,'Adnani', 'Ramesh',  
 
   (1006,'Adnani', 'Ramesh',  
 
   '1357 Appletree Ct', 'Falls Church', 'VA','22042 ',
 
   '1357 Appletree Ct', 'Falls Church', 'VA','22042 ',
Line 98: Line 101:
 
     SDO_POINT_TYPE (-77.1745,38.88505,NULL),NULL,NULL));
 
     SDO_POINT_TYPE (-77.1745,38.88505,NULL),NULL,NULL));
 
   
 
   
-- Insert stores data.
+
Vkládání dat o obchodech.
 
   
 
   
INSERT INTO stores VALUES
+
INSERT INTO stores VALUES
 
   (101,'Nashua megastore',  
 
   (101,'Nashua megastore',  
 
   '123 Commercial Way', 'Nashua', 'NH','03062',
 
   '123 Commercial Way', 'Nashua', 'NH','03062',
Line 106: Line 109:
 
     SDO_POINT_TYPE (-71.49074,42.7229,NULL),NULL,NULL));
 
     SDO_POINT_TYPE (-71.49074,42.7229,NULL),NULL,NULL));
 
   
 
   
INSERT INTO stores VALUES
+
INSERT INTO stores VALUES
 
   (102,'Reston store',  
 
   (102,'Reston store',  
 
   '99 Main Blvd', 'Reston', 'VA','22070',
 
   '99 Main Blvd', 'Reston', 'VA','22070',
Line 112: Line 115:
 
     SDO_POINT_TYPE (-77.34511,38.9521,NULL),NULL,NULL));
 
     SDO_POINT_TYPE (-77.34511,38.9521,NULL),NULL,NULL));
 
   
 
   
-- Add metadata to spatial view USER_SDO_GEOM_METADATA.
+
=====Vytvoření prostorového indexu=====
 +
 
 +
Tvorba prostorového indexu je složena ze dvou kroků, jejichž pořadí je nutné dodržet. Nejprve je nutné pro tabulku s prostorovými informacemi vložit záznam s příslušnými informacemi do systémové tabulky s metadaty. Příkaz INSERT je povolen i běžnému uživateli, ale vkládání záznamu se děje přes pohled USER_SDO_GEOM_METADATA. Ten umožňuje uživateli uložit hodnoty následujících sloupců:
 +
(TABLE_NAME  VARCHAR2(32),
 +
  COLUMN_NAME  VARCHAR2(32),
 +
  DIMINFO      SDO_DIM_ARRAY,
 +
  SRID        NUMBER
 +
);
 +
kde TABLE_NAME představuje název tabulky s prostorovými daty, COLUMN_NAME je název sloupce, který je typu SDO_GEOMETRY. DIMINFO je pole proměnlivou délkou (VARRAY(4)) obsahujícíc prvky typu SDO_DIM_ELEMENT. Atribut SRID obsahuje buď kód souřadnicového systému, ve kterém jsou lokalizovány geometrie prostorových objektů, nebo má zadánu hodnotu NULL, nejsou-li prvky spojeny s žádným konkrétním souřadnicovým systémem.
 +
 
 +
Definice SDO_DIM_ARRAY:
 +
Create Type SDO_DIM_ARRAY as VARRAY(4) of SDO_DIM_ELEMENT;
 +
 
 +
kde SDO_DIM_ELEMENT je definován:
 +
 
 +
Create Type SDO_DIM_ELEMENT as OBJECT (
 +
  SDO_DIMNAME VARCHAR2(64),
 +
  SDO_LB NUMBER,
 +
  SDO_UB NUMBER,
 +
  SDO_TOLERANCE NUMBER);
 +
 
 +
''Příklady hodnot DIMINFO'':
 +
*SS s kódem 8307 (WGS 84 coordinate system pro starší verze Oracle 8, 9 or 10gR1, později už EPSG 4326):
 +
SDO_DIM_ARRAY (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5),
 +
                SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)
 +
              )
 +
*Bez konkrétního SS (plocha o velikosti 100x100 s tolerancí 0.05):
 +
SDO_DIM_ARRAY (SDO_DIM_ELEMENT('X', 0, 100, 0.05),
 +
                SDO_DIM_ELEMENT('Y', 0, 100, 0.05)
 +
              )
 +
 
 +
Pole SDO_DIM_ARRAY má počet prvků n, odpovídající n dimenzím. Zde se DIMINFO skládá ze 2 instancí SDO_DIM_ELEMENT pro dvou-dimenzionální geometrie. Mohly by být 3 instance pro 3-dimenzionální geometrie  nebo 4 pro 4-dimenzionální geometrie. Každá instance SDO_DIM_ELEMENT v poli musí být validní (nesmí mít NULL hodnotu) pro atributy SDO_LB (dolní mez), SDO_UB (horní mez) zájmového prostoru a SDO_TOLERANCE - toleranci, se kterou jsou dva body vnímány jako totožné. Tolerance představuje přesnost pro prostorová data a musí být větší než nula.
 +
 
 +
Pro náš příklad budeme vkládat záznamy s metainformacemi o obou tabulkách přes pohled USER_SDO_GEOM_METADATA:
 
   
 
   
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)  
+
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)  
 
   VALUES ('CUSTOMERS', 'CUST_GEO_LOCATION',  
 
   VALUES ('CUSTOMERS', 'CUST_GEO_LOCATION',  
 
   SDO_DIM_ARRAY  
 
   SDO_DIM_ARRAY  
Line 121: Line 157:
 
   8307);
 
   8307);
 
   
 
   
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)  
+
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)  
 
   VALUES ('STORES', 'STORE_GEO_LOCATION',  
 
   VALUES ('STORES', 'STORE_GEO_LOCATION',  
 
   SDO_DIM_ARRAY  
 
   SDO_DIM_ARRAY  
Line 127: Line 163:
 
     SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),  
 
     SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),  
 
   8307);  
 
   8307);  
 
-- Create spatial indexes.
 
 
CREATE INDEX customers_sidx ON customers(cust_geo_location)
 
  INDEXTYPE IS mdsys.spatial_index;
 
 
CREATE INDEX stores_sidx ON stores(store_geo_location)
 
  INDEXTYPE IS mdsys.spatial_index;
 
 
-- Perform location-based queries.
 
 
-- Find the 3 closest customers to store_id = 101.
 
 
SELECT /*+ordered*/
 
  c.customer_id,
 
  c.first_name,
 
  c.last_name
 
FROM stores s,
 
  customers c
 
WHERE s.store_id = 101
 
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=3')
 
  = 'TRUE';
 
 
-- Find the 3 closest customers to store_id = 101, and
 
-- order the results by distance.
 
 
SELECT /*+ordered*/
 
  c.customer_id,
 
  c.first_name,
 
  c.last_name,
 
  sdo_nn_distance (1) distance
 
FROM stores s,
 
  customers c
 
WHERE s.store_id = 101
 
AND sdo_nn
 
  (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=3', 1)
 
    = 'TRUE'
 
ORDER BY distance;
 
 
-- Find all the customers within 100 miles of store_id = 101
 
 
SELECT /*+ordered*/
 
  c.customer_id,
 
  c.first_name,
 
  c.last_name
 
FROM stores s,
 
  customers c
 
WHERE s.store_id = 101
 
AND sdo_within_distance (c.cust_geo_location,
 
  s.store_geo_location,
 
  'distance = 100 unit=MILE') = 'TRUE';
 
  
Example 1-2 Inserting Customer and Store Records
+
Uvedené meze pro dimenze longitude (-180.0, 180.0) a latitude (-90, 90) souvisí geodetickým datem, který používá souřadnicový systém WGS84. Hodnota tolerance 0.5 znamená, že jakékoli dva body ležící od sebe méně než půl metru, jsou považovány za stejný bod v případě funkcí nebo operací pracujícími s určováním polohy.
  
-- Insert customer data.
+
Teprve nyní můžeme přistoupit k tvorbě prostorového indexu. Prostorové indexy jsou nutné pro mnoho dotazů, které používají operátory modulu Locator, a pro výkon většiny prostorových dotazů jsou důležité, neboť jinak se vyhodnocování vztahů dopočítává teprve při vykonávání dotazu. Před použitím prostorových dat v analýzách či dotazování vytváříme prostorový index pro každý prostorový sloupec. Chcete-li vytvořit prostorové indexpoužijeme příkaz CREATE INDEX a v klauzuli pro INDEXTYPE použijeme typ MDSYS.SPATIAL_INDEX.
+
Příkaz CREATE INDEX pak má v z8kladn9m tvaru následující složení(může obsahovat řadu parametrů, viz [http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_objindex.htm#i78196]):
INSERT INTO customers VALUES
+
  CREATE INDEX [schema.]index ON [schema.]table (column)
  (1001,'Nichols', 'Alexandra',
+
     INDEXTYPE IS MDSYS.SPATIAL_INDEX;
  '17 Maple Drive', 'Nashua', 'NH','03062',
 
  SDO_GEOMETRY(2001, 8307,  
 
    SDO_POINT_TYPE (-71.48923,42.72347,NULL), NULL, NULL));
 
 
INSERT INTO customers VALUES
 
  (1002,'Harris', 'Melvin',
 
  '5543 Harrison Blvd', 'Reston', 'VA', '20190',
 
  SDO_GEOMETRY(2001, 8307,
 
    SDO_POINT_TYPE(-70.120133,44.795766,NULL), NULL, NULL));
 
   
 
INSERT INTO customers VALUES
 
  (1003,'Chang', 'Marian',
 
  '294 Main St', 'Concord', 'MA','01742',
 
  SDO_GEOMETRY(2001, 8307,
 
    SDO_POINT_TYPE (-71.351,42.4598,NULL), NULL, NULL));
 
 
INSERT INTO customers VALUES
 
  (1004,'Williams', 'Thomas',
 
  '84 Hayward Rd', 'Acton', 'MA','01720',
 
  SDO_GEOMETRY(2001, 8307,
 
    SDO_POINT_TYPE (-71.4559,42.4748,NULL), NULL, NULL));
 
 
INSERT INTO customers VALUES
 
  (1005,'Rodriguez', 'Carla',
 
  '9876 Pine Lane', 'Sudbury', 'MA','01776',
 
  SDO_GEOMETRY(2001, 8307,
 
    SDO_POINT_TYPE (-71.4242,42.3826,NULL), NULL, NULL));
 
   
 
INSERT INTO customers VALUES
 
  (1006,'Adnani', 'Ramesh',
 
  '1357 Appletree Ct', 'Falls Church', 'VA','22042 ',
 
  SDO_GEOMETRY(2001, 8307,
 
    SDO_POINT_TYPE (-77.1745,38.88505,NULL),NULL,NULL));
 
 
-- Insert stores data.
 
 
INSERT INTO stores VALUES
 
  (101,'Nashua megastore',
 
  '123 Commercial Way', 'Nashua', 'NH','03062',
 
  SDO_GEOMETRY(2001, 8307,
 
    SDO_POINT_TYPE (-71.49074, 42.7229,NULL),NULL,NULL));
 
 
INSERT INTO stores VALUES
 
  (102,'Reston store',
 
  '99 Main Blvd', 'Reston', 'VA','22070',
 
  SDO_GEOMETRY(2001, 8307,
 
     SDO_POINT_TYPE (-77.34511, 38.9521,NULL),NULL,NULL));
 
  
Updating the Spatial Metadata
+
Název indexu je doporučeno poskládat z názvu tabulky, ke které je index tvořen a zkratky sidx (spatial index). Bude vytvořen na sloupci s typem SDO_GEOMETRY a je to prostorový index(mdsys.spatial_index).
  
For each spatial column (type SDO_GEOMETRY), you must insert an appropriate row into the USER_SDO_GEOM_METADATA view to reflect the dimensional information for the area in which the data is located. You must do this before creating spatial indexes (see "Creating Spatial Indexes") on the spatial columns.
+
Příkazy pro naše dvě tabulky pak vypadají takto:
 +
 +
CREATE INDEX customers_sidx ON customers(cust_geo_location) INDEXTYPE IS mdsys.spatial_index;
 +
CREATE INDEX stores_sidx ON stores(store_geo_location) INDEXTYPE IS mdsys.spatial_index;
  
The USER_SDO_GEOM_METADATA view has the following definition:
+
Teprve po vytvoření prostorového indexu můžeme využít prostředí GeoRaptoru pro zobrazení geoobjektů. Rozmístění obchodů a lokalizace zákazníků jsou patrny na obrázku [[Media:StoresCustomers.png | Obchody&Zakaznici]].
 
 
(
 
  TABLE_NAME  VARCHAR2(32),
 
  COLUMN_NAME  VARCHAR2(32),
 
  DIMINFO      SDO_DIM_ARRAY,
 
  SRID        NUMBER
 
);
 
  
The DIMINFO column is a varying length array of an object type, ordered by dimension, and has one entry for each dimension. The SDO_DIM_ARRAY type is defined as follows:
+
=====Prostorové dotazy nad bodovými daty=====
  
Create Type SDO_DIM_ARRAY as VARRAY(4) of SDO_DIM_ELEMENT;
+
Teprve poté, kdy máme vytvořené a naplněné tabulky s prostorovými daty, aktualizovaná prostorová metadata a vytvořené prostorové indexy, můžeme začít používat operátory a funkce Oracle Locator v dotazech, kde práce s prostorem je vázána na definovanou lokalitu.
  
The SDO_DIM_ELEMENT type is defined as:
+
Chceme vyhledat tři nejbližší zákazníky pro obchod se store_id = 101. V příkazu SQL použijeme operátor SDO_NN ("nearest neighbor - nejbližší soused") ve formátu
 +
SDO_NN (geometry1, geometry2, param [, číslo]);
 +
který používá prostorový index k identifikaci nejbližších sousedů ke geometrii.
  
Create Type SDO_DIM_ELEMENT as OBJECT (
+
Význam operandů:
   SDO_DIMNAME VARCHAR2(64),
+
geometry1   Určuje geometrii sloupce v tabulce. Sloupec musí být prostorově zaindexován. Datovým typem je SDO_GEOMETRY.
   SDO_LB NUMBER,
+
geometry2   Určuje buď geometrii z tabulky nebo přechodnou geometrickou instanci.
  SDO_UB NUMBER,
+
            Nejbližší soused nebo sousedé ke ''geometry2'' se vrací od ''geometry1''. Datový typ je SDO_GEOMETRY.
  SDO_TOLERANCE NUMBER);
+
param      Určuje chování operátoru. K dispozici jsou klíčová slova  v tabulce 19-4. Pokud tento parametr nezadáte,  
 +
            operátor vrátí všechny řádky v pořadí podle rostoucí vzdálenosti od ''geometry2''. Datový typ je VARCHAR2.
 +
number      Pokud SDO_NN volá operátor SDO_NN_DISTANCE, který vrací nejmenší vzdálenost mezi geometriemi. Datový typ je NUMBER.
  
The SDO_DIM_ARRAY instance is of size n if there are n dimensions. That is, DIMINFO contains 2 SDO_DIM_ELEMENT instances for two-dimensional geometries, 3 instances for three-dimensional geometries, and 4 instances for four-dimensional geometries. Each SDO_DIM_ELEMENT instance in the array must have valid (not null) values for the SDO_LB (lower bound), SDO_UB (upper bound), and SDO_TOLERANCE (tolerance) attributes.
+
Operátor SDO_NN vrací počet objektů ''geometry1'', které jsou nejblíže k objektům ''geometry2''. Při určování toho, jak blízko sebe jsou dva geometrické objekty, se použije nejkratší vzdálenost mezi dvěma body na obvodu/povrchu každého objektu.
  
Tolerance reflects the distance that two points can be apart and still be considered the same (for example, to accommodate rounding errors), and thus reflects the precision of the spatial data. The tolerance value must be a positive number greater than zero.
+
Operand ''param'' může zahrnovat některý z následujících parametrů:
  
Example 1-3 inserts rows into the USER_SDO_GEOM_METADATA view, with dimensional information for each spatial column. In both cases, the dimensional range is the entire Earth, and the coordinate system is the widely used WGS84 (longitude/latitude) system (spatial reference ID = 8307).
+
distance    Určuje počet jednotek vzdálenosti, po kterém se přestane hledat nejbližší soused.
 +
            Není-li zadána parametr unit, použije se unit(jednotka měření) stejná, jako mají data.
 +
            Datový typ je NUMBER. Například: "distance = 10 unit = míle"
 +
sdo_batch_size  Určuje počet řádků, které mají být hodnoceny v době, kdy provádění výrazu SDO_NN se vyhodnocuje vícekrát,
 +
            aby se vrátil požadovaný počet výsledků, které vyhovují klauzuli WHERE.
 +
            K dispozici je pouze tehdy, je-li použit index R-tree. Pokud zadáte sdo_batch_size = 0
 +
            (nebo je-li parametr param zcela vynechán), Spatial modul vypočítá velikost dávky, která je vhodná pro velikost výsledné sady.
 +
            Datový typ je NUMBER. Například: 'sdo_batch_size = 10'
 +
sdo_num_res    Není-li uveden sdo_batch_size, určuje kolik výsledků (nejbližších sousedů) se má vrátit.
 +
            Pokud je zadán sdo_batch_size, je toto klíčové slovo ignorováno.
 +
            Datový typ je NUMBER. Například: 'sdo_num_res = 5'
 +
unit        Je-li užito klíčové slovo ''distance'' nebo je použito volání SDO_NN_DISTANCE, určuje jednotky měření.
 +
            Hodnoty jednotek SDO_UNIT jsou uvedeny v tabulce MDSYS.SDO_DIST_UNITS.
 +
            Datový typ je VARCHAR2. Výchozí = unit (jednotka měření) spojená s daty.
 +
            U geodetických dat je výchozí hodnotou  metr. Například: 'jednotka = KM'
  
Example 1-3 Updating the Spatial Metadata
+
Podrobnosti k operátoru SDO_NN najdete v dokumentaci Oracle kapitola 19 [http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#i78067 Spatial Operators - SDO_NN].
 +
V příkazu pro vyhledání tří nejblíže bydlících zákazníků u obchodu s id 101, bude použití SDO_NN vypadat takto:
  
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)
+
SELECT c.customer_id, c.first_name, c.last_name
  VALUES ('CUSTOMERS', 'CUST_GEO_LOCATION',
+
FROM stores s, customers c
  SDO_DIM_ARRAY
+
WHERE s.store_id = 101
    (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5),
+
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=3') = 'TRUE';
    SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),
+
  8307);
+
Pokud budeme chtít výsledek upravit tak, abychom dostali seznam nejbližších zákazníků setříděný podle vzdálenosti, kterou má zákazník k obchodu, pak lze využít operátoru SDO_NN_DISTANCE a podle jeho výsledků třídít. Podobně jako u operátoru SDO_NN je i tento operátor popsán v dokumentaci kapitola 19 [http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#i80529 Spatial Operators - SDO_NN_DISTANCE].
 
   
 
   
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)  
+
SELECT /*+ordered*/ c.customer_id, c.first_name, c.last_name, sdo_nn_distance (1) distance
  VALUES ('STORES', 'STORE_GEO_LOCATION',  
+
FROM stores s, customers c
  SDO_DIM_ARRAY
+
WHERE s.store_id = 101
    (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5),
+
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=3', 1) = 'TRUE'
    SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),
+
ORDER BY distance;
  8307);
 
  
In Example 1-3, the longitude dimension of -180.0,180.0 and latitude dimension of -90.90 are required for geodetic data using the WGS84 coordinate system. The tolerance value of 0.5 means that any points less than one-half meter apart are considered to be the same point by any location-based operators or functions.
+
Kdo bydlí nejblíže obchodu 101 lze zjistit příkazem
  
Creating Spatial Indexes
+
SELECT c.customer_id, c.first_name, c.last_name
 +
FROM stores s, customers c
 +
WHERE s.store_id = 101
 +
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=1') = 'TRUE';
  
Spatial indexes are required for many queries that use Locator operators, and are important for performance for most spatial queries. Before you use spatial data for analysis or queries, create a spatial index on each spatial column. To create a spatial index, use the CREATE INDEX statement, and specify the INDEXTYPE IS MDSYS.SPATIAL_INDEX clause.
+
Detailnější rozmístění obchodů a zákazníků ukazuje obrázek [[Media:StoresCustomersDetail.png | Lokalizace detailněji]].
 +
 +
Dalším operátorem, jehož působení si ukážeme je SDO_WITHIN_DISTANCE (stránka dokumentace Oracle v kapitole 19 [http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#i77653 Spatial Operators - SDO_WITHIN_DISTANCE]). Operátor na základě prostorového indexu identifikuje sadu prostorových objektů, které jsou do určité specifikované vzdálenosti od daného objektu, jako je například oblast zájmu nebo bod zájmu. Formát operátoru:
 +
SDO_WITHIN_DISTANCE (geometry1, aGeom, params);
 +
kde
 +
geometry1    Určuje geometrie sloupce v tabulce. Polohu sady geometrických objektů operátor porovná s požadovanou vzdáleností od daného objektu (aGeom).
 +
              Sloupec musí být prostorově indexován. Datový typ je SDO_GEOMETRY.
 +
aGeom        Určuje objekt, který má být posouzen na vzdálenost od geometrických objektů v geometry1.
 +
              Zadává se buď geometrie z tabulky (pomocí proměnné vazby) nebo přechodná instance geometrie (pomocí SDO_GEOMETRY konstruktoru).
 +
              Datový typ je SDO_GEOMETRY.
 +
params      Udává v uvozovkách zadané řetězce obsahující jeden nebo více klíčových slov (s hodnotami), které určují chování operátoru.  
 +
              Mohou to být položky (distance, max_resolution, min_resolution, querytype, a unit)
 +
              (vzdálenost, max_rozliseni, min_rozliseni, typDotazu, a jednotka) a jsou chápána jako potenciální klíčová slova pro parametr params.
 +
              Datový typ těchto hodnot je VARCHAR2.
 +
Parametry operandu params:
 +
distance      Určuje hodnotu vzdálenosti. Je-li souřadný systém spojený s geometrií, vzdálenost používá jednotky spojené se souřadnicovým systémem.
 +
                Toto je povinný parametr. Datový typ je NUMBER.
 +
max_resolution Zahrnuje pouze geometrie, u nichž alespoň u jedné strany z geometrie MBR (minimálního ohraničujícícho obdélníka)
 +
                je vzdálenost menší než nebo rovna zadané hodnotě. Například, max_resolution = 10 zahrnuje pouze geometrie,
 +
                pro které je šířka nebo výška (nebo oba) z geometrie MBR menší než nebo rovna 10.
 +
min_resolution Zahrnuje pouze takové geometrie, pro které alespoň jedna strana geometrie MBR je rovna nebo větší než zadaná hodnota.
 +
                Například, min_resolution = 10 zahrnuje pouze geometrie, pro které je šířka nebo výška (nebo oba) z geometrie MBR nejméně 10.
 +
querytype      Nastavení 'querytype = FILTER' vede k prováděn9 pouze primárního filtru.
 +
                Není-li uveden querytype, pak se v operaci provedou oba filtry - jak primární, tak sekundární (výchozí nastavení).
 +
                Datový typ je VARCHAR2.
 +
unit          Určuje jednotku měření: 'unit= ', kde je hodnota SDO_UNIT převzata z tabulky MDSYS.SDO_DIST_UNITS (například 'unit = KM').
 +
                Datový typ je NUMBER. Výchozí jednotka měření je spojena s daty, u geodetických dat je výchozí hodnota metr.
  
To create a spatial index, the database user must have the CREATE TABLE privilege.
+
Chceme-li tedy vyhledat zákazníky do vzdálenosti 50 mil od obchodu se store_id = 101, použijeme v podmínce za klíčovým slovem WHERE operátor SDO_WITHIN_DISTANCE s parametrem unit pro změnu jednotek na míle.
 +
 
 +
SELECT /*+ordered*/ c.customer_id, c.first_name, c.last_name
 +
FROM stores s, customers c
 +
WHERE s.store_id = 101
 +
AND sdo_within_distance (c.cust_geo_location, s.store_geo_location,
 +
  'distance = 50 unit=MILE') = 'TRUE';
  
Example 1-4 creates spatial indexes on the CUSTOMERS.CUST_GEO_LOCATION and STORES.STORE_GEO_LOCATION columns.
+
Ve výsledku by to měli být tito 4 zákazníci:
 +
1005 Carla Rodriguez
 +
1004 Thomas Williams
 +
1003 Marian Chang
 +
1001 Alexandra Nichols
  
Example 1-4 Creating the Spatial Indexes
+
[http://gis.vsb.cz/wikivyuka/index.php/Prostorov%C3%A9_datab%C3%A1ze_-_cvi%C4%8Den%C3%AD Hlavní stránka předmětu]
 
 
CREATE INDEX customers_sidx ON customers(cust_geo_location)
 
  INDEXTYPE IS mdsys.spatial_index;
 
 
CREATE INDEX stores_sidx ON stores(store_geo_location)
 
  INDEXTYPE IS mdsys.spatial_index;
 

Latest revision as of 13:10, 24 March 2015

Příklad využívá podklady z Oracle dokumentace zaměřené na práci s modulem Locator.

Příprava tabulek CUSTOMERS a STORES

Uvedený příklad vychází z předpokladu, kdy obchodní společnost má několik maloobchodních prodejen. Aby prodejny mohly zákazníky, kteří jsou v blízkosti daného obchodu, informovat o nových reklamních akcích, je nutné uložit a uchovávat lokalizační údaje jak pro zákazníky, tak obchody. Pak je teprve možné najít odpovídající zákazníky a provádět analýzy využívající znalost polohy obchodu i zákazníků.

Data o Zákaznících budou uloženy v tabulce CUSTOMERS, která má takto definovanou strukturu:

 CUSTOMERS(
 customer_id NUMBER,
 last_name VARCHAR2(30),
 first_name VARCHAR2(30),
 street_address VARCHAR2(40),
 city VARCHAR2(30),
 state_province_code VARCHAR2(2),
 postal_code VARCHAR2(9),
 cust_geo_location SDO_GEOMETRY)

Data o obchodech budou mít strukturu definovánou v tabulce STORES:

 STORES(
 store_id NUMBER,
 description VARCHAR2(100),
 street_address VARCHAR2(40),
 city VARCHAR2(30),
 state_province_code VARCHAR2(2),
 postal_code VARCHAR2(9),
 store_geo_location SDO_GEOMETRY)

Než tabulky vytvoříme, je vhodné "vyčistit" databázi pro případ, že by tam už tabulky stejného jména existovaly. (Zejména v případě, že budeme akce opakovat:-)). Příkaz DROP vymaže z databáze tabulku nebo index daného jména, příkaz DELETE vymaže záznam, který je dán podmínkou za klíčovým slovem WHERE.

DROP TABLE customers;
DROP TABLE stores;
DROP INDEX customers_sidx;
DROP INDEX stores_sidx;
DELETE FROM USER_SDO_GEOM_METADATA 
  WHERE TABLE_NAME = 'CUSTOMERS' AND COLUMN_NAME = 'CUST_GEO_LOCATION';
DELETE FROM USER_SDO_GEOM_METADATA 
  WHERE TABLE_NAME = 'STORES' AND COLUMN_NAME = 'STORE_GEO_LOCATION';

Nyní je možné vytvořit pomocí příkazů CREATE obě tabulky:

CREATE TABLE customers (
 customer_id NUMBER,
 last_name VARCHAR2(30),
 first_name VARCHAR2(30),
 street_address VARCHAR2(40),
 city VARCHAR2(30),
 state_province_code VARCHAR2(2),
 postal_code VARCHAR2(9),
 cust_geo_location SDO_GEOMETRY);

CREATE TABLE stores (
 store_id NUMBER,
 description VARCHAR2(100),
 street_address VARCHAR2(40),
 city VARCHAR2(30),
 state_province_code VARCHAR2(2),
 postal_code VARCHAR2(9),
 store_geo_location SDO_GEOMETRY);
Vkládání dat s bodovou geometrií

Pomocí příkazů INSERT začneme vkládat data do tabulek. Hodnoty vkládané do atributů cust_geo_location a store_geo_location jsou typu POINT (hodnota 2001 na pozici SDO_GTYPE), jsou vztaženy k souřadnicovému systému s kódem 8307 (atribut SDO_SRID), dále jsou uváděny souřadnice bodu (atribut SDO_POINT), zbývající atibuty SDO_ELEM_INFO a SDO_ORDINATES mají hodnoty NULL. Při vkládání souřadnic je nutné dát pozor na následující pravidlo: Oracle Locator vyžaduje, aby hodnota hodnotu zeměpisné délky byla umístěna před hodnotou zeměpisné šířky.

Vkládání dat o zákaznících:

INSERT INTO customers VALUES
 (1001,'Nichols', 'Alexandra', 
 '17 Maple Drive', 'Nashua', 'NH','03062',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-71.48923,42.72347,NULL), NULL, NULL));

INSERT INTO customers VALUES
 (1002,'Harris', 'Melvin', 
 '5543 Harrison Blvd', 'Reston', 'VA', '20190',
 SDO_GEOMETRY(2001, 8307, 
   SDO_POINT_TYPE(-70.120133,44.795766,NULL), NULL, NULL));

INSERT INTO customers VALUES
 (1003,'Chang', 'Marian', 
 '294 Main St', 'Concord', 'MA','01742',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-71.351,42.4598,NULL), NULL, NULL));

INSERT INTO customers VALUES
 (1004,'Williams', 'Thomas', 
 '84 Hayward Rd', 'Acton', 'MA','01720',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-71.4559,42.4748,NULL), NULL, NULL));

INSERT INTO customers VALUES
 (1005,'Rodriguez', 'Carla', 
 '9876 Pine Lane', 'Sudbury', 'MA','01776',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-71.4242,42.3826,NULL), NULL, NULL));

INSERT INTO customers VALUES
 (1006,'Adnani', 'Ramesh', 
 '1357 Appletree Ct', 'Falls Church', 'VA','22042 ',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-77.1745,38.88505,NULL),NULL,NULL));

Vkládání dat o obchodech.

INSERT INTO stores VALUES
 (101,'Nashua megastore', 
 '123 Commercial Way', 'Nashua', 'NH','03062',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-71.49074,42.7229,NULL),NULL,NULL));

INSERT INTO stores VALUES
 (102,'Reston store', 
 '99 Main Blvd', 'Reston', 'VA','22070',
  SDO_GEOMETRY(2001, 8307, 
    SDO_POINT_TYPE (-77.34511,38.9521,NULL),NULL,NULL));

Vytvoření prostorového indexu

Tvorba prostorového indexu je složena ze dvou kroků, jejichž pořadí je nutné dodržet. Nejprve je nutné pro tabulku s prostorovými informacemi vložit záznam s příslušnými informacemi do systémové tabulky s metadaty. Příkaz INSERT je povolen i běžnému uživateli, ale vkládání záznamu se děje přes pohled USER_SDO_GEOM_METADATA. Ten umožňuje uživateli uložit hodnoty následujících sloupců:

(TABLE_NAME   VARCHAR2(32),
 COLUMN_NAME  VARCHAR2(32),
 DIMINFO      SDO_DIM_ARRAY,
 SRID         NUMBER
);

kde TABLE_NAME představuje název tabulky s prostorovými daty, COLUMN_NAME je název sloupce, který je typu SDO_GEOMETRY. DIMINFO je pole proměnlivou délkou (VARRAY(4)) obsahujícíc prvky typu SDO_DIM_ELEMENT. Atribut SRID obsahuje buď kód souřadnicového systému, ve kterém jsou lokalizovány geometrie prostorových objektů, nebo má zadánu hodnotu NULL, nejsou-li prvky spojeny s žádným konkrétním souřadnicovým systémem.

Definice SDO_DIM_ARRAY:

Create Type SDO_DIM_ARRAY as VARRAY(4) of SDO_DIM_ELEMENT; 

kde SDO_DIM_ELEMENT je definován:

Create Type SDO_DIM_ELEMENT as OBJECT (
 SDO_DIMNAME VARCHAR2(64),
 SDO_LB NUMBER,
 SDO_UB NUMBER,
 SDO_TOLERANCE NUMBER);

Příklady hodnot DIMINFO:

  • SS s kódem 8307 (WGS 84 coordinate system pro starší verze Oracle 8, 9 or 10gR1, později už EPSG 4326):
SDO_DIM_ARRAY (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5), 
               SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)
              ) 
  • Bez konkrétního SS (plocha o velikosti 100x100 s tolerancí 0.05):
SDO_DIM_ARRAY (SDO_DIM_ELEMENT('X', 0, 100, 0.05), 
               SDO_DIM_ELEMENT('Y', 0, 100, 0.05)
              ) 

Pole SDO_DIM_ARRAY má počet prvků n, odpovídající n dimenzím. Zde se DIMINFO skládá ze 2 instancí SDO_DIM_ELEMENT pro dvou-dimenzionální geometrie. Mohly by být 3 instance pro 3-dimenzionální geometrie nebo 4 pro 4-dimenzionální geometrie. Každá instance SDO_DIM_ELEMENT v poli musí být validní (nesmí mít NULL hodnotu) pro atributy SDO_LB (dolní mez), SDO_UB (horní mez) zájmového prostoru a SDO_TOLERANCE - toleranci, se kterou jsou dva body vnímány jako totožné. Tolerance představuje přesnost pro prostorová data a musí být větší než nula.

Pro náš příklad budeme vkládat záznamy s metainformacemi o obou tabulkách přes pohled USER_SDO_GEOM_METADATA:

INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) 
  VALUES ('CUSTOMERS', 'CUST_GEO_LOCATION', 
  SDO_DIM_ARRAY 
    (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5), 
    SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)), 
  8307);

INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) 
  VALUES ('STORES', 'STORE_GEO_LOCATION', 
  SDO_DIM_ARRAY 
    (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5), 
    SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)), 
  8307); 

Uvedené meze pro dimenze longitude (-180.0, 180.0) a latitude (-90, 90) souvisí geodetickým datem, který používá souřadnicový systém WGS84. Hodnota tolerance 0.5 znamená, že jakékoli dva body ležící od sebe méně než půl metru, jsou považovány za stejný bod v případě funkcí nebo operací pracujícími s určováním polohy.

Teprve nyní můžeme přistoupit k tvorbě prostorového indexu. Prostorové indexy jsou nutné pro mnoho dotazů, které používají operátory modulu Locator, a pro výkon většiny prostorových dotazů jsou důležité, neboť jinak se vyhodnocování vztahů dopočítává teprve při vykonávání dotazu. Před použitím prostorových dat v analýzách či dotazování vytváříme prostorový index pro každý prostorový sloupec. Chcete-li vytvořit prostorové index, použijeme příkaz CREATE INDEX a v klauzuli pro INDEXTYPE použijeme typ MDSYS.SPATIAL_INDEX. Příkaz CREATE INDEX pak má v z8kladn9m tvaru následující složení(může obsahovat řadu parametrů, viz [1]):

CREATE INDEX [schema.]index ON [schema.]table (column)
    INDEXTYPE IS MDSYS.SPATIAL_INDEX;

Název indexu je doporučeno poskládat z názvu tabulky, ke které je index tvořen a zkratky sidx (spatial index). Bude vytvořen na sloupci s typem SDO_GEOMETRY a je to prostorový index(mdsys.spatial_index).

Příkazy pro naše dvě tabulky pak vypadají takto:

CREATE INDEX customers_sidx ON customers(cust_geo_location) INDEXTYPE IS mdsys.spatial_index;
CREATE INDEX stores_sidx ON stores(store_geo_location) INDEXTYPE IS mdsys.spatial_index;

Teprve po vytvoření prostorového indexu můžeme využít prostředí GeoRaptoru pro zobrazení geoobjektů. Rozmístění obchodů a lokalizace zákazníků jsou patrny na obrázku Obchody&Zakaznici.

Prostorové dotazy nad bodovými daty

Teprve poté, kdy máme vytvořené a naplněné tabulky s prostorovými daty, aktualizovaná prostorová metadata a vytvořené prostorové indexy, můžeme začít používat operátory a funkce Oracle Locator v dotazech, kde práce s prostorem je vázána na definovanou lokalitu.

Chceme vyhledat tři nejbližší zákazníky pro obchod se store_id = 101. V příkazu SQL použijeme operátor SDO_NN ("nearest neighbor - nejbližší soused") ve formátu

SDO_NN (geometry1, geometry2, param [, číslo]);

který používá prostorový index k identifikaci nejbližších sousedů ke geometrii.

Význam operandů:

geometry1   Určuje geometrii sloupce v tabulce. Sloupec musí být prostorově zaindexován. Datovým typem je SDO_GEOMETRY.
geometry2   Určuje buď geometrii z tabulky nebo přechodnou geometrickou instanci. 
            Nejbližší soused nebo sousedé ke geometry2 se vrací od geometry1. Datový typ je SDO_GEOMETRY.
param       Určuje chování operátoru. K dispozici jsou klíčová slova  v tabulce 19-4. Pokud tento parametr nezadáte, 
            operátor vrátí všechny řádky v pořadí podle rostoucí vzdálenosti od geometry2. Datový typ je VARCHAR2.
number      Pokud SDO_NN volá operátor SDO_NN_DISTANCE, který vrací nejmenší vzdálenost mezi geometriemi. Datový typ je NUMBER.

Operátor SDO_NN vrací počet objektů geometry1, které jsou nejblíže k objektům geometry2. Při určování toho, jak blízko sebe jsou dva geometrické objekty, se použije nejkratší vzdálenost mezi dvěma body na obvodu/povrchu každého objektu.

Operand param může zahrnovat některý z následujících parametrů:

distance    Určuje počet jednotek vzdálenosti, po kterém se přestane hledat nejbližší soused. 
            Není-li zadána parametr unit, použije se unit(jednotka měření) stejná, jako mají data. 
            Datový typ je NUMBER. Například: "distance = 10 unit = míle"
sdo_batch_size   Určuje počet řádků, které mají být hodnoceny v době, kdy provádění výrazu SDO_NN se vyhodnocuje vícekrát, 
            aby se vrátil požadovaný počet výsledků, které vyhovují klauzuli WHERE. 
            K dispozici je pouze tehdy, je-li použit index R-tree. Pokud zadáte sdo_batch_size = 0 
            (nebo je-li parametr param zcela vynechán), Spatial modul vypočítá velikost dávky, která je vhodná pro velikost výsledné sady. 
            Datový typ je NUMBER. Například: 'sdo_batch_size = 10'
sdo_num_res    Není-li uveden sdo_batch_size, určuje kolik výsledků (nejbližších sousedů) se má vrátit. 
            Pokud je zadán sdo_batch_size, je toto klíčové slovo ignorováno.
            Datový typ je NUMBER. Například: 'sdo_num_res = 5'
unit        Je-li užito klíčové slovo distance nebo je použito volání SDO_NN_DISTANCE, určuje jednotky měření. 
            Hodnoty jednotek SDO_UNIT jsou uvedeny v tabulce MDSYS.SDO_DIST_UNITS. 
            Datový typ je VARCHAR2. Výchozí = unit (jednotka měření) spojená s daty. 
            U geodetických dat je výchozí hodnotou  metr. Například: 'jednotka = KM'

Podrobnosti k operátoru SDO_NN najdete v dokumentaci Oracle kapitola 19 Spatial Operators - SDO_NN. V příkazu pro vyhledání tří nejblíže bydlících zákazníků u obchodu s id 101, bude použití SDO_NN vypadat takto:

SELECT c.customer_id, c.first_name, c.last_name
FROM stores s, customers c
WHERE s.store_id = 101
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=3') = 'TRUE';

Pokud budeme chtít výsledek upravit tak, abychom dostali seznam nejbližších zákazníků setříděný podle vzdálenosti, kterou má zákazník k obchodu, pak lze využít operátoru SDO_NN_DISTANCE a podle jeho výsledků třídít. Podobně jako u operátoru SDO_NN je i tento operátor popsán v dokumentaci kapitola 19 Spatial Operators - SDO_NN_DISTANCE.

SELECT /*+ordered*/ c.customer_id, c.first_name, c.last_name, sdo_nn_distance (1) distance
FROM stores s, customers c
WHERE s.store_id = 101
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=3', 1) = 'TRUE'
ORDER BY distance;

Kdo bydlí nejblíže obchodu 101 lze zjistit příkazem

SELECT c.customer_id, c.first_name, c.last_name
FROM stores s, customers c
WHERE s.store_id = 101
AND sdo_nn (c.cust_geo_location, s.store_geo_location, 'sdo_num_res=1') = 'TRUE';

Detailnější rozmístění obchodů a zákazníků ukazuje obrázek Lokalizace detailněji.

Dalším operátorem, jehož působení si ukážeme je SDO_WITHIN_DISTANCE (stránka dokumentace Oracle v kapitole 19 Spatial Operators - SDO_WITHIN_DISTANCE). Operátor na základě prostorového indexu identifikuje sadu prostorových objektů, které jsou do určité specifikované vzdálenosti od daného objektu, jako je například oblast zájmu nebo bod zájmu. Formát operátoru:

SDO_WITHIN_DISTANCE (geometry1, aGeom, params);

kde

geometry1    Určuje geometrie sloupce v tabulce. Polohu sady geometrických objektů operátor porovná s požadovanou vzdáleností od daného objektu (aGeom). 
             Sloupec musí být prostorově indexován. Datový typ je SDO_GEOMETRY.
aGeom        Určuje objekt, který má být posouzen na vzdálenost od geometrických objektů v geometry1. 
             Zadává se buď geometrie z tabulky (pomocí proměnné vazby) nebo přechodná instance geometrie (pomocí SDO_GEOMETRY konstruktoru). 
             Datový typ je SDO_GEOMETRY.
params       Udává v uvozovkách zadané řetězce obsahující jeden nebo více klíčových slov (s hodnotami), které určují chování operátoru. 
             Mohou to být položky (distance, max_resolution, min_resolution, querytype, a unit)
             (vzdálenost, max_rozliseni, min_rozliseni, typDotazu, a jednotka) a jsou chápána jako potenciální klíčová slova pro parametr params. 
             Datový typ těchto hodnot je VARCHAR2.

Parametry operandu params:

distance       Určuje hodnotu vzdálenosti. Je-li souřadný systém spojený s geometrií, vzdálenost používá jednotky spojené se souřadnicovým systémem. 
               Toto je povinný parametr. Datový typ je NUMBER.
max_resolution Zahrnuje pouze geometrie, u nichž alespoň u jedné strany z geometrie MBR (minimálního ohraničujícícho obdélníka) 
               je vzdálenost menší než nebo rovna zadané hodnotě. Například, max_resolution = 10 zahrnuje pouze geometrie, 
               pro které je šířka nebo výška (nebo oba) z geometrie MBR menší než nebo rovna 10.
min_resolution Zahrnuje pouze takové geometrie, pro které alespoň jedna strana geometrie MBR je rovna nebo větší než zadaná hodnota. 
               Například, min_resolution = 10 zahrnuje pouze geometrie, pro které je šířka nebo výška (nebo oba) z geometrie MBR nejméně 10. 
querytype      Nastavení 'querytype = FILTER' vede k prováděn9 pouze primárního filtru. 
               Není-li uveden querytype, pak se v operaci provedou oba filtry - jak primární, tak sekundární (výchozí nastavení). 
               Datový typ je VARCHAR2.
unit           Určuje jednotku měření: 'unit= ', kde je hodnota SDO_UNIT převzata z tabulky MDSYS.SDO_DIST_UNITS (například 'unit = KM'). 
               Datový typ je NUMBER. Výchozí jednotka měření je spojena s daty, u geodetických dat je výchozí hodnota metr.

Chceme-li tedy vyhledat zákazníky do vzdálenosti 50 mil od obchodu se store_id = 101, použijeme v podmínce za klíčovým slovem WHERE operátor SDO_WITHIN_DISTANCE s parametrem unit pro změnu jednotek na míle.

SELECT /*+ordered*/ c.customer_id, c.first_name, c.last_name
FROM stores s, customers c
WHERE s.store_id = 101
AND sdo_within_distance (c.cust_geo_location, s.store_geo_location,
  'distance = 50 unit=MILE') = 'TRUE';

Ve výsledku by to měli být tito 4 zákazníci:

1005	Carla	Rodriguez
1004	Thomas	Williams
1003	Marian	Chang
1001	Alexandra	Nichols

Hlavní stránka předmětu