1
Ingineria Programrii i
Limbaje de Asamblare
Note de curs
Marian Drdal
Cristian Ioni
2
1. Aspecte generale referitoare la framework-uri i mediul .NET
1.1 Framework-uri pentru dezvoltarea de aplicaii
software
Un framework software este o platform software universal i
reutilizabil folosit la dezvoltarea aplicaiilor, produselor i soluiilor
software. Scopul unui framework este de a mbuntii eficiena procesului
de dezvoltare de noi aplicaii software. Framework-ul poate imbuntii
productivitatea procesului de dezvoltare de software i a: calitii, fiabilitii
i robusteii noului software. Productivitatea dezvoltatorului este
mbuntit prin faptul c acesta se concentreaz pe cerinele specifice ale
aplicaiei pe care o construiete n loc s consume timpul pentru a programa
infrastructura aplicaiei.
Conceptul de framework este mai extins dect cel de bibliotec. In
cazul utilizrii unei biblioteci, obiectele i metodele implementate sunt
instaniate i apelate n aplicaia dezvoltatorului. Pentru acest lucru trebuie s
se cunoasc care obiecte i metode trebuie utilizate i apelate astfel nct
aplicaia s-i ating scopul. Pe de alt parte, la utilizarea unui framework
dezvoltatorul definete obiecte i implementeaz metode care
particularizeaz aplicaia sa i acestea sunt instaniate i apelate prin
intermediul framework-ului. In acest caz, framework-ul definete un flux de
control pentru aplicaie. Un mod obinuit de a particulariza un framework
const n a suprascrie entitile implementate de ctre acesta. Pentru
alinierea la framework, programatorul poate s defineasc clase derivate din
clasele lui, s implementeze interfee definite de framework i s defineasc
metode virtuale i clase abstracte din framework.
In funcie de destinaie, framework-urile se pot clasifica n:
framework-uri destinate dezvoltrii aplicaiilor software cu caracter general,
n diferite tehnologii, respectiv framework-uri pentru dezvoltarea de aplicaii
3
software specializate. In general, indiferent de tipul de framework folosit,
dezvoltarea aplicaiilor software necesit utilizarea unui mediu de dezvoltare
care s fie capabil s coopereze cu framework-ul dorit.
Reprezentativ pentru categoria framework-urilor cu caracter general
este framework-ul construit de Microsoft, care poart numele de .NET
Framework. Astfel, dac se dorete construirea unei aplicaii de tip Windows
Forms, programatorul i poate defini propria interfa prin intermediul unei
clase (Class_Forma) care va fi derivat din clasa Form a framework-ului
.NET, dup cum urmeaz:
class Class_Forma : Form { }
Prin motenire se preiau proprieti de baz pentru fereastr, astfel nct
aceasta va avea iconi, butoane pentru: minimizare, maximizare i
nchidere, dup cum se poate observa n figura 1.4, precum i funcionaliti
implicite aferente butoanelor generate.
Figura 1.4 Forma generat implicit
Pentru a putea executa aplicaia a fost definit i clasa Principala n care s-a
definit metoda static Main, necesar pentru startarea execuiei aplicaiei.
Practic codul din Main ruleaz o instan a clasei Class_Forma definit
anterior.
class Principala { static void Main() { Application.Run(new Class_Forma());
4
} }
Pe lng framework-urile cu caracter general, exist i framework-uri
care dau posibilitatea programatorului de a dezvolta aplicaii software
specializate. Astfel, produsele software specializate pe anumite domenii de
prelucrare sunt construite pe baza acestor framework-uri. Se vor prezenta
dou astfel de framework-uri pentru a putea dezvolta aplicaii bazate pe
Office i GIS. Dezvoltatorii au la dispoziie mai multe variante de elaborare a
modulelor si anume: s construiasc aplicaii personalizate ntr-un mediu de
dezvoltare care s foloseasc framework-ul, s programeze diferite module
personalizate pe care s le integreze n aplicaiile de baz (de exemplu MS
Word sau Excel) folosind limbajul VBA (Visual Basic for Application) sau
s foloseasc medii de dezvoltare pentru a construi extensii care s fie
integrate ulterior n aplicaiile de baz i s conlucreze i cu celelalte
elemente software ale produsului.
Exist totodat i framework-uri care nu stau la baza unor produse
software specializate ci au fost fcute pentru a dezvolta diferite tipuri de
aplicaii. De exemplu, DirectX are pe lng versiunea run-time i versiunea
pentru dezvoltare DirectX SDK. In general, framework-urile pentru
dezvoltare de aplicaii au n denumire SDK, acronimul de la Software
Development Kit.
Framework-urile permit proiectanilor i dezvoltatorilor de soft s
reutilizeze codul, s abstractizeze i s proiecteze noi funcionaliti, n
general sunt construite pentru utilizarea lor pe scar larg n dezvoltarea de
aplicaii specializate.
1.2 Mediul .NET caracterizare general
Microsoft a lansat prima versiune a lui .NET Framework n anul
2000. Principalele proprieti ale mediului de programare .NET sunt:
- Mediu independent pentru execuia programelor, n sensul c toate
limbajele se bazeaz pe acelai nucleu (de exemplu, nu exist nici o
5
diferen n rularea unei aplicaii indiferent dac aceasta a fost scris
n VB.NET sau C#);
- Mediu orientat obiect n form pur, n sensul c implementeaz
complet proprietile programrii orientate obiect i arhitectura
framework-ului este orientat obiect;
- Integrare complet ntre aplicaii, asigurat prin faptul c .NET
Framework poate fi utilizat independent n raport de limbajele de
programare;
- Interoperabilitate cu alte componente software existente, ceea ce
permite aplicaiilor .NET s reutilizeze DLL-uri existente,
componente COM, ActiveX etc;
- Model simplificat de livrare a aplicaiilor, astfel nct nu mai este
necesar nregistrarea componentelor sau a aplicaiilor n regitrii din
Windows ci dup compilarea componentelor acestea se copiaz n
directorul dorit i apoi se refer pentru a fi utilizate n alte aplicaii;
- Model general de securitate, coninut n .NET Framework pentru a
seta caracteristici de securitate aplicaiilor fr a rescrie aplicaiile. In
timpul execuiei unei aplicaii framework-ul verific setrile astfel
nct sa nu permit accesul neautorizat, procesarea unor operaii
interzise etc.
Din punct de vedere istoric, .NET Framework a cunoscut o evoluie
continu, de la lansarea lui, fiecare versiune a adugat noi caracteristici sau
capabiliti, principalele fiind ilustrate n figura 1.2. Din punct de vedere
arhitectural, .NET Framework conine urmtoarele componente:
- Common Language Run-time (CLR), care furnizeaz un nivel de
abstractizare peste sistemul de operare. Partea cea mai important a
CLR se afl n fiierul mscore.dll i furnizeaz urmtoarele
caracteristici:
o Identificarea assembly-urilor necesare;
o ncrcarea lor;
6
o Identificarea tipurilor corespunztoare folosind metadatele
assembly-ului;
o Translatarea codului MSIL (Microsoft Intermediate
Language).
Figura 1.2 Evoluia .NET Framework[1]
- Biblioteca de clase de baz care se constituie din cod preconstruit
pentru sarcini des utilizate n programarea de nivel sczut.
Principalul rol al acestei componente este de a furniza servicii de
infrastructur dezvoltatorilor. Aceste servicii se constituie ca un strat
peste interfaa de programare WIN API. Directorul bibliotecii de
clase conine o mulime de assembly-uri;
- Framework-uri i tehnologii de dezvoltare, ce reprezint soluii
reutilizabile i care se pot personaliza pentru o larg varietate de
sarcini de programare.
7
2. Utilizarea interfeelor i a evenimentelor n dezvoltarea de aplicaii
2.1 Interfee
O interfa se definete similar unei clase avnd urmtoarele
particulariti:
- n loc de folosirea cuvntului cheie class se folosete interface;
- nu poate conine atribute;
- proprietile i metodele au doar semnturile nu i implementarea.
Interfeele se folosesc pentru a implementa aceleai operaii dar ntr-un alt
context de lucru. Altfel spus, o clas care implementeaz o interfa trebuie
s implementeze metodele i proprietile interfeei pentru a se alinia la un
mod de utilizare. In acest sens, un exemplu sugestiv se refer la faptul c, n
vederea implementrii unei colecii se dorete ca elementele ei s fie iterate
folosind instruciunea specific foreach.
Se propune o implementare minimal a structurii de dat list simplu
nlnuit ca fiind o colecie de noduri, nodurile fiind implementate tot
printr-o clas de sine stttoare inclus n clasa lista.
public class Lista { // clasa nod public class nod { object inf; public nod next; public nod(object k, nod urm) { inf = k; next = urm; } public object informatia { get { return inf; } set { inf = value; } } } nod cap; protected uint nrn; public Lista() { cap=null; nrn=0; }
8
public void Adaugare(object k) { nod tmp = new nod(k, cap); nrn++; cap=tmp; } }
Pentru colecia definit prin intermediul clasei Lista, instruciunea
foreach nu funcioneaz. Acest lucru devine posibil fcnd urmtoarele
completri:
clasa Lista va moteni interfaa IEnumerable;
ca o consecin a punctului anterior este necesar s se defineasc
metoda GetEnumerator(), n clasa Lista, dup cum urmeaz:
public IEnumerator GetEnumerator() { return nrn==0 ? null : new ListEnum(cap); }
In cazul n care lista e vid, metoda returneaz null, altfel metoda ntoarce
un obiect care implementeaz interfaa IEnumerator pentru o list. Obiectul
este de clas ListEnum i refer elementele listei prin intermediul capului
listei (cap);
astfel se definete clasa ListEnum care implementeaz interfaa
IEnumerator:
class ListEnum : IEnumerator {
Lista.nod aux, init; bool vb; public ListEnum(Lista.nod ccp) { aux = init = ccp; vb = true; } public object Current { get { return aux.informatia; } } public bool MoveNext() { if(aux==init && vb ) { vb=false; return true;} if (aux.next!=null) { aux=aux.next; return true; } else return false; } public void Reset() { aux=init; vb=true; }
}
9
Din codul surs se observ urmtoarele:
- constructorul iniializeaz membrii de tip nod cu capul listei i variabila
boolean vb cu true;
- metoda Reset() repune referina auxiliar aux pe nceputul listei i vb
pe true;
- proprietatea Current este de tip read-only i furnizeaz informaia util
a nodului curent (cel referit prin aux);
- metoda MoveNext() are ca scop referirea urmtorului nod valid al listei,
caz n care returneaz true; dac nu mai exist noduri n list returneaz
false.
Instruciunea foreach ncepe prin a apela metoda Reset(), dup
care apeleaz metoda MoveNext() cu scopul de a referi primul element al
coleciei, adic primul nod valid al listei; scopul variabilei vb este de a face
distincie ntre primul apel al metodei MoveNext() i celelalte, care vor
avansa referina aux atta timp ct mai exist un nod valid n list. Utilizarea
instruciunii foreach mpreun cu colecia Lista se poate face acum sub
forma:
Lista l = new Lista(); l.Adaugare(100); l.Adaugare(200); l.Adaugare(150); try {
foreach (int k in l) { Console.WriteLine(k); } } catch {
Console.WriteLine("Lista vida!!!"); }
S-a inclus instruciunea foreach ntr-un bloc try cu scopul de a lansa o
excepie n cazul n care lista este vid.
O alt modalitate de a utiliza interfeele o constituie partajarea
accesului la elementele unei clase complexe n concordan cu o logic a
utilizrii elementelor clasei. Astfel, spre exemplificare, se va implementa
clasa cont bancar care conine date personale cum ar fi: nume, prenume, cod
numeric personal, domiciliu etc ct i date financiare, ca de exemplu: iban,
10
sold etc. Evident, pentru cele dou categorii de date stocate n clasa cont se
vor defini i implementa operaii specifice: determinarea vrstei persoanei,
operaia de depunere respectiv retragere n / din cont etc. Interfeele vor fi
astfel definite i apoi implementate n clasa cont astfel nct numai prin
intermediul acestora se vor utiliza obiectele. Pentru rezolvarea problemei se
va defini clasa operaie bancar ce va conine data la care se efectueaz
operaia, tipul operaiei (depunere / extragere) i suma:
class operatie_bancara { DateTime dop; public int suma; public char tip; public operatie_bancara(DateTime fdop, int fs, char ft) {
dop = new DateTime(fdop.Year, fdop.Month, fdop.Day); suma = fs; tip = ft; }
}
Interfeele construite sunt:
- pentru date personale:
interface IDate_Pers { string Nume // proprietatea pentru numele persoanei { get; set; } // seteaza data nasterii void set_dn(int fy, int fm, int fz); // determina varsta int get_varsta(); }
- pentru date financiare:
interface IDate_Fin { string Iban // proprietatea pentru cont { get; set; } void Depune(DateTime dt, int s); //depunere void Extrage(DateTime dt, int s);//extragere int get_sold(); // determina sold }
11
Clasa Cont motenete i implementeaz cele dou interfee i are forma:
class Cont : IDate_Pers, IDate_Fin { int si; string np, iban; DateTime dn = new DateTime(); List lopb = new List(); public Cont(int fsi) { si = fsi; } //implementarea interfetei Date_Pers string IDate_Pers.Nume { get { return np; } set { np = value; } } void IDate_Pers.set_dn(int fy, int fm, int fz) { dn = DateTime.Parse(fy.ToString()+"-"+
fm.ToString()+"-"+fz.ToString()); } int IDate_Pers.get_varsta() { return DateTime.Now.Year - dn.Year; } //implementarea interfetei Date_Fin string IDate_Fin.Iban { get { return iban; } set { iban = value; } } void IDate_Fin.Depune(DateTime dt, int s) { lopb.Add(new operatie_bancara(dt, s, 'd')); } void IDate_Fin.Extrage(DateTime dt, int s) { lopb.Add(new operatie_bancara(dt, s, 'e')); } int IDate_Fin.get_sold() { int sd = 0, se = 0; foreach (operatie_bancara opi in lopb)
if(opi.tip == 'd') sd += opi.suma; else se += opi.suma;
12
return si+sd-se; } }
Se observ c la implementarea elementelor de interfa, n clasa Cont, s-a
folosit o definire explicit a interfeei prin precedarea numelui metodei sau
proprietii de numele interfeei acest lucru permite ca elementele din
interfa s poat fi folosite doar prin intermediul unei interfee i nu direct
prin intermediul obiectului. Tot legat de acest lucru se observ ca
modificatorul public nu mai este indicat la implementarea metodelor /
proprietilor deoarece, prin definirea explicit a interfeei, caracterul public
este asociat automat datorit faptului c elementele unei interfee au
ntotdeauna caracter public.
2.2 Lucrul cu evenimente
Pentru a nelege mecanismul evenimentelor se urmrete ca el s se
implementeze folosind interfee ce definesc un pattern ce trebuie
implementat de clasele care urmeaz s comunice n acest fel. Din punct de
vedere al logicii de implementare se pot stabili dou categorii de clase: cele
care genereaz obiecte observabile ct i cele care genereaz obiecte ce
observ (observatori). Pentru o legtur cu lumea real v putei imagina
relaia ntre prini i copilul lor n sesul c prinii i observ copilul, deci
joac rolul de observatori, n timp ce copilul este entitatea observabil.
Obiectul observabil notific observatorii cnd acesta i schimb starea. De
exemplu, cnd copilul nu mai are bani, acesta i ntiineaz prinii care,
apoi realizeaz o aciune (de exemplu, mama i d bani copilului iar tata l
atenioneaz c a cheltuit prea mult). Un alt element util de observat n
implementare const n faptul c oobiectele observabile se cupleaz la
observatori i atunci conlucreaz iar cnd se realizeaz operaia de decuplare
atunci ele nu mai conlucreaz.
13
O clas care genereaz obiecte ce observ (observatori) trebuie s
implementeze o interfa care conine semntura metodei (Notificare) care
implementeaz funcionalitatea ce se execut atunci cnd observatorul este
notificat. Evident, fiecare clas care genereaz observatori va implementa n
mod propriu notificarea.
interface IObservator { void Notificare(); }
Clasa care genereaz obiecte observabile trebuie s implementeze o interfa
specific IObservabil care definte semnturile a dou metode: una care
cupleaz observatori i alta care-i decupleaz:
interface IObservabil { void Cupleaza(IObservator o); void Decupleaza(IObservator o); }
Pentru a defini mecanismul de organizare a coleciei de observatori (lobs),
cuplarea i decuplarea s-a construit clasa Observabil_Impl care
implementeaz interfaa IObservabil.
class Observabil_Impl : IObservabil { protected List lobs = new List(); public void Cupleaza(IObservator o) { lobs.Add(o); } public void Decupleaza(IObservator o) { lobs.Remove(o); } }
Codul descris pn n acest moment este de maxim generalitate i poate fi
folosit de orice clase care genereaz obiecte care conlucreaz n sensul c
unele obiecte notific alte obiecte care reacioneaz la notificrile primite.
14
Pentru exemplificarea ct mai simpl a mecanismului s-a construit clasa
observabil numit Element care conine un atribut de tip ntreg (el) iar la
schimbarea valorii lui obiectul va notifica alte obiecte (observatorii).
class Element : Observabil_Impl { int el; public int Valoare_el { get { return el; } set { if (el != value) { el = value; foreach (IObservator o in lobs) o.Notificare(); } } } }
Se poate observa c la schimbarea strii elementului, el notific toi
observatorii iar prin apelul metodei Notificare a fiecrui observator,
observatorul va declana aciunea ca rspuns al notificrii.
Se propune clasa Cons_obs care va genera un observator ce va afia la
consol mesajul Element modificat!! atunci cnd obiectul observabil i
schimb starea:
class Cons_obs : IObservator { public void Notificare() { Console.WriteLine("Element modificat!!"); } }
Pentru a exemplifica funcionalitatea se construiete obiectul oel de tip
Element, se construiete obiectul cu rol de observator (cobs1), se cupleaz
observatorul la obiectul observabil i se schimb starea elementului fapt care
genereaz apelul metodei Notificare din observator care determin afiarea
mesajului corespunztor, dup care se vizualizeaz noua valoare a
elementului.
Element oel = new Element();
15
Cons_obs cobs1 = new Cons_obs(); oel.Cupleaza(cobs1); oel.Valoare_el = 10; Console.WriteLine("elment = {0}", oel.Valoare_el);
V propunem s testai ntreaga funcionalitate i anume s realizai
decuplarea observatorului dup care s schimbai starea elementului i vei
observa c mesajul de notificare nu se va mai afia pentru c obiectele nu
mai conlucreaz dup decuplare.
Pentru a complica exemplul se mai adaug un alt observator de data aceasta
o clas derivat din clasa form (Form) care va implementa interfaa
IObservator. Metoda de notificare va afia mesajul Modificat pe cte o linie
nou ntr-ul control (mes) de tip Label de pe form. Pe de alt parte, din
cadrul formei se d posibilitatea modificrii valorii elementului prin
intermediul controlului (tval) de tip TextBox la apsarea pe butonul Set_val
fapt care va determina notificarea ambilor observatori ceea ce va duce la
apariia unui mesaj la consol ct i n form. Pentru a putea modifica
elementul din form, la constructorul formei se trimite ca parametru o
referin la obiectul de tip Element care se reine ntr-un atribut al formei i
prin care se va permite modificarea strii elementului.
public partial class Form1 : Form, IObservator { Element rel = null; public Form1(object fel) { InitializeComponent(); rel = (Element)fel; } public void Notificare() { mes.Text += "Modificat"+ Environment.NewLine; } private void button1_Click(object sender, EventArgs e) { rel.Valoare_el = Convert.ToInt32(tval.Text); } }
Testarea funionalitii s-a realizat prin definirea metodei Main n forma:
static void Main(string[] args)
16
{ Element oel = new Element(); Cons_obs cobs1 = new Cons_obs(); Form1 forma = new Form1(oel); oel.Cupleaza(cobs1); oel.Cupleaza(forma); oel.Valoare_el = 10; forma.ShowDialog(); Console.WriteLine("elment = {0}", oel.Valoare_el); }
ceea ce determina apariia interfeei aplicaiei ca n figura 2.1. Primul mesaj
a fost afiat ca urmare a schimbrii strii obiectului prin atribuirea realizat
n Main iar cel de-al doilea ca urmare a modificrii strii elementului din
form.
Figura 2.1 Interfaa aplicaiei
O clas poate avea pe lng atribute, proprieti, metode i
evenimente. Prin eveniment se nelege un tip de membru al unei clase care
este activat cnd evenimentul se declaneaz, n timpul execuiei unei
aplicaii. La momentul declanrii evenimentului metoda asociat va fi
apelat.
17
Spre exemplu, dac considerm un obiect de tip Timer, atunci el are
definit evenimentul Tick care se declaneaz periodic, dup ce se scurge o
perioad de timp. Declanarea evenimentului impune apelul unei metode
care implic efectuarea unei procesri ce ine de specificul aplicaiei, deci nu
se poate defini metoda n clasa Timer ns ea poate fi cuplat la eveniment,
din exteriorul clasei Timer. Concret, se va construi o aplicaie care s
asocieze efectul de blinking unui text (textul devine vizibil respectiv
invizibil la un iterval de 300 milisecunde). Pentru acest lucru se va declara
un obiect de tip Timer (t) n clasa Form1: Timer t; Pe evenimentul Load, de
iniializare a formei, se va construi obiectul Timer, se va stabili durata
intervalului de timp, n milisecunde i se va asocia evenimentului Tick
metoda (actiune) care se va apela cnd se va declana evenimentul:
private void Form1_Load(object sender, EventArgs e) { t = new Timer(); t.Interval = 300; t.Tick += new EventHandler(actiune); }
Se observ c asocierea metodei de utilizator actiune, evenimentului Tick, s-
a realizat cu operatorul += adic prin adugarea unui nou obiect de tip
EventHandler.
Metoda actiune are un prototip prestabilit n sensul c aceste metode care se
apeleaz la declanarea evenimentelor primesc: obiectul care a interceptat
evenimentul (sender) i un obiect (e) care conine argumentele ce nsoesc
evenimentul. Aceast metod se va defini n aplicaie i va schimba starea de
vizibilitate a textului care este un control de tip Label avnd numele et:
void actiune(object sender, EventArgs e) { et.Visible = ! et.Visible; }
Pornirea timer-ului se va face prin aplelul metodei Start n timp ce, oprirea
lui, se face prin apelul metodei Stop. Ambele metode se apeleaz prin
obiectul t, de tip Timer i operaiile se vor declana prin apsarea a dou
butoane special construite n acest sens.
18
Detaare metodei evenimentului se face prin construcia:
t.Tick -= new EventHandler(actiune);
dup care, la apsarea pe butonul care starteaz timer-ul nu se va mai apela
funcia actiune; deci, efectul de blinking pentru acel text nu se va mai
produce.
La nceputul acestui subcapitol s-a precizat faptul c modalitatea de a
construi obiecte observabile i observatori reprezint, de fapt, modul n care
se implementeaz evenimentele. Folosind evenimente n aplicaii .NET noi
utilizm un mecanism mai evoluat i mai simplu de folosit dar care ascunde
n esen mecanismul descris iniial. Pentru o mai bun nelegere a
problemei se propune ca exemplul din debutul acestui subcapitol sa-i
pstreze funcionalitatea doar c se va utiliza conceptul de eveniment pentru
ca obiectele s conlucreze.
Clasa Element va fi modificat astfel nct ea va conine un delegat care este
similar unui pointer la funcie adic se precizeaz o semntur de funcie
fr a-i preciza implementarea i un eveniment care este similar unei
proprieti asociate unui delegat.
class Element { public delegate void DElement(); public event DElement Schimba_el; int el; public int Valoare_el { get { return el; } set { if (el != value) { el = value; if(Schimba_el!=null) Schimba_el(); } } } }
19
Se observ c la schimbarea strii elementului se apeleaz funcia
Schimba_el care este de tipul precizat prin delegat i care la acest moment
nu are o implementare concret. Testul Schimba_el!=null ne asigur c
delegatul refer o implementare concret altfel s-ar genera eroare la apel.
Observatorii elementului trebuie conform acestui mecanism s
implementeze metoda Schimba_el. Pentru similitudine se pstreaz aceeai
observatori iar metoda Schimba_el va pstra coninutul metodei Notificare
din exemplul iniial.
class Cons_obs { public void Schimba_el() { Console.WriteLine("Element modificat!!"); } } public partial class Form1 : Form { Element obel = null; public Form1(object fel) { InitializeComponent(); obel = (Element)fel; } public void Schimba_el() { mes.Text += "Modificat!!"+Environment.NewLine; } private void button1_Click(object sender, EventArgs e) { obel.Valoare_el = int.Parse(tb.Text); } }
Se observ c practic observatorii au rmas la fel doar ca s-a modificat
numele metodei Notificare care acum a devenit Schimba_el. Dac am fi
denumit evenimentul Notificare observatorii ar fi rmas ca n exemplu
iniial.
O alt modificare important ce tine de lucrul cu evenimente o
constituie cuplarea i decuplarea care acum se realizeaz folosind operatorii
20
+= respectiv -= pe eveniment. Acest lucru este vizibil n metoda Main, care
acum are forma:
static void Main(string[] args) { Element el = new Element(); Cons_obs cobs1 = new Cons_obs(); Form1 frm = new Form1(el); el.Schimba_el += new Element.DElement(cobs1.Schimba_el); el.Schimba_el += new Element.DElement(frm.Schimba_el); el.Valoare_el = 10; frm.ShowDialog(); Console.WriteLine("elment = {0}", el.Valoare_el); }
Construirea unei clase care s conin un membru de tip eveniment
trebuie proiectat astfel nct acel eveniment s aib condiii bine precizate
pentru a se declana. Cu alte cuvinte, cel ce proiecteaz clasa trebuie s
defineasc evenimentele la care obiectele respective vor raspunde (de
exemplu, clasa Button definete evenimentul Click care se va declana la
momentul cnd se apas pe butonul mouse-ului i cursorul acestuia se afl
pe suprafaa butonului sau clasa Timer definete evenimentul Tick care se
declaneaz periodic la un anumit interval de timp). Pentru exemplificare, se
dorete a se construi o clas care s implementeze animaia prin vizualizarea
succesiv a unor imagini (tehnica filmului). Se urmrete definirea unui
eveniment care s notifice momentul terminrii afirii secvenei de imagini.
Un alt aspect deosebit de important n implementarea lucrului cu
evenimente se refer la mecanismul prin care este posibil asocierea unei
metode care se va apela la momentul declanrii evenimentului. Ideea de
baza const n faptul c cel care proiecteaz clasa definete evenimentul ns
aciunea concret care se va efectua la momentul declansrii evenimentului
se definete de ctre cel ce utilizeaz clasa. Pentru a implementa mecanismul
n clasa care definete evenimentul trebuie declarat un delegat, de exemplu:
21
public delegate void MM_EventHandler(object sender, EventArgs e);
S-a declarat de aceast dat un delegat care se aliniaz la prototipul
delegailor ce se asociaz evenimentelor n ceea ce privete programarea
aplicaiilor Windows. Prototipul este standard n sensul c parametrii au
semnificaiile: obiectul care trimite evenimentul (sender) i obiectul (e) care
ncapsuleaz alte elemente ce sunt trimise odat cu evenimentul. Dup
declararea delegatului se declar evenimentul (Notificare_Animatie) pe baza
lui, astfel:
public event MM_EventHandler Notificare_Animatie;
Clasa care implementeaz animaia (MM_anim), prin tehnica
filmului este:
namespace animatie { public delegate void MM_EventHandler(object sender, EventArgs e); public class MM_anim { public event MM_EventHandler Notificare_Animatie; //folosit pentru a stoca imaginile ArrayList vimag = new ArrayList(); //reprezinta colectia de imagini int k; //variabila pentru referirea unei imagini din colectie PictureBox cadru; // controlul pentru afisarea imaginilor // timer pentru controlul periodicitatii afisarii imaginilor Timer t; // constructor care primeste controlul de afisare si // intervalul de timp la care vor fi afisate imaginile public MM_anim(PictureBox fcadru, int intv) { cadru = fcadru; t = new Timer(); t.Interval = intv; t.Tick += new EventHandler(actiune); } //adaugarea unei imagini la colectie; //s numele fisierului ce contine imaginea public void Add_imag(string s) { vimag.Add(new Bitmap(s)); } // metoda care declanseaza animatia
public void Play()
22
{ k = 0; // refera prima imagine din colectie t.Start(); // porneste timer-ul } // metoda cuplata la evenimentul Tick al Timer-ului // ea realizeaza afisarea tuturor imaginilor din colecie private void actiune(object sender, EventArgs e) { cadru.Image = (Bitmap)vimag[k++]; if (k == vimag.Count) { // in cazul in care s-a afisat si ultima imagine din colectie t.Stop(); // se opreste timer-ul // se invoca evenimentul Notificare_Animatie
if (Notificare_Animatie != null) Notificare_Animatie(this, new EventArgs());
} } } }
Se observ c, dup ce se afieaz i ultimul cadru, se oprete timer-ul i se
apeleaz metoda Notificare_Animatie care primete obiectul (this) i un
obiect de tip EventArgs pentru a realiza concordana cu prototipul
delegatului; n exemplul prezentat nu se realizeaz i trimiterea de informaii
suplimentare odat cu evenimentul.
Testarea funcionalitii clasei s-a realizat prin construirea unei aplicaii
Windows Forms care utilizeaz un control de tip PictureBox numit canvas i
un buton pentru a derula animaie (Play). In cadrul clasei form s-a declarat
un obiect de tip MM_anim: MM_anim anim; Metoda Form1_Load ce relizeaz
iniializarea formei are urmtoarea definiie:
private void Form1_Load(object sender, EventArgs e) { // construirea obiectului anim anim = new MM_anim(canvas, 300); int i; // calea directorului in care se regasesc imaginile string cale = "d:\\media\\pamintul\\"; // adaugarea imaginilor in colectie fisierele au numele // c1.jpg, c2.jpg, ... c15.jpg for (i = 0; i < 15; i++)
anim.Add_imag(cale + "c" + (i + 1).ToString() + ".jpg"); // asocierea metodei actiune evenimentului Notificare_Animatie
23
anim.Notificare_Animatie +=new MM_EventHandler(actiune); }
Apsarea butonului Play determin declanarea animaiei:
private void button1_Click(object sender, EventArgs e) {
anim.Play(); }
Metoda actiune care se va apela la declanarea evenimentului de terminare a
derulrii animaiei are ca obiectiv afiarea mesajului:
Animatia s-a terminat!!:
public void actiune(object sender, EventArgs e) {
MessageBox.Show("Animatia s-a terminat!!", "Notificare", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
Interfaa aplicaiei precum i notificarea terminrii animaiei se ilustreaz n
figura 2.2.
Figura 2.2 Afiarea mesajului de notificare a terminrii animaiei
Dac se dorete a se trimite odat cu mesajul i alte informaii atunci
este neceasar a se deriva o clas din clasa EventArgs care s conin propriile
elemente. In exemplul prezentat ar putea fi util s se transmit odat cu
evenimentul de notificare i informaia suplimentar cu privire la numrul
cadrului. Astfel, n domeniul de nume animatie se va defini clasa
MM_EvArgs dup cum urmeaz:
public class MM_EvArgs : EventArgs { int cs; // numarul cadrului
24
// constructorul care primeste numarul cadrului public MM_EvArgs(int z) { cs = z; }
// proprietatea pentru obtinerea numarului de cadre public int cadru_stop { get { return cs; } } }
Modificrile care decurg din folosirea unei clase proprii pentru argumentele
evenimentului sunt:
n clasa MM_anim se modific metoda actiune astfel nct apelul
metodei Notificare_Animatie va avea forma:
Notificare_Animatie(this, new MM_EvArgs(k));
n clasa Form1 unde se testeaz funcionalitatea clasei MM_anim, se
modific metoda actiune care se apeleaz pe evenimentul
Notificare_Animatie astfel nct mesajul va conine i numrul de
cadre afiate:
public void actiune(object sender, MM_EvArgs e) { MessageBox.Show("Animatia s-a terminat ultimul cadru: "
+ e.cadru_stop.ToString()+"!!", "Notificare", MessageBoxButtons.OK,
MessageBoxIcon.Asterisk); }
25
3. Prezentarea i utilizarea framework-ului ArcObjects .NET SDK pentru dezvoltarea
aplicaiilor GIS
3.1 Introducere
ArcObjects reprezint un framework dezvoltat pe tehnologia
componentelor de tip COM (Component Object Model) pe baza cruia este
construit produsul software cunoscut sub denumirea de ArcGIS, dezvoltat
de ESRI (Environmental Systems Research Institute). Cele trei versiuni de
ArcGIS (ArcView, ArcEditor i ArcInfo) partajeaz aceleai aplicaii de
baz: ArcCatalog i ArcMap. Modelul de date al geobazei de date precum i
ArcObjects constituie fundamentele celor dou aplicaii desktop.
Modelul de date georelaional implic stocarea datelor n formate
independente care se bazeaz pe divizarea atributelor n dou entiti i
stocarea lor separat. Astfel, o dat spaial este alctuit din atributul
spaial, care se stocheaz separat de atributele nonspaiale, legtura fiind
fcut prin intermediul unui cmp de identificare (ID), ce are rolul de
combina, n mod coerent, cele dou tipuri de atribute. Legtura dintre entiti
se poate face bidirecional adic fie de la cele spaiale ctre cele nonspaiale
sau invers, ca n figura 3.1.
Stocarea datelor spaiale prin modelul geobaz de date presupune
stocarea att a atributelor spaiale ct i a celor nonspaiale, mpreun, ntr-o
tabel de atribute. Cmpul care conine atributul spaial este de tip vector
(geometric).
Caracteristicile spaiale sunt implementate i procesate prin
intermediul claselor de obiecte cu toate c ele rezid n tabelele unei baze de
date relaionale. Astfel, acestea conin proprieti i metode care opereaz
asupra lor. Pentru a lucra cu framework-ul ArcObjects, n modul
programare, este necesar nelegerea tipurilor de clase care se afl n relaii
de diferite tipuri, n cadrul bibliotecii de clase.
26
Date nespaiale pentru Regiunea 5
Date nespaiale pentru Regiunea 4
Date nespaiale pentru Regiunea 3
Date nespaiale pentru Regiunea 2
Date nespaiale pentru Regiunea 1
Structuri de date spaiale Atribute nonspaiale
Regiunea 5
Regiunea 4 Regiunea 3
Regiunea 2
Regiunea 1
( a )
Date nespaiale pentru Regiunea 5
Date nespaiale pentru Regiunea 4
Date nespaiale pentru Regiunea 3
Date nespaiale pentru Regiunea 2
Date nespaiale pentru Regiunea 1
Structuri de date spaiale Atribute nonspaiale
Regiunea 5
Regiunea 4 Regiunea 3
Regiunea 2
Regiunea 1
( b )
Figura 3.1 Tipuri de legturi: nainte (a) i napoi (b)
Un sistem informatic geografic lucreaz cu date spaiale. Aceste date
se folosesc pentru a reprezenta diferite elemente din realitatea geografic,
prin tipuri de vectori (caracteristici spaiale) i prin locaia lor pe suprafaa
pmntului.
27
Principalele date spaiale de tip vectorial sunt:
- Punctul este caracterizat prin locaia sa, nu ocup spaiu i nu are
asociat o arie sau un volum. Intr-o baz de date punctul se
stocheaz printr-o msur direct a lui sau printr-o msur
indirect (transformare). Data de tip raster este un exemplu de
folosire a msurii directe a unui punct i include harta de pixeli
(imaginea bitmap). De exemplu, o imagine preluat din satelit
realizeaz o coresponden direct ntre un pixel de imagine i
suprafaa acoperit de el pe suprafaa terestr.
- Linia se caracterizeaz prin existena a cel puin dou puncte (cel
de nceput i cel de sfrit) urmnd ca punctele intermediare s fie
generate prin ecuaia dreptei. Un obiect spaial este descris, de
obicei, printr-o colecie de segmente ca de exemplu cursul unui
ru sau al unui drum, ce formeaz o polilinie. Din punct de
vedere spaial, liniei i se asociaz doar informaie de lungime nu
i informaie de grosime sau laime.
- Poligonul se caracterizeaz printr-o locaie i un contur. Locaia
este dat de un punct fix pentru a ancora poligonul n spaiu (de
obicei este punctul din centrul regiunii). In spaiul bidimensional,
conturul se vizualizeaz ca o linie iar n spaiul tridimensional ca
o suprafa. Data de tip regiune stocat ntr-o baz de date este o
aproximare geometric a unui obiect spaial (de exemplu,
judeele unei ri, lacurile etc). Acestui tip de vector i se poate
calcula aria i perimetrul. Este singura dat spaial care acoper
suprafee n spaiul geografic studiat.
Pe lng datele spaiale de tip vector, sistemele informatice
geografice mai opereaz i cu date de tip raster. Acestea se descriu printr-un
grid de culoare (hri de bii), acoper o zon bine definit de pe suprafaa
terestr i se folosesc pentru a induce mai mult realism spaiului geografic
studiat. Sub form de raster se reprezint imaginile satelitare, modelul de
altitudine al terenului (DEM), ortofotoplanul, hrile scanate etc.
28
Datele spaiale, fie c sunt vectori fie c sunt de tip raster, trebuie s
fie localizate pe suprafaa pmntului. Localizarea lor se face prin
coordonate geografice (longitudine, latitudine) sau coordonate de tip
proiecie (de exemplu, sistemul de coordonate UTM Universal Transverse
Mercator).
Prin longitudine se nelege unghiul format ntre primul meridian i
poziia pe glob, n timp ce prin latitudine se nelege unghiul format ntre
ecuator i poziia pe glob (figura 3.2).
Un sistem de coordonate de tip proiecie este un sistem de
coordonate n plan, bazat pe o proiecie a hrii. Hrile sunt reprezentate n
plan dar ele reprezint suprafee curbe. Transformarea spaiului
tridimensional ntr-un spaiu bidimensional se numete proiecie (figura 3.3).
De exemplu, sistemul de coordonate UTM se bazeaz pe proiecia Mercator.
Figura 3.2 Latitudine Longitudine [2]
Figura 3.3 Proiecia
29
3.2 Clase, obiecte, relaii i interfee
ArcObjects se compune din clase i obiecte. Clasele descriu n mod
general mulimea de obiecte care au aceleai atribute. Obiectele sunt instane
de clase i se refer la elemente concrete din realitate. Rndurile unei tabele
se identific cu obiectele unei clase de obiecte iar coloanele ei reprezint
atributele clasei.
Exist trei tipuri de clase n framework-ul ArcObjects [1]:
- Coclase care sunt utilizate pentru a genera noi obiecte, de
exemplu, clasa RgbColor este folosit pentru a defini i manipula
culori conform modelului de culoare RGB;
- Clase abstracte care nu pot fi folosite la generarea de noi obiecte
ns au rolul de a construi ierarhii de clase care pornesc de la o
entitate avnd un caracter general. Ele conin atribute i metode
care sunt motenite de toate clasele derivate direct sau indirect
din ea. De exemplu, clasele care implementeaz diferite modele
de culoare sunt derivate dintr-o clasa abstract numit Color;
- Clase, care nu se folosesc direct pentru a genera noi obiecte ci
acestea sunt construite prin intermediul altor obiecte; de exemplu,
pentru a accesa caracteristicile selectate la un moment dat pe
hart se poate construi un obiect de tip MapSelection pornind de
la obiectul hart.
In cadrul unei biblioteci de clase se stabilesc diferite tipuri de relaii
ntre clase. Inelegerea acestor relaii ajut programatorii s neleag
filosofia de dezvoltare a framework-ului i s programeze eficient aplicaiile.
Tipurile principalele de relaii [4] sunt:
- De asociere, care se pune n eviden ntre dou clase. O asociere
poate fi multipl, notat (1..*) sau avnd cel mult o asociere
(1..0). De exemplu, o astfel de relaie exist ntre clasa Color i
ColorRamp n sensul c o ramp de culori este format din mai
multe culori i este ilustrat n figura 3.4;
30
Figura 3.4 Asocierea
- De motenire, se definete ntre o superclas i o subclas.
Astfel, o subclas este o specializare a unei superclase i i
motenete atributele i proprietile. De exemplu, clasa Symbol
este o superclas pentru MarkerSymbol, LineSymbol i
FillSymbol i se figureaz dup cum se poate observa n figura
3.5;
Figura 3.5 Motenirea
- De compunere, care se descrie prin faptul c un obiect are n
compunere unul sau mai multe obiecte de alt tip. Este oarecum
similar cu asocierea doar c entitile sunt structural diferite. De
exemplu, un document de tip hart este format din mai multe
hri ceea ce se ilustreaz ca n figura 3.6, unde MxDocument este
clasa document iar Map reprezint clasa hart;
Figura 3.6 Compunere
- De agregare, care presupune c o clas este definit prin
agregarea elementelor altor clase, care sunt de tipuri diferite i
31
aprioric cunoscute. Spre exemplu, un obiect Cursor se poate crea
pornind de la un obiect de tip Table, adic o tabel i de la un
obiect de tip QueryFilter care impementeaz partea de filtrare a
datelor din tabel pentru a constitui cursorul. In figura 3.7 se
ilustreaz acest tip de relaie;
Figura 3.7 Agregare
- De instaniere, care presupune c un obiect se poate crea doar
prin intermediul altui obiect. De exemplu, n figura 3.7, se poate
observa c obiectul Cursor se poate construi prin intermediul
obiectelor Table i QueryFilter.
Biblioteca de clase ArcObjects, a fost construit n mod deosebit prin
definirea i implementarea interfeelor, lucru caracteristic tehnologiei COM.
Prin interfa se nelege o grupare logic de proprieti i metode definit
pentru una sau mai multe clase. Interfaa se bazeaz pe un anumit nivel de
generalitate sau pe necesiti specifice de utilizare. Prin convenie,
denumirile interfeelor ncep cu litera I, de exemplu: IMap, IApplication,
IDocument etc. Interfeele, pe de o parte, sunt implementate de ctre una sau
mai multe clase iar pe de alt parte, o clas poate implementa una sau mai
multe interfee. Astfel, clasa Map implementeaz mai multe interfee printre
care IMap i ITableCollection. Pornind de la coclase, se pot defini referine
(pointeri) la interfee care se ncarc prin construirea unui obiect al unei
coclase sau prin atribuirea unui obiect / interfee unei alte interfee. Este
evident faptul c acest lucru e posibil dac respectiva clas implementeaz
ambele interfee. Avnd o referin valid la o interfa, atunci doar
metodele i proprietile acelei interfee pot fi utilizate. Pentru a exemplifica
elementele descrise, se identific faptul c interfaa IMap are o proprietate
care returneaz numrul de caracteristici spaiale selectate pe hart
32
(SelectionCount), n timp ce interfaa ITableCollection are proprietatea
TableCount care returneaz numrul de tabele de atribute nonspaiale
existente n cadrul documentului hart. Presupunem c variabila doc
reprezint o referint la interfaa IMxDocument, a obiectului MxDocument
care implementeaz documentul hart:
IMxDocument doc = ArcMap.Document;
iar aceast interfa are o proprietate care furnizeaz harta curent sub forma
unei referine la IMap. In acest caz, se foreaz conversia explicit ctre un
obiect de tip hart (Map):
Map harta = (Map)doc.FocusMap;
Pentru a accesa proprietile din interfeele IMap i ITableCollection ale
clasei Map, atunci se definesc referine la acele interfee i ele se ncarc din
obiectul harta (de tip Map):
IMap pimap = (IMap)harta; ITableCollection pitc = (ITableCollection)harta;
Odat ce au fost ncrcate referinele ctre interfeele dorite, se pot accesa i
proprietile pentru a fi afiate:
// afiarea numrului de caracteristici selectate MessageBox.Show(pimap.SelectionCount.ToString()); // afiarea numrului de tabele MessageBox.Show(pitc.TableCount.ToString());
Interfeele au, de asemenea, rolul de a extinde funcionalitatea framework-
ului. Astfel, se permite programatorilor s defineasc, n ArcObjects, noi
interfee care pot fi adugate la cele existente.
O interfa conine proprieti i metode pe care utilizatorul le poate
accesa prin intermediul ei. Proprietile definesc caracteristicile (atributele)
unei interfee n timp ce metodele definesc comportamente specifice ale
interfeei. In ArcObject sunt descrise grafic interfeele, astfel nct,
programatorul s-i poat da seama care sunt proprieti i care sunt metode.
Astfel, proprietile sunt descrise prin linie n timp ce metodele se descriu
prin sgei ( ). La rndul lor, proprietile pot fi de mai multe feluri:
- read only, adic pot fi doar consultate valorile lor i se figureaz:
33
- write only, adic pot fi doar modificate valorile lor i se
figureaz: dac se atribuie prin valoare i prin
referin;
- read-write, adic pot fi att consultate ct i modificate i se
figureaz:
o n cazul n care se atribuie o valoare proprietii;
o n cazul n care se atribuie o referin proprietii.
De exemplu, interfaa IFeatureCursor (figura 3.8) motenete interfaa
IUnknown i conine:
Figura 3.8 Interfaa IFeatureCursor
colecia de cmpuri (Fields); precum i
funcii care realizeaz tergerea unei caracteristici (DeleteFeature),
cutarea unui cmp (FindField), eliberarea buffer-elor (Flush),
inserarea unei caracteristici (InsertFeature), accesarea urmtoarei
caracteristici (NextFeature) i actualizarea caracteristicii
(UpdateFeature).
3.3 Programarea aplicaiilor GIS folosind ArcObjects
Pentru a utiliza ArcObjects n mediul .NET au fost generate
assembly-uri i biblioteci de obiecte COM pentru a gestiona interaciunea
.NET-COM. Folosind ArcOjects, se pot dezvolta aplicaii n mai multe
modaliti:
Se pot dezvolta aplicaii GIS de sine stttoare folosind
componenta ArcEngine i un mediu de dezvoltare a aplicaiilor
software precum Visual Studio.NET;
34
Se pot dezvolta extensii care ulterior se ataeaz la aplicaii ale
pachetului ArcGIS i care constituie elemente de interaciune
pentru diferite procesri personalizate n GIS;
Se pot dezvolta aplicaii Web.
Exemplificarea utilizrii framework-ului s-a realizat folosind pachetul
software ArcGIS 10 i mediul de programare Visual Studio.NET 2010, n
varianta de construire a extensiilor pentru a personaliza procesrile n GIS.
4.3.1 Modul de construire a extensiilor n ArcGIS
ArcGIS 10 introduce pentru dezvoltarea extensiilor ArcGIS Desktop
noul model add-in Desktop care furnizeaz un cadru de construire a unei
colecii de elemente personalizate, incluse ntr-un singur fiier. Utilizarea
add-ins pentru personalizarea aplicaiilor GIS ofer avantajul c acestea pot
fi uor partajate ntre utilizatorii conectai la o reea, nu necesit soft de
instalare sau parcurgerea de proceduri pentru nregistrarea COM-urilor.
Add-ins pot fi scrise n tehnologiile .NET sau Java alturi de XML
(Extensible Markup Language). XML se utilizeaz pentru a descrie
elementele de interfa, n timp ce prin .NET sau Java se implementeaz
funcionalitatea extensiilor.
Tipurile de add-ins permise pentru personalizarea aplicaiilor ArcGIS
Desktop sunt:
Butoane i instrumente reprezint controale simple care pot
apare pe bare de instrumente iar n cazul butoanelor i pe
meniuri;
Combobox furnizeaz liste derulante pentru alegerea opiunilor
dar i posibilitatea de a defini zone de editare;
Meniuri i meniuri contextuale care pot apare att pe bare de
instrumente ct i sub form de meniuri pop-up adugate
contextului aplicaiei;
Multi-opiuni reprezint o colecie dinamic de opiuni ale unui
meniu care va fi creat la momentul execuiei;
35
Bar de instrumente fereastr care poate gzdui diferite tipuri
de controale: butoane, instrumente, grupuri de instrumente i
combobox-uri;
Grup de instrumente reprezint un grup compact de instrumente
care apare n bara de instrumente sub forma unui mic buton de tip
drop-down pentru a expanda celelalte elemente din grup n
vederea utilizrii lor;
Ferestre care apar n aplicaii ArcGIS Desktop. Ele pot fi
populate cu diverse tipuri de controale, inclusiv controale ESRI;
Extensii ale aplicaiei sunt utilizate pentru coordonarea
aciunilor ntre celelalte componente (butoane, instrumente i
ferestre) care exist n cadrul add-in. Aceste extensii se utilizeaz
pentru stocarea strilor asociate add-in i se pot folosi pentru a
intercepta i rspunde la diversele evenimente expuse de
aplicaia gazd;
Extensii pentru editare permit personalizarea operaiei de
editare direct n contextul de lucru al acestei operaii. Extensiile
de editare sunt ncrcate cnd se ncepe sesiunea de editare.
Construirea unui add-in pentru ArcMap n Visual Studio .NET 2010
se realizeaz n urmtoarele etape:
A. Realizarea unui document hart (fiier mxd) care s conin o
compoziie tematic. Pornind de la existena bazei de date de tip
personal geodatabase, bd_ro.mdb, care conine judeele din
Romnia, ca date spaiale de tip poligon, n aplicaia ArcMap se
ncarc stratul tematic judete, din baza de date i se va stoca
aceast compoziie tematica n fiierul h_ro.mxd, dup cum se
observ n figura 3.9. Construirea acestui document are ca scop
crearea cadrului contextual pentru a utiliza i testa
funcionalitatea extensiei.
36
Figura 3.9 Document hart n ArcMap
Figura 3.10 Tip de proiect
B. Se deschide Visual Studio.NET 2010, se alege proiect nou de tip
Visual C#, se deschide grupul ArcGIS, se alege ablonul Desktop
Add-Ins, se selecteaz varianta 3.5 de .NET Framework i se mai
selecteaz aplicaia pentru care se va construi extensia ArcMap
Add-in, ca n figura 3.10.
37
Figura 3.11 Descrierea general a add-in-ului
C. Etapa de completare a tipului de add-in ct i a metadatelor lui se
desfoar prin intermediul a dou ferestre. In prima fereastr,
figura 3.11 se introduc date cu privire la numele, compania,
descrierea i autorul add-in-ului.
Figura 3.12 Alegerea tipului i modificarea de atribute pentru add-in
38
In cea de-a doua fereastr a procesului de construire a extensiei se va alege
n primul rnd tipul de add-in, n cazul exemplului s-a ales Button dup care
se completeaz diferite informaii despre acesta, dup cum se poate observa
n figura 3.12.
Principalul atribut care se impune a se modifica este Category
deoarece comanda definit prin acest add-in va fi regsit n ArcMap la acea
categorie. De asemenea, se impune a se modifica textul ce va apare pe
buton, tooltip-ul, imagine iconiei etc. In final se apas butonul Finish i se
termin procesul de creare a noului proiect.
Dup parcurgerea acestor etape se pot observa dou fiiere,
principale, generate:
Fiierul Config.esriaddinx conine descrierea add-in-ului sub
forma unui document XML:
Test_add {154cb4c3-092a-4bfd-a203-4688972b7cbe} Test Extensie 1.0 Images\Test_add.png mar ASE 3/24/2011
Se regsesc n acest document informaiile care au fost introduse prin
formele prezentate la procesul de construire a proiectului, rezultatul fizic al
acestui proiect adic o bibliotec cu legare dinamic, n exemplul prezentat,
39
avnd numele Test_add.dll. Tot n cadrul proiectului a fost generat folderul
Images n care se observ fiierul Button1.png care conine iconia implicit
a butonului. Imaginea poate fi editat cu un editor de imagini bitmap astfel
nct programatorul s-i personalizeze elementul de interaciune.
Fiierul Button1.cs conine comportamentul acestui add-in sub
form de cod surs scris n limbajul C#:
using System; using System.Collections.Generic; using System.Text; using System.IO; namespace Test_add { public class Button1 : ESRI.ArcGIS.Desktop.AddIns.Button { public Button1() { } protected override void OnClick() { // // TODO: Sample code showing how to access button host // ArcMap.Application.CurrentTool = null; } protected override void OnUpdate() { Enabled = ArcMap.Application != null; } } }
Clasa care implementeaz comportamentul butonului are numele implicit
(Button1) iar metoda suprascris OnClick() trebuie dezvoltat astfel nct la
evenimentul Click pe buton s se efectueze aciunea dorit. Pentru
exemplificare, se va afia mesajul Ai apasat!! ntr-o caset de mesaje.
Afiarea mesajului se va face prin apelul metodei statice Show din clasa
MessageBox dup cum urmeaz: MessageBox.Show("Ai apasat!!"); n cadrul
metodei OnClick. Clasa MessageBox aparine domeniului
System.Windows.Forms care se va include: using System.Windows.Forms; i
totodat se va aduga la Solution Explorer/References componenta .NET:
System.Windows.Forms.
40
Dup aceste modificri, se va rula proiectul i se observ c se
lanseaz, n paralel, aplicaia ArcMap. Pentru a testa extensia se procedeaz
astfel:
n ArcMap se selecteaz meniul Customize/Toolbars/Customize
i apare dialogul din figura 3.13. Utilizatorul extensiei poate s-i
construiasc propriul toolbar care s fie folosit ca gazd pentru
propriile lui comenzi. Pentru acest lucru, se apas butonul New...
i se construiete o nou bar de instrumente (n exemplu, avnd
numele Test figura 3.13).
Figura 3.13 Personalizarea interfeei cu utilizatorul
Prin apsarea butonului OK se va construi noua bar de instrumente care va
fi adugat la cele deja existente n ArcMap ns ea nu va conine nici un
control figura 3.14.
Adugarea controlului (butonului) la bara de instrumente care
tocmai a fost creat; Se alege tab-ul Commands n cadrul ferestrei
de dialog Customize i va apare forma ilustrat n figura 3.15. Se
observ c fereastra conine dou controale de tip list, una
conine categoriile iar cealalt comenzile care aparin respectivei
categorii. Astfel, se caut categoria care are numele identic cu
ceea ce s-a introdus la construirea proiectului, pentru atributul
categorie (vezi figura 3.12). Dup selectarea categoriei, se poate
observa c n lista de comenzi apare comanda construit prin
41
aplicaia .NET. Se selecteaz comanda i prin drag and drop se
adaug n bara de instrumente anterior construit. Astfel, bara de
instrumente se populeaz cu comenzile pe care le dezvoltm noi
sau cu alte comenzi deja existente n ArcMap. In figura 3.16 se
ilustreaz bara de instrumente populat cu comanda Test. Dup
procesul de populare cu comenzi a barei de instrumente, se
nchide fereastra de dialog Customize apsnd pe butonul Close.
Figura 3.14 Adugarea unei noi bare de instrumente
Figura 3.15 Categorii / comenzi
42
Salvarea documentului hart din ArcMap pentru ca acesta s
stocheze i extensia personalizat. Ori de cte ori se va deschide
documentul h_ro.mxd va apare i extensia nou construit. Acest
proces de construire a extensiei se va face o singura dat, la
prima rulare a aplicaiei. In rest, se va deschide documentul i se
va testa funcionalitatea comenzii.
Figura 3.16 Extensia personalizat n ArcMap
Testarea funcionalitii comenzii se face dnd click pe butonul
din bara nou construit. Rezultatul este ilustrat n figura 3.17 i se
concretizeaz prin afiarea mesajului Ai apasat!! n caseta de
mesaje.
Figura 3.17 Rezultatul testrii comenzii
43
4.3.2 Simbologii n GIS
Una din principalele aplicaii ale GIS se refer la faptul c, pe hri,
se pot afia diverse informaii statistice, astfel, utilizatorul avnd i o
perspectiv geografic asupra fenomenului reprezentat. Afiarea rezultatelor
fenomenelor economice / sociale pe hri implic construirea de cartograme.
Prin cartogram se nelege reprezentarea grafic pe o hart a unor indicatori
statistici prin: tonuri de culoare, patternuri de afiare, dimensiuni variabile a
simbolurilor afiate etc.
Privind din perspectiva modelului relaional, se consider o baza de
date de tip personal geodatabase bd_ro.mdb, n care exist tabela judete care
conine judeele sub form de date spaiale de tip poligon i tabela populaie
care conine populaia judeelor dup cum urmeaz:
populaia n orae mari (avnd un numr de locuitori mai mare de
150000) cpop;
populaia n orae (avnd un numr de locuitori cuprins ntre
10000 i 150000) tpop;
populaia n mediul rural (avnd un numr de locuitori mai mic
de 10000) rpop.
Cele dou tabele conin un cmp comun pe baza cruia se realizeaz
jonciunea ntre cele dou tabele, este vorba de simbolul judeului aa cum
apare pe numerele de nmatriculare a autovehiculelor, cmp de tip ir de
caractere de lungime dou caractere. Numele lui este sy n tabela populaie i
sj n tabela judee.
Un prim exemplu de realizare a unei cartograme const n a colora
judeele de pe hart ntr-un gradient de culoare n funcie de populaia lor
total. Astfel, prin apsarea butonului de pe bara de instrumente construit n
acest scop, harta se va colora n funcie de totalul populaiei i va apare i
legenda corespunztoare simbologiei create.
Codul surs conine mai multe pri n funcie de etapele pe care le
soluioneaz:
44
Identificarea stratului tematic care se va colora n cazul
exemplului este vorba de layer-ul judee.
// declarare de variabile pentru a stoca numarul de layer-e (nl), // i variabila contor i nrg numrul de grupe (intervale) n care // se vor diviza judeele n funcei de populaie int nl, i, nrg=3; IMxDocument doc = ArcMap.Document; // obinerea documentului hart IMap harta = doc.FocusMap; // obinerea hrii // declarare de interfee pentru layer fiecare conine proprieti // i metode necesare n diferite contexte de lucru ILayer lyr = null; IFeatureLayer ifl = null; IFeatureClass ifc = null; // determinarea numrului de layere ce exist n cadrul hrii nl = harta.LayerCount; // iterarea layer-elor pentru a identifica layerul judete // pe care dorim sa-l colorm for (i = 0; i < nl; i++) { lyr = harta.get_Layer(i); if (lyr.Name == "judete") { // accesarea interfeei IFeatureLayer pentru layer-ul dorit ifl = (IFeatureLayer)lyr; // prin interfaa IFeatureLayer se acceseaz proprietatea FeatureClass // care conine proprieti i metode cu privire la clasa de // caracteristici spaiale ifc = (IFeatureClass)ifl.FeatureClass; } }
Construirea spaiului de lucru de tip baz de date Access care se
va mapa pe fiierul bd_ro.mdb:
Type tip = Type.GetTypeFromProgID("esriDataSourcesGDB.AccessWorkspaceFactory"); IWorkspaceFactory wsf = (IWorkspaceFactory)Activator.CreateInstance(tip); IWorkspace ws = wsf.OpenFromFile(@"d:\test_bdsa\bd_ro.mdb", 0);
Realizarea jonciunii ntre tabela de atribute spaiale judete i
tabela de atribute nonspaiale populatie. Pentru a realiza acest
lucru trebuie ca tabela de atribute nonspaiale s fie inclus n
documentul hart. Dup cum se poate observa n figura 3.17,
aplicaia ArcMap conine dou ferestre principale i anume
fereastra din stnga ce afieaz cuprinsul hrii (Table Of
45
Contents TOC) i fereastra n care se afieaz compoziia
tematic (harta) propriu-zis. In fereastra TOC se vizualizeaz
layer-ele adic straturile tematice, bara de instrumente a ferestrei
conine mai multe butoane care ofer i o alt perspectiv
coninutului ferestrei TOC. Astfel, dac se apas pe butonul List
by Source se listeaz toate entitile incluse la documentul hart
prin sursa lor de provenien. In cazul n care se adaug i tabela
de atribute nonspaiale populatie, alturi de caracteristica spaial
judee, atunci fereastra TOC va avea coninutul afiat n figura
3.18.
Figura 3.18 Afiarea entitilor unui document prin sursa lor
Adugarea tabelei de atribute nonspaiale se poate face static,
respectiv prin programare:
//se construiete un set de date cu numele tabelei (populaie) // n cadrul spaiului de lucru // construit anterior (baza de date Access bd_ro.mdb) IDatasetName dsn = new TableNameClass(); dsn.Name = "populatie"; dsn.WorkspaceName = (IWorkspaceName)(((IDataset)ws).FullName); // se deschide tabela populatie i se ncarc variabila // tpop de tip ITable IName name = (IName)dsn; ITable tpop = (ITable)name.Open(); if (tpop == null) { MessageBox.Show("Nu exista tabela"); return; } // se adaug tabela la colectia de tabele a hartii // colectia de tabele fiind (ITableCollection) // care se refer doar la tabelele de atribute nonspaiale ((ITableCollection)harta).AddTable(tpop);
46
Tabela populaie conine populaia n orae mari, n orae i n mediul rural
pentru fiecare jude. Pentru a obine populaia total se va face suma acestor
cmpuri i se va stoca ntr-un alt atribut al tabelei populaie. Cartograma se
va realiza prin colorarea hrii n funcie de populaia total a judeului.
Adugarea cmpului Total_populaie la tabela populatie:
//construirea cmpului Total_populatie de tip ntreg IField totp = new FieldClass(); IFieldEdit totped = (IFieldEdit)totp; totped.Name_2 = "Total_populatie"; totped.Type_2 = esriFieldType.esriFieldTypeInteger; //adugarea cmpului nou construit la tabela populatie tpop.AddField(totped);
Umplerea cmpului Total_populaie cu suma valorilor celor trei
cmpuri (cpop+tpop+rpop), adic populaia n orae mari, orae i
mediul rural
// construirea unui cursor mapat pe tabela populatie - tpop ICursor ctpop = tpop.Update(null, false); IRow rind; // traversarea cursorului rnd cu rnd rind = ctpop.NextRow(); while (rind != null) { // calcului valorii noului cmp int k = (Int32)rind.get_Value(1) + (Int32)rind.get_Value(2) +
(Int32)rind.get_Value(3); // setarea valorii cmpului dorit rind.set_Value(4, k); // confirmarea modificrii rndului ctpop.UpdateRow(rind); // trecerea la rndul urmtor rind = ctpop.NextRow(); }
Efectuarea jonciunii propriu-zise dintre tabela care conine
caracteristica spaial (judete) i tabela cu date nonspaiale
(populatie) pe cmpul simbol jude:
// construirea unui obiect pentru realizarea jonciunii n memorie IMemoryRelationshipClassFactory mrc = new MemoryRelationshipClassFactoryClass(); // realizarea jonciunii ntre tabelele judete identificat // prin ifc i populaie // identificat prin tpop, relaia este de tip unu la unu
47
IRelationshipClass rc = mrc.Open("test", ifc, "sj", (IObjectClass)tpop, "sy", "jud", "populatie",
esriRelCardinality.esriRelCardinalityOneToOne); // afiarea relaiei n cadrul aplicaiei ArcMap ((IDisplayRelationshipClass)ifl).DisplayRelationshipClass(rc, esriJoinType.esriLeftOuterJoin);
Construirea intervalelor pentru divizarea judeelor n funcie de
populaia lor. In ArcGIS sunt implementate mai multe tehnici de
a realiza clasificarea unor elemente n funcie de valoarea unui
indicator (atribut). Pentru a realiza acest lucru trebuie s se
identifice intervale disjuncte de valori iar elementele care au
valoarea indicatorului respectiv ntr-un anumit interval formeaz
o grup. Spre exemplu, cea mai simpl metod de calcul a
intervalelor de valori se refer la divizarea n intervale egale a
domeniului de valori aferent cmpului pe baza cruia se face
clasificarea. Metoda folosit n exemplu pentru determinarea
intervalelor o reprezint divizarea natural (NaturalBreaks) care
are la baz principiul formrii de grupe astfel nct dispersia n
interiorul grupei s fie minim iar dispersia ntre grupe s fie
maxim.
// construirea unei histograme pe baza atributului dup care // se va face clasificarea ITableHistogram ith = new BasicTableHistogramClass(); // cmpul ith.Field = "Total_populatie"; // tabela care contine cimpul ith.Table = tpop; // declararea a doua obiecte in care se vor stoca valorile // atributului (vval) si frecvenele de apariie a lor (vfrecv) object vval, vfrecv; // ncrcarea propriu-zis a obiectelor ((IBasicHistogram)ith).GetHistogram(out vval, out vfrecv); // construirea unei interfee de clasificare pe baza // metodei NaturalBreaks IClassify div_grupe = new NaturalBreaksClass(); // atribuirea datelor pe baza crora se vor genera intervalele div_grupe.SetHistogramData(vval, vfrecv); // ncrcarea numrului de grupe (intervale) care se vor genera div_grupe.Classify(ref nrg); // declararea unui vector care va conine limitele intervalelor double[] vecgr;
48
// generarea limitelor vecgr = (double [])div_grupe.ClassBreaks;
Astfel, dac se dorete clasificarea judeelor, din punct de vedere a
populaiei, n trei grupe, atunci vectorul vecgr va conine patru valori, iar
intervalele se formeaz astfel:
o Primul interval: [ vecgr[0], vecgr[1] );
o Al doilea interval: [ vecgr[1], vecgr[2] ); i
o Al treilea interval: [ vecgr[2], vecgr[3] ];
Pe hart, acest lucru se vizualizeaz prin colorarea diferit a judeelor n
funcie de intervalul de valori la care va aparine valoarea cmpului
Total_populatie (figura 3.20). Cu alte cuvinte, intervalelor li se vor asocia
culori, de obicei se utilizeaz culori graduale, adic un gradient de culoare.
Figura 3.19 Rampe de culoare din galeria de stiluri definit de ESRI
Generarea culorilor cu care se vor colora judeele de pe hart. In
terminologia ESRI, culorile se definesc fie individual, n acest
caz exist clase specializate pe diferite modele de culoare, de
exemplu RgbColor aferent modelului RGB, fie colecii de culori
modelate prin clase de tip ramp de culori (ColorRamp).
Coleciile de culori pot fi generate de ctre programator sau pot fi
utilizate i colecii predefinite care se afl n galeria de stiluri
definit de ESRI, dup cum se poate observa n figura 3.19.
49
Pentru a accesa galeria, se selecteaz n ArcMap Customize/Style
Manager i va apare dialogul din figura 3.19.
Pentru a accesa culorile din rampa de culori avnd numele Yellow to Dark
Red se va proceda astfel:
// definirea unei interfee de tip ramp de culoare IColorRamp rcul = null; // se alege din galeria ESRI un element (rampa de culoare) // avnd categoria Default Ramps IEnumStyleGalleryItem vst = doc.StyleGallery.get_Items("Color Ramps",
"ESRI.style", "Default Ramps"); // se itereaz elementele pn cnd se identific rampa de culoare cu // numele Yellow to Dark Red IStyleGalleryItem elem = vst.Next(); while (elem != null) { if (elem.Name == "Yellow to Dark Red") { rcul = (IColorRamp)elem.Item; break; } elem = vst.Next(); } // calibrarea rampei de culori la nrg culori; // din rampa de culori Yellow to Dark Red // se vor folosi doar nrg culori n exemplu, nrg = 3 rcul.Size = nrg; bool varb; // construirea rampei de culori rcul.CreateRamp(out varb);
Colorarea hrii folosind culorile din rampa de culori i
clasificarea n cele trei intervale de valori generate anterior:
// definirea unui obiect pentru simbologie bazat pe intervale // de valori IClassBreaksRenderer cbr = new ClassBreaksRenderer(); // specificarea cmpului pe baza cruia se va face redarea cbr.Field = "Total_populatie"; // stabilirea numrului de grupe cbr.BreakCount = nrg; // setarea valorii minime care reprezint limita inferioar a // primului interval de valori cbr.MinimumBreak = vecgr[0]; // declararea unei interfee care exprim modul de umplere // al poligoanelor - umplere uniform cu culoare ISimpleFillSymbol fs; for (i = 0; i < cbr.BreakCount; i++)
50
{ fs = new SimpleFillSymbol(); // stabilirea culorii de umplere fs.Color = rcul.get_Color(i); // asocierea simbolului de umplere cbr.set_Symbol(i, (ISymbol)fs); // setarea valorii limitei superioare a intervalului cbr.set_Break(i, vecgr[i+1]); // etichetarea n legenda hrii ce va apare in TOC cbr.set_Label(i, vecgr[i].ToString()+ "-" +
vecgr[i+1].ToString() ); }
IGeoFeatureLayer gfl = (IGeoFeatureLayer)lyr; // asocierea simbologiei (cbr) layer-ului lyr, ce corespunde judeelor gfl.Renderer = (IFeatureRenderer)cbr; // redesenarea coninutului vizualizrii curente doc.ActiveView.Refresh(); // actualizarea coninutului ferestrei TOC (afiarea legendei) doc.UpdateContents();
Figura 3.20 Colorarea hrii n gradient de culoare pe baza populaiei judeului
Un alt tip de simbologie, se refer la afiarea graficelor pe datele
spaiale pentru a surprinde proporiile unor variabile n cadrul datelor
statistice reprezentate. Pentru exemplificare, s-a ales s se reprezinte pe
hart, prin grafice de tip pie proporia populaiei din: orae mari, orae i din
mediul rural n total populaie, pentru toate judeele rii, dup cum se poate
observa n figura 3.21. Datele cu privire la populaia judeelor n orae mari,
51
orae i mediul rural sunt stocate n tabela populatie n cadrul bazei de date
bd_ro.mdb dup cum s-a prezentat n exemplul anterior. Pentru a nu duplica
codul din exemplul anterior, se vor prezenta acele aspecte care difer sau
trebuie adugate. Astfel, s-au fcut, n plus, declaraiile:
string[] vs = { "Populatia in orase mari", "Populatia in orase", "Populatia in rural" };
string[] numec = { "cpop", "tpop", "rpop" };
unde:
- vs reprezint vectorul de etichete ce se va folosi la descrierea
elementelor din legenda hrii; iar
- numec reprezint vectorul ce conine numele cmpurilor pe
baza crora se va constitui graficul de tip pie.
Secvena de cod conine etapele deja prezentate n exemplul anterior:
identificarea stratului tematic judete pe care se va afia simbologia de tip
piechart (setarea variabilei lyr), construirea spaiului de lucru mapat pe baza
de date bd_ro.mdb, adugarea tabelei populatie la documentul hart,
realizarea jonciunii ntre tabela judete i tabela populatie. Pentru a afia
efectiv simbologia de tip piechart pe stratul tematic judete, din hart, dup
ce s-au parcurs etaplele enumerate anterior, se procedeaz astfel:
// construirea unei rampe de nrg (= 3) culori pe baza rampei de culori // Red to Green, din galeria ESRI IColorRamp rcul = null; // doc are aceeai semnificaie ca i n exemplul anterior // documentul hart IEnumStyleGalleryItem vst = doc.StyleGallery.get_Items("Color Ramps", "ESRI.style", "Default Ramps"); IStyleGalleryItem elem = vst.Next(); while (elem != null) { if (elem.Name == "Red to Green") { rcul = (IColorRamp)elem.Item; break; } elem = vst.Next(); } rcul.Size = nrg; bool vb; rcul.CreateRamp(out vb);
52
// definirea unei interfee pentru descrierea tipului de umplere ISimpleFillSymbol fs; // construire interfa pentru simbologia de tip piechart IPieChartSymbol pcs = new PieChartSymbolClass(); // construire interfa pentru redarea simbologiei de tip chart IChartRenderer cr = new ChartRenderer(); // setarea sensului de construire a feliilor graficului // (sensul acelor de ceas) pcs.Clockwise = true; // mrimea simbolului (a piechart-ului) ((IMarkerSymbol)pcs).Size = 30; // se sabilesc parametrii pentru cele nrg (=3) variabile care vor // compune piechart-ul for (i = 0; i < nrg; i++) { // construirea unui nou simbol de umplere fs = new SimpleFillSymbol(); // asocierea culorii de umplere preluat din rampa de culoare
// anterior construit fs.Color = rcul.get_Color(i); // adugarea simbolului la colecia de simboluri ((ISymbolArray)pcs).AddSymbol((ISymbol)fs); // adugarea cmpului care se va reda prin piechart ((IRendererFields)cr).AddField(numec[i]); // asocierea etichetei cmpului pentru afiare la legend ((IRendererFields)cr).set_FieldAlias(i, vs[i]); } // asocierea simbologiei de tip piechart construit la simbologia // de tip chart cr.ChartSymbol = (IChartSymbol)pcs; // stabilirea simbolului pentru background-ul hrii IRgbColor cul = new RgbColor(); fs = new SimpleFillSymbol(); // setare culoare de umplere cul.Red = 250; cul.Green = 250; cul.Blue = 250; // asocierea culorii la simbolul nou creat fs.Color = cul; // asocierea simbolului construit ca background cr.BaseSymbol = (ISymbol)fs; // construirea legendei se va afia n fereastra TOC cr.CreateLegend(); // etichetarea n legend a simbologiei cr.Label = "Distributia populatiei pe medii"; // evitarea suprapunerii graficelor cr.UseOverposter = true; // asocierea simbologiei (cr) layer-ului lyr, ce corespunde judeelor IGeoFeatureLayer gfl = (IGeoFeatureLayer)lyr; gfl.Renderer = (IFeatureRenderer)cr; // redesenarea coninutului vizualizrii curente doc.ActiveView.Refresh();
53
// actualizarea coninutului ferestrei TOC doc.UpdateContents();
Figura 3.21 Simbologie de tip PieChart
3.3.3 Elemente de geoprocesare
Pe lng realizarea de simbologii pe hri, prin GIS, se realizeaz i
procesri de date spaiale. Operaiile referitoare la geoprocesare sunt
implementate n cadrul produsului software ArcGIS i pot fi utilizate n
diferite forme. In cadrul acestui capitol accentul se va pune pe partea de
efectuare a geoprocesrii prin programare ns pentru a realiza acest lucru
este necesar a cunoate semnificaia operaiilor de geoprocesare precum i
varianta vizual (user friendly) de declanare a lor.
Pentru exemplificare, se consider compoziia tematic (figura 3.22)
compus din straturile:
- ruri, de tip polilinie ce conine rurile romniei.
- judete, de tip poligon ce conine judeele romniei;
i se dorete identificarea rurilor care strbat anumite judee.
Rezolvarea acestei probleme const n efectuarea a dou operaii:
- selecia judeelor pentru care dorim s identificm ce ruri exist
n ele;
54
- efectuarea operaiei de decupare (clip) a stratului tematic ruri n
funcie de judeele selectate.
Rezultatul operaiei va fi un nou strat tematic ce va conine doar rurile care
se afl n judeele selectate.
Efectuarea vizual a acestei operaii presupune folosirea unei
componente din ArcMap care se numete ArcToolbox i se invoc:
Geoprocessing/ArcToolbox, dup cum se poate observa n figura 3.22.
Figura 3.22 Componenta ArcToolbox
Componenta ArcToolbox conine instrumente care permit executarea de
operaii elementare n ArcGIS. Aceste operaii sunt grupate n funcie de
tipul datelor spaiale pe care ele opereaz, de categoria de prelucrri
efectuate etc. Pentru a face selecia unei caracteristici spaiale folosind un
atribut nonspaial, prin componenta Toolbox, se acceseaz grupul de operaii
Data Management Tools / Layers and Table Views iar din cadrul grupului se
execut instrumentul Select Layer by Attribute (figura 3.23). Interfaa
instrumentului i precum i modul de completare a parametrilor pentru a
selecta judeul care are simbolul judeului (sj=ag), adic judeul Arges, se
prezint n figura 3.23. Rezultatul operaiei de selecie este vizualizat n
figura 3.24. O alternativ mai simpl pentru selecie const n a selecta
55
instrumentul de selecie din bara de instrumente a aplicaiei, ce are simbolul:
, dup care se d click pe judetul care se dorete a se selecta. In cazul n
care judeul este Arge, rezultatul ar fi identic cu ceea ce s-a prezentat n
figura 3.24. Decuparea rurilor care exist n judeul Arge se face prin
execuia instrumentului: Analysis Tools / Extract / Clip. Ca parametrii,
acest operaie primete: caracteristica spaial care se va decupa (rauri),
caracteristica spaial pe baza creia se face decuparea (judete),
cacarteristica spaial care va stoca rezultatul (rauri_rez) care este
parametrul de ieire al operaiei. Un parametru opional al operaiei n
constituie tolerana decuprii exprimat n uniti de lungime. Dup
efectuarea operaiei se va construi un nou strat tematic (rauri_rez) care se va
aduga hrii i care va conine toate rurile care se afl n judeul Arge, ca
n figura 3.25.
Figura 3.23 Interfaa operaiei de selecie a caracteristicii spaiale prin atribute
nonspaiale
Operaiile din ArcToolbox se pot declana i n modul programare,
prin construirea de extensii dup cum s-a prezentat n paragraful 3.3.1.
Categoriile de instrumente de geoprocesare sunt definite sub form de
module care se adauga n proiectul Visual Studio.NET. Referina poart
56
acelai nume cu categoria i se regsesc ca i componente .NET. Astfel, dac
se dorete efectuarea operaiei de decupare, se adaug referina .NET cu
numele ESRI.ArcGIS.AnalysisTools i se adaug domeniul de nume:
using ESRI.ArcGIS.AnalysisTools;
Figura 3.24 Selecia judeului Arge pe hart
In acest context, toate intrumentele se regsesc ca fiind clase i lor li se
atribuie parametrii de intrare, de ieire i eventual ali parametrii necesari
execuiei operaiei, n mod similar lucrului cu comenzi:
// se construiete un obiect Clip Clip ob_clip = new Clip(); // se seteaz caracteristica ce se va decupa ob_clip.in_features = "rauri"; // se seteaz caracteristica pe baza creia se va face decuparea ob_clip.clip_features = "judete"; // se seteaz caracteristica ce va stoca rezultatul operaiei ob_clip.out_feature_class = @"D:\test_bdsa\bd_ro.mdb\rauri_rez";
Dup construirea obiectului Clip i dup ce au fost ncrcai parametrii,
pentru a efectua propriu-zis operaia se procedeaz astfel:
// se construiete un obiect de tip Geoprocessor Geoprocessor gp = new Geoprocessor(); // proprietatea OverwriteOutput = true determin ca rezultatul s fie // suprascris la o nou execuie a comenzii gp.OverwriteOutput = true; // executarea propriu-zis a comenzii identificat prin
57
// obiectul ob_clip gp.Execute(ob_clip, null);
Figura 3.25 Rezultatul operaiei de decupare
Pentru a obine rurile care se afl n judeul Arge, mai nti se selecteaz
judeul folosind instrumentul de selecie din bara de instrumente a aplicaiei
ArcMap dup care se apas butonul din extensia construit de utilizator iar
rezultatul va apare dup cum se poate observa n figura 3.25.
58
4. Dezvoltarea aplicaiilor software bazate pe MS Office
4.1 Introducere
Aplicaiile bazate pe Office sunt deosebit de utile, n practic,
deoarece folosesc facilitile existente n aplicaiile pachetului software
Microsoft Office. Pentru a dezvolta astfel de aplicaii sau extensii, pe
platforma .NET a fost construit un framework cunoscut sub denumirea de
Visual Studio Tools for Office (VSTO). Acesta ofer suport de programare
.NET pentru Word, Excel, Outlook, PowerPoint, Project, Visio i InfoPath
n Visual Studio. De asemenea, VSTO permite ca documente Word i Excel
s foloseasc caracteristici de programare din .NET cum ar fi suport pentru
legarea datelor, controale care se pot folosi n forme windows etc.
Figura 4.1 Ierarhia modelului EOM
Scrierea codului pentru aplicaiile bazate pe Office implic utilizarea
modelului cunoscut sub denumirea de OOM Office Object Model. Acest
model conine un set de clase i obiecte necesare pentru pentru controlul
aplicaiilor Office. Modelele sunt particularizate n funcie de aplicaiile pe
59
care le controleaz, de exemplu: EOM Excel Object Model, WOM Word
Object Model etc. In general, aceste modele conin o ierarhie de clase i sunt
organizate astfel nct n rdcina ierarhiei se afl clasa Application care
modeleaz comportamentul unei aplicaii particulare din pachetul software
MS Office. Pe lng clasa Application care este prezent n toate ierarhiile,
exist i clase particulare n ierarhie ce depind de aplicaia propriu-zis i
corespund entitilor pe care le manipulm efectiv n aplicaiile Office. De
exemplu, pentru aplicaia Excel, principalele clase ct i relaiile dintre ele
sunt ilustrate n figura 4.1.
Figura 4.2 Ierarhia modelului WOM
Se observ c, la baza ierarhiilor se afl clasa Application care
modeleaz comportamentul aplicaiei Office i prin intermediul acestei clase
se construiete o instan a aplicaiei. Instana aplicaiei poate conine o
colecie de documente modelat prin intermediul coleciei Documents n
WOM sau Workbooks n EOM. Un element al coleciei, adic un obiect de
tip Document sau Workbook, poate conine o colecie de paragrafe
(Paragraphs) sau o colecie de foi de calcul Worksheets.
Pentru aplicaia Word, ierarhia este prezentat n figura 4.2.
60
Pentru dezvoltarea de aplicaii bazate pe PowerPoint, modelul este
PPOM i are ierarhia prezentat n figura 4.3.
Figura 4.3 Ierarhia modelului PPOM
Din figur se observ c aplicaia este compus dintr-o colecie de prezentri
(Presentations) care are elemente de tip prezentare (Presentation), o
prezentare la rndul ei se compune dintr-o colecie de slide-uri (Slides) de
elemente Slide n care se gsesc diferite tipuri de obiecte, cu corespondent
vizual, coninute ntr-o colecie de elemente Shapes.
Ierarhiile de clase specifice tipurilor de aplicaii Office conin clase
care descriu entitile cu care opereaz aplicaiile pachetului Office.
Folosind elemente ale modelului de programare OOM se pot
dezvolta aplicaii n diferite modaliti:
- Aplicaii de utilizator ce interacioneaz cu aplicaii Office; adic
programatorul i dezvolt propria sa aplicaie care n background va
controla i interaciona cu aplicaii i documente Office. De exemplu,
se construiete o aplicaie independent, n mod consol sau
Windows Forms, care are ca scop introducerea unor date ntr-un
document Word pentru a fi ulterior stocat sau imprimat pe hrtie.
Executarea unei astfel de aplicaii va determina lansarea n execuie a
aplicaiei Office pentru a efectua diferite procesri, specifice. In acest
61
mod, aplicaia de utilizator se va executa ntr-un proces distinct fa
de aplicaia Office.
- Construirea de module funcionale existente sub form de biblioteci
cu legare dinamic (DLL Dynamic Link Library) care se includ n
aplicaiile Office pentru a personaliza prelucrrile aplicate
documentelor. De exemplu, construirea unui modul add-in care s
aib ca element de interfa un buton pentru efectuarea unei
prelucrri nestandard asupra datelor existente ntr-o foaie de calcul;
- Ataarea de cod documentelor Office, implic construirea unei
aplicaii pe baza unui ablon de aplicaie Office, definit n mediul
Visual Studio ca tip distinct de proiect (de exemplu, pe baza unui
ablon de aplicaie Excel). Codul ataat permite efectuarea de
prelucrri personalizate i impune construirea de noi interfee pentru
declanarea procesrilor. Secvenele de cod se pot ataa fie
documentelor Office fie abloanelor de documente.
Ultimele dou modaliti prezentate de a dezvolta aplicaii bazate pe Office
au caracteristic faptul c secvenele de cod personalizate ruleaz cu aplicaia
Office n acelai proces; conceptul poart numele de cod gazduit. Pentru a
rula codul n procesul aplicaiei Office, aplicaia respectiv trebuie s