Parcely

From Wikivyuka
Revision as of 09:33, 5 August 2014 by Dur30 (talk | contribs) (Podkladová síť)

Jump to: navigation, search

Příklad Parcely

Představme si velmi jednoduchý systém pro evidenci parcel a jejich vlastníků. Vytvoříme jednoduchou datovou strukturu, pomocí které budeme evidovat vlastníka/vlastníky pozemku/ů. Připouštíme variantu, kdy jeden vlastník může vlastnit více parcel (současně i postupně v čase). Stejně jako jedna parcela může mít více vlastníků v daném okamžiku.

Rozborem situace zjistíme, že lze nadefinovat datové entity VLASTNIK a PARCELA, mezi kterými vznikne vztah typu M:N:

VLASTNIK m – VLASTNI – n  PARCELA

Strukturu entitních typů zapíšeme pomocí lineárního zápisu:

VLASTNIK(idVlastnik, jmenoVla, prijmeniVla, adresaVla),
PARCELA(idParcela, KU, tvarParcela),
VLASTNI(VLASTNIK, PARCELA, datumOd, datumDo) 

kde atributy s prefixem 'id' představují primární atributy, a vazba umožňuje díky vazebním atributům sledovat kdo vlastnil parcelu v určitém období.

Před vytvořením struktury v databázi připravíme rozkladem této vazby vazební tabulku, jejíž záznamy budou představovat údaje o vlastníkovi parcely, včetně časového intervalu vlastnictví.

VLASTNIK 1 --- m VLASTNICTVI n---1  PARCELA

Vazební tabulka VLASTNICTVI bude mít primární atribut a dva atributy typu cizí klíč, a atributy vazby.

VLASTNICTVI(idVlastnictvi, idVlastnik, idParcela, vlastniOd, vlastniDo).

Vytvoření tabulek a vložení dat

Tabulky vytvoříme pomocí příkazu CREATE TABLE, kde uvedeme název tabulky, názvy a datové typy atributů, a omezení na atributy či tabulku.

Tabulka VLASTNIK

Před tvorbou samotné tabulky je vhodné ošetřit možnost existence tabulky se stejným názvem (například z důvodu předchozího nepovedeného příkazu:-)).

DROP TABLE VLASTNIK;
CREATE TABLE VLASTNIK(
idVlastnik NUMBER PRIMARY KEY,
jmenoVla VARCHAR2(25) NOT NULL,
prijmeniVla VARCHAR2(25) NOT NULL,
adresaVla VARCHAR2(30)
);

Do tabulky VLASTNIK vložíme několik záznamů pomocí příkazu INSERT INTO table_name VALUES (value1, value2, value3, ...), kdy je nutno dodržet pořadí vkládaných hodnot podle definice tabulky.

INSERT INTO vlastnik VALUES (1, 'Jan', 'Volný', 'Frýdek-Místek');
INSERT INTO vlastnik VALUES (2, 'Petr', 'Krátký', 'Frýdek-Místek');
INSERT INTO vlastnik VALUES (3, 'Jan', 'Bohustý', 'Frýdek-Místek');
INSERT INTO vlastnik VALUES (4, 'Jindřich', 'Volný', 'Ostrava');
INSERT INTO vlastnik VALUES (5, 'Jana', 'Volná', 'Ostrava');
INSERT INTO vlastnik values (6, 'Věra', 'Krásná', 'Frýdek-Místek');

Ověříme uložení dat kontrolním výpisem z tabulky: SELECT * FROM VLASTNIK.

Tabulka PARCELA

Dále vytvoříme tabulku PARCELA podobným působem jako VLASTNIK.

DROP TABLE PARCELA;
CREATE TABLE PARCELA
(idParcela NUMBER PRIMARY KEY,
ku VARCHAR2(8) NOT NULL,
tvarParcela SDO_GEOMETRY
);

Vložíme data o několika parcelách:

INSERT INTO parcela VALUES(20, 'ova005',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,1), -- polygon
SDO_ORDINATE_ARRAY(5,10, 4,10, 2,10, 9,15, 9,16, 20,10, 5,10 ) )
);
INSERT INTO parcela VALUES(21, 'ova005',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,1),  -- polygon
SDO_ORDINATE_ARRAY(5,1, 8,1, 8,6, 5,7, 5,1) ) 
);
INSERT INTO parcela VALUES(0,'ova01',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,3), --obdelnik
SDO_ORDINATE_ARRAY(1,1,5,10) )
);
INSERT INTO parcela VALUES(23, 'ova005',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,1), 
SDO_ORDINATE_ARRAY(5,7, 5,10, 2,10, 1,9, 1,7, 5,7) ) 
);
INSERT INTO parcela VALUES(24, 'ova005',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,1), 
SDO_ORDINATE_ARRAY(5,10, 5,7, 8,6, 7,10, 5,10) ) 
);
INSERT INTO parcela VALUES(25, 'ova001',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,1),  --polygon
SDO_ORDINATE_ARRAY(1,9, 2,10, 9,15, 9,20, 1,16, 1,9) ) 
);
INSERT INTO parcela VALUES(26, 'ova001',
SDO_GEOMETRY(2003, NULL, NULL, 
SDO_ELEM_INFO_ARRAY(1,1003,1),  --polygon
SDO_ORDINATE_ARRAY(9,20, 1,16, 1,20, 9,20) ) 
);
Tvorba prostorového indexu

