Dezvoltare GIS
 

News  Technical Articles  Romanian Press 

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

 


Copyright © Geo Strategies 1995-2004

January 2004