Difference between revisions of "Points"

From Wikivyuka
Jump to: navigation, search
m (Vkládání dat s bodovou geometrií)
m (Vytvoření prostorového indexu)
 
(36 intermediate revisions by the same user not shown)
Line 61: Line 61:
 
=====Vkládání dat s bodovou geometrií=====
 
=====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. Oracle Locator vyžaduje, aby hodnota hodnotu zeměpisné délky byla umístěna před hodnotou zeměpisné šířky.
+
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:
 
Vkládání dat o zákaznících:
Line 115: Line 115:
 
     SDO_POINT_TYPE (-77.34511,38.9521,NULL),NULL,NULL));
 
     SDO_POINT_TYPE (-77.34511,38.9521,NULL),NULL,NULL));
 
   
 
   
Přidání záznamů s metainformacemi o obou tabulkách do systémové tabulky 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)  
Line 130: Line 163:
 
     SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),  
 
     SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),  
 
   8307);  
 
   8307);  
 
Vytvoření prostorového indexu:
 
 
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;
 
  
=====Ukázka prostorových dotazů=====
+
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.
-- Perform location-based queries.
+
 
+
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.
-- Find the 3 closest customers to store_id = 101.
+
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]):
+
  CREATE INDEX [schema.]index ON [schema.]table (column)
SELECT /*+ordered*/  c.customer_id, c.first_name, c.last_name
+
    INDEXTYPE IS MDSYS.SPATIAL_INDEX;
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
+
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).
  
-- Insert customer data.
+
Příkazy pro naše dvě tabulky pak vypadají takto:
 
   
 
   
INSERT INTO customers VALUES
+
  CREATE INDEX customers_sidx ON customers(cust_geo_location) INDEXTYPE IS mdsys.spatial_index;
  (1001,'Nichols', 'Alexandra',
+
  CREATE INDEX stores_sidx ON stores(store_geo_location) 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
+
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]].
  
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.
+
=====Prostorové dotazy nad bodovými daty=====
  
The USER_SDO_GEOM_METADATA view has the following definition:
+
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
  TABLE_NAME  VARCHAR2(32),
+
  SDO_NN (geometry1, geometry2, param [, číslo]);
  COLUMN_NAME VARCHAR2(32),
+
který používá prostorový index k identifikaci nejbližších sousedů ke geometrii.
  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:
+
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.
  
Create Type SDO_DIM_ARRAY as VARRAY(4) of SDO_DIM_ELEMENT;
+
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.
  
The SDO_DIM_ELEMENT type is defined as:
+
Operand ''param'' může zahrnovat některý z následujících parametrů:
  
Create Type SDO_DIM_ELEMENT as OBJECT (
+
distance    Určuje počet jednotek vzdálenosti, po kterém se přestane hledat nejbližší soused.
   SDO_DIMNAME VARCHAR2(64),
+
            Není-li zadána parametr unit, použije se unit(jednotka měření) stejná, jako mají data.
  SDO_LB NUMBER,
+
            Datový typ je NUMBER. Například: "distance = 10 unit = míle"
  SDO_UB NUMBER,
+
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,
  SDO_TOLERANCE NUMBER);
+
            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'
  
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.
+
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:
  
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.
+
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 [http://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#i80529 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;
  
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).
+
Kdo bydlí nejblíže obchodu 101 lze zjistit příkazem
  
Example 1-3 Updating the Spatial Metadata
+
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';
  
INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID)
+
Detailnější rozmístění obchodů a zákazníků ukazuje obrázek [[Media:StoresCustomersDetail.png | Lokalizace detailněji]].
  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)  
+
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:
   VALUES ('STORES', 'STORE_GEO_LOCATION',  
+
SDO_WITHIN_DISTANCE (geometry1, aGeom, params);
  SDO_DIM_ARRAY
+
kde
    (SDO_DIM_ELEMENT('LONG', -180.0, 180.0, 0.5),
+
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).
     SDO_DIM_ELEMENT('LAT', -90.0, 90.0, 0.5)),  
+
              Sloupec musí být prostorově indexován. Datový typ je SDO_GEOMETRY.
  8307);
+
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.
  
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.
+
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.
 
+
 
Creating Spatial Indexes
+
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';
  
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.
+
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
  
To create a spatial index, the database user must have the CREATE TABLE privilege.
+
[http://gis.vsb.cz/wikivyuka/index.php/Prostorov%C3%A9_datab%C3%A1ze_-_cvi%C4%8Den%C3%AD Hlavní stránka předmětu]
 
 
Example 1-4 creates spatial indexes on the CUSTOMERS.CUST_GEO_LOCATION and STORES.STORE_GEO_LOCATION columns.
 
 
 
Example 1-4 Creating the 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;
 

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