Nejprve je nutno do systému zadat existenci nové tabulky s geometrickou složkou. Uložíme nový záznam přes pohled user_sdo_geom_metadata, kam zapíšeme název tabulky, jméno sloupce obsahujícího geosložku, rámec prostoru, nad kterým bude vytvořen prostorový index a souřadnicový systém, ke kterému jsou data vztažena.

INSERT INTO user_sdo_geom_metadata  VALUES ('parcela', 'tvarparcela',
SDO_DIM_ARRAY(sdo_dim_element('X',0,30,0.005),
sdo_dim_element('Y',0,30,0.005)),
NULL
);

Ověření správně uložených informací: :'select * from user_sdo_geom_metadata';

Požadavek na prostorové zaindexování geometrie parcel urychlí další práce s prostorovou složkou. Bez zaindexování nelze zobrazit geometrie v prohlížeči, ani pokládat některé typy dotazů.

CREATE INDEX sp_par_idx ON parcela(tvarparcela) INDEXTYPE is mdsys.spatial_index; 

Po správném vytvoření prostorového indexu je možné zobrazit geometrickou složku v GeoRaptoru. Klikněte pravým tlačítkem na název tabulky a zvolte GeoRaptor. Poté si vyberte 'Přidat do prohlížeče'. Otevře se nové okno, které je provázáno s prostorovou složkou tabulky.

Tvorba vazební tabulky VLASTNICTVI

Vytvoříme tabulku VLASTNICTVI, která zachycuje kdo je vlastníkem parcely v daném čase. Pokud ve sloupci 'doVlastni' nebude uvedena hodnota, pak je parcela ve vlastnictví majitele s odpovídajícím idVlastnik, proto je zde povolena hodnota NULL. Dále jsou při vytváření tabulky uvedena omezení, která plynou z vazby na tabulky VLASTNIK a PARCELA. Jsou zde vytvořeny cizí klíče se shodnými názvy, jako primární klíče u nadřazených tabulek.

DROP TABLE VLASTNICTVI;
CREATE TABLE VLASTNICTVI(
idVlastnictvi NUMBER PRIMARY KEY,
idVlastnik NUMBER(6) NOT NULL, 
idParcela NUMBER(6) NOT NULL,
odVlastni DATE NOT NULL, -- datum nabyti parcely
doVlastni DATE,  -- datum pozbyti parcely
constraints vla_vla FOREIGN KEY (idVlastnik) references VLASTNIK,
constraints vla_pa FOREIGN KEY (idParcela) references PARCELA
);

Vložíme záznamy do tabulky Vlastnictví. Pro vložení hodnot datumu je využita konverzní funkce to_date, která umožňuje zadávat datum ve zvoleném formátu (zde DD-MM-YY).

insert into vlastnictvi values(1, 2, 20, to_date('01-01-07', 'DD-MM-YY'),to_date('01-01-08', 'DD-MM-YY'));
insert into vlastnictvi values(2, 4, 20, to_date('01-01-09', 'DD-MM-YY'),to_date('01-01-11', 'DD-MM-YY'));
insert into vlastnictvi values(3, 2, 20, to_date('01-01-12', 'DD-MM-YY'),null);
insert into vlastnictvi values(4, 3, 21, to_date('01-12-10', 'DD-MM-YY'),null);
insert into vlastnictvi values(5, 5, 22, to_date('01-05-13', 'DD-MM-YY'),null);

Co ukazují tyto záznamy? O jaké změny vlastnictví v čase se jedná? Tatáž parcela (s id=20) mění majitele, poté se vrací zpět prvně uvedenému vlastníkovi.

Vyhledání aktuálního vlastníka parcely s číslem id=20.

select y.jmenovla, y.prijmenivla
from vlastnictvi x, vlastnik y
where x.idVlastnik = y.idVlastnik and x.doVlastni is null and x.idParcela = 20;

Vyhledání aktuálních vlastníků parcel z katastrálního území 'ova005'.

