Aplicatie Pentru Constructia DE Harti Digitale
CUPRINS
CAPITOLUL I
INTRODUCERE
Conceptul de hartă digitală …………………………………………………………………………..4
1.1. Definiții ……………………………………………………………………………………………..10
1.2. Reprezentare GIS. Repere istorice …………………………………………………………11
1.3. Structura proiectului …………………………………………………………………………….13
CAPITOLUL II
FUNDAMENTE TEORETICE
Ecuatia dreptei…………………… ……………………………………………………15
2.2. Formule de transformare a coordonatelor 3D în 2D ………………………………………15
2.3. Primitive grafice 3D…………………………………………………………………………………..19
2.4. Grafică 3D ……………………………………………………………………………………………….22
2.4.1. Spațiul tridimensional …………………………………………………………………………….22
2.4.2. Primitive grafice 3D ……………………………………………………………………………….23
2.4.3. Proiecții ………………………………………………………………………………………………..26
2.5. Sistemul GPS …………………………………………………………………………………………..40
2.5.1. Metode de lucru ale sistemului GPS…………………………………………………………43
Sistemul de sateliți GPS ………………………………………………………………………..45
CAPITOLUL III
PROIECTAREA ȘI IMPLEMENTAREA APLICAȚIILOR PENTRU
CONSTRUCȚIA DE HARȚI DIGITALE
Algoritmul problemei ………………………………………………..46
Colectarea datelor …………………………………………………………..54
3.2.1 Colectarea manuală …………………………………………………………………………………54
3.2.2 Colectarea automată…………………………………………………………………………………56
CAPITOLUL IV
TESTAREA ȘI EVALUAREA APLICAȚIEI
Actualizarea hărților existente …………………………………..57
Actualizarea automată a coordonatelor …………………….58
CAPITOLUL V
CONCLUZII …………………………………………………………………………………………………63
BIBLIOGRAFIE……………………………………………………………………………………………..64
Anexa aplicatie
Pagini 89
=== APLICATIE PENTRU CONSTRUCTIA DE HARTI DIGITALE ===
CUPRINS
CAPITOLUL I
INTRODUCERE
Conceptul de hartă digitală …………………………………………………………………………..4
1.1. Definiții ……………………………………………………………………………………………..10
1.2. Reprezentare GIS. Repere istorice …………………………………………………………11
1.3. Structura proiectului …………………………………………………………………………….13
CAPITOLUL II
FUNDAMENTE TEORETICE
Ecuatia dreptei…………………………………… ……………………………………………………15
2.2. Formule de transformare a coordonatelor 3D în 2D ………………………………………15
2.3. Primitive grafice 3D…………………………………………………………………………………..19
2.4. Grafică 3D ……………………………………………………………………………………………….22
2.4.1. Spațiul tridimensional …………………………………………………………………………….22
2.4.2. Primitive grafice 3D ……………………………………………………………………………….23
2.4.3. Proiecții ………………………………………………………………………………………………..26
2.5. Sistemul GPS …………………………………………………………………………………………..40
2.5.1. Metode de lucru ale sistemului GPS…………………………………………………………43
Sistemul de sateliți GPS ………………………………………………………………………..45
CAPITOLUL III
PROIECTAREA ȘI IMPLEMENTAREA APLICAȚIILOR PENTRU
CONSTRUCȚIA DE HARȚI DIGITALE
Algoritmul problemei ……………………………………………………………………………….46
Colectarea datelor …………………………………………………………………………………….54
3.2.1 Colectarea manuală …………………………………………………………………………………54
3.2.2 Colectarea automată…………………………………………………………………………………56
CAPITOLUL IV
TESTAREA ȘI EVALUAREA APLICAȚIEI
Actualizarea hărților existente ……………………………………………………………………57
Actualizarea automată a coordonatelor ………………………………………………………..58
CAPITOLUL V
CONCLUZII …………………………………………………………………………………………………63
BIBLIOGRAFIE……………………………………………………………………………………………..64
ANEXE ……………………………………………………………………………………………………………………65
CAPITOLUL I
INTRODUCERE
1.Conceptul de hartǎ digitalǎ
Trǎim într-o lume tridimensionalǎ. Însǎ modul de vizualizare obișnuit al unui monitor este bidimensional. Apariția graficii 3D a fost impusǎ de necesitatea de a asigura o reprezentare cât mai realistă a scenelor de obiecte din realitate care erau utilizate fie pentru proiectare asistatǎ (CAD), fie pentru realizarea de simulǎri ale lumii reale în care era necesarǎ o reprezentare cât mai apropiatǎ de realitate a modelelor.
Odatǎ cu intrarea graficii 3D în domeniul PC-urilor a avut loc o revoluție în ceea ce privește perfomanțele sistemelor grafice, în momentul de fațǎ acesta fiind domeniul cel mai dinamic al dezvoltǎrii hardware-ului, mai dinamic chiar decât dezvoltarea procesoarelor [11].
Dezvoltarea a dus la apariția unor circuite destinate accelerǎriii operațiilor grafice la început pentru grafica 2D și mai apoi pentru grafica 3D. Aceste circuite dedicate au fost concepute fie sub forma unui singur chip (2D+3D) care sǎ asigure performanțe mulțumitoare pentru ambele tipuri de graficǎ, fie sub forma unor chipuri dedicate unui anumit tip de graficǎ care sǎ asigure o accelerare a operațiilor grafice cât mai ridicata în domeniul pentru care au fost concepute. Astfel au apǎrut acceleratoare 3D dedicate cu preformanțe foarte bune capabile sǎ realizeze chiar și în cazul PC-urilor o graficǎ de calitate [2].
În esență , pornind de la faptul că “GIS” este abrevierea de la “Geographic Information System” ( “sistem informatic geografic” ) , vom accepta că este vorba de o aplicație informatică ( pentru calculatoare ) ce lucrează unitar. Probabil că cititorul familiarizat cu termenul de GIS ar putea sări peste următoarele încercări de definire, totuiși ele nu doar reflectă necesitatea de a iniția corect într-un domaniu însa insuficient conturat în România , ci și lamuresc aspecte mai rafinate [8].
Sistemele Informaționale Geografice (Geographical Information System – GIS) reprezintă o tehnică de lucru tot mai utilizată în lumea contemporană, atât în domeniul cercetărilor teoretice, cât și în foarte multe activități practice.[13]
GIS-ul este de fapt un sistem care are mai multe componente de tip informațional raportate la coordonate geografice. [13].
Introducerea, stocarea, manipularea și analiza componentelor se face cu ajutorul calculatorului; rezultatul constă în primul rând în vizualizarea unor informații complexe referențiate spațial față de coordonatele geografice reale, iar în al doilea rând în posibilitatea efectuării unor analize și corelații de mare complexitate, imposibil de realizat eficient cu tehnicile clasice.
Tehnicile GIS permit combinarea de informații de diferite tipuri (cifre, imagini, hărți etc.), componente hardware și software, toate aflate sub directa coordonare și determinare a componenței umane.
Harțile digitale pe care vi le punem la dispoziție sunt harți vectoriale digitale de mare precizie. Detaliile disponibile utilizatorilor în legaturǎ cu harțile digitale ale Romaniei sunt :
Romania – scarǎ 1:100.000 – incluzând toate granițele de țară și de județ , orașele, comunele, satele, drumurile europene, naționale, județene și comunale, lacuri, râuri, cǎi ferate ;
198 de localități – scară 1:10.000 sau mai bine – inclusiv toate municipiile reședința de județ (40 de localitati), cu detalii de nume de cartiere, bulevardele, puncte de interes, parcurile și strǎzile
București (include SAI) – scară 1:10.000 – cu detalii cu numerele de case de la intersecții, toate cartierele, bulevardele, punctele de interes, parcurile și strǎzile.
Harțile digitale vectoriale utilizate de S.A.S GRUP SRL permit recunoasterea și citirea dintr-o bazǎ de date a adresei detaliate a poziției autovehicolului. Hǎrțile digitale raster uzual folosite de terți permit vizualizarea doar ca si POZA a unei părți de hartǎ, farǎ a putea recunoaște și furniza adresa unde se aflǎ autovehicolul.
Chiar și aplicații care folosesc "controale" de hărți de tip Google Maps sau Virtual Earth (sau altele asemamanatoare) nu pot citi adresele pozițiilor unui vehicul, astfel încât ulterior nu pot fi utilizate în nici un fel de rapoarte informațiile legate de rutele parcurse de auto vehicule.
Rapoartele noastre permit evaluarea (la nivel de adresă detaliată) a activitǎții mașinilor monitorizate prin soluția S.A.S GRUP de localizare flote auto prin GPS, sunt extrem de clare, precise, ușor de obținut și utile în gestionarea eficientă a flotilei auto. Orice poziție sau rută parcursǎ de unul sau mai multe vehicule se poate vizualiza pe harțile digitale vectoriale printr-un simplu click de mouse.
Indiferent de mărimea parcului auto, viteza de afișare a oricăror hărți/informații nu depǎșește 2-3 secunde.
În prezent putem localiza autovehiculele clienților noștri în cele circa 240 de orașe importante ale României la nivel de stradǎ.
Dacă datele ce urmează a fi utilizate nu sunt încă în format digital, adică într-o formă recunoscută de către calculator, există mai multe tehnici prin care aceste informații pot fi capturate.
Hărțile pot fi digitizate, sau trasate cu ajutorul mouse-ului, pentru a colecta coordonatele diferitelor elemente. Dispozitivele electronice de scanare pot de asemenea converti liniile și punctele de pe o hartă în format digital.
Introducerea datelor în sistem este componentă cu cele mai mari cerințe din punctul de vedere al resurselor de timp din cadrul unui GIS. Fiecare apariție a obiectelor dintr-o hartă trebuie specificată; la fel și relațiile spațiale dintre ele. Editarea informației capturate automat poate fi, de asemenea, dificilă.
Scanerele electronice înregistrează petele de pe o hartă cu aceeași acuratețe cu care capturează elementele interesante de pe hartă.
De exemplu, o astfel de pată poate duce la conectarea a două linii care nu ar trebui să se întâlnească. Astfel de informații nedorite trebuiesc editate sau eliminate din fișierul de date. Elemente de topografie si geodezie
Hartă și plan. Scară de reprezentare
Vă propunem să ne imaginăm că avem afișată , pe ecranul calculatorului , harta unei zone de teren. Această reprezentare conține – integrate în ansamblu și relaționate după diverse criterii – date specifice :
informații georafice native : forme de relief , rețea hidrografică , drumuri ;
pozițiile specifice și denumirile obiectivelor din zonă (străzi , clădiri , centre , înteprinderi , rețele de apă , electricitate , telefonie sau gaze);
informații descriptive ale obiectivelor urmărite (după destinația GIS-ului) .
Aplicația informatică prin intermediu căreia avem acces la această hartă inteligentă permite o gamă largă de interogări , de genul :
* cine este proprietarul casei pe care o punctez cu mouse-ul;
* care este suprafața terenului selectat ;
* unde se află obiectivul căutare ;
* care este ruta recomandată pentru traseul dintre două obiective;
* ce distanță este intre două puncte , pe un traseu impus;
* evidențierea intersecțiilor dintre rețelele telefonice ș ice le electrice (adică aplic1ri de tip “ Call before you dig! ”) ;
* evidențierea intersecțiilor dintre rețeaua de gaze și parcelele din teritoriu ;
* evidențierea clădirilor care se află sub anumite distanțe față de o rețea (buffer) ;
* organizarea investițiilor prin corelarea spațială a resurselor .
Esența proiectului GIS este constituită de relațiile univoce dintre entitățile grafice (A) și atributele descriptive (B) asociate acestora.
Vom incepe cu componenta grafică a proiectului (fiind aceasta mult mai pretențioasă decât baza de date alfa-numerice , a cărei tratare este deja ardinară în informatică ) .
Deci, fondul graphic se poate compune din următoarele tipuri de entități :
– entități genetice ale
fondului graphic ,
Fig1.3
* puncte : reprezintă entitți punctiforme (simboluri) de pe plan/hatră (puncte de referința geografică și geodezică , puncte de măsurători locale , stâlpi , borne , stații de transformare , centre administrative );
* linii : succesiuni de segmente liniare constituind rețele filare ce apar în reprezentarea grafiică (hidrologică , de energie electrică , de telefonie , drumuri , căi ferate ) ;
* poligoane : conturi închise reprezentând entități caracterizate esențialmente de suprafața de sol ;
* etichete : texte ( denumiri , adnotări/note ) ;
* imagini : obținute prin scanarea hărților din arhivă sau prin aerofotografierea teritoriului modelat , acestea pot viza : delimitări administrative și parcelare , cartografierea formelor de relief , topografie , exploatări de resurse minerale , fenomene seismice .
Datele alfa-numerice reprezintă cumulul organizat și structurat de informații asaciate entităților grafice.Stratificarea entităților grafice :
Fig 1.4
Prin definiția de mai sus faceam distincția dintre “ hartă “ și “ plan “ în accepțiunea profesioniștilor fiind evidentǎ dependența acestei dijuncții terminologice de suprafațǎ considerate de proiectul / aplicația GID – cu cât zona este mai cuprinzǎtoare cu atât va trebui luatǎ in considerare sfericitatea scoarței.
Deși scara de reprezentare este crucialǎ in producerea de harți , planuri și alte documente cartografice , trebuie sǎ observǎm cǎ in exploatarea cotidianǎ a GIS-ului conceptual de “ scar” iși cam pierde din relevanțǎ. Afișarea compoziției cartografice pe monitor pentru analize cotidiene este una liberǎ din punct de vedere al scalǎrii și panoramǎrii – odatǎ cǎ ecranul nu poate fi considerat dimensional , apoi cǎ de obicei facem zoom –area liber si necuantificat.
Odata ce omenirea a acceptat faptul cǎ Terra nu este platǎ a inceput o nouǎ era privind “ modelarea “Pamântului. In foarte multe reprezentǎri se folosește de atunci sistemul de coordinate geografice exprimat in:
>> latitudine semnificând distanța unghiularǎ fațǎ de linia ecuatorialǎ , sper unul dintre polii geografici , nord sau sud.
>> longitudine referitoare la distanța unghiularǎ spre est/vest pe suprfața terestră.
Pentru eventualitatea în care cititorul nu este deplin familiarizat cu aceste concepte amintesc că latitudinea este “ marcată “ pe glob prin paralele , iar longitudinea prin meridiane.
In geodezie aceste coordonate sferice se măsoară usual prin unghiurile “ lambda “ și “ fi “.
Originea geometricǎ a acestui sistem de coordonate este localitatea britanicǎ Greenwich , unde s-a ales prin convenție meridianul 0 , constituind totodatǎ o referințǎ internatională pentru corelarea orei pe glob. Mai apoi ( 1715 -1885 ) , dovedindu-se cǎ planeta noastrǎ nu este sferica , și nici măcar elipsoidala , s-a generalizat denumirea de geoid și s-au manifestat mai multe modele de aproximare cât mai precisǎ a formei terestre.
Când se folosește mediul GIS la construirea de planuri / hărți se pornește de la câteva chestiuni elementare , actualmente încetațenite professional la noi in țaraǎ :
* Sistemul de axe de coordonate se prezintǎ astfel :
axa X este oreintatǎ spre Nord
axa Y este oreintatǎ spre Est
axa Z este oreintatǎ in sus
Notă : Observați , studiind vectorii acstor axe , că nu este un sistem cartezian , deoarece vectorul “ z “ nu se obține prin rotorul vectorilor “ x “ si “ y” ca în fizică / matematică.
* Planurile/ harțile conțin un simbol de “ Nord “ orientat spre punctul cardinal nord , adica indicând drecția pozitivǎ a axei X.
Generarea proiecției propriu-zise determina aspectul rețelei geodezice , deoarece alegerea suprafeței de proiecție afecteazǎ modul in care va apǎrea rețeaua de paralele/meridiane dupa proiectarea pe suprafața 2D.
1.1 Definiții
Geographical Information System (GIS) : “ Sistemul informatic geografic este acel sistem organizat pe baza tehnicii informatice – adică un ansamblu coerent constituit din echipamente de calcu (hardware) , programe (software) , informații , personae , reguli și metode de lucru – care permit , conceperea , definirea , construirea, actualizarea și exploatarea de hărți geo-topografice asociate cu informații descriptive cu repartiție teritorială ” [9].
Hartă : reprezentare grafică a unei zone de teren (teritoriu) , evidențiind atât elemente naturale (forme de relief , ape , aspecte biologice , fenomene climaterice ) , cât și elemente antropice (construite de om : drumuri , poduri , clădiri , rețele , baraje ) .
Împotriva deviațiilor semantice :
Dupǎ informațiile de mai sus am putea denumi “GIS” orice alcǎtuire coerentă de echipamente informatice și software având ca scop generarea , prelucrarea și exploaterea de informație referita geografic . Totuși în accepțiuna moderna , GIS înseamnă în primul rand un sistem de suport al deciziilor (DSS) , primind deci facilitațile de analiză asupra datelor.
Din păcate funcțională este și prejudecata de a spune GIS doar software –ului nucleu/platformă , neglijănd accentual care ar trebui să cadă pe colecția de date , fără de care aplicația GIS nu are sens .
GIS este acronimul în limba engleză pentru Sisteme Informaționale Geografice: Geographic Information Systems (SUA), Geographical Information Systems (Marea Britanie, Australia, Canada), Geographical Information Science (academic) [13].
„O formă particulară a Sistemelor Informatice aplicată datelor geografice…Un ansamblu de echipamente, programe și proceduri proiectat pentru stocarea, administrarea, manipularea, analiza, modelarea și vizualizarea datelor spațiale pentru rezolvarea problemelor de planificare complexă și administrare”
(Goodchild&Kamp 1990).
GIS-ul reprezintă combinarea administrării datelor cu conținut și indexare, reprezentării spațiale și a tehnicilor de analiză în scopul facilitării înțelegerii entităților lumii reale și a interacțiunilor dintre acestea.
1.2 Reprezentare GIS. Repere istorice.
Idea de a concentra în cadrul unei hărți diferite straturi tematice și fenomene geografice, a existat cu mult înainte de apariția calculatorului.
De exemplu harta bătăliei de la Yorktown (toamna anului 1781), creație a cartografului francez Louis-Alexandre Berthier, redă destul de bine traseele trupelor implicate în luptă.
În anul 1819, francezul Pierre Charles Dupin a întocmit prima hartă choropletă (redarea prin umbre a suprafețelor), ce redă distribuția și intensitatea analfabetismului în Franța, aceasta reprezentând, poate, prima hartă statistică modernă. [13]
Fig 1.1
La jumătatea secolului al XIX-lea, apare “Atlas to Accompany the Second report of the Irish Railway Commissioners”, ce redă pe aceeași hartă date despre populație, migrația acesteia precum și date geologice și topografice.
De asemenea doctorul John Snow a realizat o hartă pentru a reda locațiile deceselor cauzate de holeră din centrul Londrei, în anul 1854, pentru a identifica sursa contaminării, aceasta constituind un exemplu timpuriu de analiză geografică.
De-a lungul evoluției sale, din 1950 și pâna astăzi, putem observa 3 faze delimitate în funcție de aplicații, date și interacțiunea dintre utilizatori și furnizori (Crain și MacDonald, 1984).
Astăzi, GIS-ul este mult mai prietenos și nu mai este folosit doar de experți, el fiind utilizat și de geologi, ecologi, doctori, economiști, etc. Cu ajutorul lui se pot accesa, gestiona date în diferite formate și stocate în diferite locuri. Aplicațiile sunt în mare măsură axate pe gestionarea cat mai bună a diferitelor fenomene, și de luarea de decizii eficiente (Spatial Decision Support Systems) [13].
Iată și o schița a celor 3 etape în evoluția Sistemelor Informaționale Geografice:
Structura proiectului
Aplicația de față se bazează pe modelarea unei porțiuni tridimensionale din spațiul cu ajutorul sistemului de coordonate cartezian.
Astfel în prima parte a algoritmului, se generează o rețea grid în planul XoY, care se extinde la aceeași scară și pe celelalte două plane ale triedului.
În primul capitol am prezentat conceptul de hartă digitală precum și noțiunea de sistem geografic informatic (GIS) și modul de reprezentare al acestuia.
În capitolul doi am tratat formulele de lucru și sistemul de coordonate ale gridului 3D, metodele de lucru pentru înregistrarea datelor. De asemenea am făcut o scurt istoric al sistemului GPS cât și a dezvoltării acestuia pe parcursul evoluției până la forma actuală. Folosind noțiunea de GPS am descris sistemul de sateliți GPS ce orbitează deasupra Pământului.
În capitolul trei am prezentat modalitatea de proiectare și implementare a aplicațiilor pentru construcția de hărți digitale. Această proiectare și implementare parcurge mai multe etape dintre care amintim:
descrierea algoritmilor problemei;
descrierea scenelor grafice 2D cu ajutorul obiectelor grafice;
prezentarea coordonatelor omogene și a matricilor de transformare precum și a primitivelor grafice 2D.
Plecând de la cele descrise anterior am realizat transformarea din 2D în 3D raportându-ne la grafica 3D și primitivele acesteia, spațiul tridimensional și proiecțiile realizate în acest spațiu.
În ultima parte a acestui capitol am prezentat construcția unei hărți care acceptă puncte de reprezentare atât prin introducerea lor de la tastatură cât și prin colectarea automată de la sistemul GPS.
Capitolul patru descrie modalitatea de actualizare a hărților existente precum și colectarea automată a coordonatelor.
Capitolul cinci prezintă câteva concluzii legate de modul de implementare și funcționare al aplicației.
CAPITOLUL II
FUNDAMENTE TEORETICE
Crearea hărții virtuale are la bază formule matematice ce definesc primitive folosite în grafică. Pe lângă aceste formule mai întâlnim și o serie de transformări ce vor fi prezentate în cele ce urmează [3].
2.1 Ecuația dreptei
Ecuația dreptei determinată de două puncte M1(x1,y1), M2(x2,y2)) este:
:
Panta dreptei M1M2 este egală cu:
Unde :
-M1M2 este dreapta;
-M1(x1,y1) esti primul punct al dreptei;
-M2(x2,y2) adoi-lea punct al dreptei;
-m—panta dreptei dreptei in raport cu axa abciselor.
2.2.Formule de transformare a coordonatelor din 3D în 2D:
Să presupunem că vrem să desenăm o linie care are următoarele coordonate 3D: (x1, y1, z1, x2, y2, z2). Linia va trebui să fie desenată de la punctul (x1, y1, z1) la punctul (x2, y2, z2).
Limbajele de programare, în general, nu acceptă decât coordonate în x și y. In exemplul nostru va trebui să transformam (x1, y1, z1) în (rx1, ry1), respectiv (x2, y2, z2) în (rx2, ry2) [5].
Transformarea din 3D a unui punct într-un plan 2D (care în cele mai multe cazuri, va fi de tip ecran). This is the absolute basics you have to know before trying to code 3D effects.
Imaginați-vă că dorim să proiectam, un cub de pe un plan. If we want to draw the situation, it would look somewhat like this (note that the base we use has been rotated a bit): Dacă vrem să atragă situațiea, ar arata ceva de genul acesta :
The projection plane will in the end be the screen that the user sees.
Planele de proiecție în final vor fi de tip ecran pe care utilizatorul îl poate vedea. If we want to project a point of our cube on this plane according to the user's view , we'll need to intersect the line (= ray of light) between the point to project and the user's point of view with our projection plane. Dacă vrem sa punem un punct în proiecția cubului nostru , în funcția “view” a utilizatorului, vom avea nevoie de intersecția de linii între punctul proiectului și al utilizatorului din punctul nostru de proiecție cu planul. Let's call the point we want to project a , and the user's point of view b . Să numin punctul pe care vrem să îl proiectăm a, și punctual de plecare b, linia [ab] va intersecta proiecțiile planului nostru și punctul va fi numit a’. [7]
The projection plane will in the end be the screen tha
Metode de abordare
Since we are working in a 3 dimensional space, all points are represented by three co-ordinates (the x-coordinate, the y-coordinate and the z-coordinate). Deoarece lucrăm într-un spațiu 3 D, toate punctele sunt reprezentate de trei coordonate (x, y z). Our point a from the cube will have three coordinates, let's call them (x,y,z) .. To make the calculations a bit easier, we'll put the user in the point zero (exactly where the user belongs :). Pentru a face calculele un pic mai ușor, vom pune utilizatorul în punctul zero .
Planul de ecuație este:First of all, we'll need to define the plane we want to project everything on.planul z = valoare, în cazul în care valoarea este compensată de plan. Deoarece computerele pot lucra foarte usor, cu puteri de 2D, vom folosi plane z = 256 ca plan de proiecție (aceasta înseamnă că cel de-al treilea din toate punctele de coordonate în planul de proiecție este 256). There's also another reason why we choose 256, try changing the value to a bigger or lower value to see the result!. Exista de asemenea un alt motiv pentru care vom alege 256, încercați să schimbați la o valoare mai mare sau mai mică valoare pentru a vedea rezultatul; veți vedea că If the third coordinate of all points in the plane equals 256, then the coordinates of our point a' will look like (u,v,256) (the point a' has to lie in our projection plane, and all third coordinates of points in that plane arecel de-al treilea din toate punctele de coordonate în plan echivalează cu 256.In urma acestor calcule coordonatele din punctul nostru vor arăta (u, v, 256) .This means that we only have to look for two more coordinates ( u and v ). Aceasta înseamnă că vom arata mai mult de doua coordonate (u și v).
We can get those two coordinates by calculating the intersection point of the line [ab] with the plane z=256 . Avem posibilitatea de a obține cele două coordonate de calculare a punctului de intersecție de linie [ab] cu planul z = 256. First we need to define the line between two points: mathematically, the line [ab] is the collection of all points between the point a and the point b : În primul rând avem nevoie să se definească linia între două puncte: matematic, linia [ab] este o colecție de toate punctele dintre un punct și punctul b:
[ab] = {all points between a and b } [ab] = (toate punctele între A și B)
Without going into too much detail about the linear algebra, I'll tell you that the equation for a line is given as: Fără a pătrunde prea mult în detaliu despre algebra liniară, vă spun că ecuatia pentru o linie este:
[ab] = b + c * ( a – b ) [ab] = B + C * (a – b)
where c can be any real value. unde c poate fi orice valoare reală. We just described that all points have three coordinates, and a = (x,y,z) , b = (0,0,0) , so we could also say that the equation is: Am descris doar că toate au trei puncte de coordonate, și o = (x, y, z) iar b = (0,0,0), deci am putea spune de asemenea că ecuația este:
[ab] = (0,0,0) + c * (x – 0, y – 0, z – 0) [ab] = (0,0,0) + c * (x – 0, y – 0, Z – 0)
[ab] = (0,0,0) + c * (x, y, z) [ab] = (0,0,0) + c * (x, y, z)
[ab] = (0 + c*x , 0 + c*y , 0 + c*z) [ab] = (0 + c * x, 0 y + c *, 0 + c * z)
This means that a point (e,f,g) is on the line [ab] when a certain value c exists so that: Aceasta înseamnă că un punct (E, F, G) este pe linia [ab], atunci când o anumită valoare c există astfel încât:
(e,f,g) = ( c*x , c*y , c*z ) (E, F, G) = (c * x, y C *, C * z)
Our point a' = (u,v,256) also lies on the line [ab] , so we can say that there is a certain value for c so that: Punctul nostru de un '= (u, v, 256) se afla de asemenea, pe linia [ab], astfel încât să putem spune că există o anumită valoare pentru c :
(u,v,256) = ( c*x, c*y, c*z ) (u, v, 256) = (c * x, y C *, C * z)
This means that: Aceasta înseamnă că:
u = c * x u = c * x
v = c * y v = c * y
256 = c * z 256 = c * Z
This last equation allows us to find the value for c : Aceasta ultima ecuație ne permite sa găsim o valoare pentru c:
c = 256 / z c = 256 / z
So the coordinates of the point a' = (u,v,256) become: Deci coordonatele punctului de uv = (u, v, 256) devin:
(u,v,256) = ( x * 256 / z , y * 256 / z , 256 ) (u, v, 256) = (x * 256 / z, y * 256 / z, 256)
2.3. Primive grafice 2D
Cea mai micǎ unitate graficǎ pe care o putem controla din zona de desenare poartǎ denumirea de pixel.
Zona de desenare poate fi consideratǎ ca o matrice bidimensionalǎ de pixeli. Accesul la un pixel se face prin specificarea unei perechi de valori întregi (dcx, dcy) care
precizeazǎ poziția acestuia în matricea zonei de desenare, relativ la un sistem de coordonate având originea în colțul stânga sus.
Acest spațiu de adresare se numește spațiu dispozitiv (sau spatiu ecran) și definește rezoluția graficǎ a acestuia.
Zona de desenare este caracterizată prin:
a) numărul maxim de pixeli pe orizontală npo
b) numărul maxim de pixeli pe verticală npv
Considerând ca lungimea fizică a zonei de desenare (în mm) este lung, iar înaltimea fizica (în mm) este înalt, din aceste patru mărimi pot fi deduse o serie de mărimi derivate, care prezintă interes pentru proiectantul pachetelor de programe pentru grafică pe calculator:
rezoluția pe orizontală:
rez_o = npo / lung
dimensiunea unui punct pe orizontalǎ:
dim_po = lung / npo
rezoluția pe verticalǎ:
rez_v = npv / inalt
dimensiunea unui punct pe verticalǎ:
dim_pv = inalt / npv
numărul total de puncte adresabile (rezoluția):
rez = npv * npo
rezolutia bidimensionalǎ:
rez_a = re / (lung * înalt)
Rezoluțiile verticale, orizontale și bidimensionale reprezintǎ rezoluțiile fizice ale dispozitivelor grafice și presupun mǎsurǎri fizice ale distanțelor.
Mai multe echipamente pot avea aceeași rezoluție graficǎ, dar cu totul alte rezoluții fizice.
În general dimensiunile punctelor pe verticalǎ, respectiv pe orizontalǎ sunt diferite (dim_po <> dim_pv). Ca urmare, punctele din spațiul imagine au o anumitǎ suprafațǎ finitǎ, iar forma lor este dreptunghiularǎ.
Se definește raportul de aspect grafic ca raportul
aspect = dim_po / dim_pv
iar raportul de aspect fizic
aspect_fiz = inalt / lung
Este de dorit ca echipamentele grafice sǎ aiba puncte "patrate", adicǎ un raport de aspect grafic cât mai apropiat de 1.
Un pǎtrat vizualizat pe un astfel de achipament grafic va fi intr-adevar reprezentat de un pǎtrat in spațiul imagine. In general insǎ pǎtratul apare sub formǎ de dreptunghi, deoarece echipamentele grafice posedǎ, de cele mai multe ori, un raport de aspect grafic diferit de 1.
Sisteme de coordonate
Coordonate (dcx,dcy) se numesc coordonate hardware sau coordonate ale dispozitivului.
Desigur,
0 <= dcx <= npo1 = NPO-1
0 <= dcy <= npv1 = NPV-1
Domeniul de variatie al valorilor dcx, dcy este diferit pentru diversele dispozitive grafice. Pentru a asigura o tratare unitarǎ, independentǎ de dispozitivul grafic, în scopul asigurǎrii portabilitǎții aplicațiilor, s-au introdus coordonatele dispozitiv normalizate (NDC), care sunt valori reale in domeniul [0,1].
0 <= ndcx <= 1
0 <= ndcy <= 1
Punctul (ndcx=0;ndcy=0) poate corespunde punctului (dcx=0;dcy=0), iar punctul (ndcx=1;ndcy=1) poate corespunde punctului (dcx=npo1;dcy=npv1). Utilizând coordonatele normalizate, descrierea obiectelor grafice la nivelul aplicației va fi independentǎ de dispozitivele grafice particulare.
Transformarea intre cele doua sisteme de coordonate se poate face simplu, prin funcțiile liniare [6]:
dcx = round (ndcx * npo1)
dcy = round (ndcy * npv1)
La nivelul aplicației, elementele grafice se definesc într-un spețiu de coordonate carteziene al utilizatorului (spațiul utilizatorului). Acest spațiu poate fi spațiul euclidian (R2 sau R3). În cazul spațiului R2, obiectele se precizează prin coordonatele carteziene (x,y), cu valori reale.
Desigur, pentru a reprezenta pe ecran un obiect din spațiul utilizator, este necesarǎ transformarea coordonatelor sale în coordonate din spațiul imagine: (x,y) -> (dcx,dcy). În general, coordonate (xi,yi) ale punctelor din scenă grafică pot fi încadrate într-un spațiu dreptunghiular
xmin <= xi <= xmax
ymin <= yi <= ymax
Acest domeniu dreptunghiular din spațiul obiect se numește fereastră (window). Conținutul sǎu va fi transpus in ecran intr-un domeniu dreptunghiular din spațiul dispozitiv numit port de vedere (viewport), utilizând o serie de transformǎri de coordonate. În orice moment, este necesar sǎ fie definite o fereastrǎ și un port de vedere, definite de programul de aplicțtie și reținute în structurile interne ale pachetului grafic.
Implementare
În cadrul lucrǎrii se vor implementa proceduri și funcții necesare pentru realizarea urmǎtoarelor operații:
activarea unei ferestre grafice
definirea ferestrelor
definirea porturilor de vedere
corecția aspectului grafic
transformarea coordonatelor utilizator în coordonate ecran
trasarea segmentelor de dreapta în spațiul utilizator.
Aceste operații de bază se găsesc la nivelul cel mai scazut într-o abordare ierarhică a structurii unui pachet grafic. Ele se vor include în modulul G2D nucleu.
2.4 Grafică 3D
2.4.1 Spațiu tridimensional
Spațiul tridimensional este un mod al realitǎții specific creierului uman.
Descrierea obiectelor :
-alegerea sistemului de coordinate ;
-precizarea coordonatelor , punctelor representative ;
-prelucrarea tolopogiei ;
-verificarea planeitǎții dacǎ au mai mult de 3 vârfuri ;
-opțional pentru fiecare fațǎ pot fi definite atribute (culoarea) .
Alegerea tipului de proiecție , hotarâm asupra tipului de proiecție :
-ascendentǎ ;
-perspectiva descendentǎ ;
-perspectiva normalǎ ;
-perspectiva pentru tablouri , plane inclinate ;
-perspectiva pentru tablouri , plane verticale ;
-perspective covaliere ;
Determinarea coordonatei perspective :
*formulǎ a ecuatiei drepte intr-un plan
Punctul M0(x0 , y0) aparține dreptei (se afla pe dreapta )
(d) : y=mx+n ,
dacǎ coordonatele sale verifica ecuatia dreptei , adica y0=mx0+n
2.4.2. Primitive grafice 3D
Elementele grafice 3D pe care le vom utiliza sunt: punctul, segmentul de dreapta, poligonul.
Aceste elemente grafice definite in 3D vor fi reprezentate în spațul imagine 2D utilizând una din metodele de proiecție reprezentate.
Fiecarui element grafic va corespunde o procedurǎ de reprezentare numitǎ primitivǎ graficǎ.
Aceastǎ procedurǎ va converti coordonatele 3D în coordonate în planul 2D utilizând procedura de proiecție după care va apela, în general, primitivele grafice corespunzǎtoare din pachetul grafic 2D, G2D_NUCLEU.
De exemplu:
procedure linie_3D(x1,y1,z1, x2,y2,z2 : real);
var xp1,yp1,xp2,yp2 : real;
begin
proiectează (x1,y1,z1,xp1,yp1);
proiectează (x2,y2,z2,xp2,yp2);
linie_2d(xp1,yp1,xp2,yp2);
end;
De remarcat că apelul procedurii linie_2d asigurǎ totodatǎ secționarea (clipping) relativ la fereastra definitǎ în spațiul imagine (ecran) bidimensional.
Trasarea curbelor 3D se va realiza dupǎ aceleași principiu ca și curbele 2D adicǎ prin aproximarea curbei cu segmente de dreapta.
Pachetul grafic 3D care va fi dezvoltat în continuare apare ca un nivel superior al pachetului grafic 2D.
Clipping-ul obiectelor 3D se va realiza prin proiectarea obiectelor în planul ecranului iar apoi prin utilizarea procedurii de clipping 2D.
Toate funcțiile 2D puse la dispoziție de pachetul grafic 2D vor putea fi referite, operand in cadrul planului de proiecție (plan de vedere).
.Definiții:
Se numește element geometric de bazǎ o entitate geometricǎ simplǎ, necesarǎ în mod frecvent in descrierea șcenelor grafice. O realizare a unui element geometric de baza într-un sistem grafic (implementarea acestuia) se numește element grafic de bază.
Cele mai simple elemente grafice de bazǎ sunt: punctul, segmentul de dreapta, arcul de cerc, cercul.
Elementele grafice de bază sunt recunoscute de sistem fie prin ecuații analitice, fie printr-un set reprezentativ de puncte din care se pot deduce ecuații analitice. De exemplu, un cerc poate fi generat pe dispozitivul de ieșire pornind de la ecuația:
x2 + y2 = r2 sau precizând două puncte diametral opuse A(x1, y1) , B(x2, y2).
Pentru fiecare element grafic de bazǎ, în sistem este prevazutǎ o rutinǎ graficǎ (procedura) a cǎrei execuție poate produce imaginea sa pe dispozitivul de ieșire (ecran). Aceste rutine grafice vor fi numite în continuare primitive grafice de ieșire (pe scurt, primitive grafice).
Deoarece în procesul reprezentǎrii scenelor grafice aceste primitive se executa de un numǎr considerabil de ori (ele stand la baza celorlalte elemente grafice) este necesar ca ele sǎ fie realizate eficient din punct de vedere a timpilor de execuție.
Din acest considerent ele se implementeazǎ in limbaj de asamblare, utilizând algoritmi specializați. În cadrul lucrării vom considera ca primitivele grafice pentru punct și segmentul de dreapta sunt disponibile sub forma procedurilor PUTPIXEL și LINE din unitatea GRAPH. În afara acestor proceduri, vom defini și implementa rutine grafice pentru urmǎtoarele elemente grafice de bazǎ:
linia poligonalǎ
dreptunghiul
cercul
arcul de cerc
Acest set de primitive grafice poate fi extins dupǎ necesitǎți.
.Reprezentarea curbelor plane.
Implementarea primitivelor grafice poate porni de la ecuațiile analitice ale elementelor grafice de baza. Este doesebit de util ca sistemul grafic sǎ prevadǎ și procedura generalǎ pentru reprezentarea curbelor plane descrise analitic.
Ecuația unei curbe plane poate fi datǎ in una din formele:
a) forma explicitǎ y=f(x) in coordonate carteziene sau polare. În acest caz pentru fiecare valoare a lui x se poate gǎsi o singura valoare y. Curbele inchise sau cu mai multe variabile nu pot fi descrise printr-o singurǎ ecuație explicitǎ.
forma implicitǎ f(x, y)=0 descrie atat curbele deschise cât și pe cele închise sau cu mai multe ramuri, dar sunt dificil de utilizat.
forma parametricǎ, în care fiecare coordonatǎ a unui punct p(x, y) al curbei este datǎ ca o funcție dependentǎ de un parametru:
x=x(t)
y=y(t)
cu parametrul t în intervalul [a,b].
Vectorul de poziție al unui punct al curbei este
p(t) = [x(t), y(t)]
Reprezentarea parametricǎ a unui segment de dreapta definit de punctele P1(x1, y1) si P2(x2, y2) este:
P(t) = P1 + (P2 – P1)*t,
sau
x(t) = x1 + (x2 – x1)*t
y(t) = y1 + (y2 – y1)*t
cu t în intervalul [0,1]
iar pentru un cerc cu centrul în origine și raza R:
P(t) = [R*cos(t), R*sin(t)]
sau
x(t) = R*cos(t)
y(t) = R*sin(t)
cu t in [0,2PI].
Reprezentarea curbelor se poate face prin aproximare cu o secvență de segmente de dreapta. Aceste segmente sunt determinate de creșteri egale ale parametrului.
Numǎrul de segmente utilizate se alege ținând cont de aspectul grafic al imagini rezultate.
Procedura generala pentru trasarea curbelor parametrice are ca parametri cele două funcții care descriu ecuațiile:
x = x(t)
y = y(t)
și limitele variației parametrului.
2.4.3. Proiecții
Mediile pe care se pot reprezenta imaginile grafice sunt bidimensionale : ecranul unui display, plotterul, imprimantǎ.
Atunci când dorim sǎ vizualizǎm un obiect 3D este necesarǎ transformǎrii reprezentǎrii tridimensionale a obiectului într-o formǎ bidimensionala ce poate fi redatǎ pe mediul de reprezentare. Aceastǎ transformare poartă denumirea de proiecție.
O proiectie poate fi comparata cu umbra pe care o "aruncǎ" un obiect asupra unui perete. Modelul matematic utilizat pentru determinarea proiecției obiectului este insǎ mai simplu, pentru ca in graficǎ pe calculator atât obiectul cât și “peretele” pe care se obține umbra sunt imaginare.
Vom calcula proiecțiile tuturor punctelor obiectului, unele din acestea fiind insǎ invizibile în realitate. Îndepartarea acestor puncte este o problemă aparte în cadrul graficii asistate de calculator.
Spațiul tridimensional în care este definit un obiect real poartă denumirea de spațiu obiect și poate fi asimilat cu lumea înconjuratoare. Spațiul bidimensional pe care se proiectează obiectul poartă denumirea de spațiu imagine și poate fi asimilat cu ecranul calculatorului.
Un obiect este format dintr-o infinitate de puncte. Calcularea proiectiei fiecarui punct este practic imposibila.
Tipurile de proiecții pe care le vom considera in continuare au insǎ proprietatea ca segmentele de dreaptǎ 3D sǎ proiecteaza in segmente de dreaptǎ 2D.
Ca urmare proiecția unui segment de dreaptǎ poate fi obținutǎ proiectând cele 2 capete ale sale din spațiul obiect și apoi conectând cele doua puncte obținute in spațiul imagine.
Proiecțiile geometrice plane ale obiectelor sunt obtinute prin intersecția unor drepte numite proiectori cu un plan numit plan de proiecție.
Proiectorii sunt drepte duse dintr-un punct arbitrar numit centru de proiecție, prin fiecare punct al obiectului. Dacă centrul de proiecție este plasat într-un punct finit al spațiului rezultatul este o proiecție perspectivă.
Dacă centrul de proiecție este localizat la infinit, toți proiectorii sunt paraleli iar rezultatul este o proiecție paralelă.Pentru dezvoltarea ecuațiilor care descriu o proiecție este necesară introducerea unui sistem de coordonate în spațiul obiect.
Vom considera planul ecranului paralel cu planul xoy al sistemului de axe de coordonate. Pentru axa oz vom alege sensul dinspre observator, perpendicular pe planul xoy adică un sistem cartezian triortogonal stâng:
Fig 3.1
Coordonatele unui punct oarecare P vor fi (x,y,z) sau în coordonate omogene (x,y,z,1).
Vom presupune ca centrul de proiecție (pozitia ochiului observatorului) este fix plasat pe semiaxa oz negativǎ iar planul de proiecție perpendicular pe axa Oz (analog pentru proiectiile pe planele yoz si zox ).
Proiecția paralelă
Proiecția paralelǎ simuleazǎ umbra aruncatǎ pe un perete de un obiect iluminat de o sursǎ de luminǎ aflatǎ la mare distantǎ de aceastǎ (centrul de proiectie se afla la infinit). Proiecția paralelǎ a unui punct P(x,y,z) din spațiul obiect se obține trasând o dreaptǎ cu o anumitǎ direcție in spațiu prin acest punct.
Intersecția acestei drepte cu planul z=0 este proiecția punctului P. Unghiul dreptei de proiecție determinǎ proiectia in planul xOy care este și planul ecranului.
În forma parametricǎ un proiector pe direcția v(xp,yp,zp) are ecuațiile:
xu = x + u*xp
yu = y + u*yp
zu = z + u*zp
Punctele din planul xOy au zu=0 deci u= -z/zp iar coordonatele proiecției vor fi:
xp1 = x – z/zp*xp
yp1 = y – z/zp*yp
zp1 = 0
Dacǎ vectorul de proiecție este normal planului xOy avem xp=0, yp=0, zp=1 deci:
xp1 = x
yp1 = y
zp1 = 0
Aceste ecuații definesc proiecția ortograficǎ..
Proiecția ortograficǎ nu modificǎ lungimea liniilor paralele cu planul de proiecție. Punctele din spațiul obiect care au aceleași coordonate x și y au în aceeași proiecție.
Dacǎ dreptele de proiecție nu este paralela cu axa Oz se obține proiectia oblicǎ. Un exemplu este umbra aruncatǎ pe pamant de lumina solarǎ.
Aceastǎ proiecție se utilizeazǎ pentru desenarea umbrelor pe ecran dar nu si pentru corpuri deoarece ea produce distorsiuni nenaturale ale imaginilor.
Proiecția paralelǎ cu directiile xp, yp nenule va genera o proiecție oblicǎ. Coordonatele proiecției unui punct vor fi deci:
xobl = x – z/zp*xp
yobl = y – z/zp*yp
zobl = 0
Un caz special de proiectie oblica este proiectia cabinet. Aceasta utilizeaza un vector de proiectie ce formeaza cu axa Oz un unghi de aproximativ 26.6º. Dreptele paralele cu axa Oz vor fi proiectate dupa drepte la un unghi de 30º cu axa Ox. Directia proiectorilor este in acest caz: xp = 0.433, yp = 0.25 zp = -1
Proiecția perspectivǎ
Proiecția perspectivǎ produce imagini mult mai apropiate de modul în care sunt percepute obiectele reale de ochiul omului.
Centrul de proiecție corespunde poziției ochiului observatorului. Vom presupune cǎ centrul de proiecție se aflǎ în fața ecranului și este specificat în același sistem de coordonate pe care îl utilizǎm pentru descrierea obiectelor.
Poziția centrului de proiecție nu are nici o legaturǎ cu distanța fizicǎ realǎ a observatorului fațǎ de ecran.
Ecranul însuși se presupune a fi în punctul z=0 al sistemului de coordonate xoyz. Obiectul este astfel descris încat el sǎ fie poziționat în spatele ecranului, așa cum este vǎzut de observator.
Distanța centrului de proiecție fațǎ de ecran (z=0) se va da ca un numǎr pozitiv d.
Coordonatele centrului vor fi (0,0,-d).
Fig 3.2 Fig3.3
Un punct P(x,y,z) se proiecteazǎ în punctul P’(xps,yps) cu :
xps = d*x/(d+z)
yps = d*y/(d+z)
zps = 0
Presupunerea cǎ centrul proiecției se aflǎ pe axa Oz și nu este restrictivǎ, pentru că formulele pentru o proiecție perspectivǎ cu un alt centru și pe un alt plan pot fi obținute prin aplicarea transformărilor de vedere.
Transformǎrile planului de vedere vor aduce întotdeauna centrul de proiecție pe axa Oz. Este important însǎ ca planul de proiecție sǎ fie perpendicular pe axa Oz pentru a obține formule simple.
Ecranul calculatorului se considerǎ a fi parte a planului de proiecție. Zona rectangularǎ a ecranului pe care dorim sǎ reprezentǎm o imagine este un port de vedere. Dacǎ dorim sǎ aflǎm zona din spațiul ce poate fi reprezentat în portul de vedere, va trebui să trasăm drepte din centrul de proiecție prin cele 4 colțuri ale zonei ecran.
Aceste drepte vor constitui muchiile așa numitei piramide de vedere. Vârful acestei piramide va fi centrul de proiecție.
Volumul Cubului-extindere in 3D a proporției continue
O proporție continuǎ, definita prin trei numere a, b, c, poate sta la baza construcției unui corp în spațiu ( un paralelipiped).
Incercǎrile de a construi îÎnsǎ un asemenea corp s-au lovit de imposibilitatea rezolvǎrii pe cale graficǎ a unor ecuații de gradul trei.
Realizarea unei proporții ideale în "trei timpi" nu a fost luatǎ în considerare de cǎtre antici, aceștia considerând cǎ spațiul 3D este generat prin "dinamica planului (2D)". O încercare de depǎșire a impasului este atribuitǎ lui Platon, care remarcǎ importanța "mediatatii" în geometria în spațiu. Ideea este materializată de Hippocrate în rezolvarea problemei privind dublarea volumului unui cub dat:
sau (1)
În baza modelului clasic plan și depașind limitele rezolvarilor grafice, ne-am pus problema identificarii unui "volum de aur" si implicit un numǎr de aur atașat spațiului 3D.
În acest scop, definim paralelipipedul P(ABCDA'B'C'D'), fig.1, cu laturile bazei L, l și inalțimea h. Volumul acestui corp geometric este notat cu Vi.
Fig.3.5
Asemǎnator modului de generare a structurii de "aur" plane, se divide volumul Vi într-un paralelipiped având baza un pǎtrat Pi (Vpi) și se definește corpul rǎmas ca fiind complementarul lui Vpi (Vcpi), procesul repetându-se recursiv.
În baza modelului sugerat de divizarea unui dreptunghi de aur (modelul clasic) impunem urmǎtoarea relație cantitativǎ dintre parțile rezultate din aplicarea recurentǎ a acestei divizǎri:
(2)
care, explicitată în funcție de dimensiunile alese inițial L, h< l, devine:
(3)
respectiv:
(4)
Notând L/l = a si h/l = , din (4) rezultă:
(5)
Ecuația caracteristică :
(6)
are o singurǎ rădăcinǎ realǎ numitǎ de noi Numar de aur 3D (= 1,324717…) iar paralelipipedul astfel definit il numim Volumul de aur.
De remarcat faptul cǎ înalțimea h este media geometricǎ dintre L și l, fapt ce conferǎ structurii o unitate specialǎ, elementele paralelipipedului (L,h,l) fiind legate prin proporția continuǎ:
(7)
La același rezultat matematic se ajunge și prin alt mod de gândire. În locul operației de divizare a unei structuri particulare se pot alătura dupǎ o anumitǎ regulǎ, elemente identice structural: pătrate în cazul modelului clasic plan.
Astfel, dreptunghiul (Xn+1 ; Xn), format la limitǎ, dupǎ un numǎr infinit de adiții succesive de pǎtrate -(reprezentare grafica a generarii seriei lui Fibonacci)- permite definirea numǎrului de aur: = lim (Xn+1 / Xn)=1.618034… ; n->4. (fig.3.6).
Fig3.6
Procedand asemanator și înlocuind elementul generator: pătratul cu unul tridimensional: cubul, am definit construcția din fig 3 .7.
Fig3.7
Aceasta este imaginea geometrică a recurentei liniare de ordinul trei:
Xn+3 = Xn+1 + Xn (8)
pornită de la volumul inițial: X 0=1, X1 =1, X2 =1.
Recurența (8) are ecuația canonică:
X3 – X – 1 = 0 (9)
cu rǎdǎcinile:
(10)
unde:
(11)
Soluția relației (8) este:
(11)
unde C1, C2, C3 sunt constante reale ce se determină din condițiile inițiale ale relației (8). Ținând cont de faptul că > 1, rezultă:
(12)
În mod asemanator, studiile efectuate de noi au vizat identificarea de proprietați geometrice ale paralelipipedului de aur, proprietăți menite să și justifice denumirea de "Volum de Aur".
a) Considerând coordonatele unui colț al unui paralelipiped de aur: A0 (x0, y0, z0) și ținând cont că:
(13)
se pot determina coordonatele punctului Ag, centrul de convergenta al structurii generate prin divizare:
(14)
Ținind cont că verifica relația (6), expresia : se poate rescrie astfel:
(15)
Fig.3.8
b) Cu această notație, se determină coordonatele centrului de convergența în raport cu un referențial centrat în B (0, 0, 0) (fig.4). Față de această origine, coordonata xAg devine:
(16)
respectiv:
(17)
c) Punctul de convergență Ag și B (fig.5) formează două colțuri opuse ale unui nou paralelipiped de aur de laturi:
(18)
d) Continuând analiza structurii obținute prin divizarea paralelipipedului de aur, notam fiecare punct caracteristic de pe suprafata initiala cu cifre de la 0 la 23 (fig.5), respectand o anumită ordine impusă. Se remarca apariția într-o evoluție completă (6 faze) a unui numar de 24 puncte importante, situate pe suprafața corpului supus divizării.
Fig3.9
Considerăm centrul de convergenta Ag, ca fiind originea unui sistem de axe directoare. Prin unirea lui Ag cu cele 24 de puncte importante de pe suprafata paralelipipedului se obtin 24 de directii ce determina 12 drepte concurente în Ag și definesc un număr de 9 plane distincte.
Am demonstrat că punctele de tipul A6k+i (k=0, 1, 2, …,n si i=0,..,23) si A6(k+p)+i, p=k+1,…,n sunt coliniare (fig.3.10 si 3.11). Am studiat si proiectia structurii pe cele trei
plane principale ale sistemului triortogonal atasat paralelipipedului inițial.
Fig3.10 Fig.3.11
e) Punctele P1, P11, P14, P16, P20, P22,… sunt coplanare. Planul Q astfel definit, secționează paralelipipedul de aur și formează cu planul orizontal un unghi diedru de 55,5 grade.
El conține atât germenele Ag cât și diagonalele seriei de pătrate ce "infașoară" paralelipipedul (fig. 3.9).
Fig3.12 Fig3.13
(19)
f) Distanțele 1 Ag , 11 Ag , 14 Ag etc., formează o progresie geometrica cu rația:
1/. Ele definesc un sistem de 6 directii centrați în Ag, față de care se poate studia atat evolutia spiralei, cat si a paralelipipedului. Am demonstrat ca unghiul dintre două direcții consecutive este exact PI/3.
Am denumit planul Q : "plan director" date fiind proprietățile remarcabile pe care le are: el conține "cheia" întregii structuri ce poate fi generată prin simple proiecții într-un spațiu tridimensional orientat adecvat.
În concluzie:
precizăm că o serie numerică bazată pe o recurentă liniară având forma:
(20)
oricare ar fi L0,h0,l0, are proprietatea ca:
(21)
unde este cea mai mare radacina reala a ecuatiei canonice:
(22)
Dintre toate recurentele liniare de ordinul trei:
(23)
remarcabilǎ prin particularitǎțile structurii generate, este:
( 24)
ce permite delimitarea si studiul unei structuri geometrice de exceptie pe care am denumit-o Volumul de Aur. Valoarea=1.327717… este in spatiul 3D ceea ce =1.618034.. este pentru plan. Tabela de puncte, lista de poligoane, numele si atributele formeaza o structura de date care implementeaza un obiect grafic 3D.
La rândul lor corpurile formează o listă de corpuri componente ale unui grup de corpuri (scena grafica 3D). În această formă se pot descrie structuri ierarhice de corpuri și grupuri de corpuri de orice nivel.
În mod evident, pachetul grafic trebuie să pună la dispozitie un set de operații (proceduri și funcții) pentru crearea și manipularea acestor structuri de date, de exemplu:
preluarea descrierii obiectelor 3D din fișiere externe
salvarea descrierii obiectelor 3D din fișiere externe
reprezentarea grafică pe dispozitivele de ieșire
transformări geometrice
instanțierea obiectelor grafice 3D
Descrierea obiectelor se preia din fișiere text, realizate fie prin utilizarea unui editor de texte, fie ca urmare a operațiilor de salvare.
Aceste fișiere (având, de exemplu, extensia .SYM) pot avea structura următoare:
<nume_obiect>
<nr_puncte in tabela de puncte: n> <culoarea>
<tabela de puncte> {cate un punct pe o linie}
x1 y1 z1
x2 y2 z2
xn yn zn
<definitie poligon 1>
{sub forma p k i1 i2 i3 … ik}
<definitie poligon 2>
<definitie poligon m>
e {sfarsit definitie obiect}
Aceastǎ structurǎ poate fi repetatǎ in cadrul aceluiași fișier pentru mai multe corpuri. De exemplu pentru definirea unui cub cu un colț teșit, având latura de 10 unitǎți și centrul in punctul C(5,5,5), avem:
Fig.3.14
2.5. Sistemul GPS
este un sistem de navigare prin satelit bazat pe o retea de 24 sateliți plasați pe orbita de cǎtre Departamentul deApǎrare al Statelor Unite. Sistemul GPSa fost inițial realizat pentru aplicatii militare,insa in anii '80, Guvernul Statelor Unite a hotǎrât ca acest sistem sǎ fie disponibil pentru uz civil.
GPS (Global Positioning Sistem) este un sistem de pozitionare in spatiu cu ajutorul satelitilor [1].
Sectorul spațial include in prezent 24 de sateliți amplasați pe orbite la aproximativ 20 200 km de Pamant, cu o perioada de revolutie de aproximativ 12 ore.
Acesti sateliti sunt repartizati pe șase planuri, înclinate la aproximativ 55į fața de ecuator.
Dintre acestea, doar L1 poate fi folosită de către utilizatorii civili, L2 având doar utilizatori militari. Sectorul de control este alcătuit din cinci stații de control repartizate pe glob, dintre acestea Colorado Springs din S.U.A. fiind cea care controlează întregul sistem.
Determinarea distanței fața de satelit se face pe baza diferenței de timp necesare semnalului emis de satelit să ajungă la receptor.
Cunoscând intervalul de timp și viteza propagǎrii semnalului (viteza luminii), se poate determina distanța.Pentru a determina foarte precis intervalul de timp necesar semnalului emis de satelit sǎ ajungǎ la receptor, acesta din urma emite un semnal identic, care va fi decalat față de cel provenit de la satelit.
Acest decalaj se poate mǎsura foarte precis. Fiecare satelit poate fi identificat pe baza unui numar atribuit (PRN – Pseudo Random Number), numǎr care este inclus in semnalul radio emis (Botton et al., 1997). În prezent este metoda utilizabilǎ în mediu forestier.
În acest caz, distanța satelit-receptor este imparțitǎ într-un număr întreg de lungimi de undă și o fracțiune de lungime de undǎ.
Sateliții GPS transmit două semnale radio de putere joasǎ, denumite L1 si L2. Gps-ele civile folosesc frecvența L1 de 1575,42 MHz în bandă UHF. Semnalele sunt în spectrul vizibil, ceea ce inseamnǎ cǎ vor trece prin nori, sticlǎ, plastic, însǎ nu vor trece de majoritatea obiectelor solide (clădiri, munți, etc) [4].
Un semnal GPS conține trei biți de informație un cod pseudoaleator, date efemeride și date almanah.
Codul pseudoaleator este un simplu cod I.D., ce identifica satelitul care a transmis informația. Puțeti vizualiza acest cod în pagina sateliților de pe GPS-ul dvs. Garmin.
Datele efemeride, care sunt transmise în mod constant de către fiecare satelit, conțin informații importante despre starea satelitului, data și ora curentă. Această parte a semnalului este esențială pentru determinarea poziției curente.
Datele almanah comunică receptorului GPS unde anume ar trebui să se găsească fiecare satelit la un anumit moment al zilei. Fiecare satelit transmite date almanah conținând informații orbitale pentru acel satelit și pentru toți ceilalți sateliți din sistem.
Sateliții GPS inconjoară pământul de două ori pe zi, pe orbite foarte precis determinate și transmit semnale/informații către stațiile terestre.
Receptoarele GPS culeg aceste informații și folosesc triangulații pentru a calcula localizarea exactă a utilizatorului [10].
Mai exact, receptorul GPS compară timpii de transmisie a semnalului de la satelit și recepționare a acestuia.
Diferența de timp este folosită de către receptorul GPS pentru calculul distanței la care se găseste satelitul.
În continuare, folosind măsurători de distanță pentru mai mulți sateliți, receptorul poate determina localizarea exactă a utilizatorului și o afișează pe display.
Un receptor GPS trebuie să primească simultan semnale de la minimum trei sateliti pentru a putea calcula o poziție 2D (latitudine si longitudine) și track-ul.
Dacă receptorul culege informații de la patru sau mai mulți sateliți, poate calcula o poziție 3D (latitudine, longitudine si altitudine).
Odată determinată poziția exactă a utilizatorului, unitatea GPS poate calcula alte informații utile, cum ar fi viteza, cursul, directța de mișcare, distanța parcursă, distantă pâna la destinație, ora răsăritului și apusului și altele.
Precizia GPS Receptoarele GPS din ziua de azi sunt foarte precise, datorita tehnologiei "parallel multi-channel".
Receptoarele Garmin cu canale paralele culeg foarte rapid informația de la satelit de la prima pornire și memorează poziția astfel încat pot naviga cu succes chiar și în medii neprietenoase (de exemplu mediul urban, cu cladiri inalte).
Anumiți factori atmosferici sau surse de erori pot afecta buna funcționare a receptoarelor GPS. Receptoarele GPS au o precizie în jur de 15 metri.
Noile receptoare GPS cu capabilități WAAS (Wide Area Augmentation System) pot îmbunătăți precizia până la sub 3 metri. Nu sunt necesare abonamente sau taxe pentru a beneficia de WAAS.
De asemenea, utilizatorii pot beneficia de o mai bună precizie cu DGPS (Differential GPS), o tehnologie care corecteaza semnalul GPS pana la o precizie de 3-5 metri. Paza de Coastǎ a Statelor Unite oferǎ cel mai comun serviciu de corecție DGPS. Acest sistem constǎ dintr-o rețea de antene care capteazǎ semnalul GPS și retransmit un semnal corectat prin transmitatoare tip "beacon".
Pentru a receptiona acest semnal, utilizatorul trebuie sǎ aibǎ un receptor diferential și o antena "beacon" in plus fața de receptorul GPS.
2.5.1. Metode de lucru ale sistemului GPS
Metoda staticǎ.
Inregistrarea datelor se face in puncte bine localizate, în care operatorul instaleazǎ receptorul (pe un trepied) perioade de timp bine determinate (15 sec-3 min).
În acest caz, receptorul GPS inregistreaza în fiecare secundă (in general) o valoare (X, Y, Z), iar la sfârșit se obține media tuturor valorilor.
Metoda dinamicǎ
Înregistrarea datelor se face în deplasare. Receptorul înregistreazǎ la diferite intervale de timp (5 secunde, in general) câte o valoare (X, Y, Z), iar la sfârșit se obține o succesiune de puncte.
Metoda dinamicǎ "Stop and Go" Aceastǎ metodǎ este de fapt o imbinare a primelor douǎ metode. Operatorul se deplaseazǎ cu reeceptorul GPS din punct în punct pe traseul dorit, în fiecare punct staționandu-se o anumitǎ perioadǎ de timp. Aceastǎ metodǎ este cea mai indicatǎ in cazul utilizǎrii GPS-ului în pǎdure.
2.5.2. Sistemul de sateliti GPS
Cei 24 sateliți care formeazǎ sistemul GPS orbiteazǎ la circa 12.000 mile deasupra pǎmântului. Aceștia au o mișcare constantǎ, parcurgând douǎ orbite complete in mai puțin de 24 ore. Viteza de deplasare este de circa 7000 mile/orǎ.
Sateliții GPS sunt alimentați de energia solarǎ. Au baterii de back-up pentru a asigura buna funcționare în cazuri extreme (eclipse solare).
Pe fiecare satelit existǎ mici propulsoare ce asigurǎ direcția corecțǎ.
Iata cateva informatii interesante despre satelitii GPS (denumiti si NAVSTAR, numele oficial atribuit sistemului GPS de cǎtre Departamentul Apǎrǎrii din Statele Unite):
a) Primul satelit GPS a fost lansat pe orbită in 1978.
b) O constelație completǎ de 24 de sateliți a fost realizatǎ în 1994.
c) Fiecare satelit este construit pentru a funcționa circa 10 ani. În mod constant noi sateliți sunt construiți și lansați pe orbitǎ.
d) Un satelit GPS cântareste aproximativ 1 tonǎ și are o lungime de circa 5,6 metri cu panourile solare deschise.
e) Puterea transmitatorului este de numai 50 W.
Surse de erori pentru semnalul GPS
Factorii care pot degrada semnalul GPS și astfel pot afecta precizia sunt:
a) Întârzierile în ionosferă si troposferă – semnalul GPS este încetinit la trecerea prin atmosferǎ. Sistemul GPS folosește un model încorporat care calculeazǎ întarzierea medie pentru a corecta parțial acest tip de erori.
b) Reflexia semnalului – acest tip de eroare intervine atunci când semnalul GPS este reflectat de clădiri înalte sau suprafețe dure înainte de a ajunge la receptor. Aceasta duce la întarzieri și deci, erori.
c) Erori datorate ceasului receptorului – ceasul incorporat al receptorului nu este atât de precis ca ceasurile atomice de la bordul sateliților GPS. De aceea este posibilă apariția unor erori minime datorate decalajului de timp.
d) Erori orbitale – cunoscute si ca erori efemeride, sunt datorate inadvertentelor dintre pozițiile raportate ale sateliților.
e) Geometria sateliților , aceasta se refer la poziția relativă a sateliților la un moment dat. Geometria ideală a sateliților este atinsă atunci când sateliții se găsesc sub unghi cât mai mare unul față de celelalte.
Geometria nesatisfăcătoare este atinsă atunci când sateliții se găsesc în linie sau sunt grupați.
CAPITOLUL III
PROIECTAREA ȘI IMPLEMENTAREA APLICAȚIILOR PENTRU CONSTRUCȚIA DE HARȚI DIGITALE
Algoritmul problemei
Vertexurile din lista de poligoane se vor specifica într-o ordine inversă acelor de ceasornic atunci când se parcurge fațeta, privitǎ dinspre observator.
Pentru obținerea șcenelor dorite, corpurile trebuie poziționate în spațiu ceea ce implică transformǎri 3D asupra lor. Aceste transformǎri se pot realiza atât la nivel individual cât și ca grup.
Primul pas din implementarea a gridului il reprezintǎ desenarea chenarului :
g.DrawRectangle(pen, xStart, yStart, lungimeG3D, inaltimeG3D);
am desenat pentru inceput planul XOZ , plecând de la crearea
liniilor verticale :
În aceastǎ parte de cod trasez liniile verticale ale planului XOZ , de tip “pen” ce sunt situate între punctele “i” și “yo” , începand din punctual “ I , ystart ” ;
a liniilor orizontale:
Pentru cele orizontale trasarea liniilor se face între punctele “yStart si y0 “ în funcție de valoarea “pas” cu care se face scalarea gridului, iar variabila “nr” calculeazǎ numǎrul de celule pe axa X , numǎr ce este afișat pe interfața graficǎ.
Al doile-a mare pas pentru desenarea chenarului este acela de a face proiecția
planului YOZ desenând :
liniile verticale :
Aceastǎ parte de cod este similarǎ primului plan XOZ numai ca acum se deseneazǎ YOZ, liniile sunt tot de tip “pen” ce sunt situate între punctele “i” și “yo” , începând din punctul “xY , x0 ” ;
a liniilor orizontale :
Bucla iterativă traseazǎ linii folosind funcția “DrawLine ” ai cǎrei parametrii indicǎ punctul de start ca fiind “yStart” și punctul de sfârșit “ y0 “.
Fiind un grid 3 D avem nevoie și de o a treia axǎ :
planul YOX desenând :
liniile verticale
Pentru axa YOX trasarea se face in mod asemanator ca la celelalte doua axe
diferențele constând în parametrii buclei iterative ce se desfașoarǎ între x0 și lungimeG3D , unde vaiabila “pas” indicǎ valoarea cu care se face scalarea gridului , de ea depinzând numǎrul de linii care se trasează și distanța dintre ele.
și a liniilor orizontale :
Axa yoz este trasatǎ în același mod începând cu punctul yo pânǎ i-a o valoare calculatǎ cu expresia (înalțimeG3D + y0) / 2 .
Am desenat cele trei axe :
Pentru implementarea software a gridului 3D am folosit limbajul de nivel înalt C# ce aparține pachetului de dezvoltare Microsoft Visual Studio 2008 [12].
Un corp poliedral poate fi modelat ca o listǎ de fețele plane poligonale. Un corp ale cǎrui suprafete exterioare sunt curbe poate fi aproximat printr-o lista de poligoane generate pornind de la puncte ale suprafetei.
Aproximarea poate fi imbunatatita desigur prin marirea numarului de poligoane care "acopera" suprafata exterioara a corpului.
Aceasta forma de modelare a corpurilor poarta denumirea de reprezentare prin retea de poligoane (poligon-mesh).
Fiecare fațetǎ poligonalǎ planǎ a modelului corpului este definitǎ de o listǎ de puncte din spațiul obiect numita listǎ de vertex-uri, și de o serie de atribute precum vizibilitatea, culoarea, textura, etc.
Structurile de date necesare reprezentarii unui corp pot fi statice sau dinamice. In cele ce urmeaza vom prezenta o metoda de reprezentare care utilizeaza structuri de date statice.
Fiecarui corp component al unei scene grafice 3D i se asociaza o tabela de puncte care contine valorile coordonatelor x, y, z ale tuturor vertex-urilor care compun fatetele poligonale plane ale modelului. Aceste valori sunt date in general relativ la un sistem de coordonate propriu.
Fiecare fațetă poligonală va cita câte un index în tabela punctelor pentru fiecare vertex din componenta sa.
Identificarea unui corp se face printr-un nume simbolic. Vom considera ca atribute ale corpului culoarea și matricea de transformare.
Pentru a reprezenta punctele pe hartă aplicația trebuie să preia punctele cu cele trei dimensiuni: latitudine, longitudine și altitudine. Aceste puncte pot fi preluate fie de la utilizator prin introducerea de la tastatură fie din protocolul de tip NMEA generat de sietemul GPS.
Protocoalele NMEA sunt formate din linii ce definescu puncte, linii a căror structură este prezentată în cele ce urmează:
$GPGGA,123519,4807.038,N,01131.000,E,1,08,545.4,M,46.9,M,,*47
Unde:
GGA Global Positioning System Fix Data
123519 Ora 12:35:19 UTC
4807.038,N Latitudine 48 deg 07.038' N
01131.000,E Longitudine 11 deg 31.000' E
1 Fix quality: 0 = invalid
1 = GPS fix (SPS)
2 = DGPS fix
3 = PPS fix
4 = Real Time Kinematic
5 = Float RTK
6 = estimated (dead reckoning) (2.3 feature)
7 = Manual input mode
8 = Simulation mode
08 Numărul sateliților de la care primește date
545.4,M Altitudinea
46.9,M Înălțimea raportată la sistemul GPS și nivelul mării.
(empty field) timpul în secunde de la ultima actualizare
(empty field) ID-ul GPS-ului
*47 Datele de verificare, încep mereu cu *
În funcție de sateliții care furnizează date protocolul NMEA poate avea următorea configurație:
$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
Unde:
GSA Starea satelitului
A Selecția automată din 2D sau 3D (M = manual)
3 3D – valorile incluse: 1 = fără
2 = 2D
3 = 3D
04,05… PRNs of satellites used for fix (space for 12)
2.5 PDOP (diluția preciziei)
*39 datele de verificare, întotdeauan începe cu *
La apăsarea butonului încărcare manuală se apelează funcția button2_Click care realizează două lucruri:
setează variabila start2 în 1 ceea ce duce la citirea fișierului și afișarea punctelor pe grid;
deschide fișierul text pentru editare, cu scopul de a modifica coordonatele punctelor disponibile.
private void button2_Click(object sender, EventArgs e)
{
start2 = 1;
pictureBox1.Refresh();
System.Diagnostics.Process.Start("traseu1.txt");
}
Citirea automată a datelor de la sistemul GPS se face prin intermediul protocolului NMEA al cărui fișier este descris , dupa cum urmeaza:
–am declarat fișierul StreamReader care deschide deschide protocolul exp-NMEA din care citesc coordonatele, iar după aceea am declarat un string care va conține linia curentă pe care o citește din protocolul NMEA sub formă de șir de caractere.
–cât timp linia pe care o citește nu este 0, adică nu s-a ajuns la sfârșitul fișierului vom efectua:
– în temp1 copiez șirul de caracrere din linia curentă care începe la poziția 26 unde regăsim temp1 pentru latitudine(x) , temp 2 pentru longitudine(y) , temp3 pentru altitudine(z).
După ce copiem datele le vom converti din strind în double.
Odată ce le-am convertit voi face trecerea din 3d în 2d pentru a le putea scala și reprezenta , adică să le afișăm pe grid.
Pentru ca afișarea să fie automată am făcut un buton numit încărcare automată , iar când acesta este folosit va lua valoarea “1” ceea ce înseamnă că pe grid au fost afișate coordonatele
Codul următor implementează toți acești pași.
StreamReader s2 = File.OpenText("exp-NMEA.nmea");
string read1 = null;
string temp1, temp2, temp3;
//int x, y, z;
while ((read1 = s2.ReadLine()) != null)
{
temp1 = read1.Substring(26, 3);
temp2 = read1.Substring(39, 3);
temp3 = read1.Substring(52, 3);
if (read1[50] == ',')
if (read1[53] == ',')
temp3 = read1.Substring(51, 2);
else if (read1[50] == ',')
if (read1[54] == ',')
temp3 = read1.Substring(51, 2);
else temp3 = read1.Substring(52, 3);
coordonata1x = Convert.ToDouble(temp1);
coordonata1y = Convert.ToDouble(temp2);
coordonata1z = Convert.ToDouble(temp3);
pos1X = 0.7 * (coordonata1x – coordonata1y);
pos1Y = 0.7 * (0.7 * (coordonata1x + coordonata1y) + coordonata1z);
pos1X = (pos1X – 400) * 25;
pos1Y = (pos1Y – 100) * 1.2;
pos1X1 = Convert.ToInt32(pos1X);
pos1Y1 = Convert.ToInt32(pos1Y);
if (start == 1)
g.DrawEllipse(culoare1, pos1X1 + zoom_value, pos1Y1 – zoom_value, 3, 3);
}
s2.Close();
Formulele de transformare din 3D în 2D:
u = x * 256 / z
v = y * 256 / z
Unde :
-x,y,z-coordonatele punctului 3d;
-u si v coordonatele punctiu transformat din 3d in 2d;
-256 este valoarea punctului de intersectie pentru a desena un punct din 3d in 2d;
Codul care implementează aceste formule este următorul:
pos2X = 0.7 * (coordonata2x – coordonata2y);
pos2Y = 0.7 * (0.7 * (coordonata2x + coordonata2y) + coordonata2z);
pos2X1 = Convert.ToInt32(pos2X);
pos2Y1 = Convert.ToInt32(pos2Y);
Colectarea datelor
Colectarea manuală a datelor
Încărcarea manuală a datelor se face prin introducerea unor coordonate într-un fisier text , iar apoi se face citirea și afișarea acestora. Aceste coordonate pot fi date chiar de utilizator prin introducerea acestora de la tastatură.
Structura fișirului în care introducem datele manual are următoarea structură :
După transformarea datelor din 3d în 2d are loc afișarea punctelor folosind primitiva “DrawElipse”:
g.DrawEllipse(culoare2, pos2X1 + zoom_value, pos2Y1 – zoom_value, 3, 3);
Odată transformate datele și introduse în fisierul de mai sus ele vor fi reprezentate pe grid astfel:
Fig. grid 1
3.2.2. Colectarea automată
Pentru a reprezenta punctele pe hartă aplicația trebuie să preia punctele cu cele trei dimensiuni: latitudine, longitudine și altitudine. Aceste puncte pot fi preluate fie de la utilizator prin introducerea de la tastatură fie din fișierul de tip NMEA generat de sietemul GPS.
Fișierele NMEA sunt formate din linii ce definescu puncte, linii a căror structură este prezentată în cele ce urmează:
Colectarea automata a datelor :
-prin intermediul protocolului de tip NMEA ce provine de la GPS:
-* Preluarea automată a datelor din fișierul NMEA se face în următoarele etape:
– se deschide fișierul NMEA folosind următoarea instrucțiune
StreamReader s1 = File.OpenText("exp-NMEA.nmea");
-se citește fișierul linie cu linie până se ajunge la sfârșit
while ((read1 = s1.ReadLine()) != null)
– la fiecare linie se preiau coordonatele de latitudine, longitudine și înălțime prin crearea unui subșir de caractere ce conține valoarea respectivă.
temp1 = read1.Substring(26, 3);
temp2 = read1.Substring(39, 3);
temp3 = read1.Substring(52, 3);
-cele trei subșiruri ce conțin coordonatele sunt convertite în tipul de date double
coordonata1x = Convert.ToDouble(temp1);
coordonata1y = Convert.ToDouble(temp2);
coordonata1z = Convert.ToDouble(temp3);
coordonatele 3D sunt transformate în coordonate 2D și punctul va fi afișat pe grid.
Protocolul NMEA
Fig NMEA1
CAPITOLUL IV
TESTAREA ȘI EVALUAREA APLICAȚIEI
Acest capitol își propune să prezinte modul în care aplicația a fost testată și modul de evaluare a performanțelor aplicației.
Aplicația are ca scop desenarea unui hărți 3D pornind de la datele de intrare ce reprezintă coordonatele punctelor din care se compune harta. Aceste coordonate sunt oferite de către sistemul GPS, ele fiind prelucrate pentru a putea fi folosite în aplicația curentă.
Privind în ansamblu aplicația trebuie să fie capabilă să efectueze cel puțin două operații: actualizarea hărților existente și colectarea automată a coordonatelor.
Actualizarea hărților existente
Un criteriu important al performanței este posibilitatea aplicației de a actualiza harta imediat ce se operează modificări asupra datelor de intrare. Sistemul GPS creează un fișier de tip nmea în care salvează caracteristicile fiecărui punct prin care trece.
Dintre aceste caracteristici cele mai importante sunt latitudinea, longitudinea și înălțimea. Cele trei formează datele de intrare pentru fiecare punct ce va fi afișat pe hartă. Hărțile astfel create sunt stocate pentru reutilizare evitându-se astfel reconstrucția acestora de fiecare dată când se dorește lucrul cu ele.
Aplicația trebuie să fie capabilă să modifice aceste hărți stocate pentru a introduce noi puncte sau pentru a șterge din cele existente dacă sistemul GPS semnalizează modificări. Aplicația pe care am realizat-o dispune de această facilitate de a actualiza hărțile. De asemenea aplicația este capabilă și de colectarea automată a coordonatelor, facilitate ce va fi prezentată în cele ce urmează.
După cum am spus și în capitolul precedent că avantajul introducerii manuale este acela de a interveni cu noi reprezentări dacă între timp am continuat traseul sau dacă sistemul de coordonate tridimensional este folosit de exempul pentru reprezentarea sălilor de curs într-o facultate și între timp s-a mai adăugat o sală , acestea pot fi ușor adăugate de utilizator,fără a face noi măsurări.
Sistemul de coordonate tridimensional ”grid2” prezentat mai jos este continuarea după reactualizare a figurii „grid 1” reprezentată mai sus , acest traseu fiind efectuat pe raza orașului Pitești, cu plecare din cartierul Nord, trecând prin – cartier Trivale – Cornul Vânătorului – Băbana.
Fig. grid2
Introducerea automată a coordonatelor
Un alt avantaj al acestei aplicații este reprezentat de posibilitatea de colectare automată a datelor.
Această facilitate este se datorează în special faptului că datele de intrare (coordonatele) sunt citite direct din fișierul de tip nmea în care sistemul GPS înregistrează parametrii pentru fiecare punct.
Modul de de actualizare este simplu. El constă practic din următorii pași:
aplicația realizează un refresh la un interval de timp cu scopul de a verifica dacă datele din fișierul nmea au suferit modificări;
dacă sistemul GPS a realizat modificări asupra coordonatelor aplicația va citi din nou fișierul nmea și va prelua valorile actualizate;
noile valori sunt prelucrate, după care punctele sunt afișate pe hartă.
Testarea aplicației și în special a acestor două facilități s-a realizat prin colectarea datelor de pe teren și întocmirea unor hărți cu ajutorul datelor culese. Același lucru s-a realizat folosind aplicația care și-a efectuat propriile hărți. Comparând rezultatele s-a observat că aplicația noastră realizează hărți 3D în conformitate cu realitatea ele având aceleasi similitudini cu spatiul fizic reprezentat.
Pentru ca introducerea coordonatelor să fie una automată am facut un buton pe interfațas grafică a sistemului meu de coordonate numit „încărcare automată” iar prin apăsarea acestiua datele extrase de la receptorul meu GPS prezentate în figura „NMEA1” prezentată mai sus se vor afișa pe gridul meu . Traseul de mai jos reprezintă coordonate atâtintroduse manual adică cele de culoare verde cât și cele introduse automat adică cele de culoare roșie. Cele de culoare roșie reprezintă un traseu efectuat în timp real efectuat de mine în orașul Curtea de Argeș cu plecare din comuna Albești până aproape de barajul Vidraru.
Fig. grid3
Tot în timp real și reprezentat prin introducerea automată a coordonatelor , este efectuat și traseul reprezentat de mai jos odată cu protocolul NMEA din carea cesta a fost extras de la un recepror GPS.
Al doi-lea traseu este tot unul efectuat în timp real numai că acesta nu este unul efectuat cu mașina ci unul facut pas cu pas de către mine si reprezintă un traseu de munte numit „Valea lui Stan” ce este situat de-a lungul barajului Vidraru .
Fig. NMEA2
În figura de mai jos sunt reprezentate cele 2 trasee reprezentate prin „încărcarea automată”:
Fig grid4
În finalul testării aplicației mele vă voi prezenta cele trei trasee efectuate de mine , atât cele introduse automat (cele de culoare roșie) , cât și cele introduse manual (cele de culoare verde).
CAPITOLUL V
CONCLUZII
Prin acest proiect de diplomă ne-am propus să realizăm o aplicație care construiește hărți 3D. Motivația acestui proiect a reprezentat-o faptul că sistemele GPS sunt folosite pe scară largă și putem construi ușor hărți virtuale pentru diferite scopuri. Construcția hărților se face pe baza unor puncte ale căror coordonate ne sunt oferite de receptorul GPS.
Implementarea nu a fost una ușoară, pe parcurs ivindu-se mai multe probleme, cele mai importante fiind cele de parcurgere a traseului atât pe jos cât și cu mașina cât și cele legate de preluarea datelor de la receptorul GPS deoarece a trebuit să folosim mai multe programeluate de pe internet neștiind cum se lucrează cu acestea cât și reprezentarea acestora în formatul dorit. După studii și documentări am ajuns la concluzia că cel mai bine era să folosim protocolul nmea pentru a prelua date în timp real de la receptorul GPS. De asemenea am implementat un algoritm care transforma punctele din dimensiunea 3D în dimensiunea 2D pentru a reprezenta în mod fidel punctele pe harta virtuală.
Aplicația a fost realizată în C#, rularea ei necesitând un număr redus de resurse.
Ne propunem pe viitor să dezvoltăm și mai mult această aplicație astfel încât ea să ofere mult mai multe date despre punctele situate pe harta.
Comparând rezultatele s-a observat că aplicația noastră realizează hărți 3D în conformitate cu realitatea ele având caracteristicile fizice similare cu cele din realitate.
BIBLIOGRAFIE
[1] http://tycho.usno.navy.mil/gpsinfo.html
[2] http://www.arheotim.uvt.ro/documente%20pdf/Arheovest/1_2004/Micle%20a%201_2004.pdf
[3] http://labs.cs.utt.ro/labs/Graphics/html/EGC/Lucrarea3.html
[4] http://en.wikipedia.org/wiki/Global_Positioning_System
[5] http://www.cs.utt.ro/ro/Activitati/Curricula/Ingineri/AnIII/EGC_Babii.html
[6] http://www.catia.ro/tutoriale/3dsmax/morph/morph.htm
[7] http://www.designlaboratory.com/computing/tools/3d_to_2d_by_dxf.html
[8] http://www.ace.tuiasi.ro/~fleon/BVIA/GIS.pdf
[9] http://www.qlikinfo.com/GIS.htm
[10] http://en.wikipedia.org/wiki/Global_Positioning_System
[11] Ionita Silviu -”Grafica pe calculator . Note de curs”
[12] Charles Petzold – “Programare Windows cu C#”
[13] Mircea Băduț – „GIS-Sisteme informatice geografice”
ANEXA 1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.IO;
using System.Windows.Forms;
namespace GridGenerator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int zoom_value=0;
int val_scara=10000;
int pos1X1, pos1Y1;
int pos2X1, pos2Y1;
int start = 0;
int start2 = 0;
double pos1X;
double pos2X;
double pos1Y;
double pos2Y;
double coordonata1x;
double coordonata2x;
double coordonata1y;
double coordonata2y;
double coordonata1z;
double coordonata2z;
string fisier;
Stream strm;
StreamReader reader;
private void pictureBox1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
Brush rosu = new SolidBrush(Color.Red);
Font arial = new Font("Arial", 14);
g.DrawString(" X ", arial, rosu, 500, 181);
g.DrawString(" y ", arial, rosu, 5, 263);
g.DrawString(" z ", arial, rosu, 5, 3);
Pen pen = new Pen(Color.Gray, 1);
Pen penAxe = new Pen(Color.Blue, 3);
int xStart = 0;// coordX a gridului 3d
int yStart = 0;// coordY a gridului 3d
int inaltimeG3D = 400;
int lungimeG3D = 500;
// calcul pas
int pas = trackBar1.Value;
// calcul Centrul Gridului punct de coord (0,0,0)
int x0 = lungimeG3D / 4;
int y0 = inaltimeG3D / 2;
//int xY = (lungimeG3D – x0) / 2;
// 0. DESENEZ CHENAR
g.DrawRectangle(pen, xStart, yStart, lungimeG3D, inaltimeG3D);
// 1. DESENEZ PLAN XOZ
// desenez linii verticale |
int nr = -1;
for (int i = lungimeG3D / 2 – x0; i <= lungimeG3D; i = i + pas)
{
g.DrawLine(pen, i, y0, i, yStart);
nr++;
}
nr = -1;
// desenez linii orizontale –
for (int i = y0; i >= yStart; i = i – pas)
{
g.DrawLine(pen, x0, i, lungimeG3D, i);
nr++;
}
nr = ((inaltimeG3D + y0) / 2 – y0) / pas;
int rest = ((inaltimeG3D + y0) / 2 – y0) % pas;
int xY = x0 – nr * pas – rest;
label4.Text = "" + 1 + ":" + val_scara;
val_scara = 10100 – 100 * zoom_value;
// 2. DESENEZ PLAN YOZ
// desenez linii verticale |
int aux = y0;
for (int i = x0; i >= xY; i = i – pas)
{
g.DrawLine(pen, i, aux, i, yStart);
aux += pas;
}
// desenez linii orizontale –
for (int i = y0; i >= yStart; i = i – pas)
{
g.DrawLine(pen, xY, i + (inaltimeG3D + y0) / 2 – y0, x0, i);
}
Pen culoare1 = new Pen(Color.Red);
Pen culoare2 = new Pen(Color.Green);
Point p1 = new Point(50, 50);
Point p2 = new Point(51, 51);
//g.DrawLine(culoare1, p1, p2);
int line1 = 0;
int line2 = 0;
string read2 = null;
if (start2 == 1)
{
StreamReader s1 = File.OpenText("traseu1.txt");
while ((read2 = s1.ReadLine()) != null)
{
if (line2 == 0)
{
coordonata2x = Convert.ToDouble(read2);
}
else if (line2 == 1)
{
coordonata2y = Convert.ToDouble(read2);
pos1Y = Convert.ToInt32(coordonata2y);
}
else
{
coordonata2z = Convert.ToDouble(read2);
//pos = Convert.ToInt32(coordonatay);
}
line2++;
pos2X = 0.7 * (coordonata2x – coordonata2y);
pos2Y = 0.7 * (0.7 * (coordonata2x + coordonata2y) + coordonata2z);
pos2X1 = Convert.ToInt32(pos2X);
pos2Y1 = Convert.ToInt32(pos2Y);
if (line2 == 3)
{
g.DrawEllipse(culoare2, pos2X1 + zoom_value, pos2Y1 – zoom_value, 3, 3);
line2 = 0;
}
}
s1.Close();
}
StreamReader s2 = File.OpenText("exp-NMEA.nmea");
string read1 = null;
string temp1, temp2, temp3;
//int x, y, z;
while ((read1 = s2.ReadLine()) != null)
{
temp1 = read1.Substring(26, 3);
temp2 = read1.Substring(39, 3);
temp3 = read1.Substring(52, 3);
if (read1[50] == ',')
if (read1[53] == ',')
temp3 = read1.Substring(51, 2);
else if (read1[50] == ',')
if (read1[54] == ',')
temp3 = read1.Substring(51, 2);
else temp3 = read1.Substring(52, 3);
coordonata1x = Convert.ToDouble(temp1);
coordonata1y = Convert.ToDouble(temp2);
coordonata1z = Convert.ToDouble(temp3);
pos1X = 0.7 * (coordonata1x – coordonata1y);
pos1Y = 0.7 * (0.7 * (coordonata1x + coordonata1y) + coordonata1z);
pos1X = (pos1X – 400) * 25;
pos1Y = (pos1Y – 100) * 1.2;
pos1X1 = Convert.ToInt32(pos1X);
pos1Y1 = Convert.ToInt32(pos1Y);
if (start == 1)
g.DrawEllipse(culoare1, pos1X1 + zoom_value, pos1Y1 – zoom_value, 3, 3);
}
s2.Close();
// 3. DESENEZ PLAN YOX
// desenez linii verticale |
aux = xY;
for (int i = x0; i <= lungimeG3D; i = i + pas)
{
g.DrawLine(pen, i, y0, aux, (inaltimeG3D + y0) / 2);
aux += pas;
}
// desenez linii orizontale –
aux = x0;
for (int i = y0; i <= (inaltimeG3D + y0) / 2; i = i + pas)
{
g.DrawLine(pen, aux, i, lungimeG3D, i);
aux -= pas;
}
//4. DESENEZ AXE
//0X
g.DrawLine(penAxe, x0, y0, lungimeG3D, y0);
//OY
g.DrawLine(penAxe, x0, y0, xY, (inaltimeG3D + y0) / 2);
//OZ
g.DrawLine(penAxe, x0, y0, x0, yStart);
}
private void button1_Click(object sender, EventArgs e)
{
start = 1;
pictureBox1.Refresh();
}
private void trackBar1_ValueChanged(object sender, EventArgs e)
{
pictureBox1.Refresh();
}
private void pictureBox1_Click(object sender, EventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void trackBar1_Scroll(object sender, EventArgs e)
{
zoom_value = trackBar1.Value;
pictureBox1.Refresh();
}
private void button2_Click(object sender, EventArgs e)
{
start2 = 1;
pictureBox1.Refresh();
System.Diagnostics.Process.Start("traseu1.txt") } } }
Nmea Protocol
using System;
using System.Collections.Specialized;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
namespace GPS
{
public class NMEAProtocol
{
private const int NP_MAX_CMD_LEN = 8; // lungimea maxima (NMEA address)
private const int NP_MAX_DATA_LEN = 256; //
private const int NP_MAX_CHAN = 36; // numarul maxim de caractere
private const int NP_WAYPOINT_ID_LEN = 32; // lungimea maxima a sirului setului de coordonate
private NMEAState nState; private byte checksum; // Calculeaza NMEA
private byte receivedChecksum; // Calculeaza NMEA daca exista
private int index; // Index lovosit pentru date
private byte[] command; // NMEA comanda
private byte[] data; // NMEA data
// numarul de comanda NmEA primit (prezentat sau neprezentat)
public int CommandCount;
public GPGGAData GPGGA;
public GPGSAData GPGSA = new GPGSAData();
public GPGSVData GPGSV = new GPGSVData();
public GPRMBData GPRMB;
public GPRMCData GPRMC;
public GPZDAData GPZDA;
public NMEAProtocol()
{
command = new byte[NP_MAX_CMD_LEN];
data = new byte[NP_MAX_DATA_LEN];
}
public void ParseBuffer(byte[] buffer)
{
foreach(byte b in buffer)
{
ProcessNMEA(b);
}
return;
}
public void ProcessNMEA(byte btData)
{
switch(nState)
{
case NMEAState.NP_STATE_SOM :
if(btData == '$')
{
checksum = 0; index = 0; nState = NMEAState.NP_STATE_CMD;
}
break;
// Primeste comanda (Adresei NMEA)
case NMEAState.NP_STATE_CMD :
if(btData != ',' && btData != '*')
{
command[index++] = btData;
checksum ^= btData;
// Verifica comanda instalata
if(index >= NP_MAX_CMD_LEN)
{
nState = NMEAState.NP_STATE_SOM;
}
}
else
{
command[index] = (byte)'\0'; // incheie comanda
checksum ^= btData;
index = 0;
nState = NMEAState.NP_STATE_DATA; }
break;
case NMEAState.NP_STATE_DATA:
if(btData == '*')
{
data[index] = (byte)'\0';
nState = NMEAState.NP_STATE_CHECKSUM_1;
}
else {
if(btData == '\r')
{
data[index] = (byte) '\0';
ProcessCommand(EncodeToString( command), data);
nState = NMEAState.NP_STATE_SOM;
return;
}
checksum ^= btData;
data[index] = btData;
if(++index >= NP_MAX_DATA_LEN) // {
nState = NMEAState.NP_STATE_SOM;
}
}
break;
case NMEAState.NP_STATE_CHECKSUM_1:
if( (btData – '0') <= 9)
{
receivedChecksum = (byte)((btData – '0') << 4);
}
else
{
receivedChecksum = (byte)((btData – 'A' + 10) << 4);
}
nState = NMEAState.NP_STATE_CHECKSUM_2;
break;
case NMEAState.NP_STATE_CHECKSUM_2:
if( (btData – '0') <= 9)
{
receivedChecksum |= (byte)((btData – (byte)'0'));
}
else
{
receivedChecksum |= (byte)((btData – (byte)'A' + 10));
}
if(checksum == receivedChecksum)
{
ProcessCommand(EncodeToString(command), data);
}
nState = NMEAState.NP_STATE_SOM;
break;
default :
nState = NMEAState.NP_STATE_SOM;
break;
}
}
#region INMEAProtocol Members
public void ProcessGPRMB(GPRMBData gprmc)
{
}
public void ProcessGPZDA(GPZDAData gpzda)
{
}
public void ProcessGPRMC(string data)
{
string[] fields = Regex.Split(data, ",");
//Timp: Ore, Minute, Secunde
GPRMC.Hour = Convert.ToInt32(fields[0].Substring(0, 2));
GPRMC.Minute = Convert.ToInt32(fields[0].Substring(2, 2));
GPRMC.Second = Convert.ToInt32(fields[0].Substring(4, 2));
GPRMC.Day = Convert.ToInt32(fields[8].Substring(0, 2));
GPRMC.Month = Convert.ToInt32(fields[8].Substring(2, 2));
GPRMC.Year = Convert.ToInt32(fields[8].Substring(4, 2));
GPRMC.DataValid = Convert.ToChar(fields[1]);
//Latitudine
GPRMC.Latitude = Convert.ToDouble(fields[2]) / 100;
if (fields[3] == "S")
GPRMC.LatitudeHemisphere = Cardinal.South;
else
GPRMC.LatitudeHemisphere = Cardinal.North;
//Longitudine
GPRMC.Longitude = Convert.ToDouble(fields[4]) / 100;
if (fields[5] == "E")
GPRMC.LatitudeHemisphere = Cardinal.East;
else
GPRMC.LatitudeHemisphere = Cardinal.West;
GPRMC.GroundSpeed = Convert.ToDouble(fields[6]);
GPRMC.Count++;
}
public void ProcessGPGSV(string data)
{
string[] fields = Regex.Split(data,",");
uint totalNumberOfMessages = Convert.ToUInt32(fields[0]);
//ne asiguram ca data este valida. Tipul valid este 1..8 if ((totalNumberOfMessages > 8) || (totalNumberOfMessages <= 0))
return;
GPGSV.TotalNumberOfMessages = totalNumberOfMessages;
//numarul mesajului
int nMessageNumber = Convert.ToInt32(fields[1]);
//asibgura-te ca este 0..9 if ((nMessageNumber > 9) || (nMessageNumber < 0))
return;
//satelitul este conectat(in raza vizuala)
GPGSV.SatellitesInView = Convert.ToInt32(fields[2]);
for (int iSat = 0; iSat < 4; iSat++)
{
Satellite sat = new Satellite();
sat.Id = Convert.ToInt32(fields[3+iSat*4]);
sat.Elevation = Convert.ToInt32(fields[4+iSat*4]);
sat.Azimuth = Convert.ToInt32(fields[5+iSat*4]);
sat.SignalQuality = Convert.ToInt32(fields[6+iSat*4]);
sat.Used = IsSatelliteUsed(sat.Id);
GPGSV.Satellites.Add(sat);
}
GPGSV.Count ++;
}
private bool IsSatelliteUsed(int satelliteId)
{
if(null == GPGSA.SatsInSolution) return false;
foreach(int satId in GPGSA.SatsInSolution)
{
if (satId == satelliteId) return true;
}
return false;
}
public void ProcessGPGSA(string data)
{
try
{
string[] fields = Regex.Split(data, ",");
GPGSA.Mode = Convert.ToChar(fields[0]);
GPGSA.mFixMode = Convert.ToByte(fields[1]);
GPGSA.SatsInSolution = new int[12];
for (int i = 2; i <= 13; i++)
{
int satId = -1;
if (int.TryParse(fields[i], out satId))
{
if (satId != -1)
{
GPGSA.SatsInSolution[i – 2] = satId;
}
}
}
GPGSA.PDOP = Convert.ToDouble(fields[14]);
GPGSA.HDOP = Convert.ToDouble(fields[15]);
GPGSA.VDOP = Convert.ToDouble(fields[16]);
GPGSA.Count++;
}
catch (Exception e)
{
System.Diagnostics.Trace.WriteLine("Chaos in ProcessGPGSA! " + e.ToString());
}
}
public void ProcessGPGGA(string data)
{
try
{
string[] fields = Regex.Split(data,",");
//Timp: Ore, Minute, Secunde
//Time is Zulu
GPGGA.Hour = Convert.ToInt32( fields[0].Substring(0,2));
GPGGA.Minute = Convert.ToInt32(fields[0].Substring(2,2));
GPGGA.Second = Convert.ToInt32(fields[0].Substring(4,2));
//Latitudine
GPGGA.Latitude = Convert.ToDouble(fields[1])/100;
if(fields[2]=="S")
GPGGA.LatitudeHemisphere = Cardinal.South;
else
GPGGA.LatitudeHemisphere = Cardinal.North;
//Longitudine
GPGGA.Longitude = Convert.ToDouble(fields[3])/100;
if(fields[4]=="E")
GPGGA.LatitudeHemisphere = Cardinal.East;
else
GPGGA.LatitudeHemisphere = Cardinal.West;
//Semnalul GPS-ului este de calitate
GPGGA.GPSQuality = (GPSQuality)Convert.ToUInt32( fields[5] );
//Satelitii
GPGGA.NumberOfSatellitesInUse = Convert.ToInt32(fields[6]);
GPGGA.HDOP = Convert.ToDouble( fields[7] );
//Altitudine
GPGGA.Altitude = Convert.ToDouble(fields[8]);
//mareste numarul mesajelor
GPGGA.Count ++;
}
catch(Exception e)
{
System.Diagnostics.Trace.WriteLine("Chaos in ProcessGPGGA! " + e.ToString());
}
}
public bool IsSatUsedInSolution(int SatelliteID)
{
return IsSatelliteUsed(SatelliteID);
}
public void Reset()
{
}
private string EncodeToString(byte[] buffer)
{
string s = System.Text.ASCIIEncoding.GetEncoding(1252).GetString(buffer);
string[] strings = s.Split('\0');
return strings[0];
}
public void ProcessCommand(string sCmd, byte[] bData)
{
string data = EncodeToString(bData);
switch(sCmd)
{
case "GPGGA":
ProcessGPGGA(data);
break;
case "GPGSA":
ProcessGPGSA(data);
break;
case "GPGSV":
ProcessGPGSV(data);
break;
case "GPRMC":
ProcessGPRMC(data);
break;
case "GPRMB":
break;
case "GPZDA": break;
default:
break;
}
CommandCount = CommandCount + 1;
}
#endregion
}
}
Aici introduc datele pentru a putea fi ciitite
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
using System.IO.Ports;
using GPS;
namespace GPSClient
{
public class MainForm : System.Windows.Forms.Form
{
public NMEAProtocol protocol = new NMEAProtocol();
public SerialPort port = new SerialPort();
System.Text.Encoding encoding = System.Text.ASCIIEncoding.GetEncoding(1252);
private System.Windows.Forms.TabControl tabControl1;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.TabPage tabPage4;
private System.Windows.Forms.Button connectButton;
private System.Windows.Forms.ListBox COMlistBox;
private System.Windows.Forms.Button disconnectButton;
private System.Windows.Forms.Timer timer1;
private System.Windows.Forms.TextBox NMEAText;
private System.Windows.Forms.CheckBox dumpRawDataCheck;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label labelLatitude;
private System.Windows.Forms.Label labelLongitude;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label labelAltitude;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.Label labelTime;
private System.Windows.Forms.ListBox listGPSQuality;
private System.Windows.Forms.ColumnHeader IdColumn;
private System.Windows.Forms.ColumnHeader ElevationColumn;
private System.Windows.Forms.ColumnHeader AzimuthColumn;
private System.Windows.Forms.ColumnHeader UsedColumn;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.Label label6;
private System.Windows.Forms.Label labelSatellitesInView;
private System.Windows.Forms.ListView listSatellites;
private System.Windows.Forms.PictureBox picSats;
private Label labelFixMode;
private Label label5;
private Label labelVDOP;
private Label label12;
private Label labelHDOP;
private Label label10;
private Label labelPDOP;
private Label label8;
private Label labelDataValid;
private Label label9;
private Label label7;
private Label labelDate;
private Label label11;
private Label labelTimeLocal;
private Label label13;
private System.ComponentModel.IContainer components;
public MainForm()
{
InitializeComponent();
}
/// <summary>
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Windows Form Designer generated code
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.picSats = new System.Windows.Forms.PictureBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.labelSatellitesInView = new System.Windows.Forms.Label();
this.label6 = new System.Windows.Forms.Label();
this.listSatellites = new System.Windows.Forms.ListView();
this.IdColumn = new System.Windows.Forms.ColumnHeader();
this.ElevationColumn = new System.Windows.Forms.ColumnHeader();
this.AzimuthColumn = new System.Windows.Forms.ColumnHeader();
this.UsedColumn = new System.Windows.Forms.ColumnHeader();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.label11 = new System.Windows.Forms.Label();
this.labelTimeLocal = new System.Windows.Forms.Label();
this.label7 = new System.Windows.Forms.Label();
this.labelDate = new System.Windows.Forms.Label();
this.labelDataValid = new System.Windows.Forms.Label();
this.label9 = new System.Windows.Forms.Label();
this.labelVDOP = new System.Windows.Forms.Label();
this.label12 = new System.Windows.Forms.Label();
this.labelHDOP = new System.Windows.Forms.Label();
this.label10 = new System.Windows.Forms.Label();
this.labelPDOP = new System.Windows.Forms.Label();
this.label8 = new System.Windows.Forms.Label();
this.labelFixMode = new System.Windows.Forms.Label();
this.label5 = new System.Windows.Forms.Label();
this.listGPSQuality = new System.Windows.Forms.ListBox();
this.labelLatitude = new System.Windows.Forms.Label();
this.label1 = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.labelLongitude = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.labelAltitude = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.labelTime = new System.Windows.Forms.Label();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.dumpRawDataCheck = new System.Windows.Forms.CheckBox();
this.NMEAText = new System.Windows.Forms.TextBox();
this.tabPage4 = new System.Windows.Forms.TabPage();
this.label13 = new System.Windows.Forms.Label();
this.COMlistBox = new System.Windows.Forms.ListBox();
this.connectButton = new System.Windows.Forms.Button();
this.disconnectButton = new System.Windows.Forms.Button();
this.timer1 = new System.Windows.Forms.Timer(this.components);
this.tabControl1.SuspendLayout();
this.tabPage3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.picSats)).BeginInit();
this.groupBox1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage4.SuspendLayout();
this.SuspendLayout();
this.tabControl1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage4);
this.tabControl1.Location = new System.Drawing.Point(13, 13);
this.tabControl1.Name = "tabControl1";
this.tabControl1.SelectedIndex = 0;
this.tabControl1.Size = new System.Drawing.Size(700, 450);
this.tabControl1.TabIndex = 0;
this.tabPage3.Controls.Add(this.picSats);
this.tabPage3.Controls.Add(this.groupBox1);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Size = new System.Drawing.Size(692, 424);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Satellite Tracking";
this.picSats.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.picSats.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(128)))), ((int)(((byte)(128)))), ((int)(((byte)(255)))));
this.picSats.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.picSats.Location = new System.Drawing.Point(10, 11);
this.picSats.Name = "picSats";
this.picSats.Size = new System.Drawing.Size(407, 401);
this.picSats.TabIndex = 2;
this.picSats.TabStop = false;
this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Right)));
this.groupBox1.Controls.Add(this.labelSatellitesInView);
this.groupBox1.Controls.Add(this.label6);
this.groupBox1.Controls.Add(this.listSatellites);
this.groupBox1.Location = new System.Drawing.Point(423, 11);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(260, 401);
this.groupBox1.TabIndex = 1;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "Satellite Details";
this.labelSatellitesInView.AutoSize = true;
this.labelSatellitesInView.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelSatellitesInView.Location = new System.Drawing.Point(99, 24);
this.labelSatellitesInView.Name = "labelSatellitesInView";
this.labelSatellitesInView.Size = new System.Drawing.Size(10, 13);
this.labelSatellitesInView.TabIndex = 3;
this.labelSatellitesInView.Text = "0";
this.label6.AutoSize = true;
this.label6.Location = new System.Drawing.Point(8, 24);
this.label6.Name = "label6";
this.label6.Size = new System.Drawing.Size(85, 13);
this.label6.TabIndex = 2;
this.label6.Text = "Satellites in View:";
this.label6.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.listSatellites.AllowColumnReorder = true;
this.listSatellites.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.listSatellites.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.IdColumn,
this.ElevationColumn,
this.AzimuthColumn,
this.UsedColumn});
this.listSatellites.FullRowSelect = true;
this.listSatellites.Location = new System.Drawing.Point(6, 41);
this.listSatellites.Name = "listSatellites";
this.listSatellites.Size = new System.Drawing.Size(248, 354);
this.listSatellites.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.listSatellites.TabIndex = 0;
this.listSatellites.View = System.Windows.Forms.View.Details;
this.IdColumn.Text = "Satellite Id";
this.IdColumn.Width = 81;
//
this.ElevationColumn.Text = "Elevation";
this.ElevationColumn.Width = 52;
this.AzimuthColumn.Text = "Azimuth";
this.AzimuthColumn.Width = 51;
this.UsedColumn.Text = "In-use";
this.UsedColumn.Width = 45;
this.tabPage2.Controls.Add(this.label11);
this.tabPage2.Controls.Add(this.labelTimeLocal);
this.tabPage2.Controls.Add(this.label7);
this.tabPage2.Controls.Add(this.labelDate);
this.tabPage2.Controls.Add(this.labelDataValid);
this.tabPage2.Controls.Add(this.label9);
this.tabPage2.Controls.Add(this.labelVDOP);
this.tabPage2.Controls.Add(this.label12);
this.tabPage2.Controls.Add(this.labelHDOP);
this.tabPage2.Controls.Add(this.label10);
this.tabPage2.Controls.Add(this.labelPDOP);
this.tabPage2.Controls.Add(this.label8);
this.tabPage2.Controls.Add(this.labelFixMode);
this.tabPage2.Controls.Add(this.label5);
this.tabPage2.Controls.Add(this.listGPSQuality);
this.tabPage2.Controls.Add(this.labelLatitude);
this.tabPage2.Controls.Add(this.label1);
this.tabPage2.Controls.Add(this.label2);
this.tabPage2.Controls.Add(this.labelLongitude);
this.tabPage2.Controls.Add(this.label3);
this.tabPage2.Controls.Add(this.labelAltitude);
this.tabPage2.Controls.Add(this.label4);
this.tabPage2.Controls.Add(this.labelTime);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Size = new System.Drawing.Size(594, 424);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Summary";
this.label11.Location = new System.Drawing.Point(284, 64);
this.label11.Name = "label11";
this.label11.Size = new System.Drawing.Size(116, 24);
this.label11.TabIndex = 15;
this.label11.Text = "Local DateTime:";
this.label11.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.labelTimeLocal.AutoSize = true;
this.labelTimeLocal.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelTimeLocal.Location = new System.Drawing.Point(409, 64);
this.labelTimeLocal.Name = "labelTimeLocal";
this.labelTimeLocal.Size = new System.Drawing.Size(26, 13);
this.labelTimeLocal.TabIndex = 16;
this.labelTimeLocal.Text = "N/A";
this.label7.Location = new System.Drawing.Point(328, 40);
this.label7.Name = "label7";
this.label7.Size = new System.Drawing.Size(72, 24);
this.label7.TabIndex = 13;
this.label7.Text = "Date (Zulu):";
this.label7.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.labelDate.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelDate.Location = new System.Drawing.Point(409, 40);
this.labelDate.Name = "labelDate";
this.labelDate.Size = new System.Drawing.Size(120, 24);
this.labelDate.TabIndex = 14;
this.labelDate.Text = "N/A";
this.labelDataValid.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelDataValid.Location = new System.Drawing.Point(144, 188);
this.labelDataValid.Name = "labelDataValid";
this.labelDataValid.Size = new System.Drawing.Size(184, 24);
this.labelDataValid.TabIndex = 12;
this.labelDataValid.Text = "N/A";
this.label9.AutoSize = true;
this.label9.Location = new System.Drawing.Point(73, 188);
this.label9.Name = "label9";
this.label9.Size = new System.Drawing.Size(55, 13);
this.label9.TabIndex = 11;
this.label9.Text = "Data Valid:";
this.labelVDOP.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelVDOP.Location = new System.Drawing.Point(144, 164);
this.labelVDOP.Name = "labelVDOP";
this.labelVDOP.Size = new System.Drawing.Size(184, 24);
this.labelVDOP.TabIndex = 10;
this.labelVDOP.Text = "N/A";
this.label12.AutoSize = true;
this.label12.Location = new System.Drawing.Point(92, 164);
this.label12.Name = "label12";
this.label12.Size = new System.Drawing.Size(36, 13);
this.label12.TabIndex = 9;
this.label12.Text = "VDOP:";
this.labelHDOP.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelHDOP.Location = new System.Drawing.Point(144, 139);
this.labelHDOP.Name = "labelHDOP";
this.labelHDOP.Size = new System.Drawing.Size(184, 24);
this.labelHDOP.TabIndex = 8;
this.labelHDOP.Text = "N/A";
this.label10.AutoSize = true;
this.label10.Location = new System.Drawing.Point(92, 139);
this.label10.Name = "label10";
this.label10.Size = new System.Drawing.Size(37, 13);
this.label10.TabIndex = 7;
this.label10.Text = "HDOP:";
this.labelPDOP.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelPDOP.Location = new System.Drawing.Point(144, 112);
this.labelPDOP.Name = "labelPDOP";
this.labelPDOP.Size = new System.Drawing.Size(184, 24);
this.labelPDOP.TabIndex = 6;
this.labelPDOP.Text = "N/A";
this.label8.AutoSize = true;
this.label8.Location = new System.Drawing.Point(92, 112);
this.label8.Name = "label8";
this.label8.Size = new System.Drawing.Size(36, 13);
this.label8.TabIndex = 5;
this.label8.Text = "PDOP:";
//
// labelFixMode
//
this.labelFixMode.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelFixMode.Location = new System.Drawing.Point(144, 88);
this.labelFixMode.Name = "labelFixMode";
this.labelFixMode.Size = new System.Drawing.Size(184, 24);
this.labelFixMode.TabIndex = 4;
this.labelFixMode.Text = "N/A";
this.label5.AutoSize = true;
this.label5.Location = new System.Drawing.Point(79, 88);
this.label5.Name = "label5";
this.label5.Size = new System.Drawing.Size(49, 13);
this.label5.TabIndex = 3;
this.label5.Text = "Fix Mode:";
this.listGPSQuality.Enabled = false;
this.listGPSQuality.FormattingEnabled = true;
this.listGPSQuality.Items.AddRange(new object[] {
"Fix Not Available",
"GPS SPS Mode",
"Differential, GPS SPS Mode, FixValid",
"GPS PPSMode, Fix Valid"});
this.listGPSQuality.Location = new System.Drawing.Point(329, 90);
this.listGPSQuality.Name = "listGPSQuality";
this.listGPSQuality.Size = new System.Drawing.Size(231, 17);
this.listGPSQuality.TabIndex = 2;
this.labelLatitude.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelLatitude.Location = new System.Drawing.Point(144, 16);
this.labelLatitude.Name = "labelLatitude";
this.labelLatitude.Size = new System.Drawing.Size(184, 24);
this.labelLatitude.TabIndex = 1;
this.labelLatitude.Text = "N/A";
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(81, 16);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(47, 13);
this.label1.TabIndex = 0;
this.label1.Text = "Latitude: ";
this.label1.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.label2.AutoSize = true;
this.label2.Location = new System.Drawing.Point(75, 40);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(53, 13);
this.label2.TabIndex = 0;
this.label2.Text = "Longitude:";
this.label2.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.labelLongitude.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelLongitude.Location = new System.Drawing.Point(144, 40);
this.labelLongitude.Name = "labelLongitude";
this.labelLongitude.Size = new System.Drawing.Size(184, 24);
this.labelLongitude.TabIndex = 1;
this.labelLongitude.Text = "N/A";
this.label3.AutoSize = true;
this.label3.Location = new System.Drawing.Point(87, 64);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(41, 13);
this.label3.TabIndex = 0;
this.label3.Text = "Altitude:";
this.label3.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.labelAltitude.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelAltitude.Location = new System.Drawing.Point(144, 64);
this.labelAltitude.Name = "labelAltitude";
this.labelAltitude.Size = new System.Drawing.Size(184, 24);
this.labelAltitude.TabIndex = 1;
this.labelAltitude.Text = "N/A";
this.label4.Location = new System.Drawing.Point(329, 16);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(72, 24);
this.label4.TabIndex = 0;
this.label4.Text = "Time (Zulu):";
this.label4.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.labelTime.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.labelTime.Location = new System.Drawing.Point(409, 16);
this.labelTime.Name = "labelTime";
this.labelTime.Size = new System.Drawing.Size(120, 24);
this.labelTime.TabIndex = 1;
this.labelTime.Text = "N/A";
this.tabPage1.Controls.Add(this.dumpRawDataCheck);
this.tabPage1.Controls.Add(this.NMEAText);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Size = new System.Drawing.Size(692, 424);
this.tabPage1.TabIndex = 0;
this.tabPage1.Text = "Raw NMEA Data";
this.dumpRawDataCheck.Location = new System.Drawing.Point(16, 8);
this.dumpRawDataCheck.Name = "dumpRawDataCheck";
this.dumpRawDataCheck.Size = new System.Drawing.Size(240, 24);
this.dumpRawDataCheck.TabIndex = 1;
this.dumpRawDataCheck.Text = "Output NMEA data";
this.NMEAText.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.NMEAText.Font = new System.Drawing.Font("Courier New", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.NMEAText.Location = new System.Drawing.Point(9, 40);
this.NMEAText.Multiline = true;
this.NMEAText.Name = "NMEAText";
this.NMEAText.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.NMEAText.Size = new System.Drawing.Size(672, 375);
this.NMEAText.TabIndex = 0;
this.tabPage4.Controls.Add(this.label13);
this.tabPage4.Controls.Add(this.COMlistBox);
this.tabPage4.Location = new System.Drawing.Point(4, 22);
this.tabPage4.Name = "tabPage4";
this.tabPage4.Size = new System.Drawing.Size(594, 424);
this.tabPage4.TabIndex = 3;
this.tabPage4.Text = "Set Up";
this.label13.AutoSize = true;
this.label13.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.label13.Location = new System.Drawing.Point(19, 23);
this.label13.Name = "label13";
this.label13.Size = new System.Drawing.Size(112, 13);
this.label13.TabIndex = 2;
this.label13.Text = "Select a COM Port:";
this.COMlistBox.FormattingEnabled = true;
this.COMlistBox.Items.AddRange(new object[] {
"COM1",
"COM2",
"COM3",
"COM4",
"COM5",
"COM6",
"COM7",
"COM8"});
this.COMlistBox.Location = new System.Drawing.Point(20, 39);
this.COMlistBox.Name = "COMlistBox";
this.COMlistBox.Size = new System.Drawing.Size(136, 69);
this.COMlistBox.TabIndex = 1;
this.connectButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.connectButton.Location = new System.Drawing.Point(16, 469);
this.connectButton.Name = "connectButton";
this.connectButton.Size = new System.Drawing.Size(112, 23);
this.connectButton.TabIndex = 0;
this.connectButton.Text = "Connect";
this.connectButton.Click += new System.EventHandler(this.connectButton_Click);
this.disconnectButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
this.disconnectButton.Enabled = false;
this.disconnectButton.Location = new System.Drawing.Point(134, 469);
this.disconnectButton.Name = "disconnectButton";
this.disconnectButton.Size = new System.Drawing.Size(112, 23);
this.disconnectButton.TabIndex = 2;
this.disconnectButton.Text = "Disconnect";
this.disconnectButton.Click += new System.EventHandler(this.disconnectButton_Click);
this.timer1.Interval = 700;
this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
this.ClientSize = new System.Drawing.Size(725, 499);
this.Controls.Add(this.tabControl1);
this.Controls.Add(this.connectButton);
this.Controls.Add(this.disconnectButton);
this.Name = "Form1";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "GPS in .NET";
this.Load += new System.EventHandler(this.Form1_Load);
this.tabControl1.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.picSats)).EndInit();
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.tabPage2.ResumeLayout(false);
this.tabPage2.PerformLayout();
this.tabPage1.ResumeLayout(false);
this.tabPage1.PerformLayout();
this.tabPage4.ResumeLayout(false);
this.tabPage4.PerformLayout();
this.ResumeLayout(false);
}
#endregion
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new MainForm());
}
private void Form1_Load(object sender, System.EventArgs e)
{
//set com5 by default
COMlistBox.SelectedIndex = 4;
}
private void connectButton_Click(object sender, System.EventArgs e)
{
connectButton.Enabled = false;
disconnectButton.Enabled = true;
COMlistBox.Enabled = false;
port.PortName = COMlistBox.SelectedItem as string;
port.Parity = Parity.None;
port.BaudRate = 4800;
port.StopBits = StopBits.One;
port.DataBits = 8;
port.Open();
timer1.Enabled = true;
}
private void disconnectButton_Click(object sender, System.EventArgs e)
{
disconnectButton.Enabled = false;
connectButton.Enabled = true;
COMlistBox.Enabled = true;
timer1.Enabled=false;
try
{
port.Close();
}
catch(Exception ex)
{
System.Diagnostics.Trace.WriteLine("Trouble closing the SerialPort! " + ex.ToString());
}
}
private void timer1_Tick(object sender, System.EventArgs e)
{
ReadData();
}
private void ReadData()
{
byte[] bData = new byte[256];
try
{
port.Read(bData, 0, 256);
protocol.ParseBuffer(bData);
}
catch(Exception e)
{
System.Diagnostics.Debug.WriteLine(e.ToString());
//swallow it.
}
DisplayNMEARawData(bData);
DisplayGeneralInfo();
DisplaySatellites();
}
private void DisplayNMEARawData(byte[] bData)
{
string sData="";
if(null != bData)
{
sData = encoding.GetString(bData);
}
if (dumpRawDataCheck.Checked)
{
if(NMEAText.Text.Length > 100*1000)
{
NMEAText.Text = NMEAText.Text.Substring(50000,50000);
}
NMEAText.Text = NMEAText.Text + sData;
NMEAText.SelectionStart = NMEAText.Text.Length-1;
NMEAText.ScrollToCaret();
}
}
private void DisplayGeneralInfo()
{
labelLatitude.Text = protocol.GPGGA.Latitude.ToString();
labelLongitude.Text = protocol.GPGGA.Longitude.ToString();
labelAltitude.Text = protocol.GPGGA.Altitude.ToString();
DateTime utc = DateTime.MinValue;
if (protocol.GPRMC.Month != 0 && protocol.GPRMC.Year != 0 && protocol.GPRMC.Day != 0)
{
utc = new DateTime(protocol.GPRMC.Year + 2000, protocol.GPRMC.Month, protocol.GPRMC.Day, protocol.GPGGA.Hour, protocol.GPGGA.Minute, protocol.GPGGA.Second, DateTimeKind.Utc);
labelDate.Text = utc.ToShortDateString();
labelTimeLocal.Text = utc.ToLocalTime().ToString();
labelTime.Text = utc.ToShortTimeString();
}
listGPSQuality.SelectedIndex = (int)protocol.GPGGA.GPSQuality;
labelFixMode.Text = protocol.GPGSA.Mode == 'A' ? "Automatic" : "Manual";
labelPDOP.Text = protocol.GPGSA.PDOP.ToString();
labelVDOP.Text = protocol.GPGSA.VDOP.ToString();
labelHDOP.Text = protocol.GPGSA.HDOP.ToString();
labelDataValid.Text = protocol.GPRMC.DataValid == 'A' ? "Data Valid" : "Navigation Receive Warning";
}
private void DisplaySatellites()
{
labelSatellitesInView.Text = protocol.GPGSV.SatellitesInView.ToString();
Pen circlePen = new Pen(System.Drawing.Color.DarkBlue,1);
Graphics g= picSats.CreateGraphics();
int centerX = picSats.Width/2;
int centerY = picSats.Height/2;
double maxRadius = (Math.Min(picSats.Height,picSats.Width)-20) / 2;
double[] elevations = new double[] {0,Math.PI/2, Math.PI/3 ,Math.PI / 6};
foreach(double elevation in elevations)
{
double radius = (double)System.Math.Cos(elevation) * maxRadius;
g.DrawEllipse(circlePen,(int)(centerX – radius) ,(int)(centerY – radius),(int)(2 * radius),(int)( 2* radius));
}
g.DrawLine(circlePen,new Point(centerX-3,centerY),new Point(centerX + 3,centerY));
g.DrawLine(circlePen,new Point(centerX,centerY-3),new Point(centerX,centerY+3));
Pen satellitePen = new Pen(System.Drawing.Color.LightGoldenrodYellow,4);
foreach(Satellite sat in protocol.GPGSV.Satellites.Values)
{ ListViewItem lvItem = (ListViewItem)sat.Thing;
if(null == lvItem)
{
lvItem = new ListViewItem
(
new string[]
{
sat.Id.ToString() ,
sat.Elevation.ToString(),
sat.Azimuth.ToString(),
sat.Used.ToString()
}
);
listSatellites.Items.Add(lvItem);
sat.Thing = lvItem;//lvItem;
}
else
{
lvItem.Text = sat.Id.ToString();
lvItem.SubItems[1].Text = sat.Elevation.ToString();
lvItem.SubItems[2].Text = sat.Azimuth.ToString();
lvItem.SubItems[3].Text = sat.Used.ToString();
}
double h = (double)System.Math.Cos((sat.Elevation*Math.PI)/180) * maxRadius;
int satX = (int)(centerX + h * Math.Sin((sat.Azimuth * Math.PI)/180));
int satY = (int)(centerY – h * Math.Cos((sat.Azimuth * Math.PI)/180));
g.DrawRectangle(satellitePen,satX,satY, 4,4);
g.DrawString(sat.Id.ToString(), new Font("Verdana", 8, FontStyle.Regular), new System.Drawing.SolidBrush(Color.Black), new Point(satX + 5, satY + 5));
}}}}
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Aplicatie Pentru Constructia DE Harti Digitale (ID: 149237)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
