MapBasic 3.0 - un limbaj dedicat GIS-urilor
Dacă eşti end-user al unui GIS, totul ţi se pare o minunăţie fără sfâşit,
cu hărţi şi baze de date ce defilează necontenit pe ecran. Pentru un programator cu
pretenţii se pune imediat întrebarea: cum scriu o aplicaţie pentru GIS ? Un răspuns
posibil ni-l oferă tot cei de la MapInfo prin mediul de dezvoltare aplicaţii MapBasic ajuns la
versiunea 3.0.
De ce MapBasic ?
Chiar dacă se vinde separat de MapInfo, MapBasic este conceput pentru a scrie programe destinate să
ruleze sub MapInfo, în lipsa căruia orice program ar rămâne fără suport. Numele
mediului a fost împrumutat şi de limbajul de programare suportat şi pentru care sunt înglobate
un editor de texte, un debugger şi help, totul la un nivel mediu, departe de mediile de programare
gigant ca Visual Basic. Sursa .mb este compilată în MapBasic, iar modulul obiect .mbx pentru MapInfo
poate fi rulat din interiorul acestuia (aşa cum se rulează .dbo-urile din dBase).
Ceea ce caracterizează însă MapBasic este structura pe care e conceput limbajul său de
programare: bătrânul BASIC este nivelul de jos de la care s-a pornit. Aceasta înseamnă că
toate definiţiile de variabile, tipuri de date (de baza şi user-defined) cunoscute de BASIC
(vezi PC Report Nr. 25, pag. 62-64) rămân valabile şi aici, alături de regulile de
vizibilitate a variabilelor. Programele scrise în MapBasic au o structură modulară, cu o
procedură (SubMain) ce se execută în regim de program principal şi din interiorul căreia
se pot apela funcţii şi proceduri standard sau definite de user. Se moşteneşte şi
aici sintaxa instrucţiunilor BASIC de selecţie şi repetiţie, iar parametrii funcţiilor
pot fi transferati atât prin adresă cât şi prin valoare. Astfel se justifică particola de
BASIC din denumirea produsului. Map-ul se referă la trăsătura ce-l distinge de BASIC şi
anume faptul că este desemnat să lucreze cu hărţi digitale ca limbaj de interfaţă
pentru GIS.
Mai mult decât un simplu limbaj
Sub o haină de "limbaj pentru amatori" descoperim un instrument puternic de programare a
aplicaţiilor. Având în vedere că GIS-ul presupune o colecţie de date spaţiale,
etajul superior al limbajului este cel care-l evidenţiază prin caracteristicile lui:
- oferă suport pentru lucrul cu baze de date relaţionale
- poate efectua calcule şi operaţii spaţiale asupra obiectelor aflate pe hartă
- are implementată toată gama de accesorii necesare programării unei interfeţe
Windows, Macintosh, Sun sau HP
- suportă schimbul de date DDE cu un server Windows
- poate apela rutinele din biblioteci DLL cum ar fi dialogurile Open, Save, Print
MapBasic - limbaj de gestiune baze de date
Aplicaţiile fiind concepute să ruleze din MapInfo este evident că ele să aibă
instrucţiuni ce îndeplinesc comenzile MapInfo. De aceea, la deschiderea unei tabele (.tab) sunt
automat deschise fişierele ce compun această tabelă:
- harta cu dispunerea spaţială a obiectelor (.map)
- baza de date asociată obiectelor (.dbf sau analog)
- baza de date cu identificatorii obiectelor (.id)
- eventuale fisiere index (.ind)
Cum printre ele apare şi o bază de date .dbf, asupra ei pot fi efectuate operaţii
specifice folosind sintaxa pusă la dispoziţie de MapBasic. Este de fapt o combinaţie între
SQL şi comenzi de gestiune BD care aduc foarte mult cu limbajul lui FoxPro. Principalele comenzi de
operare asupra BD relaţionale (tratate ca tabele) suportate de MapInfo sunt:
| Open Table |
- |
deschide un fisie .tab (apelând dacă este cazul la dialogul DLL Open) |
| Alter Table |
- |
modifică structura unei tabele |
| Create Table |
- |
crează o nouă tabelă |
| Close Table |
- |
închide o tabelă |
| Create Index/Drop Index |
- |
crează /şterge un fişier index |
| Insert |
- |
introduce linie nouă |
| Update |
- |
modifică linie |
| Delete |
- |
şterge linie Fetch - analog cu GO TO Browse |
| Select |
- |
analog cu comanda SQL Select |
Un fragment de cod se poate vedea în exemplul. 1 (textul ce urmează dupa apostrof este considerat
comentariu).
Ex. 1 Un exemplu dintr-o aplicatie
' Creaza un tabel cu campurile specificate
Create Table CLIENT (Nume Char(20), Adresa Char(30), Oras Char(30), Sold Decimal(5,2), Client_ID
Integer) File "CUST.TAB"
' Creaza harta conform tabelului
Create Map For CLIENT CoordSys Earth
' Creaza fisier index dupa identificator
Create Index On CLIENT (Client_ID)
' Creaza fisier index dupa nume
Create Index On CLIENT (Nume)
' Modifica structura tabelului
Alter Table CLIENT (Rename Adresa Adresa_client, Modify Nume Char(25), Add Cod_postal Char(10) )
Select Cliet_ID From CLIENT Where Nume = "Sandu" And Sold > 0
|
Operaţii pe date spaţiale
O tehnică simplă este implementată în cadrul lucrului cu obiecte în MapBasic: fiecare
obiect are un identificator unic în BD care îi este asociată şi care îl leagă de tabelă.
Însă o tabelă cu date spaţiale are o coloană suplimentară numită object
(sau obj) care se creează automat şi care pointează spre obiectul grafic correspondent. Dacă
o linie din tabelă nu are încă un corespondent grafic (cazul referinţelor rămase
nerezolvate la geocodare) atunci ea va avea în coloana object valoarea nulă. Coloana object (referită
ca orice colonă prin nume_tabel.nume_coloană) nu apare în MapInfo la un Browse normal, ea poate
fi manipulată numai din MapBasic sau din SQL-ul inclus MapInfo.
MapBasic suportă zece tipuri de obiecte (puncte, linii, polilinii, regiuni, text, arce, elipse,
dreptunghiuri, dreptunghiuri rotunjite, frame-uri) ce pot fi create în urma unor funcţii care
returnează o variabilă de tip Object. Informaţii despre obiectele astfel create putem afla
cu funcţiile ObjectGeography, ObjectNodex, ObjectNodey sau putem modifica proprietăţile cu
Alter Object ( ex. 2).
Ex. 2 Crearea unui obiect de tip cerc
' Deschide un fisier .tab
Open Table "floodmap.tab"
' Flood_area va fi o variabila reala
Dim flood_area As Float
' Pozitionare pe prima inregistrare
Fetch First From floodmap
' Calculeaza aria primului obiect
flood_area = Area (floodmap.obj, "sq km")
' Target_area va fi de tip object
Dim target_area As Object
' Mai exact un cerc
target_area = CreateCircle(103.4, 58.6, 100)
|
Se poate umbla şi la atributele de desenare (Pen), umplere (Brush) şi stil (Style). Valorile
implicite ale acestora sunt luate din fişierul MAPBASIC.DEF, un fel de .ini al lui MapInfo.
Însă forţa prelucrării spaţiale rezidă în operatorii care pot fi aplicaţi
asupra obiectelor în condiţiile de selecţie. Cei 7 operatori sunt arătaţi în tabelă.
| Operator |
Sintaxa |
ia valoarea TRUE daca: |
| Contains |
objectA Contains objectB |
primul obiect conţine centrul celui de-al doilea obiect |
| Contains Part |
objectA Contains Part objectB |
primul obiect conţine o parte din al doilea obiect |
| Contains Entire |
objectA Contains Entire objectB |
primul obiect îl conţine în întregime pe al doilea |
| Within |
objectA Within objectB |
primul obiect este în interiorul celui de-al doilea |
| Partly Within |
objectA Partialy Within objectB |
o parte din primul obiect este conţinută în cel de-al doilea |
| Entirely Within |
objectA Entirely Within objectB |
primul obiect este inclus în întregime în cel de-al doilea |
| Intersects |
objectA Intersects objectB |
cele două obiecte au puncte commune |
În exemplul 3 este arătat codul selecţiei ce crează o tabelă cu o linie şi o
coloană în care se află lungimea tuturor autostrăzilor din Romania.
Ideea implementării unei funcţii de creare buffer (vecinătate de distanţă egală
în jurul unui obiect) a apărut la calculul suprafeţei pentru un bazin hidrografic (ex. 4).
Ex. 3 O selectie de date spatiale
Select Sum(ObjectLen(object, "km")) From autostr Where obj Within (Select object From
Country Where abbr = "RO" )
Ex. 4 Calculul suprafetei unui bazin hidrografic
Dim hidro_area As Object
Create Object As Buffer From selection Into Variable hidro_area Width 300 Units "m"
Select Sum(ObjectArea(object, "sq km")) From hidro_area
|
Nu lipsesc operatorii de reuniune (Union), intersecţie (Intersection) şi diferenţă
simetrică (Merge) între două obiecte.
Suportul de programare Windows
Dacă Visual Basic oferă un set foarte bogat de facilităţi în programarea aplicaţiilor
Windows, MapBasic-ul nu se lasă mai prejos, mergând până la (aproape) acelaşi cod şi
pentru platforme Macintosh. Spre deliciul fan-ilor Windows, putem include în codul aplicaţiei toate
tipurile de resurse cunoscute de acesta însă păcatul cel mare este lipsa unui editor de resurse
integrat, cel care scrie aplicaţiile trebuind să "potrivească" mai întai pe hârtie
asezarea controalelor.
Pentru a aminti numai câteva din facilităţile oferite de sculele de proiectare a interfeţei
grafice, vom spune că se pot crea :
- Meniuri de tip bar şi pop-up cu tot dichisul (separatori, acceleratori, marcare, activ /
inactiv) care ulterior pot fi considerate ca separate sau se pot adăuga meniurilor MapInfo .
- Dialoguri, de la cele mai simple (obţinute în urma unei comenzi Notify) până la cele
"dotate" cu tot felul de controale de tip
- Button
- Radio Button
- Check Box
- Edit Text
- List Box
- Combo Box
- Group Box
- Static Text
- Picker (butoane de alegere font, culoare, stil)
Conform standardului API sunt furnizate funcţii de gestiune citire/setare a parametrilor pentru
controale şi care efectuează eventual saltul la subrutine de tipul On Error de tratare a
erorilor. În cazul erorilor run-time ne putem folosi şi de debugger-ul încorporat (e drept că
fără prea mari pretenţii).
Suportul pentru DDE -un lucru devenit firesc
Comunicarea între procese IPC (InterProcess Communication) este termenul generic pentru a desemna
schimbul de informaţii între pachete software separate. IPC este implementat sub Windows prin
protocolul DDE (Dynamic Data Exchange). Două aplicaţii active ce suportă DDE pot schimba
instrucţiuni şi date. Există doua tipuri de comunicatii DDE:
- conversaţia
- legătura (paste link)
MapBasic recunoaşte ambele tipuri spre deosebire de MapInfo ce suportă numai conversaţia
în care poate juca rolul de server pentru execuţia sarcinilor cerute de clientul conectat la el.
Limbajul suportă următoarele funcţii şi comenzi care permit unei aplicaţii să
devină client într-o conversatie DDE:
DDEInitiate - deschide o conversatie
DDERequest$ - cere informatii de la server
DDEPoke - trimite informatii catre server
DDEExecute - transmite serverului sarcina de a indeplini o actiune
DDETerminate - inchide o conversatie DDE
Concluzii
Ca mediu integrat de dezvoltare aplicaţii, MapBasic are înca multe de pus la punct însă
prin ideile noi cu care vine limbajul de programare şi mai ales prin flexibilitate şi usurinţa
tocmai în mânuirea datelor spaţiale - pentru care a fost proiectat - fac din el un instrument
redutabil pentru scrierea de aplicaţii specifice unui GIS. Facilităţile de portare a aplicaţiilor
între platforme diferite, particularităţile fiecărui tip de sistem (apelarea de DLL-uri în
varianta Windows, pasarea mesajelor prin funcţii XCMD în varianta Macintosh, faptul că suportă
comenzi de comunicare între aplicaţii de tip RPC sub UNIX şi posibilitatea de creare a
propriului Help On Line ) vin să argumenteze afirmaţia că -cel puţin deocamdată -
MapBasic este un concurent serios pe piaţa limbajelor de programare GIS.
Cu resurse minime (PC 286 cel puţin, pe care să ruleze Windows, sau staţii SUN) putem
beneficia nu numai de un limbaj de programare dar şi de un (mini) SGBD care pentru utilizatorii de
MapInfo se dovedesc a fi vitale.
PC Report
Nr.35 August 1995
|
|