select y.jmenovla, y.prijmenivla
from vlastnictvi x, vlastnik y, parcela z
where x.idparcela = z.idparcela and x.idVlastnik = y.idVlastnik and x.doVlastni is null and z.ku = 'ova005';

V případě, že chceme zobrazit parcely vyhledaných vlastníků, přidáme do výstupu i geometrickou složku parcely a tu zobrazíme v GoeRaptoru kliknutím na hodnoty geometrie ve výsledku dotazu.

select y.jmenovla, y.prijmenivla, z.tvarparcela
from vlastnictvi x, vlastnik y, parcela z
where x.idparcela = z.idparcela and x.idVlastnik = y.idVlastnik and x.doVlastni is null and z.ku = 'ova005';
Podkladová síť

Pro lepší orientaci ve vizuálních výstupech je možné si vytvořit síťový podklad ve stejném prostoru, jako jsou uloženy parcely. Jde o jednoduchou tabulku NET s dvěmi složenými geometriemi typu linie.

DROP TABLE NET; 
CREATE TABLE NET (
id NUMBER,
geo SDO_GEOMETRY);

Vložíme dva záznamy se složeným typem geometrie (2006):

INSERT INTO net VALUES (1, sdo_geometry (2006, null, null,
sdo_elem_info_array (1,2,1, 5,2,1, 9,2,1, 13,2,1, 17,2,1, 21,2,1, 25,2,1, 29,2,1, 33,2,1, 37,2,1, 
41,2,1, 45,2,1, 49,2,1, 53,2,1, 57,2,1, 61,2,1, 65,2,1, 69,2,1, 73,2,1, 77,2,1), 
sdo_ordinate_array (0,0,0,20, 1,0,1,20, 2,0,2,20, 3,0,3,20, 4,0,4,20, 5,0,5,20, 6,0,6,20, 
7,0,7,20, 8,0,8,20, 9,0,9,20, 10,0,10,20, 11,0,11,20, 12,0,12,20, 13,0,13,20, 14,0,14,20, 
15,0,15,20, 16,0,16,20, 17,0,17,20, 18,0,18,20, 19,0,19,20)) 
); 
INSERT INTO net VALUES (2, sdo_geometry (2006, null, null,
sdo_elem_info_array (1,2,1, 5,2,1, 9,2,1, 13,2,1, 17,2,1, 21,2,1, 25,2,1, 29,2,1, 33,2,1, 37,2,1, 
41,2,1, 45,2,1, 49,2,1, 53,2,1, 57,2,1, 61,2,1, 65,2,1, 69,2,1, 73,2,1, 77,2,1), 
sdo_ordinate_array (0,0,20,0, 0,1,20,1, 0,2,20,2, 0,3,20,3, 0,4,20,4, 0,5,20,5, 0,6,20,6, 
0,7,20,7, 0,8,20,8, 0,9,20,9, 0,10,20,10, 0,11,20,11, 0,12,20,12, 0,13,20,13, 0,14,20,14, 
0,15,20,15, 0,16,20,16, 0,17,20,17, 0,18,20,18, 0,19,20,19)) 
);

Před vytvořením prostorového indexu uložíme metainformace o nové tabulce:

INSERT INTO USER_SDO_GEOM_METADATA (TABLE_NAME, COLUMN_NAME, DIMINFO, SRID) 
 VALUES ('net', 'geo', 
 SDO_DIM_ARRAY (SDO_DIM_ELEMENT('X', 0, 30, 0.5),
 SDO_DIM_ELEMENT('Y', 0, 30, 0.5)), 
 NULL);

a vytvoříme prostorový index:

CREATE INDEX NET_SPIDX ON net(geo) INDEXTYPE IS mdsys.spatial_index;

Na výsledek se můžeme podívat v prohlížeči GeoRaptor a měl by vypadat podboně jako na obrázku podkladová síť. Tuto "vrstvu" můžeme nechat zobrazenou po celou dobu další práce, mělo by to vést k lepšímu pochopení principů, na kterých jsou postaveny topologické vztahy mezi geobjekty.

Kontrola validnosti geometrie

SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT

Dotazy s prostorovou složkou

Chceme zjistit, co se stane s parcelami v případě, že budu chtít postavit novou budovu. Jak bude vypadat průnik stavby a dotčených parcel?

Novou budovu s její geometrií uložím do tabulky STAVBA.

CREATE TABLE STAVBA
(idStavba  NUMBER PRIMARY KEY,
typStavba VARCHAR2(8) NOT NULL,
tvarStavba SDO_GEOMETRY
);
INSERT INTO stavba VALUES(1122,'rodDum',
SDO_GEOMETRY(2003, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(4,6, 8,8))
);

Zopakujeme kroky se zadáním záznamu metadat o tabulce s prostorovými dat do systémové tabulky user_sdo_geom_metadat

INSERT INTO user_sdo_geom_metadata  VALUES ('stavba', 'tvarStavba',
SDO_DIM_ARRAY(sdo_dim_element('X',0,30,0.005),
sdo_dim_element('Y',0,30,0.005)),
NULL
);

a vytvoříme prostorový index.

CREATE INDEX sp_stav_idx ON stavba(tvarStavba) INDEXTYPE is mdsys.spatial_index;

Zjistíme, které parcely by novou stavbou byly dotčeny?

select idparcela, SDO_GEOM.RELATE(p.tvarparcela,'anyinteract',s.tvarstavba,0.005) dd
from parcela p, stavba s
where s.idstavba = 1122;

Protože zasahuje i do cizích pozemků, je nutno korigovat umístění stavby

INSERT INTO stavba VALUES(222,'rodDum',
SDO_GEOMETRY(2003, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(1.5, 4.5, 4.5,6))
);

Ověřte, na které parcele je plánovaná stavba teď. Komu patří?

Bazén

Vlastník parcely 21 chce postavit nový bazén s osvětlením.

INSERT INTO stavba VALUES(1144,'bazen',
SDO_GEOMETRY(2003, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,1003,4),
SDO_ORDINATE_ARRAY(7,2, 6,6, 8,6))
);

Plánuje nasvětlení bazénu z těchto míst:

INSERT INTO stavba VALUES(1,'sloupek1',
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(7,2, NULL), NULL, NULL)
);
INSERT INTO stavba VALUES(2,'sloupek2',
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(6,6, NULL), NULL, NULL)
);
INSERT INTO stavba VALUES(3,'sloupek3',
SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(8,6, NULL), NULL, NULL)
); 

Vyjde postavit bazén požadovaného tvaru na jeho pozemku? Naformulujte dotaz, kterým je možné to ověřit.

SELECT s.idstavba, p.idparcela, SDO_GEOM.SDO_INTERSECTION(p.tvarparcela,s.tvarstavba,0.005)
FROM parcela p, stavba s
WHERE s.idstavba = 1144; 
SELECT p.idparcela
FROM parcela p, stavba s
WHERE SDO_GEOM.SDO_INTERSECTION(p.tvarparcela,s.tvarstavba,0.005) is not null and s.idstavba = 1144;

Jsou alespoň sloupky na jeho pozemku?

SELECT s.idstavba, s.tvarstavba, s.typstavba
FROM parcela p, stavba s
WHERE  SDO_CONTAINS(p.tvarparcela,s.tvarstavba) = 'TRUE' and p.idparcela=21;

Vyjde tento menší?

INSERT INTO stavba VALUES(1177,'bazen',
SDO_GEOMETRY(2003, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,1003,4),
SDO_ORDINATE_ARRAY(7.0,2.0, 5.0,3.0, 6.0,3.0))
);

Nebo tento?

INSERT INTO stavba VALUES(1199,'bazen',
SDO_GEOMETRY(2003, NULL, NULL,SDO_ELEM_INFO_ARRAY(1,1003,4),
SDO_ORDINATE_ARRAY(6,2, 5.5,3.5, 6.5,3.5))
);

Kolik půdy zabere stavba posledního bazénu?

SELECT s.idstavba, SDO_GEOM.SDO_AREA(s.tvarstavba, 0.005) 
FROM stavba s 
WHERE s.idstavba = 1199; {vybrán bazén s id=1199}

Kolik by zabraly všechny bazény?

SELECT SUM(SDO_GEOM.SDO_AREA(s.tvarstavba, 0.005))
FROM stavba s 
WHERE s.typstavba = 'bazen'; 

Jak daleko je poslední bazén od sousedního pozemku (pozemek s idparcela 22)?

SELECT SDO_GEOM.SDO_DISTANCE(p.tvarparcela,s.tvarstavba, 0.005)
FROM parcela p, stavba s
WHERE p.idparcela=22 AND s.idstavba=1199;

Využití metod, které jsou definovány pro třídu objektů SDO_Geometry. Lze ověřit hodnoty atributů v prostorové složce objektů.

Ověření dimenze objektů:

SELECT s.idstavba, s.typstavba, s.tvarstavba.Get_Dims() 
FROM stavba s;

Hodnota označení typu geoobjektu, která je uložena v parametru SDO_GTYPE:

SELECT s.idstavba, s.typstavba, s.tvarstavba.Get_GType()
FROM stavba s;

Ověření validnosti objektu (podle standardu "The ISO/IEC SQL Multimedia standard" pak nese označení "well formed for valid").

SELECT s.idstavba, s.typstavba, s.tvarstavba.ST_IsValid()
FROM stavba s;


Hlavní stránka předmětu