Information Technology | Geographical IT » Dovák István - Térinformatikai lehetőségek a mobil kommunikáció területén

Datasheet

Year, pagecount:2001, 160 page(s)

Language:Hungarian

Downloads:178

Uploaded:April 04, 2007

Size:447 KB

Institution:
-

Comments:

Attachment:-

Download in PDF:Please log in!



Comments

No comments yet. You can be the first!

Content extract

EÖTVÖS LORÁND TUDOMÁNYEGYETEM TERMÉSZETTUDOMÁNYI KAR INFORMATIKA TANSZÉKCSOPORT Szakdolgozat A dolgozat címe: Térinformatikai lehetőségek a mobil kommunikáció területén Készítette: Leadási dátum: Szak: Tagozat: Témavezető neve: Belső témavezető neve: CD Melléklet: Dovák István 2001. január Programozó Matematikus Nappali dr. Paller Gábor Dr. Sándor Antal WapRoute 1.0 mobil térinformatikai alkalmazás 2. oldal 1 Témaválasztás . 5 1.1 2 3 Feladat specifikációja. 7 Az alkalmazás specifikációja . 8 3.1 3.2 3.3 3.4 3.5 3.6 4 Szervlet paraméterei . 25 Kliens kiszolgálása . 25 A kód elemzése . 28 Az alkalmazás nemzetközisítése . 32 Program továbbfejlesztései és más objektum modell absztrakciók. 33 7.1 7.2 7.3 8 Új útvonal adatbázis készítése. 18 Útvonal adatbázis készítése AutoCAD 2000-rel . 18 A program indítása (paraméterek) . 19 A menürendszer és parancsok leírása . 19 AutoCAD objektumok leírása .

23 Útvonal ellenőrzés . 23 WapRoute szervlet megvalósítása. 25 6.1 6.2 6.3 6.4 7 Átviteli formátum . 15 Logikai formátum. 15 Absztrakt szintaxis. 16 Példa WRD állományra. 16 Útvonal adatbázis készítése és az „Útvonal adatbázis készítő kiegészítés” . 18 5.1 5.2 5.3 5.4 5.5 5.6 6 Útvonal adatbázis . 8 Útvonal adatbázis készítő eszköz . 8 Jáva kód futtató alkalmazás. 8 WapRoute szervlet. 8 Fejlesztői környezet kialakítása. 11 Telepítő környezet . 14 Útvonal adatbázis formátuma . 15 4.1 4.2 4.3 4.4 5 Magyarázkodás. 5 WapRoute útvonal adatbázis készítő továbbfejlesztése. 33 Attribútumok számának tartalmának bővítése. 33 Hibák a programban . 33 Irodalom jegyzék . 34 8.1 8.2 8.3 Elektronikus irodalom . 34 Irodalom . 34 Mobil alkalmazások listája . 34 I. Forrás melléklet:Adatbázis készítő indító programja 35 Database designer/sources/Main.cpp 35 II. Forrás melléklet: Jáva futtató alkalmazás 47

WapRoute-Java-Source/Main.cpp 47 III. Forrás melléklet: Adatbázis tervező alkalmazás 51 Database designer/arxsources/AcadPlus.h 51 Database designer/arxsources/AcadPlus.cpp 51 Database designer/arxsources/Commands.h 62 Database designer/arxsources/Commands.cpp 63 Database designer/arxsources/default.h 78 Database designer/arxsources/Error.h 78 Database designer/arxsources/Error.cpp 79 Database designer/arxsources/WapRoute.cpp 79 Database designer/arxsources/WapRoute.def 81 Database designer/arxsources/WapRoute.h 81 3. oldal Database designer/arxsources/WRUiCheck1Dialog.h82 Database designer/arxsources/WRUiCheck1Dialog.cpp 83 Database designer/arxsources/WRUiCheck2Dialog.h88 Database designer/arxsources/WRUiCheck2Dialog.cpp 89 Database designer/arxsources/WRUiFindNodeDialog.h 94 Database designer/arxsources/WRUiFindNodeDialog.cpp 94 Database designer/arxsources/WRUiFindTraceDialog.h96 Database designer/arxsources/WRUiFindTraceDialog.cpp 97 Database

designer/arxsources/WRUiGetString.h 101 Database designer/arxsources/WRUiGetString.cpp101 Database designer/arxsources/WRUiModifyTraceDialog.h 102 Database designer/arxsources/WRUiModifyTraceDialog.cpp 103 Database designer/arxsources/WRUiNewTraceDialog.h105 Database designer/arxsources/WRUiNewTraceDialog.cpp105 Database designer/arxsources/WRUiProgressDialog.h 107 Database designer/arxsources/WRUiProgressDialog.cpp107 IV. Forrás melléklet: WapRoute alkalmazás osztályai 109 WapRoute/Database/Point.java109 WapRoute/Database/Trace.java111 WapRoute/Database/Path.java114 WapRoute/Database/PathDatabase.java 116 WapRoute/PathDatabaseViewer.java 129 WapRoute/WapRouteResources en EN.java 134 WapRoute/WapRouteResources hu HU.java137 WapRoute/WapRouteServlet.java 139 4. oldal 1 Témaválasztás A szakdolgozatomat melynek címe „Térinformatikai rendszerek a mobil kommunikációban”, a Nokia Magyarország Kft. támogatásával készítetem el, ahol a külső témavezetőm Paller

Gábor (gaborpaller@nokiacom) A támogató cég profiljából nyilvánvalóan adódik, hogy valamilyen a távközléssel kapcsolatos témából kellett választanom szakdolgozat témát. Az én választásom azért esett erre az első hallásra bonyolultnak tűnő feladatra, mert egyetem mellett egy térinformatikai alkalmazások (GIS) készítésével foglalkozó cégnél dolgoztam, ahol betekintést nyertem a GIS felépítésébe és készítésük rejtelmeibe. A témaválasztás időpontjában még nem volt a piacon olyan rendszer, amely térképi adatokat jelenített volna meg WAP felületen. Sőt a WAP technológia is csak a fejlesztő mérnökök műhelyeiben működött még teljes biztonsággal Ezért a szakdolgozatom témája olyan újdonságnak tűnt, amiben új területét dolgozhatom fel az informatikának. A WAP premierje óta azonban a nagy cégek mind elkészítették a mobil terminálokon is működő GIS lekérdező felületüket, ennek ellenére nem érzem

fölöslegesnek a szakdolgozat elkészítésével eltöltött időt. Sőt - erről szól az alábbi magyarázkodás. 1.1 Magyarázkodás Míg fél évvel ezelőtt úgy tűnt, hogy a "WAP kézi készülékek a világ minden táján hiánycikknek számítanak" (Figyelő, 2000/14. szám), addig ma a mobil internetezésre alkalmas készüléket a világ fejlettebb régióiban ajándékként osztogatják számítógép, vagy digitális televízió vásárlásakor - úgy, mint nálunk a videóhoz a kazettát. “Ha Magyarországon ma valaki WAP-telefonra vágyik, akkor bármelyik szolgáltatótól, bármelyik mobiltelefon-kereskedőnél megveheti, akár 20 ezer forintért. A British Telecom adatai szerint NagyBritanniában eddig 200 ezer WAP-készüléket adtak el, miközben a használatban lévő összes mobiltelefon száma 30 millió. Az adat a piaci tervektől is jócskán elmarad, hiszen az év első felére 500 ezernyi eladást prognosztizáltak. Nálunk a Taylor Nelson

Sofres Modus felmérése körülbelül 50 ezresre teszi a WAP-olók számát, de a Figyelő becslése szerint ez a szám igencsak túlzó. Még az itthon eladott WAP-készülékek sem érik el ezt a mennyiséget, s azt a szolgáltatók is elismerik, hogy ezeknek alig egy részét használják internetezésre a tulajdonosok. Mi az oka annak, hogy a WAP eddig nem váltotta be a hozzá fűzött reményeket? Jórészt maguk a remények, amelyek túlfűtöttnek bizonyultak. Az egy éve bemutatott technológiának ugyanis számos korlátja van, amelyre nem hívták fel a figyelmet a fejlesztők, akik a korlátlan internetezés lehetőségével kecsegtették a potenciális vásárlókat. Nyírő András, a Westel tartalomszolgáltatási igazgatója szerint nem önmagában a WAP a fontos, hanem a mobil-internetezés. Hogy azt a WAP hozza el vagy sem, az sokkal kevésbé lényeges kérdés Ő az új csomagkapcsolt adatátviteli technológiától, a GPRS elterjedésétől vár áttörést, bár

az eddigi trendet tekintve sem olyan pesszimista, mint a szaksajtó általában. Mint elmondta, a Westel WAP-szolgáltatását naponta közel 4 ezer ügyfél veszi igénybe, főleg a hírek kedvéért, de népszerű a horoszkóp is. Kiemelte a WAP-nak azt a vonását is, hogy általa szinergiát alkothat a WAP és az SMS. A Pannon GSM sajtó- és információs igazgatója, Suba János 10 ezer főre teszi azok számát, akik Pannon előfizetéssel együtt birtokolnak WAP-os eszközt. Nyírőhöz hasonlóan ő is úgy látja, hogy ígéretesen nő a hazai felhasználók száma. A Pannon szolgáltatásai közül a menetrend a legnépszerűbb Suba szerint a WAP kényszerszülemény volt, de jobb híján két-három évig meglesz még a helye a vezető technológiák között. Később csak ott marad majd meg, ahol kielégítő a rövid tájékoztatás” Miért tűnik számomra mégis ígéretesnek egy WAP alkalmazás fejlesztése? Leginkább azért mert a szakdolgozatban nem a WAP

alkalmazás kapja a fő hangsúlyt, hanem a térinformatikai rendszerek ember közelivé tétele. Míg 10 évvel ezelőtt egy GIS rendszer elképzelhetetlen volt egy ház nagyságú számítógép nélkül, addig mára már a személyi számítógépeken is megjelentek ezek a szoftverek. Ma egy térinformatikai rendszer (a kliens – szerver logikára épülve) egy erős adatbázis kezelőből (például ORACLE 8i) és sok kisebb teljesítményű munkaállomásból áll, ahol a munkaállomások személyi számítógépek. A szoftver, ami az adatokat megjeleníti a munkaállomásokon nem más, mint egy böngésző alkalmazás, amit a térinformatikai rendszerrel szállítanak. Az Internet térhódításának köszönhetően azonban mindenkinek megnőttek az igényei. Egy üzletember a világ minden pontján – akár a tárgyalások szünetében is – el tudja olvasni a leveleit, akkor miért ne tudhatná megnézni a repülő menetrendet vagy a vonatindulásokat. Szeretne információt

kapni arról, hogy hazafele számíthat-e útlezárásra, 5. oldal traffipaxra, vagy szeretné virtuálisan bejárni a gyárait, raktárait az eladható készletek után kutakodva. Ezeknek az igényeknek köszönhetően a GIS rendszerek fejlesztői arra kényszerültek, hogy eddigi drága alkalmazásaikhoz egy általános, könnyen megvalósítható megjelenési felületet biztosítsanak. Minden platformra egy-egy felület megvalósítása túl költséges megoldás lett volna. A mai nagy GIS szállítók az Internetre szavaztak. A HTTP protokollon keresztül szolgáltatnak adatot a munkaállomások felé, amit egy tetszőleges böngésző is meg tud jeleníteni. Ma már számos ilyen alkalmazás van a piacon: Siemens: GIS termék neve: SICAD-IMS GIS termék honlapja: http://www.sicadcom/products/is/is roadmaphtm Mobil GIS honlapja: http://www.siemensbe/ic/en/web applications/gis waphtml ESRI: GIS termék neve: ArcIMS GIS termék honlapja:

http://www.esricom/software/arcims/indexhtml Jelenleg nincs működő mobil GIS megoldása. MapInfo GIS termék neve: MapXtreme GIS termék honlapja: http://dynamo.mapinfocom/products/web/Overviewcfm?productid=162 Mobil GIS honlapja: http://www.mapinfocom/wireless/indexcfm OpenGIS Consortium Mobil GIS honlapja: http://www.openlsorg/News/00-10-30htm Ezek közül a multinacionális cégek közül azonban csak néhánynak van kifejezetten mobil eszközökre fejlesztett felülete. Ezért úgy érzem érdemes ezzel a területtel foglalkozni, ha ekkora cégek látnak benne fantáziát Továbbá véleményem szerint a WAP technológia jelenlegi mélyrepülése ellenére egy ígéretes felület, nem csak az email üzenetek megjelenítésére, hanem a térinformatika rendszerek adatainak megjelenítésére is. Jelenleg ugyan a telefonok kis kijelzői nem képesek a megfelelő felbontást nyújtani egy igényes GIS felülethez, de ez nyilvánvalóan változni fog a nagyobb méret és felbontás

irányába. Erre a nemzetközi informatikai kiállításokon bemutatott új telefonok megjelenésének okán lehet következtetni. 6. oldal 2 Feladat specifikációja Egy WAP tartalom szolgáltató Java szervlet készítése. Amely servlet a Nokia WAP Server részeként képes egy adatbázisból adatok lekérésére, és azok megjelenítésére egy mobil terminál felületén. Az adatbázis egy útvonal hálózatot, mint gráfot ír le. A gráfban az éleket az útnak nevezzük, a csomópontok az utak – találkozási és – végpontjai. Egy él a kezdő és végpontból valamint töréspontokból áll. Vannak kitüntetett csomópontok, ezeket városnak nevezzük Minden útnak és városnak van neve. Az utak lehetnek kétirányúak vagy egyirányúak Egyirányú úton csak a kezdőponttól a végpont felé lehet haladni. A gráfban az utakból útvonalakat lehet alkotni. Egy útvonal egy összefüggő körmentes részgráf, amely legalább egy élet tartalmaz. Jelen esetben az

útvonal a gráfoknál megismert út fogalmához hasonlítható a legjobban, illetve annak ez egy speciális esete. A szervletnek képesnek kell lennie, a mobil terminálról érkező kérések alapján: • Város megtalálására annak neve alapján. A nevet a felhasználó egy listából választhatja ki, vagy begépelheti. • A térkép dinamikus (on-the-fly GetMap) generálására az adatbázisból. • A generált térképeken dinamikus navigálásra (nagyítás, távolítás, mozgatás a nyolc égtáj felé). • Bizonyos tulajdonságú (legrövidebb) útvonalkeresésre és megjelenítésre, két – a felhasználó által megadott – város között. A megjelenítés kétféle módon történhet: A térkép megmutatása és abban nagyító funkciók alkalmazása, vagy az útvonal elemeinek listában történő felsorolásával. 7. oldal 3 Az alkalmazás specifikációja 3.1 Útvonal adatbázis A feladat megoldásának lépesei között az első faladat az útvonal

adatbázis formátumának definiálása. Ennek a definícióját ebben a dokumentumban a „Útvonal adatbázis formátuma” fejezet tartalmazza. Az adatbázis formátumának kialakításánál a következő szempontok játszottak szerepet: • Könnyen – akár egy olyan egyszerű szövegszerkesztővel is, mint a „vi” vagy „sed” módosíthatónak kell lennie. Jelen megoldás és egy általános CDF (Comma Delimited Format) ábrázolású rekordokra épülő adatbázist valósít meg. Így az állomány megfelelő tagolással és megjegyzések használatával könnyen áttekinthetővé válik. • A megoldás lehetőleg platform független legyen. Hiszen a Java szervletek legfőbb erőssége, hogy platform független implementációt tesznek lehetővé. Azaz az adatbázis másolásakor, mozgatásakor ne kelljen külön figyelmet szentelni a küldő és fogadó operációs rendszer közötti kódolási rendszerek közötti különbségre. Jelen megoldás – figyelembe véve,

hogy Nokia WAP Server implementáció csak ASCII kódolású rendszeren van – az ASCII kódrendszert használja. • A megoldás valamilyen szabvány vagy ajánlás alapján készüljön el, hogy könnyen érthető legyen a későbbi módosítások során más fejlesztőknek és felhasználóknak is. 3.2 Útvonal adatbázis készítő eszköz Az útvonal adatbázis módosítására létrehozására lehetőség van egyszerű szövegszerkesztőkkel, de lehetőség szerint az adatbázis adminisztrátorok kezébe egy olyan eszközt kell adni, amivel könnyen átlátják az útvonal gráfot. Erre a legalkalmasabbnak egy grafikus rajzolóprogram használata tűnik, ahol grafikusan is képesek módosítani, lekérdezni az útvonal adatbázist. Ennek az eszköznek a részletes leírását valamint az új útvonal adatbázis létrehozásának módszereit a „Útvonal adatbázis készítése és az Útvonal adatbázis készítő kiegészítés” című fejezet tartalmazza. Ez az eszköz

két általam elkészített modulból áll. Az egyik az AutoCAD megkeresésével és indításával foglakozik (Ennek terméke a „Database Designer.exe” állomány) A másik pedig egy AutoCAD környezet alá integrált modul (Ennek terméke a „WapRoute.arx” állomány) 3.3 Jáva kód futtató alkalmazás A Win32-es környezetben a Ghost Install telepítő környezetben nem megoldható probléma a rendszer analizálása a telepítés pillanatában. Azaz nem lehetséges leellenőrizni, hogy a rendszeren telepítve van-e a Jáva futtató környezet Ezért egy alkalmazást készítettem, amelynek feladata a Windows Registry alapján a Jáva futtató környezet megkeresése és a WapRoute.jar állomány megfelelő indítása a WRD kiterjesztésű állományok nézegetéséhez, azaz a PathDatabaseViewer osztály indításához (Ennek terméke a „startjava.exe” állomány) 3.4 WapRoute szervlet A szakdolgozat témabejelentőjének megírásakor már nyilvánvaló volt, hogy

azt a Java szervlet technológiával fogom elkészíteni. Ezt a döntést azonban megelőzte egy átgondolási fázis Ekkor külső témavezetőmmel Paller Gáborral együtt átgondoltuk a feladatot és a feladat megoldásához rendelkezésre álló alkalmazásokat. Így a következő okok miatt döntöttünk a Java szervlet implementáció mellett a CGI-szkriptes megoldások ellen: • A Java nyelv miatt platform független megoldást biztosít a rendszerint platformfüggő CGI-szkriptekkel szemben. • A WEB szerveren futó virtuális gép miatt sokkal gyorsabb kiszolgálást eredményez, mivel elmarad a minden egyes kérés kiszolgálásához szükséges külső program indítása. • A WEB szerveren belül állandóan futó virtuális gép miatt leegyszerűsödik a kéréskiszolgálások szinkronizációja. • A Nokia WAP Server alkalmazás 30 napos próbaverzióval ingyenesen kipróbálható, és ez a WEB szerver képes szervletek fent említett jó tulajdonságai melletti

futtatására. Az így kialakult koncepciónak – szakdolgozat szempontjából – egy hátrányos oldalát látom, mégpedig, hogy az alkalmazás futtatásához sok programot kell a rendszerre telepíteni mielőtt kipróbálható lenne. Azonban ez a szoftver nem feltétlenül egy késztermék, amiben minden környezetre gondolni kell. Viszont az alkalmazás tovább 8. oldal fejleszthetőségét, esetleg termékké fejlesztésének lehetőségét mindig szem előtt tartom – tartottam – a dolgozat készítésekor. Ez a modul végzi el a tényleges munkát, amelyet az előző fejezetben specifikáltam a „Feladat specifikációja” cím alatt. Ez a modul egy szervlet implementációt és egy futtatható alkalmazást tartalmaz, amelyek képesek a lentebb specifikált útvonal adatbázisok megjelenítésére. A szervlet képes a feladatban specifikált módon az adatbázisban keresni és a keresés alapján, adatokat megjeleníteni WAP terminálon. A futtatható alkalmazás

viszont csak az adatok grafikus megjelenítését teszi lehetővé az adminisztrátor számára a szerver gépen (Ennek terméke a „WapRoute.jar” állomány). Az alkalmazás elkészítéséhez szükség van még a környezet meghatározásán kívül a felhasználói felület megadására is. Ezt a következő bekezdés tartalmazza 3.41 WAP terminálon megjelenő felhasználói felület Az alkalmazás elkészítése előtt az Interneten szörfölve megtekintettem a legtöbb tréinformatikai szoftver készítő cég honlapját és termékeit, de a jelen alkalmazáshoz hasonlót nem találtam. Így a szakdolgozatban ennek megtervezésére is külön figyelmet kell szánnom. A felhasználói felület kialakításában „WAP Service Designers Guide To Nokia Handsets” dokumentum volt segítségemre. Ebben a dokumentumban a Nokia szakembereinek segítségével bepillantást nyerhettem a mobil terminálokon javasolt technikák használatába. Ennek megfelelően a következő

folyamatábrán az egyes lekérdezések sorrendjét mutatom be. Az ábrán az egyes dobozok első sorának tartalma a WAP terminálon megjelenő képernyő címét adja meg. A hozzá tartozó – alatta elhelyezkedő – doboz, pedig egy rövid funkció leírást ad Később a cím alapján fogok hivatkozni az egyes oldalakra, amikor azok pontos tartalmát megadom. Bejelentkezés Bemutatkozás és funkció kiválasztása Város keresés Város nevének kiválasztása listából Út keresés Út nevének kiválasztása listából Útvonal keresés Kezdő és végpontvárosok kiválasztása Térkép Navigálás térképen, látható objektumok Látható elemek Lista a látható elemekről, elem kiv. Itt az egyes oldalak tartalma alatt a Deck-ek tartalmát értem. Azaz egy Deck több oldalt is tartalmazhat annak megfelelően, hogy a kérdés kiszolgálása hogyan tehető felhasználó baráttá. Így a fenti folyamat ábra valójában csak a lekérdezések sorrendjét adja meg, nem

pedig a képernyők rákövetkezési relációját. Az egyes nyilak egy-egy kérésnek felelnek meg, amit a WAP szervernek a szervlet felé kell továbbítania, és amire a szervletnek a következő Deck-et kell szolgáltatnia. Az egyes Deck-ek leírásánál nem térek ki a választás mikéntjére, mert ez a WAP termináloktól erősen függ. Viszont a dolgozat egy későbbi „WapRoute használata Nokia7110-es terminálról” című fejezetében pontosan ismertetem az alkalmazás használatát. 9. oldal 3.411 Bejelentkezés Ennek a képernyőnek a feladata a termék megnevezése és használatának ismertetése. Hogyan kérhet a felhasználó segítséget, bármelyik képernyőn? Itt egy listából kell kiválasztania, hogy melyik funkcióval szeretne továbblépni, melyik lekérdező funkciót akarja használni. Választhat: Városkeresés, Útkeresés és Útvonalkeresés név szerint funkciók közül. Ezen az oldalon választhatja ki a felhasználó továbbá azt is hogy

az alkalmazás milyen nyelven jelenítse meg az oldalakat. Jelenleg a felhasználó magyar és angol nyelvek közül választhat 3.412 Városkeresés Itt a felhasználónak ki kell választania a várost, amit szeretne a térképen megjeleníteni, aminek adatait szeretné lekérdezni. A felhasználónak itt lehetősége van többféle lehetőség közül választani: • Választás név szerint listá(k)ból. • Választás név szerinti szűréssel. A névszerinti lista választás esetén a felhasználónak ki kell választania azt a karakter tartományt, ahova a keresett város neve esik. A kiválasztás után megjelenik a kiválasztott tartományba eső városnevek listája Ahol minden lista elem egy hyper-link, azaz a kiválasztás után a város adatai megjelennek a képernyőn. – Jelen alkalmazás esetében ezek az adatok csak a város neve és rajz koordinátái lesznek. A névszerinti szűréssel választás esetén a felhasználónak ki kell töltenie egy szövegmezőt

a keresett város nevében található bármilyen hosszú karakter sorozattal. Az oldal tartalmát a kitöltés után konfirmálnia kell a szöveg mező alatti hivatkozással, minek hatására az alkalmazás a következő oldalon megjeleníti azokat a városneveket, amelyekben szerepel a beütött karakter sorozat. A megjelenő oldalon szintén minden elem egy hivatkozás, melynek kiválasztásával a kiválasztott város adatai megtekinthetőek. Ha a kiválasztás így nem adott eredményt, akkor a városok listája helyett egy „Nincs egyező nevű város!” felirat jelenik meg és a felhasználó a WAP böngészőjének „Vissza” gombjával navigálhat az előző oldalra vissza. 3.413 Útkeresés Ebben az állapotban a felhasználónak a „Város keresés” funkcióval teljesen megegyező formában kell az adatbázisban található utak közül választania. A kiválasztáskor itt is két keresési forma közül választhat a felhasználó. Az egyetlen különbség a

választás után az adatok megjelenítésében van, ugyanis ekkor az út által érintett városokat is felsorolja majd az alkalmazás. 3.414 Útvonalkeresés Ebben az állapotban a felhasználónak két várost kell azonosítania a lekérdezés futtatásához. A két város az indulási és érkezési pont városa. Az útvonalak kiválasztása után a lap alján található linkkel aktiválhatja a felhasználó a keresést. Aminek eredményeképpen a felhasználó egy listát kap a meghatározott városok közötti útvonalról. Az útvonal leírása tulajdonképpen egy link sorozat, aminek az egyes elemeire kattintva lehetőség van az egyes elemek tulajdonságainak megtekintésére úgy, mint: • Érintett város esetén: Adatok lekérdezése, megtekintés térképen • Útvonal esetén: Útvonal szegmens adatainak lekérdezése, megtekintés térképen • Útelágazás esetén (város nélkül): Megtekintés térképen. 3.415 Térkép Ez az állapot tulajdonképpen nem

feltétlenül térkép egy megjelenítését jelenti, hanem az útvonal adatbázisban levő adatok alapján egy a keresésnek megfelelő eredmény szolgáltatását a WAP terminál felé. Azért ezt a címet adtam mégis ennek az állapotnak, mert a szakdolgozat legfontosabb eleme itt jelenik meg, a grafikus információ megjelenítése a WAP terminálon. Ebben az állapotban a keresési feltételeknek megfelelően többféle információ jelenhet meg a WAP terminálon: • Térkép megjelenítése és a nagyító funkciók megvalósítása • Objektum lista megjelenítése 10. oldal • Objektum adatainak megjelenítése A „Térkép megjelenítésé”-hez az alkalmazásnak szüksége van a megjelenítendő térképről készítendő kép jobb alsó és bal felső koordinátájára (LLX, LLY, URX, URY paraméterek). A nagyító és mozgató funkciók is ezeken a paramétereken keresztül kommunikálnak az alkalmazással. Azaz ha növelni akarjuk a nagyítást, akkor kisebb

téglalapot határozunk meg. Valamint ha mozgatni akarjuk a térképet, akkor a négyzetet mozgatjuk Ezek a funkciók a térinformatika alkalmazásoknál megszokott módon működnek. Az „Objektum lista” egy útvonal leírására szolgál. Így ennek meghatározásához az alkalmazásnak szüksége van az induló és cél állomások nevére, és ha van ilyen, akkor a közbenső állomás(ok) nevére is (START,END,ACROSS paraméter). Az „Objektum adatai”-nak megjelenítésénél egy szimplán szöveges képernyőt kap a felhasználó, ahol az adott objektum adatait tekintheti meg. Ez egy városnál a város neve és koordinátái, egy útnál az út összes hossza, a szegmensek száma, valamint a szegmensekből és a darabszámból kiszámított átlagos szegmenshossz. Az útvonalnál ez a képernyő az „Objektum listá”-nak feleltethető meg. Ennek a képernyőnek a generálásához az alkalmazásnak szüksége van az objektum azonosítására (TYPE, ID paraméterek).

3.416 Látható elemek Az alkalmazás másik tisztán térinformatikai lekérdezése ez. Azaz a mobil terminálon látható térképen levő elemek listájának lekérdezése. Ekkor a felhasználó egy listát kap azokról az elemekről, amiket a képernyőjén lát Ebben a listában is, mint mindenhol általában az elemek linkek, amelyekre kattintva azok adatai tekinthetőek meg. Ennek a lekérdezésnek a megvalósításához az alkalmazásnak szüksége van a befoglaló terület meghatározására (LLX, LLY, URX, URY paraméterek). 3.42 Az alkalmazás telepítése A WapRoute alkalmazás elkészülése után egy darab állományból áll, melynek neve „WapRoute.jar” Ez az állomány tartalmazza a szervletet is, amelyet a Nokia WAP Szerver futtat, és amely a specifikációnak megfelelő WML és WBMP oldalakat generál. Ahhoz, hogy a Nokia WAP Szerver ezt a szervletet példányosíthassa az előbb említett állományt a szerver megfelelő könyvtárába kell másolni, és a

szervert, úgy konfigurálni, hogy az a WapRoute szervletet futathassa. Azaz a szervletet regisztrálni kell a szerverben A telepítés elvégzését megkísérli a telepítő program, de ha az sikertelen, akkor az adminisztrátornak kell a Nokia WAP Szerverhez mellékelt leírások alapján a regisztrációt elvégeznie. 3.5 Fejlesztői környezet kialakítása A fejlesztői környezet kialakításánál is fontos szerepet játszott, hogy könnyen átültethető legyen más operációs rendszerek alá is. Itt olyan operációs rendszerekre gondolok, ahol a szervlet majd fordítható és futtatható lesz Így a környezetet két részre kell bontani az egyik rész, tartalmazza a platformfüggő útvonal adatbázis készítő eszközt, a másik pedig a platform független szervlet alkalmazást. Minden részegységnek egy külön könyvtárat alakítottam ki, és ahol további tagolás volt szükséges ott újabb könyvtárakat alakítottam ki az egyes feladatok megoldásához. A

fejlesztői környezet tartalmazza a fordító állományokat, amelyek futtatásával az egyes egységek – újra – fordíthatóak. Valamint tartalmaz egy olyan könyvtárat, ahol a szakdolgozatból telepítő CD készítéséhez minden megtalálható. A következő struktúra az így kialakult könyvtárszerkezet és állományok rövid leírását tartalmazza. A könyvtárakat vastag betűvel az állományokat normál betűvel írtam. Az egyes állományok rövid leírását a jobb oldalon dőlt betűvel szedtem. magyarorszag.wrd purgeall.bat readme.txt startjava.exe WapRoute.doc WapRoure.jar Database Designer Readme.txt Database Designer.exe Database Designer.dsw Magyarország főbb városait tartalmazó útvonal adatbázis Az ideiglenes állományok törlését végzi el Rövid leírás a szakdolgozatról és a telepítés menetéről Jáva futtatókörnyezet kereső alkalmazás Szakdolgozat dokumentációja A szervlet fordított illetve futtatható változata Útvonal

adatbázis tervezőeszköz projectje (platformfüggő: WIN32) Projekt fordításának és futtatásának leírása Az útvonal adatbázis tervező kiegészítés indító állománya Az kiegészítés VC++ projectjeinek indító állománya 11. oldal WapRoute.arx WapRoute.mnu WapRoute.arg Check1-??.bmp Create-Node-??.bmp Create-Trace-??.bmp Find-Node-??.bmp Find-Trace-??.bmp Modify-Node-??.bmp Modify-Trace-??.bmp Layer-??.bmp Import-??.bmp Export-??.bmp arxsources AcadPlus.h AcadPlus.cpp AcadStdafx.h Commands.h Commands.cpp Defult.h Error.h Error.cpp resource.h StdAfx.h StdAfx.cpp WapRoute.h WapRoute.cpp WapRoute.def WapRoute.rc WRUiCheck1Dialog.h WRUiCheck1Dialog.cpp WRUiCheck2Dialog.h WRUiCheck2Dialog.cpp WRUiFindNodeDialog.h WRUiFindNodeDialog.cpp WRUiFindTraceDialog.h WRUiFindTraceDialog.cpp WRUiGetString.h WRUiGetString.cpp WRUiModifyNodeDialog.h WRUiModifyNodeDialog.cpp WRUiModifyTraceDialog.h WRUiModifyTraceDialog.cpp WRUiNewNodeDialog.h WRUiNewNodeDialog.cpp

WRUiNewTraceDialog.h WRUiNewTraceDialog.cpp WRUiProgressDialog.h WRUiProgressDialog.cpp acad15.ico applikacao.ico check1.ico check2.ico crnode.ico crtrace.ico export.ico fnnode.ico fntrace.ico import.ico layers.ico monode.ico motrace.ico 12. oldal A kiegészítés AutoCAD-be betölthető állománya A kiegészítés AutoCAD-es menürendszerét leíró állomány A kiegészítés AutoCAD-es felületét leíró állomány A check1 funkció különböző méretű ikonjai az AutoCAD eszköztáron A csomópont készítő funkció ikonjai az eszköztáron Az út készítő funkció ikonjai az eszköztáron A csomópont kereső funkció ikonjai az eszköztáron Az útkereső funkció különböző méretű ikonjai az eszköztáron A csomópont módosító funkció ikonjai az eszköztáron Az módosító funkció különböző méretű ikonjai az eszköztáron A feliratokat ki/bekapcsoló funkció ikonjai az eszköztáron Az import funkció különböző méretű ikonjai az eszköztáron Az

export funkció különböző méretű ikonjai az eszköztáron ”waproute.arx” elkészítéséhez szükséges állományok AutoCAD funkcionalitás kibővítő funkció könyvtár definíciója AutoCAD funkcionalitás kibővítő funkció könyvtár implementációja Az AutoCAD előrefordított fejléceinek definíciós állománya Az alkalmazás parancsait definiáló állomány Az alkalmazás parancsait implementáló állomány Saját definíciós állomány Az alkalmazás hibakezelő moduljának definíciója Az alkalmazás hibakezelő moduljának implementációja Az erőforrások definíciói Az előrefordított fejlécek definíciós állománya Az előrefordított fejlécek fordító állománya Az alkalmazás kommunikációs felületének definíciója Az alkalmazás fő osztálynak implementációja Az ARX kommunikációs felületének definíciója Az erőforrás állomány Az egyes számú ellenőrző ablak osztályának definíciója Az egyes számú ellenőrző ablak

osztályának implementációja Az kettes számú ellenőrző ablak osztályának definíciója Az kettes számú ellenőrző ablak osztályának implementációja A csomópont kereső ablak osztályának definíciója A csomópont kereső ablak osztályának implementációja Az útkereső ablak osztályának definíciója Az útkereső ablak osztályának implementációja Egy karaktersorozatot bekérő ablak osztályának definíciója Egy karaktersorozatot bekérő ablak osztályának implementációja A csomópont tulajdonságait módosító osztály definíciója A csomópont tulajdonságait módosító osztály implementációja Az út tulajdonságait módosító ablak osztályának definíciója Az út tulajdonságait módosító ablak osztályának implementációja Új csomópont készítésénél használt ablak definíciója Új csomópont készítéséhez használt ablak implementációja Új út készítésénél használt ablak osztályának definíciója Új út

készítésénél használt ablak osztályának implementációja Egy progress kontrollt kirajzoló ablak osztályának definíciója Egy progress kontrollt kirajzoló ablak osztályának megvalósítása Ikon Ikon Ikon Ikon Ikon Ikon Ikon Ikon Ikon Ikon Ikon Ikon Ikon tracedif.ico Ikon tracelr.ico Ikon tracelrs.ico Ikon tracerl.ico Ikon tracerls.ico Ikon tracetwo.ico Ikon tracetwos.ico Ikon ObjectArx 2000 AutoCAD API-jának include állományai sources ”Database Designer.exe” elkészítéséhez szükséges állományok db4acad15.dsp Indító modul projektje main.cpp Az indító modul megvalósítása resource.h Erőforrások definícióit tartalmazó állomány db4acad15.rc Erőforrásokat tartalmazó állomány acad15.ico Ikon check1.ico Ikon check2.ico Ikon crnode.ico Ikon crtrace.ico Ikon export.ico Ikon fnnode.ico Ikon fntrace.ico Ikon import.ico Ikon monode.ico Ikon motrace.ico Ikon Image „waproute-setup.exe” elkészítéséhez szükéges állományok

createinstall.bat Telepítő környezetet elkészítése waproute.gin Ghost-Install telepítő project Presetup Ghost-Install project telepítési állományai app.ins Alkalmazás telepítését leíró állomány gins.bmp A telepítő ablakok fejlécében levő kép gins.ini Alkalmazás telepítését leíró állomány readme.txt A telepítéskor az „Olvass.el” ablak tartalma Data Ghost-Install project telepítendő állományai Misc A szakdolgozathoz kapcsolódó egyéb állományok magyarorszag.dwg Magyarország főbb városait tartalmazó útvonal adatbázis pelda.wrd Ebben a dokumentációban említett példa útvonal adatbázis todo.txt Szakdolgozat hiányzó elemeinek leírása WapRoute-Java-Source ”WapRoute.jar” elkészítéséhez szükséges állományok clean.bat Fordított állományok törlése az alkönyvtárakban compile.bat Java típusú állományok fordítása az alkönyvtárakban compileEach.bat A paraméterben megadott java forrás állomány fordítása

runapp.bat WapRoute.PathDatabaseViewer osztály futtatása WapRoute A WapRoute package forrásállományait tartalmazza PathDatabaseViewer.java PathDatabaseViewer osztály WapRouteServlet.java A szervlet forrása WapRouteServlet.properties A szervlet paramétereit és azok kezdőértékeit tartalmazza WapRouteResources hu HU.java WapRooute szervlet nyelvfüggő erőforrásai (magyar) WapRouteResources en EN.java WapRooute szervlet nyelvfüggő erőforrásai (angol) 11.gif Észak-kelet irányba mozgató gomb ikonja 12.gif Észak irányba mozgató gomb ikonja 13.gif Észak-nyugat irányba mozgató gomb ikonja 21.gif Kelet irányba mozgató gomb ikonja 22.gif A kép mértetét nyagyító csőkkentő gomb ikonja 23.gif Nyugat irányba mozgató gomb ikonja 31.gif Dél-kelet irányba mozgató gomb ikonja a 32.gif Dél irányba mozgató gomb ikonja 33.gif Dél-nyugat irányba mozgató gomb ikonja in.gif Nagyítást növelő gomb ikonja out.gif Nagyítást csökkentő gomb ikonja za.gif Teljes

adatbázist mutató gomb ikonja appicon.gif Az alkalmazás ablakának jobb felső sarkában megjelenő ikon Database A WapRoute.Database package forrásállományait tartalmazza 13. oldal Node.java Point.java PathDatabase.java Trace.java WapRoute-Starter-Source startjava.dsp startjava.dsw startjava.rc main.cpp resource.h crnode.ico Install CD 3.6 Node osztály a gráf egy csomópontját irja le Point osztály egy kétdimenziós dupla pontosságú pontot írj le PathDatabase osztály irja le és jeleníti meg a gráfot Trace osztály a gráf egy élét irja le ”startjava.exe” elkészítéséhez szükséges állományok Microsoft Visual Stúdió project Microsoft Visual Stúdió munkaterület állomány Az erőforrásokat tartalmazó állomány Az indító modul megvalósítása Az erőforrások definiciói Ikon Telepítő könyvtár. Az itt található állományokat egy CD-re írva a teljes szakdolgozat telepíthető bármely WIN32 alapú rendszeren. Telepítő környezet

Manapság minden programot könnyen kezelhető telepítő felülettel szállítanak a program készítői. Ezért szerintem egy szakdolgozat keretén belül elkészülő alkalmazás sem lehet kivétel. A telepítő környezet megvalósításához a Ghost Installer nevű freeware programot használom. A telepítő környezetet a Windows operációs rendszer alatti telepítő állományok létrehozásához fejlesztette ki Alexey Popov. A telepítő állomány előkészítéséhez és létrehozásához szükséges állományokat egy külön könyvtárban helyeztem el (Image). 14. oldal 4 Útvonal adatbázis formátuma Ez a paragrafus tartalmazza az útvonal adatbázis logikai és fizikai formátumának specifikációját. A rekord formátum definíció az ASN.1 általános formátum definíciót használja, amelyet széles körben alkalmaznak a távközlés világában. A fizikai formátum specifikáció két részből áll: • Az absztrakt szintaxis definíciójából • Az

átviteli formátum definíciójából (pl. kódolási szabályok) 4.1 Átviteli formátum Az útvonal adatbázis kódolásánál az ASCII karakterkészletű karaktereket kell használni. Így az adatbázis leírásához csak a karakter készlet látható karakterei közül (ahol a karakter kódja nagyobb egyenlő 30 és kisebb vagy egyenlő 127) is csak néhányat használunk fel. Ez azt jelenti, hogy az adatbázis ASCII rendszereken belül akár levélben illetve FTP-vel könnyen mozgatható különböző munkaállomások között. Az adatformátum szerint az újsor karakterkódolása kétféleképpen is történhet. Erre a Windows és Unix rendszerek közötti különbség miatt van szükség, azaz 0A 0D vagy 0D kódú karakterek is új sort jelentenek. 4.11 Állomány elnevezési konvenciók A WapRoute útvonal adatbázis állományok neve tetszőleges számú karaktert tartalmazhat a használt operációs rendszer által megengedett formátumban. Az adatbázisok nevére

egyetlen kikötés van, hogy az állomány név kiterjesztésének „WRD”-nek kell lennie. Ezt az állomány név típust a megfelelő operációs rendszer használatakor (Windows) az alkalmazás regisztrálja, amivel bizonyos műveletek (megnyitás, szerkesztés) végrehajtását a felhasználó számára könnyebbé teszi. 4.2 Logikai formátum WRDatabase WRDConfigSection WRDConfigLine WRDEntitySection WRDNode NodeName NodePoint WRDTrace TraceName TraceType PointSequence WRDPoint X Y 15. oldal 4.3 Absztrakt szintaxis Ebben a pontban az absztrakt szintaxis leírásánál használt ASN.1 jelöléseket és az adatbázis ASN1 leírását tartalmazza. Név szerint a következő adatformátumokat használom a leírásnál: INTEGER, FLOAT OCTET STRING Új adattípusok és elemek leírásához az alábbi ASN.1 konstrukciókat használom: SEQUENCE / SEQUENCE OF CHOICE Formátum leírása ASN.1 szabvány szerint: WRD UTVONAL ADATBAZIS ::= BEGIN WRDatabase ::= SEQUENCE {

ConfigSection WRDConfigSection EntitySection WRDEntitySection } WRDConfigSection ::= WRDConfigLine WRDConfigLine ::= [DATA 0] SEQUENCE { Scale INTEGER } WRDEntitySection ::= SEQUENCE OF WRDEntity WRDEntity ::= CHOICE { Node WRDNode Trace WRDTrace } WRDNode ::= SEQUENCE [DATA 1] { NodeName WRDName NodePoint WRDPoint } WRDTrace ::= SEQUENCE [DATA 2] { TraceName WRDName TraceType WRDTraceType PointSequence WRDLineDef } WRDLineDef ::= SEQUENCE { StartPoint WRDPoint MiddlePoints WRDPointSequence EndPoints WRDPoint } WRDPointSequence ::= SEQUENCE OF WRDPoint WRDPoint ::= [DATA 3] SEQUENCE { x FLOAT y FLOAT } WRDName ::= OCTET STRING WRDTraceType ::= CHIOCE { 0, 1 } END 4.4 Példa WRD állományra Az útvonal adatbázis egy úgynevezett CDF formátumú szöveges adatbázis, aminek kiterjesztése WRD. Az állomány egy speciális, adat táblának feleltethető meg, amely az ASN1 szabvány alapján épül fel. Azaz az állomány egyes sorai rekordokat azonosítanak, melyben az értékeket

egy speciális határoló jellel választjuk el – ez általában a vessző, azaz ’,’ karakter. Szavakban kifejezve az adatbázis kétféle rekordot tartalmaz. Az egyiket a nevesített csomópontok, a másikat az útvonalak polygonjainak leírására. A következőkben bemutatok egy egyszerű példát az adatbázisra: 0,1000 1,45676572,300,60 1,4275646170657374,0,0 1,4D69736B6F6C63,360,0 2,3330,0 3 ,0 ,0 3,300,30 2,3330,0 16. oldal # Méretarány 1:1000 # Eger: 300,60 # Budapest: 0,0 # Miskolc: 360,0 # 30as út: 0,0 ó 300,30 # 30as út: 300,30 ó 360,0 3,300,30 3,360,0 2,3335,0 3,300,30 3,300,60 2,333431,1 3,300,60 3,360,0 2,4D33,0 3 ,0 ,0 3,180,10 3,360,0 # 35ös út: 300,30 ó 300,60 # 341es út: 300,60 à 360,0 # M3as út: 0,0 ó 320,0 Az egyes rekord kódok jelentése: 0 – Konfiguráció. 1 – Nevesített csomópont. 2 – Nem megszakítható egy vagy kétirányú útvonal, két pont között. 3 – Pont leíró Az egyes útvonal típus kódok jelentése: 0 –

Kétirányú útvonal. 1 – Egyirányú útvonal. A nem megszakítható útvonalak használatával modellezhetővé válik például, hogy az autópályáról nem lehet akárhol lehajtani, illetve nem lehet autóval a várfalon átkelni. Ez persze azt teszi szükségessé, hogy az útvonal adatbázist a lehető legfrissebb formájában tároljuk mindig, mert ha új utakat készítenek azokat is fel kell vinni az adatbázisba, de ez a valóságban mindig megoldható, hiszen az autós térképek is csak évente frissülnek, viszont amikor kikerülnek a nyomdából szinte máris elavultnak mondhatóak bizonyos szempontból, mert az új utak nem egyszerre készülnek el. A konfigurációs rekord teszi lehetővé, hogy az útvonal adatbázis egyes tulajdonságait beállítsuk. Ilyen tulajdonság lehet pl. a méretarány, de további beállítások is lehetségesek, amelyek az import és export funkciókat segítik A nevesített csomópont első attribútuma a csomópont neve, ezt OCTET

STRING-ként tároljuk, ahol az egyes karaktereket az ANSI táblabeli értékének hexadecimális értékével reprezentáljuk. A következő két paraméter a csomópont koordinátáját adja meg. Az útvonal első attribútuma szintén a neve, mely a csomóponthoz hasonlóan épül fel. Ha ez üres, akkor az útnak nincs (száma) neve, ilyen lehet például egy földút reprezentációja. A második attribútum az út járhatóságát mutatja, ha ez az érték 0, akkor mindkét irányban járható útról beszélünk, ha 1 az értéke, akkor csak a kiinduló pontból járható útról van szó. Ilyen egyirányú út lehet például egy hegyi útszakasz, ami télen csak lefele járható Ezután jön az útvonal polygonját leíró pont szekvencia. A polygont leíró szekvencia legalább két pontból kell, hogy álljon. Az egyik a kiindulópont a másik a végpont, ennek a megkülönböztetésnek csak az egyirányú utak esetén van jelentősége. Viszont állhat több pontból is

azért, hogy az út hosszát pontosabban lehessen megállapítani. 17. oldal 5 Útvonal adatbázis készítése és az „Útvonal adatbázis készítő kiegészítés” A program tartalmaz egy kiegészítést, amivel könnyebben és hatékonyabban lehet felépíteni az WapRoute alkalmazás útvonal adatbázisát. Ez a kiegészítés az AutoCAD 2000 program egy kiterjesztése Mivel az AutoCAD egy grafikus tervező rendszer, melynek grafikus felülete kiválóan alkalmas síkba rajzolható gráfok szerkesztésére is, ez a tulajdonsága nagyon hatékonnyá és szemléletessé, illetve könnyen javíthatóvá és ellenőrizhetővé teszi az útvonal adatbázis felépítését. Hiszen egy AutoCAD használatában jártas személy pillanatok alatt képes lehet egy digitalizáló tábla segítségével mérethelyes térképszerű vonalhálózatot készíteni, ami teljes egészében megfelel a WapRoute program útvonal absztrakciójának. Itt meg kell említeni, hogy más féle

absztrakciók is elképzelhetőek, hiszen például szükség lehetne az útvonal mellett haladó járdákra, esetleg telefonhálózatra vagy egyéb nem leíró, hanem grafikusan is megjelenő információra. Esetleg az útvonal helyes szintezése érdekében 3 dimenziós rajzok készítése is szükséges lehet. Ezeknek a feladatoknak a megoldásához már bonyolultabb GIS rendszer támogatását kellene igénybe venni az útvonal adatbázis felépítéséhez. Egy ilyen átfogó GIS rendszer felépítése önmagában is egy külön szakdolgozati téma lehetne. 5.1 Új útvonal adatbázis készítése Az útvonal adatbázis egy úgynevezett CDF formátumú szöveges adatbázis. Az állomány egy speciális, adat táblának feleltethető meg, amely az ASN1 szabvány alapján épül fel. Azaz az állomány egyes sorai rekordokat azonosítanak, melyben az értékeket egy speciális határoló jellel választjuk el – ez általában a vessző, azaz ’,’ karaker. Az egyes rekordok

jelentését az útvonal adatbázis formátumának szintakszisát megadó leírás tartalmazza. Ezt az „Útvonal adatbázis formátuma” című fejezet tartalmazza. Az ott található példából egy „pelda.wrd” állomány készíthető Ezt a példát az installáló CD is tartalmazza és telepíti a rendszerre, ha a példa adatbázisok telepítését is kiválasztja. Ez az állomány tetszőleges szövegszerkesztővel módosítható. Egy útvonal adatbázis létrehozása után azt a WapRoute szervlet által elérhető helyre kell másolni, valamint annak konfigurációs állományát módosítani, hogy az új adatbázist használja a válaszok generálására. Ennek menetéről a WapRoute szervlet konfigurálása fejezetben olvashat többet. 5.2 Útvonal adatbázis készítése AutoCAD 2000-rel Ahogy az előző példában látható az útvonal adatbázist leíró állomány szerkezete nem bonyolult. Így akár egy szövegszerkesztővel is könnyen módosítható. Azonban

grafikus felület nélkül a vonalak nehezek képzelhetőek el, és térképről való mérethelyes bevitelük is nehézkes a szövegszerkesztővel, bár nem lehetetlen. Egyes javításokat esetleg könnyebben elvégezhetünk a szövegszerkesztős módosítással, például ha egy utat átneveznek, alacsonyabb rendűvé nyilvánítanak a szövegszerkesztők „keres és helyettesít” funkciója igen hatékony megoldást jelent a hibamentes adatjavításhoz. Viszont a kezdeti adatbázis előállítása illetve a hibakeresés könnyebben kezelhető egy grafikus felületen, ahol a felhasználó szinte a rajzolás pillanatában látja, hogy két út találkozik egy adott pontban vagy nem. Ahol a városokat (Nevesített csomópontokat) más szimbólum jelöli, mint az útkereszteződéseket. Az egy irányban járható utakat más vonaltípus jelöli, mint a kétirányúakat valamint a vonaltípusban megjelenő információ az útvonal irányítottsága is. Ezért készült az AutoCAD-ben

futó „Útvonal adatbázis készítő kiegészítés”. Ennek használatához a felhasználónak szüksége van az AutoCAD 2000 program csomagra, valamint a kiegészítés installálására. Ha a kiegészítés telepítésekor az AutoCAD 2000 már a rendszer része, akkor a programindító csoportba bekerül egy „Útvonalkészítés AutoCAD 2000-rel” feliratú indító menü, amivel a kiegészítés elindítható. Ha az AutoCAD 2000 később kerül installálásra, akkor a kiegészítés könyvtárában található EXE program futtatásával indíthatja el a kiegészítést. Illetve ha a programot parancssorból indítja CREATE paraméterrel, akkor a fent említett menüpontot létrehozza a program a „Start” menüben, hogy később könnyebben elérhető legyen a funkció. 18. oldal 5.3 A program indítása (paraméterek) Az AutoCAD-et indító program a „WapRoute” telepítési könyvtárában levő „Database designer” könyvtárban található. Ez az EXE

program indítja el az AutoCAD-et olyan környezeti beállításokkal, amelyek lehetővé teszik az útvonaltervezést. Az EXE program paraméterek nélküli indítása megkeresi az AutoCAD-et a rendszerben, ha nem találja, akkor a felhasználóval egy ablakban tudatja, hogy a keresett program nem található. Ekkor ellenőrizze, hogy az AutoCAD tényleg megfelelően lett-e a rendszerre telepítve. Hat féle indítás lehetséges: Paraméter nélküli, CHECK, CREATE, DESKTOP, PROFILE és REGISTER. Példák az indításra: Db4acad15.exe Db4acad15.exe PROFILE • CHECK paraméterrel indítja el a programot, akkor az ellenőrzi, hogy az AutoCAD rendesen lett-e a rendszerre telepítve, ha igen, akkor 0-val tér vissza a program. Ha a telepítés nem sikerült, akkor 1-vel tér vissza. Ezeket a visszatérési értékeket a parancssori szkriptekben az ERRORLEVEL változóval lehet lekérdezni. Ennél az indítási formánál a program nem ír semmit a képernyőre, csak a visszatérési

értékben jelez. (Installáló program használja) • CREATE paraméterrel indítja a programot, akkor a WapRoute Start menü könyvtárban létrehoz egy gyorsító menü pontot, ahonnan gyorsan el tudja indítani az útvonalkészítő kiegészítést. Ha az ikon létrehozása nem sikerül, akkor ezt semmilyen formában nem tudatja a felhasználóval. (Installáló program használja) • PROFILE paraméterrel indítja, ekkor létrehoz egy WapRoute.arg nevű állományt a „Database Designer” könyvtárban, amiben a WapRoute program AutoCAD felhasználói profilja található. Ebben az állományban az általános felhasználói profil adatai vannak az útvonal-adatbázis kiegészítés futtatásához szükséges paraméterekkel kiegészítve. Ezáltal a program a megfelelő menüket fogja megjeleníteni az AutoCAD megjelenítésekor. Ha az állomány létrehozása nem sikerül, akkor ezt semmilyen formában nem tudatja a felhasználóval. (Installáló program használja) •

DESKTOP paraméterrel indítja a programot, akkor az aktuális felhasználó desktopján hoz létre egy gyorsító ikont. Ha az ikon létrehozása nem sikerül, akkor ezt semmilyen formában nem tudatja a felhasználóval (Installáló program használja) • REGISTER paraméterrel indítva a programot az ellenőrzi, hogy a megfelelő verziószámú AutoCAD installálva van-e a rendszeren. Ha igen, akkor az útvonal kezelő alkalmazás parancsait installálja az AutoCAD-be. Azaz a felhasználónak nem kell az alkalmazás indításakor a külső „WapRoutearx” programot az AutoCAD-be betöltenie, hanem az a megfelelő parancsok kiadásakor automatikusan a memóriába kerül. Ha ezt a parancsot nem futtatja a rendszeren és a csak a telepítés után kerül a rendszerbe a program, akkor minden egyes alkalmazás indításkor az „APPLOAD” paranccsal a fent említett programot be kell töltenie az AutoCAD-be. Ha a programot ezzel a paraméterrel indítja és nem található a

rendszerben megfelelő verziószámú AutoCAD, akkor egy ablakban értesíti erről a felhasználót, valamint a visszatérési értékben a hívó programot. (Installáló program használja) • Ha paraméterek nélkül indítja a programot, akkor a registry-ből törli a felhasználóhoz tartozó WapRoute profilt, így az AutoCAD indításakor az a „WapRoute.arg” állományt fogja használni a felhasználói beállítások lekérdezéséhez. Ezért ha bármikor más beállításokat szeretne használni, azokat az AutoCAD-be történt változtatás után el kell mentenie (exportálnia kell) a „WapRoute.arg” állományba, hogy például az új háttérszín beállításai megmaradjanak. 5.4 A menürendszer és parancsok leírása A paraméter nélküli indítás esetén az AutoCAD elindul és a felhasználói felülete a WapRoute kiegészítés menürendszerét fogja tartalmazni, melynek leírását ebben a paragrafusban találja. A menürendszerből minden funkciója

elérhető a kiegészítésnek, ha az AutoCAD sikeresen betöltötte a megfelelő ARX kiterjesztésű állományt. Ez az állomány tartalmazza az új parancsokat és funkciókat. A program helyes betöltéséről úgy győződhet meg, hogy a menürendszer elemei aktívak, valamint az aktuális rajz tartalmazza azokat a speciális rétegeket, amelyek az útvonal adatbázis készítéséhez szükségesek. A címek mellett található kétféle jelölés (Modális parancs és Transzparens parancs). Ezek közül a Modális jelző azt jelenti, hogy a parancsot csak akkor lehet kiadni, ha más parancs nem aktív, azaz ha az AutoCAD parancs ablakában a „Command:” felirat után villog a kurzor. Transzparens parancs esetén a funkciót egy másik parancs futása közben 19. oldal is meg lehet hívni. Ha menü rendszerből hívja meg a parancsokat a Modális parancsok az előző utasítás futását megszakítják, hogy az újat végre tudják hajtani. Transzparens parancsok esetén

az transzparens utasítás végrehajtása után az előző funkció folytatódik onnan, ahol a transzparens parancs megszakította. Amikor az AutoCAD-ben a felhasználó egy mentés parancsot ad ki az alkalmazás megkérdezi a felhasználót, hogy a mentéssel párhuzamosan exportálja-e az állományt. Ha a felhasználó ekkor igent mond, akkor a rajz állomány mellett egy azonos nevű de „WRD” kiterjesztésű állomány is keletkezik. Ezt az állományt kell majd később a „WapRoute” alkalmazás konfigurációs állományában megadni, mint adatbázisforrást. 5.41 Útvonal rajzolása – Modális parancs Ennek a parancsnak az aktiválására a program egy ablakot jelenít meg, amelyben a felhasználónak meg kell adnia az új útvonal adatait úgy, mint a neve és az irányítottsága. Az út nevének nem kell egyedinek lennie, hiszen az utakat meg is lehet, sőt kell szakítani egy-egy kereszteződésben, hogy a program, később a csatlakozásokat megfelelően tudja

értelmezni. • Az út neve tartalmazhat bármilyen – nem vezérlő – karaktereket. Ezt a nevet a program, később a megrajzolt út felett meg is jeleníti. Az alkalmazás a név kezdetén és végén található white-space karaktereket törli, a névnek a törlés után kell legalább egy karaktert tartalmaznia. • Az út irányítottsága háromféle lehet a rajzon. Kétirányú, azaz az úton kétirányú közlekedés valósítható meg. Egyirányú balról jobbra, azaz az út a rajzolás irányában egyirányú, és egyirányú jobbról balra, azaz az út egyirányú a rajzolás irányával ellentétes irányban. Ha ezeket a paramétereket megfelelően beállította, akkor a „Rendben” gombra kattintás után az út nyomvonalát kell megadnia. Ez egy legalább két pontból álló polyline kell, hogy legyen A vonal megrajzolása után a program létrehozza az útvonal objektumot. Az objektum létrehozásával párhuzamosan a program az út felett szegmensekét elhelyezi

az út nevét is. Ezek a feliratok adatot nem hordoznak csak a rajzolónak vizuális információt szolgáltatnak, így tetszőlegesen törölhetőek. A funkció közben azt bármikor megszakíthatjuk az ESCAPE billentyű, vagy a „Mégse” gomb egyszeri megnyomásával. 5.42 Csomópont (Város) rajzolása – Modális parancs A parancs egy ablakot jelenít meg, ahol a felhasználónak meg kell adnia az új csomópont (város) nevét, majd a „Rendben” gomb vagy az „ENTER” billentyű megnyomásával az adatokat fixálnia kell. A név megadása után a csomópont beszúrási pontját kell megadnia a felhasználónak. Ezután az alkalmazás létrehozza az objektumot, és egy feliratot helyez el a csomópont felett, ami a csomópont nevét tartalmazza. A csomópont nevét az alkalmazás trimmeli, azaz a kezdetén és a végén található white-space karaktereket törli, a helyes névnek a törlés után kell legalább egy karaktert tartalmaznia. A funkció közben azt bármikor

megszakíthatjuk az ESCAPE billentyű, vagy a „Mégse” gomb egyszeri megnyomásával. 5.43 Útvonal módosítása – Modális parancs A parancs aktiválása után a felhasználónak ki kell választania a módosítandó útvonalakat a rajz területen. A kiválasztást az „ENTER” billentyűvel fejezheti be. Ha a felhasználó nem választ ki elemeket a rajzon, akkor ezt az alkalmazása egy üzenetben tudatja vele. Az útvonalakat az AutoCAD-ben általános kiválasztási módszerekkel lehet megadni. A kiválasztás után egy ablakban jeleníti meg a kiválasztott útvonalak tulajdonságait a program. Ha különböző nevű útvonalakat választott ki, akkor az útvonal neve mező nem lesz kitöltve. Ha a kiválasztott útvonalak különböző irányítottságúak, akkor az útvonal típusánál a legördülő mezőben „àKülönböző típusú útvonalakß” felirat jelenik meg. A felhasználó ezeknek az értékeknek a módosításával tudja a kiválasztott útvonalak

megfelelő tulajdonságait megváltoztatni. Ha az útvonal neve mezőt üresen hagyja, akkor a kiválasztott útvonalak nevei nem fognak változni Ha a legördülő menüben a „àKülönböző típusú útvonalakß” választást nem változtatja meg a felhasználó, akkor a kiválasztott elemek típusát a módosításkor a program nem fogja megváltoztatni. 20. oldal A változtatások szerint az elemek csak akkor módosulnak, ha a felhasználó az ablakot a „Rendben” gombbal zárja be. Ha a „Mégse” gombra kattint vagy az „ESCAPE” billentyűt megnyomja egyszer, akkor a funkció semmilyen módosítást nem végez el és terminál. 5.44 Csómópont (Város) módosítása – Modális parancs A csomópontokat az útvonalaktól eltérően csak egyesével lehet módosítani. A funkció aktiválásakor a program a felhasználótól egy csomópont kiválasztását kéri, majd a kiválasztás után a kiválasztott csomópont nevét egy ablakban jeleníti meg. Ha a

felhasználó nem választ ki semmit, akkor erre figyelmezteti a program, és ismét a kiválasztási funkció lép működésbe. Az ablakban megjelenő felirat a csomópont eredeti neve melyet tetszőlegesen megváltoztathat a felhasználó úgy, hogy az még érvényes azonosító legyen. (nem tartalmazhat csak white-space karaktereket) A változtatást a felhasználó a „Rendben” gombra kattintva mentheti a rajzra. Ekkor a rajzon a csomóponthoz tartozó felirat is megváltozik az új értékre. A funkció az ESCAPE billentyű egyszeri megnyomásával vagy a „Mégse” gombra való kattintással megszakítható, ekkor semmilyen változás nem történik a rajzon. 5.45 Város keresése név szerint – Transzparens parancs A program egy ablakot megjelenítve várja, hogy a felhasználó kiválasszon egy várost. A kiválasztás történhet a keresett város nevének beütésével, vagy a legördülő menüből. Amikor a felhasználó begépeli a város nevét, akkor a

legördülő menü listájából a program a legelső azonos prefixü városnév további karaktereivel egészíti ki a beviteli mező értékét úgy, hogy ha további karaktereket visz be a felhasználó akkor az addigi prefix mindig megmarad és a postfix érték törlődik. Így elérhető, hogy a keresett városnak nem kell a teljes nevét begépelni, elég annak csak egy prefixét, hogy a kiválasztás megtörténjen. A kiválasztás pillanatában a rajzon az aktuálisan kiválasztott elem piros színnel a képernyő közepén jelenik meg. A kiválasztás után a „Rendben” gombra kattintva vagy az „ENTER” billentyű leütésére a program a kiválasztott várost a képernyő közepére hozza az aktuális nagyítással. A parancs a „Mégse” gombbal vagy az „ESCAPE” gomb megnyomásával megszakítható. A parancs megszakítása esetén a parancs indításakor nézet marad A parancs végrehajtása után más, például a transzparens Zoom parancsokkal a megfelelő

nagyításban gyönyörködhetünk a kiválasztott városban. 5.46 Útvonal keresése név szerint – Transzparens parancs A program egy ablakot megjelenítve várja, hogy a felhasználó kiválasszon egy út nevet. A kiválasztás történhet a keresett út nevének beütésével, vagy a legördülő menüből. Amikor a felhasználó begépeli az út nevét akkor a legördülő menü listájából a program a legelső azonos prefixü útnév további karaktereivel egészíti ki a beviteli mező értékét úgy, hogy ha további karaktereket visz be a felhasználó akkor az addigi prefix mindig megmarad és a postfix érték törlődik. Így elérhető, hogy a keresett útnak nem kell a teljes nevét begépelni, elég annak csak egy prefixét, hogy a kiválasztás megtörténjen. Az út kiválasztás után a legördülő menü alatt található lista dobozban az útvonalhoz tartozó szegmensek számával megegyező számú ikon jelenik meg. Az ikonok az egyes szegmenseket útvonal

típusának megfelelően jelennek meg Egy útvonal név kiválasztás után az összes ikont kiválasztott formában jeleníti meg az ablak, de a felhasználó ezt a kiválasztást megváltoztathatja. A rajzon megjelenő nagyítás ennek a listának az állapotától függ Az itt kiválasztott szegmensekre Zoom-ol a program és azok vonalának színét pirosra is állítja, hogy könnyebben megtalálhassa őket a felhasználó. A színezés csak a funkción belül él Utána az egyes szegmensek felveszik eredeti színüket A kiválasztás után a „Rendben” gombra kattintva vagy az „ENTER” billentyű leütésére a program az aktuális nézetet megtartja. A parancs a „Mégse” gombbal vagy az „ESCAPE” gomb megnyomásával megszakítható, ekkor az eredeti nézet lesz ismét aktuális. A parancs végrehajtása után más – például a Zoom – transzparens parancsokkal a megfelelő nagyításban gyönyörködhetünk a kiválasztott városban. 21. oldal 5.47

Feliratok elrejtése (megjelenítése) – Transzparens parancs Erre a menüpontra kattintva a feliratokat tudjuk megjeleníteni, illetve elrejteni a rajzon. A menüpont felirata annak megfelelően változik, hogy a feliratok rétege látható vagy nem látható, ettől függően a menüpont mellett egy pipa is megjelenik, hogyha a réteg látható. 5.48 Azonos nevű útvonalak összefüggőségének ellenőrzése – Modális parancs A program egy az „Útvonal keresés név szerint” funkcióval teljesen azonos ablakot jelenít meg. Az ablakban az útvonalakat szintén a nevük szerinti csoportosításban jeleníti meg, de csak azokat, amelyek a rajzon nem alkotnak összefüggő gráfot. Az összefüggőséget az útvonalak végpontjainál ellenőrzi csak Azaz egy több vonalból álló szegmens csak a végpontjainál csatlakozhat a gráfhoz. (Ez a szemlélet megegyezik azzal, ahogy az adatbázist kezeli majd az alkalmazás – azaz az utak csak a végpontjaiknál

csatlakozhatnak.) Az ablak megjelenésileg és funkcionálisan is teljesen megegyezik a fent említett funkció ablakával. Azaz a legördülő dobozban kell kiválasztani a keresett utat és a doboz alatti listában, a közelebbről megtekinteni kívánt szegmenseket. Az ablak bezárása a „Rendben” gombbal az aktuális nézet megtartását jelenti. A „Mégse” gombbal pedig a funkció előtti nézet aktiválódik ismét. 5.49 Útvonal ellenőrzés két csomópont (város) között – Modális parancs Ez a funkció egy az eddigieknél jóval bonyolultabb feladatot lát el. A funkcióval két tetszőlegesen kiválasztott csomópont közötti összes út lekérdezhető, amelynek hossza a legrövidebb út hosszának legfeljebb kétszerese. Ez az utóbbi feltétel azért szükséges, mert a funkció adminisztratív jellegű. Feladata az adminisztrátor számára az adatbázisban olyan útvonalak keresése, amelyek egy meglevő útvonalat kiválthatnak. Jelenleg a funkciónak

nincsen haszna a szakdolgozatban megadott feladatok megoldása szempontjából. De a program tovább fejlesztésének egy olyan fokán, amikor az útvonal keresés több szempont szerint történik már (jelenleg csak a legrövidebb útvonal keresésére van lehetőség) akkor az adminisztrátornak ezeket a legrövidebb utakat meg kell tudnia nézni. Azokat rangsorolnia kell tudni Ebben a funkcióban láthatja el az adminisztrátor az ellenőrzési feladatot is, amikor egy útlezárás alkalmával alternatív útvonalat(-akat) kell javasolnia a felhasználónak. A funkció további feladata az útvonalak mentén szereplő városok ellenőrzése, hogy az adott út tényleg érint-e egy várost, másik útvonalat vagy csak digitalizálási hiba folytán kapcsolódik logikailag egy másik objektumhoz. Ebben a funkcióban megvalósítandó lehetséges útkeresési algoritmus leírását lejjebb az „Útvonal ellenőrzés” fejezet tartalmazza. 5.410 Útvonal adatbázis betöltése –

Modális parancs Az útvonal adatbázis készítő program képes már létező adatbázisokat importálni az AutoCAD-es rendszer alá. Ezzel a funkcióval lehetővé válik már létező adatbázisok grafikus tesztelése (ld. Ellenőrző funkciók) A funkció indításakor egy ablakban ki kell választani a betöltendő állományt. Az ablakban csak a WRD kiterjesztésű állományok kiválasztása lehetséges. A kiválasztás után a funkció a kiválasztott állományt végig olvassa, és a számára értelmezhető objektumokból rajz objektumokat hoz létre. Majd végül egy összesítést jelenít meg, amiben tételesen felsorolja, hogy hány elem importálása volt sikeres hány byte-ot illetve sort olvasott be, valamint hény elemet talált hibásnak az importálás során. 5.411 Útvonal adatbázis mentése – Modális parancs Az útvonal adatbázis készítő alapfunkciója a rajzon létező adatformátum exportálása útvonal adatbázis (WRD) formátumban. A funkció

indításakor egy ablakban kell megadni a készítendő állomány nevét és útvonalát. Ha a felhasználó egy már létező állományra mutat, akkor a program erre figyelmezteti. Ekkor a program az ismételt megerősítés hatására a már létező állományt felülírja. Az exportálás végeztével a program ekkor is, mint az importálásnál egy összesítést jelenít meg az exportban eltárolt elemek számáról, a létrehozott sorok számáról és a létrehozott állomány hosszáról. 22. oldal 5.5 AutoCAD objektumok leírása 5.51 Útvonal Az útvonal objektumot az alkalmazás az AutoCAD-en belül egy polyline-ként (LWPOLYLINE) ábrázolja. Az út irányítottságát a vonal típusa határozza meg ami lehet „BJ-Egyirányú”, „JB-Egyirányú” vagy egyéb. • Az egyéb vonaltípust az alkalmazás a kétirányú útnak felelteti meg. • A „BJ-Egyirányú” vonaltípus a kezdőponttól a végpont felé egyirányú útnak felel meg. • A

„JB-Egyirányú” vonaltípus a végponttól a kezdőpont felé egyirányú útnak felel meg. Az útvonalaknak az alkalmazáshoz regisztrált XData részében az alkalmazás elmenti az útvonal nevét a 1001-es gcjü lista elemben, hogy az később az adatmódosításnál, az objektum azonosításnál illetve az exportálásnál könnyen elérhető legyen. Az útvonalak nevét a program az útvonalak felett szakrajzon megjelenő feliratok írásirányával megegyező formában is megjeleníti. Ezek a feliratok csak a rajzolónak nyújtanak információt, pozíciójuk és tartalmuk nem kerül elmentésre az export alkalmával. Ezért a feliratok tetszőlegesen másolhatók, mozgathatóak, törölhetőek és módosíthatóak. 5.52 Csomópont A csomópont objektumot az alkalmazás az AutoCAD-en belül egy blokként (INSERT) ábrázolja. A blokk egy telített kört tartalmaz és egy feliratot, amely a csomópont nevét adja meg. A csomópontot a programmal a WP VAROS rétegen

helyezheti el a felhasználó. Ennek a rétegnek a színe kék, így a kör is kék színben jelenik meg A blokkhoz tartozó másik elem a felirat egy másik rétegen a WR FELIRAT rétegen helyezkedik el, ezért annak színe zöld. A felirat megjelenését a menüben található „Feliratok elrejtése (megjelenítése)” menüponttal állíthatja be a felhasználó. A feliratot a program kör fölött középre rendezve jeleníti meg, de ez a pozíció a grafikus felületről vagy az AutoCAD más elem manipuláló parancsaival megváltoztatható. Jelenleg a programcsomag a feliratok helyét nem használja fel semmire, de ez a későbbiekben könnyen megváltoztatható az ASN1 leírás és az import export funkciók megváltoztatásával. A csomópontnak az alkalmazáshoz regisztrált XData részében az alkalmazás elmenti a csomópont nevét a 1001-es gc-jü lista elemben, hogy az később az adatmódosításnál, az objektum azonosításnál illetve az exportálásnál könnyen

elérhető legyen. 5.6 Útvonal ellenőrzés Az útvonal adatbázis tervező kiegészítés legfontosabb funkciója. Ezzel a funkcióval vizuálisan ellenőrizhető a létrejött adatbázis összefüggősége. Az adatbázison történő egyes lekérdezések eredményei szimulálhatóak, és hiba esetén könnyen javíthatóak a többi funkció segítségével. Az programnak programozás technikailag ez a legösszetettebb része, ezért ennek a funkciónak szentelek a legtöbb figyelmet a leíráson belül. Míg a többi funkció a megjegyzések által a kódban is könnyen átlátható, addig ez a funkció igényli a dokumentumban eddig szereplő ismereteket, valamint az itt ismertetésre kerülő algoritmus ismeretét is. Az útvonal ellenőrzés feladata, hogy két adott (különböző) csomópont között az összes lehetséges útvonalat megtalálja, és azokat valamilyen formában a felhasználó által lekérdezhetővé megtekinthetővé tegye. Az összes út meghatározása

itt feltétlenül szükséges, hiszen ez egy ellenőrző funkció, aminek nem feladata az útvonalak szempontok szerinti szűrése. Viszont ez a feladat egy nagy adatbázis esetén óriási erőforrás mennyiséget igényelne Ezért a funkcióban szükségszerűen mégis egyszerűsítéseket kell beleépíteni. Így az összes út meghatározásánál: • Nem veszünk figyelembe olyan utakat, amelyek köröket tartalmaznak • Az utakat csak a legrövidebb út hosszának legfeljebb 2 szereséig vizsgáljuk Ezek a szempontok az útkeresés hatékonyságát az út hosszában csökkentik, így az algoritmus kevesebb memóriát igényel majd. De ezen szempontok szerinti útkeresés még mindig nagyon lassú lehet Gondoljunk arra hogy, ha az adatbázis nem csak az országutakat hanem a városon belüli rövid kis utcákat is tartalmazza. Akkor egy rosszul megválasztott algoritmus egy városba beérve a kis utcákon akar továbbjutni, amikor nyilvánvaló, hogy ott a legrövidebb utat kell

választani, és igazából az útvonal hatékonysága a hosszabb utak kiválasztásán múlik. Ezek az igények egy speciális algoritmus használatát követelik meg. 23. oldal Hiszen ilyen körülmények között nem választhatjuk egyik általános legrövidebb útkereső algoritmust sem, mert azok általában azon alapulnak, hogy az algoritmus a kezdőpontból veszi a legrövidebb kimenő utat, és úgy épít fel egy minimális súlyú feszítő fát. Ez az algoritmus akkor lehet optimális, ha az utak hosszai közel azonosak, vagy tényleg egy minimális feszítő fára vagyunk kíváncsiak. Mert ha egy város közepéről indulunk, akkor ezek az algoritmusok a város feszítő fája után városhoz legközelebb eső város feszítőfáját építik és így tovább. Mikor nyílván egy főutat kellene célba venniük. Más gráf kereső algoritmusokat használnak az MI területén ott az útkeresőket, úgy okosítják meg, hogy a következő él kiválasztását

függvényekkel próbálják jósolni. Ezek a heurisztikák az élekből kiinduló utakat osztályozzák és az algoritmus a legjobbnak tűnőt választja. Ezeknek az algoritmusoknak a hibája lehet, hogy a jelen probléma megoldásához nagyon bonyolult heurisztikákat kell kiszámolnia, valamint egy út megtalálása esetén nem biztosítja a további utak könnyed megkereséséhez az elegendő információt. Valahogy a kettőt kellene ötvözni, hogy optimális keresési algoritmust találjunk a jelenlegi problémára. Ezt a korcsot, amit a két algoritmusból hozok létre nevezem toleráns keresésnek. A toleráns szót a „tolerancia” szó alapján választottam. Mivel az algoritmus az egy városban levő csomópontokat egy csomópontkánt fogja kezelni Így gyakorlatilag az útvonal adatbázist két szintre osztom az útvonalak hossza alapján. Mostantól ebben a részben az út fogalmát egy kicsit módosítom mivel így szerintem könnyebben érthetővé válik a feladat

megoldása. Azaz az út a gráfban egy él volt Most egy olyan él-sorozatot értek rajta, amelyik nem tartalmaz olyan csomópontot ahonnan kettőnél több él vezetne kifele. Azaz az olyan utakat amelyek megtörnek de csak két élet köt össze összevonom egy úttá. Ez az összevonás csak logikailag történik, meg azaz az új út hossza meg fog egyezni az eredeti utak út hosszának összegével. • Városban levő utak, amelyeknek a hossza egy bizonyos értéket nem halad meg. • Városon kívüli utak, amelyeknek a hossza nagyobb az előbb említett hossz értéknél. Az így létrejött úthalmazok alapján a következő műveletekre van még szükség. A városban levő utakat városonként csoportosítani kell, és az így létrejött halmaz mellé meg kell jegyezni a városból kivezető utak indító koordinátáit is, és ezek alapján a koordináták alapján ki kell számítani az adott városban az összes kivezető út közötti legrövidebb utat. Az így

létrejött logikai utakat a városon kívüli utak halmazához hozzá kell adni A bővített városon kívüli utak halmazán elvégezni a legrövidebb útkereső algoritmust. A legrövidebb útkereső algoritmus leírását később fogom megadni, a WapRoute szervlet tárgyalásánál. 24. oldal 6 WapRoute szervlet megvalósítása 6.1 Szervlet paraméterei A szervletet a Nokia WAP Szerver fogja futtatni, mint azt már az előző paragrafusban is írtam. Viszont még nem esett szó arról, hogy a szervlet helyes müködéséhez azt megfelelöen paraméterezni kell. Ezek a paraméterek a szervlet élete során konstans értékű paraméterek. Ilyen paraméterekben kell megadni a szervletnek az útvonal adatbázis helyét és nevét és egy temporáris állomány nevét, amelyet a válaszok generálásának gyorsításához használhat. A késöbbiekben a a programbővítése esetén ez a paraméterlista bövülhet A Nokia WAP Szervernél ezeket a paramétereket a szervlet

inicializálásakor kell beállítani. Ezek az értékek 6.11 „database” paraméter Az útvonal adatbázis helyét és nevét adja meg. Ez általában egy WRD kiterjesztésű állomány A paraméter beállításánál különösen oda kell figyelni, mert rossz állomány megadása esetén a szervletet nem lehet inicializálni, ami a szolgáltatás elérhetetlenségét eredményezi. Ennek megadása például: database C:WapRoutepelda.wrd 6.12 „language” paraméter A szervlet alapértelmezett nyelvét adja meg. Ha nem adjuk meg ennek a paraméternek az értékét, akkor az alapértelmezett nyelv a magyar lesz. A paraméter értékei a nyelvek kétbetűs ISO632 szabványnak megfelelő értékek lehetnek. Ezen kívül az érték megadásán túl, a nyelv használatához szükség van még arra, hogy az adott nyelven egy erőforrás osztály legyen elérhető a szervlet számára. Erről bővebben ugyanebben a fejezetben az „Az alkalmazás nemzetközisítése” cím alatt

olvashat még. Ennek megadása történhet például: language en 6.13 „temp” paraméter Egy ideiglenes állományok tárolására szolgáló könyvtárat jelöl ki. Ebben a könyvtárban fogja az alkalmazás elhelyezni azokat az ideiglenes információkat, amelyeket a kliensek, kiszolgálásánál használ. Ha nem adunk meg ilyen paramétert, akkor a szervlet az operációs rendszer ideiglenes állományokat tartalmazó könyvtárát fogja használni az ilyen állományok tárolására. Az ideiglenes állományokat olyan jelzőbittel látja el a szervlet, amelynek hatására a Java VM törölni fogja azokat mielőtt terminál. Ha a Jáva VM valamilyen okból kifolyólag nem megfelelően áll le, akkor ezeket az állományokat sem törli. Ezért lehetősége szerit ezt a könyvtárat úgy kell megválasztani, hogy a rendszer minden indításkor törölje az ott található állományokat. Ennek a paraméternek megadása és értéke például a következő lehet: temp 6.2

C:Temp Kliens kiszolgálása A WapRoute szervlet a hozzá érkező kérések alapján azok elemzése után különböző funkciókat végez el, majd a funkciók eredményeképpen WML vagy WBMP formátumú választ ír a kliens termináljára. A kéréseket a kérés paraméterei és a válaszok alapján különböző csoportokba sorolhatjuk. Én három ilyen csoportot különböztetek meg Az egyik ilyen csoport a kezdő képernyő, nyelv választás és a súgó funkciók generálása. Ebben a csoportban találhatóak azok a feladatok, amelyek megoldásához nem szükséges az útvonal adatbázis jelenléte az alkalmazásban. Az így megjelenített oldalakat vagy csak kártyákat lehet statikus oldalaknak is nevezni, hiszen nem függenek harmadik személy által módosítható adatoktól. Egy másik csoport az adatbázis alfanumerikus adatait lekérdező funkciókból áll. Ezek a funkciók a paraméterekben megadott feltételeknek megfelelően egy szöveges képernyőt generálnak.

Ahol az információt a felhasználó a sorok közül olvashatja ki. Az ilyen oldalakon van lehetőség az átlagos úthossz, népsűrűség, stb megjelenítésére A harmadik csoportja a lekérdezéseknek a grafikus információt lekérdező funkciók. Itt a szervlet az útvonal adatbázis adatai alapján olyan oldalt készít, amelyen megjelenő kép(ek) hordozzák az információ tartalmat. Az ilyen oldalakon a felhasználónak lehetősége van például vizuálisan nyomon követni a kiválasztott útvonalat. 25. oldal 6.21 A kezdő képernyő ULR: http://domain-name/waproute A kezdőképernyőt a szervlet akkor generálja, ha paraméter nélkül hívják meg a szervletet. Ez általában akkor fordul elő, ha a felhasználó maga gépelte be a szervlet URL-t, vagy egy oldalról a szervletre hivatkozó URL-t aktivizál. Ettől eltérő esetben is produkálhatja a kezdőképernyőt a szervlet akkor, ha érvénytelen paraméterezéssel hívják meg. A kezdőképernyő egy

DECK-ből és négy kártyából áll. 6.211 Bemutatkozás ULR: http://domain-name/waproute#WRS Az első kártya feladata a bemutatkozás. Ezen az oldalon a program neve, a készítőjének a neve, a készítés dátuma valamint a program célja olvasható. Innen a felhasználó egy kattintással eljuthat a „Funkciók” kártyára vagy a „Bemutatkozás - Súgó” kártya tartalmát olvashatja el. A súgón kívül a felhasználó az opciók között fogja még találni a nyelvválasztás lehetőségét kínáló linkeket is. Itt minden link egy-egy támogatott nyelv feliratával rendelkezik az adott nyelven megadott módján. A link aktiválásakor a bemutatkozó oldal újra generálódik, de a feliratok már a kiválasztott nyelvnek megfelelően fognak megjelenni. A nyelvválasztás funkcióját azért a legelső oldalon oldottam meg, mert ez az oldal még, csak olyan információkat tartalmaz, amelyeket minden nyelven közel azonosan fog a program megjeleníteni. Az itt

megjelenő program név mindig ugyanaz lesz, így a felhasználó tudhatja, hogy ez-e az az oldal, amit ő keres. Valamint az „Opciók” felirat a mobil terminálon kiválasztott nyelv szerint jelenik meg. Tehát a felhasználó, ha nem tudja elolvasni a jobb oldalon található „Funkciók” feliratot valószínűleg az „Opciók”-at fogja választani, ahol szerencsés esetben meg fogja találni a saját nyelve szerint leírt „nyelv” szót. Így azok számára is elérhető lesz a szolgáltatás, akik nem értik az alapbeállításban megadott nyelvet. 6.212 Bemutatkozás – Súgó ULR: http://domain-name/waproute#WRH1 Ennek a kártyának a feladata, hogy bővebben kifejtse a „Bemutatkozás” kártyán található információkat. Pontos instrukciót adjon a program használatának megkezdéséről, illetve az abban található általános (Minden oldalon elérhető) funkciókat ismertesse. 6.213 Funkciók ULR: http://domain-name/waproute#WRF Ezen a kártyán a

felhasználónak választania kell a szervlet által nyújtott szolgáltatások közül. Ilyen szolgáltatások az „Városkeresés”, „Útkeresés” és „Útvonalkeresés”. Az egyes szolgáltatásokat a nevükkel megadott linkeken keresztül lehet elérni. Az egyes linkek egy új DECK-et fognak letölteni a szerverről Erről az oldalról elérhető még az oldalhoz tartozó súgó is („Funkciók - Súgó”). Amelyre mutató linket az opciók között talál meg a felhasználó. 6.214 Funkciók – Súgó ULR: http://domain-name/waproute#WRH1 Ennek a kártyának a feladata, hogy az oldalon elvégzendő feladatot pontosítsa a felhasználó számára. Illetve a felhasználót segítse a döntése meghozatalában. Leírja, hogy az egyes linkek milyen további funkciókat fognak meghívni és a felhasználó a kérdések megválaszolása után milyen eredményeket láthat majd a képernyőn. 6.22 Városkeresés I ULR: http://domain-name/waproute?search=C Ezen az oldalon a

felhasználónak választania kell a keresési stratégiák közül. Kétféle módszerrel kereshet az adatbázisban szereplő városnevek között. Az egyik módszer a név alapján rendezett városokat csoportosítja 20 elemes csoportokba. Az oldalon ez a stratégia egy link listaként jelenik meg A linkek feliratai a csoportban szereplő első és utolsó város nevét mutatják. A felhasználó a link aktivizálásával léphet a „Városkeresés II” oldalra, ahol a kiválasztott csoport elemeit találja majd a felhasználó. 26. oldal A második keresési módszer a keresett város nevének egy része alapján történik. A megadott rész alapján a szervlet azoknak a városoknak a nevét adja majd vissza a „Városkeresés II.” oldalon, amelyek tartalmazzák a megadott karaktersorozatot. Ha ilyen város, nincs akkor ismét a „Városkeresés I” oldalt kapja majd vissza a felhasználó 6.23 Városkeresés II – csomag alapján, név alapján ULR:

http://domain-name/waproute?search=C&pile=1 ULR: http://domain-name/waproute?search=C&byname=bu Ezt az oldalt a „Városkeresés I.” oldal sikeres végrehajtása után jeleníti meg a szervlet Azaz ha a „Városkeresés I” oldalon a felhasználó kiválasztott egy városnév csoportot vagy a rész sztring alapján történő keresés eredménye nem egy üres halmaz. Az itt megjelenő oldalon linkek vannak, melyek feliratai az előző oldalon megadott keresési feltételnek tesznek eleget. Az itt megjelenő linkek a „Elemek alfanumerikus adatainak megjelenítése” oldalra mutatnak, ahol majd a kiválasztott város alfanumerikus tulajdonságait tekintheti meg a felhasználó. 6.24 Útkeresés I ULR: http://domain-name/waproute?search=L Ezen az oldalon a felhasználónak választania kell a keresési stratégiák közül. Kétféle módszerrel kereshet az adatbázisban szereplő útnevek között. Az egyik módszer a név alapján rendezett utakat csoportosítja 20

elemes csoportokba. Az oldalon ez a stratégia egy link listaként jelenik meg A linkek feliratai a csoportban szereplő első és utolsó út nevét mutatják. A felhasználó a link aktivizálásával léphet a „Útkeresés II” oldalra, ahol a kiválasztott csoport elemeit találja majd a felhasználó. A második keresési módszer a keresett út nevének egy része alapján történik. A megadott rész alapján a szervlet azoknak az utaknak a nevét adja majd vissza a „Útkeresés II.” oldalon, amelyek tartalmazzák a megadott karaktersorozatot. Ha ilyen út, nincs akkor ismét a „Útkeresés I” oldalt kapja majd vissza a felhasználó 6.25 Útkeresés II – csomag alapján, név alapján ULR: http://domain-name/waproute?search=L&pile=1 ULR: http://domain-name/waproute?search=L&byname=bu Ezt az oldalt a „Útkeresés I.” oldal sikeres végrehajtása után jeleníti meg a szervlet Azaz ha a „Útkeresés I” oldalon a felhasználó kiválasztott egy

útnév csoportot vagy a rész sztring alapján történő keresés eredménye nem egy üres halmaz. Az itt megjelenő oldalon linkek vannak, melyek feliratai az előző oldalon megadott keresési feltételnek tesznek eleget. Az itt megjelenő linkek a „Elemek alfanumerikus adatainak megjelenítése” oldalra mutatnak, ahol majd a kiválasztott út alfanumerikus tulajdonságait tekintheti meg a felhasználó. 6.26 Elemek alfanumerikus adatainak megjelenítése ULR: http://domain-name/waproute?query=alpha&obj=1001,1004 ULR: http://domain-name/waproute?query=alpha&box=0,0,100,100 Ezt az oldalt a sikeres keresési funkciók, illetve a grafikus képet megjelenítő oldal hívja meg. A bejövő paraméterek alapján ekkor a szervlet összeállítja azoknak az elemeknek a listáját, amelyek azonosítója az obj listában szerepel, vagy amelyek a box területén belül helyezkednek el. Ezeket az elemeket egy listában jeleníti meg az alkalmazás, amely listának minden eleme

egy táblázat. A táblázatban pedig egy-egy elem tulajdonságai szerepelnek A táblázatok alatt közvetlenül pedig egy link mutat egy olyan oldalra, ahol az adott elemet grafikusan tekintheti meg a felhasználó (Elemek grafikus megjelenítése). 6.27 Elemek grafikus megjelenítése ULR: http://domain-name/waproute?query=gamma&obj=1001,1004 ULR: http://domain-name/waproute?query=gamma&box=0,0,100,100 ULR: http://domain-name/waproute?query=image&box=0,0,100,100 Ezt az oldalt az alfanumerikus adatokat megjelenítő oldal vagy ez az oldal – például navigáláskor – hívja meg. Ha a szervlet obj paraméterekkel kerül meghívásra, akkor előbb kiszámolja az adott objektumok befoglaló területét, és ezután ugyanaz történik, mintha a szervletet csak a box paraméterrel hívták volna meg. Ha a szervletet a box paraméterrel hívják meg, akkor a szervlet megjelenít egy olyan WML oldalt, amely tartalmazza a box paraméter alapján kiszámított navigáló

műveleteket, valamint egy hivatkozást egy képre. Ez a hivatkozás lesz a „query=image” paraméterrel indított szervlet hívás. 27. oldal Ha a szervletet „query=image&box=” paraméterekkel hívják meg, akkor az egy WBMP képet generál a box paraméterben megadott területről. Az előző három művelet gyakorlatilag egyetlen lekérdezést valósít meg mindenre kiterjedő gondossággal. 6.3 A kód elemzése A szervlet írása során egy funkció megírására különösen nagy gondot fordítottam. Ez a szervlet inicializálásakor meghívott útvonal adatbázis beolvasó rutin. Azért tartom érdekesnek ezt a funkciót, mert az adatbázis importálása az útvonalkészítő kiegészítésben is tartalmazza ugyanezen funkciót. Ezért a két funkció megírásakor arra törekedtem, hogy azok könnyen összehasonlíthatóak legyenek. Könnyen láthatóak legyenek a két nyelv (C++ és Java) közötti különbségek. A másik két érdekes funkció a szervlet

bejövő paraméter feldolgozása, valamint annak megvalósítása, hogy a szervletet és a WapRoute környezetet könnyű legyen telepíteni. Így az alkalmazás által megjelenített oldalakat (még a statikus tartalmúakat is) a szervlet generálja. Így elkerültem azt hogy speciális könyvtárakat kelljen létrehozni és azok működését össze kelljen hangolni. A kód írásakor megpróbáltam a Jáva által nyújtott lehetőségekkel élni és a dokumentáció készítésére is alkalmas kódot készíteni. Valamint a privát tagok lekérdező műveletei „getxxx” és a beállító metódusok „setxxxx” alakúak, ahogy azt a Jáva programozási nyelvet oktató könyvek javasolják. 6.31 WapRoute/Database/Pointjava Ez az osztály tartalmazza a saját duplapontosságú Point objektumom implementációját. Erre az objektumra azért van szükségem, hogy az útvonal adatbázis gráfjának felépítésénél egységesen tudjam kezelni a pontokat. A tervezés pillanatában

még kevés tapasztalatom volt a Java programozásában – inkább csak C++ és ADA programozási nyelvben írtam objektum orientált programokat – ezért úgy gondoltam, hogy valamilyen módszerrel lehetőségem lesz az „==” operátor felül definiálására. De mint később kiderül erre nincs lehetőség Illetve két objektum összehasonlításánál azok csak akkor lesznek azonosak ha tényleg azonos objektumra mutató referenciák. És nem lehetséges olyan függvény írása amellyel az „==” – logikai egyenlőség operátor – feldefiniálható. Így az „equals” metódust kellett implementálnom és azzal kellett az egyenlőséget eldöntenem. Erről a problémáról bövebben a Nyékiné: Java2 II kötet 151oldalán lehet többet olvasni. Az osztály ezen kívül két privát változóval rendelkezik, amelyek beállítását és lekérdezését metódusok teszik lehetővé. Két speciális metódus a „max” és a „min” metódus, amelyek két pontból

előállítják a két pont áltam meghatározott téglalap bal alsó és jobb felső koordinátáit. 6.32 WapRoute/Database/Nodejava Ez az osztály tartalmazza a gráf ábrázolásomban a nevesített csomópontot. Három privát tagja van, amelyek lekérdezésére és beállítására publikus metódusok szolgálnak. Az osztály tartalmaz egy azonosítót, ami a többi útvonal adatbázisbeli elemtől különbözteti meg. Valamint egy „Point” osztályú helymeghatározásra alkalmas elemet Ezenkívül mivel nevesített pontról van szó, egy nevet is tartalmaz „String” osztályként. A speciális metódusok között található egy olyan, amely az adott objektumot pontként – egy másik pedig feliratként kirajzolja egy Graphics2D objektumra. Egy másik metódus annak eldöntését támogatja, hogy az adott objektum látható-e egy nézetben. Ha látható, akkor igazat ad eredményül egyébként hamisat. A láthatóságot a pont koordinátái alapján állapítja meg

Bemeneti paraméterei egy téglalapot definiálnak. 6.33 WapRoute/Database/Tracejava Az útvonal adatbázis gráfjának ábrázolásához szükséges másik alapobjektum. Az előző fejezetekben útként definiált objektum megadására. Ezzel az objektummal lehetőség van legalább két szegmenset tartalmazó csomópontokat összekötő út megadására. Ennek az objektumnak is van egyedi azonosítója, amely az adatbázisban való keresést segíti az egyes műveleteknél, neve, amely alapján a felhasználó az utakat meg tudja különböztetni egymástól. Valamint egy lista, amely azokat a szegmens pontokat tartalmazza, amelyek megadják az út grafikus megjelenését. 28. oldal Ne felejtsük el, hogy a specifikációban minden út vég és nevesített csomópont egy-egy csúcsnak felel meg, egy gráf reprezentáció esetén. A privát elemek beállításáról és lekérdezéséről szóló metódusokon kívül lehetőség van az út befoglaló négyzetének

lekérdezésére, az út hosszának és szegmensszámának lekérdezésére. Valamint ezen metódusok felhasználásával az előző osztály hasonló nevű metódusára hasonlít, és megállapítja, hogy az adott objektum egy téglalap formájában megadott pozícióról látható. 6.34 WapRoute/Database/Pathjava Egy útvonal reprezentációját megvalósító osztály. Az osztály path változójába csomópontokat és utakat lehet rakni Az osztály által ellenőrzötten. Azaz az új elemet nem lehet hozzáadni a halmazhoz, ha az nincs kapcsolatban az előző elemmel. Azaz az útvonalnak összefüggőnek kell maradnia, és nem lehet benne kör Az útvonal hozzáadás történhet egyes elemek hozzáadásával, valamint egy teljes útvonal hozzáillesztésével. Az így létrejött objektum lista lekérdezhető egy iterátor segítségével. 6.35 WapRoute/Database/PathDatabasejava Az útvonal adatbázis reprezentálásához használom ezt az osztályt. Az osztály műveletekkel

lehetőség van arra, hogy egy útvonal adatbázist építsünk fel, amely a fentebb részletezett specifikációnak megfelel. Azaz tartalmaz nevesített csomópontokat, csomópontokat és utakat, amelyek két csomópontban végződnek. Egy beágyazott osztály segítségével az osztály példányosításakor megadott WRD formátumú állományból az osztály beolvassa az útvonal adatokat. Az állományból beolvasott adatokat az osztály privát változóiban tárolja Ezek az adatok speciális metódusokkal lekérdezhetőek. Ilyen lekérdezések például az adott területen látható elemek halmazának lekérdezése, adott terület képének lekérdezése. Ebben az osztályban vannak a GIS lekérdezések implementálva. Ez az osztály végzi a legösszetettebb működést, így ennek megvalósítása is a legbonyolultabb. Ezért ennek a metódusai közül néhánynak a működését külön is részletezem. 6.351 privát változók // A felhasználói interfészt befolyásoló

konstansok. final long NumberOfMaxLinksOnACard = 16; // Minden elemet tartalmazó név szerint rendezett lista, ebből történik a rajzolás private ArrayList Entities = new ArrayList(0); // Az objektumok tulajdonságainak lekérdezését gyorsító tagok. private HashMap NodeIDToObject = new HashMap(0); private HashMap TraceIDToObject = new HashMap(0); // A keresési müvelet gyorsításához használt objektumok // A nevek részhalmazainak képzése már a konstruktorban megtörténik // igy nem kell külön idöt tölteni a névhalmaz "NumberOfMaxLinksOnACard" // darabos egységekre bontásával private SortedMap NodePileNames = new TreeMap(); private SortedMap TracePileNames = new TreeMap(); private ArrayList NodePileIds = new ArrayList(0); private ArrayList TracePileIds = new ArrayList(0); // Statisztikai információk tárolására szolgáló változók public final long readObjects; public final long readErrors; public final long readLines; public final long

readWords; public final long readChars; Az első konstans azt adja meg, hogy a keresési funkció eredményes megjelenítéséhez mekkora csomag méretet használjon a program, amikor a városok neveit (illetve az utvonalak neveit) megjeleníti. Ilyen lekérdezések futtatásakor az alkalmazás az adatbázisban tárolt összes objektumokat sorba rendezi név szerint, és az így létrejött csoportok egyenként legfeljebb hány elemet tartalmazzanak. Ez azért fontos, mert a mobil termináloknak nemcsak a mérete kicsi, hanem a memóriája is és legfeljebb 1400byte hosszúságú adatot képesek egyszerre megjeleníteni. A második lista az adatbázis elemeit tartalmazza. Ebből az adatbázisból történik a rajzolás, illetve az olyan keresés, amelyet nem lehet (vagy nehéz) indexelni annak valamilyen speciális tulajdonsága alapján. A név szerinti rendezés azért van rajta, hogy a program inicializálása tovább tartson :-) 29. oldal A NodeIDToObject és TraceIDToObject

változók az objektumok azonosító alapján történő keresését hivatottak gyorsítani. A következő négy változó a nevek csoportokba osztásánál játszanak fontos szerepet, amelyet az első konstans leírásánál részleteztem. Az utolsó hat változót az adatbázis beolvasásánál történt hibák és egyéb statisztikák tárolására használom. Ezeket a példányosító osztály használhatja például ellenőrzésre. 6.352 A konstruktor: PathDatabase( String DatabaseFile ) Ezzel a metódussal inicializálódik az osztály, aki a paraméterben megadott állományból betölti a WRD formátumú adatot. Ha a beolvasás során fatális hiba történik, akkor ezt egy exceptionnal jelzi Ha viszont nem fatális hibák vannak például az állomány formátuma néhány helyen nem megfelelő, akkor csak a statisztikai információkban jelzi a hibát a hívó félnek. Ennek a metódusnak a jellegzetessége, hogy kétszer írtam meg. Először az adatbázis tervező modulban

került implementálásra C++ nyelven, másodszor pedig ebben az osztályban. Ez lehetőséget ad a két programozási nyelvben elkövethető hibák és programozási konstrukciók összehasonlítására. 6.353 public SortedMap getListOfTraceNames( String substr ) Ez a metódus az útvonal adatbázisból azokat az útvonalakat gyűjti le amelyeknek a neve tartalmazza a paraméterben megadott karakter sorozatot. A metódus által visszaadott SortedMap az útvonalak azonosítójához rendeli az útvonal neveket. Az így szolgáltatott halmaz nevek szerint van rendezve A visszatérési értéknek azért választottam ezt a típust mert ez szolgálja ki azt a funkciót ami meghívja ezt a szervletből. A funkció a "TraceIDToObject" változó kulcsain iterálva nézi végig az adatbázist a keresett elemek után kutatva. Majd amikor minden elemet megtalált akkor az így kapott halmazt név szerint rendezi. 6.354 public ArrayList getElementSet( Point LowerLeft, Point

UpperRight ) Ez a metódus végzi az elemeknek egy grafikus lekérdezését. Megnézi, hogy a paraméterben megadott téglalapba esik-e egy objektum. Ha igen akkor az objektumot a visszatérési érték számára megjegyzi Ennek a funkciónak a működése a az adatbázisban ábrázol objektumokban implementált isVisible metóduson alapul. 6.355 public BufferedImage getImage(double llx1, double lly1, double urx1, double ury1, int imgWidth, int imgHeight ) Ez a metódus szolgáltatja az adatbázis megjelenítéséhez szükséges képet. A paraméterekben megadott téglalap alakú területet megjeleníti az utolsó paraméterben megadott felbontás szerint. Ebben a funkcióban a legbonyolultabb annak megvalósítása volt, hogy a megfelelő affin-transzformációs mátrixot előállítsam. Ezután a Graphics2D objektumra az egyes adatbázis elemek magukat rajzolják ki A megfelelő felbontás eléréséhez BufferedImage objektum tulajdonságait használtam ki. Azaz a megjelenítendő

felületnek adtam meg ezeket a paramétereket a kirajzolás eléréséhez. 6.356 public static String writeWBMP( BufferedImage bi ) Az előző metódus által előállított BufferedImage objektumból egy WBMP állományt készít. Az állomány egy ideiglenes állomány lesz, amelynek törléséről és elhelyezéséről az operációs rendszer vagy a Jáva futtató környezet gondoskodik. Ha az állomány létrehozása nem lehetséges akkor azt a hívó felé egy exceptionnal jelzi A funkció megvalósításában a nehézséget a WBMP formátumú képek generálása jelentette. Azaz egy olyan függvény megadása amely univerzálisan bármilyen szélességű és magasságú képből képes a WBMP formátum generálására. A WBMP formátum egy 4 byteos headerrel kezdődik amelynek első két byteja nulla A harmadik byte a kép szélességét a negyedik pedig a magasságát adja meg pixelekben. Az állomány további bytejai a kép pixeleit írják le sorfolytonosan. Egy pixelt egy

bit ad meg Azaz az első nyolc bit adja meg az első nyolc pixel értékét Így csak fekete fehér képet lehet megjeleníteni, de a mai mobil terminálok csak erre képesek. 30. oldal 6.357 public Path getShortestPath( Node ndStart, Node ndEnd ) Ez a metódus végzi a legrövidebb út keresését két megadott nevesített csomópont között. A visszatérési értéke a legrövidebb útvonalat fogja tartalmazni ha van ilyen. Ha nincs akkor null értékkel tér vissza a funkció Az útkeresést a Dijkstra algoritmus alapján végzi. Az algoritmus implementációjához az utakat két csoportra osztom az egyik a már felhasznált a másik a még nem felhasznált útvonalakat tartalmazza. Ezenkívül egy Path tipusú elemeket tartalmazó halmazt is használok (paths) amelyben - a már felhasznált utak segítségével elérhető végpontokba mutató - jelenleg legrövidebb utakat tárolom. Az iteráció addig folytatódik amíg a minden utat fel nem használok. Egy iteráció a

következőképpen néz ki: • A legrövidebb olyan utat amely a paths halmazhoz legalább egy pontban csatlakozik kiválasztom és törlöm a nem felhasznált utak halmazából. • Ha az út csak egy pontban csatlakozik a jelenleg legrövidebb utakhoz akkor egy új útvonalat adok a paths változóhoz így eggyel növelem az elérhető csomópontok számát. • Ha az út két ponton csatlakozik a jelenleg legrövidebb utak halmazához akkor mivel lehetséges hogy egyes szakaszokon rövidebb az eddig talált megoldásoknál. végig ellenőrzöm a jelenleg legrövidebb utakat tartalmazó halmazt hogy nem-e átvágás, ha igen akkor a régi útvonalakat helyettesítem az új szegmenssel. Különben az utat eldobom Mindenegyes iteráció alkalmával ha új útvonal keletkezik akkor az útvonal végpontjában található városokat hozzáadom az útvonalhoz. 6.36 WapRoute/WapRouteServletjava Ez az osztály nem tartalmaz különösebben bonyolult eljárásokat. Megértéséhez csak WML

és szervlet ismeretekre van szükség. A szervlet a WAP szerver konzoljára információkat ír ki Ezek az információk segítik az adminisztrátort a hibák felderítésében és javításában. Minden a szervlet által a konzolra írt üzenet a szervlet szöveges azonosítójával kezdődik. Ezt a szöveges azonosítót a getServletInfo metódus szolgáltatja A konzolon megjelenő információk angolul tájékoztatják az adminisztrátort a hibákról illetve egyéb eseményekről. A szervlet a HTTP metódusok közül csak a doGet (HTTP - GET) metódust implementálja. Mivel: • a kliens -> szerver irányú kommunikációban átvitt adatok mennyisége olyan csekély, hogy annak átvitelére a GET metódus is alkalmas • a GET metódus alkalmazásával az szervlet által szolgáltatott dinamikus adatok is könnyen bookmarkol hatóak lesznek • az így szolgáltatott adatokat (például: képek megjelenítése) más szolgáltatók is könnyen felhasználhatják az URL-ben

megadott paraméterek segítségével. Az osztály példányosítása után futó "init" metódus feladata az útvonal adatbázis betöltése egy PathDatabase osztályba. Itt történik a hibakezelés is Ha hiba történik a szervlet példányosítása nem lehetséges és a futtató környezet valószínűleg hibával le fog állni. 6.361 doGet metódus A szervletet futtató WAP szerver ezt a funkciót hívja meg ha a GET tipusú HTTP kérés érkezik a szervlethez rendelt címen (általában: http://xxx.yyyzzz/waproute?a=b&c=d formában) A szervlet csak ezt az egy típust implementálja. Lehetőség lenne még a POST használatára is a feladat megoldásához, de akkor az egyes oldalakat nem lehetne bookmarkolni a mobil terminálon. A kérések kiszolgálását a metódus más privát metódusoknak továbbítja miután azonosította a kéréssel azonosított funkciót. A funkciókat a metódus paraméterei és azok értékei alapján azonosítja. 6.362 void

printStartPage( HttpServletResponse response, ResourceBundle res, String addPar ) Egy olyan WML oldalt ír a kliens terminálra amin a felhasználó kiválaszthatja milyen nyelven szeretné igénybe venni a szolgáltatást valamint keresési feltételek közül választhat. A metódus paraméterei a következő funkciókat látják el: Az első paraméter segítségével fogom a mobilé terminálra írni a válasz. A response objektumból először egy PrintWriter objektumot készítek majd ebbe írom a választ. // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); 31. oldal PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); A második paraméterben megadott ResourceBoundle-éből állítom elő az oldalon megjelenítendő nyelvfüggő információkat általában statikus szövegeket: // Az oldalon tárolható nyelv függő elemek betöltése String MSG1016 = (String)res.getObject("MSG1016"); A

funkció további részei az outMsg változó megfelelő feltöltéséről gondoskodnak. Ez a tagolás minden kérés kiszolgáló funkcióban (azokban amelyeket a doGet metódus hív meg) megtalálható. A kiszolgáló funkciók általában a PathDatabase objektum megfelelő metódusának meghívása után a kapott értékeket jeleníti meg a terminálon. 6.37 WapRoute/PathDatabaseViewerjava Az alkalmazás az első paraméterben megadott WRD adatbázist betölti és megjeleníti egy ablakban. Az alkalmazás második paramétere egy nyelvet határoz meg amely a grafikus interfészen illetve a konzolon megjelenített üzenetek nyelvét adja meg. Jelenleg ez kétféle lehet, en vagy hu Az alkalmazás egy egyszerű felület biztosít a WAP szerver adminisztrátorának, hogy a WapRouteServlet osztályhoz érkező kérések eredményeképpen generált WBMP képeket megnézze ellenőrizze. Ennek a programnak a futtatásához nincs szükség speciális alkalmazásra. (Nem úgy mint a

Database Designer-nél) Az adminisztrátor az alkalmazás indításakor egy két részből álló ablakot lát. A bal oldalon található az útvonal adatbázisról készített kép, a jobb oldalon pedig egy irányító pult. Az irányító pult segítségével a felhasználó kiléphet a programból, vagy a megjelenített képet mozgathatja illetve a méretarányt növelheti illetve csökkentheti. A használatot a gombokon megjelenő "tooltip"-ek segítik, amelyek a gomb megnyomásakor végrehajtott funkciót írják le néhány szóban. A bal oldalon látható kép alapállapotban nagyított formában jelenik meg, hogy a mobil terminálon látható nagyítás is ellenőrizhető legyen. A megjelenített képet mobil terminál méretűre lehet zsugorítani az irányító pult középső gombjával. Ennek a gombnak az ismételt lenyomásával a kép ismét a régi formájában lesz látható Az alkalmazás a generált képekkel együtt egy WML oldalt is készít amely egy

hivatkozást tartalmaz egy WBMP képre. Ez a WML oldal a lokális gépen futó WAP böngészővel is megtekinthető, vagy a megfelelő könyvtárba helyezve egy mobil terminálról is lekérdezhető. (És a kismókusok kenyérre is kenhetik :-) Az előbb említett két állományt az alkalmazás a rendszer ideiglenes állományokat tartalmazó könyvtárában helyezi el "WapRoutetest.wml" valamint "WapRoute-nnnnwbmp" néven (Ahol az nnnn egy) négyjegyű számot jelent 6.4 Az alkalmazás nemzetközisítése Egy akkora méretű alkalmazás fejlesztésénél, amekkora ez a szolgáltatás a megcélzott felhasználói kör általában több országban él, különböző nyelven beszél. A felhasználók joggal várhatják el, hogy a szoftver az ő nyelvükön szóljon hozzájuk. Mindezek megvalósítására dolgozták ki a „környezet független” programozást Én is ezt a Jáva által támogatott javasol technikát, alkalmazom. Jelen esetben a nyelvfüggő

erőforrások csak üzenetek, amelyeket a felhasználó elolvas a mobil terminálján. Így én ezeket a karaktersorozatokat a ListResourceBundle osztály implementálásával oldom meg. Ennek az osztálynak kiterjesztéseként jelenleg két nyelvet implementáltam. Ha további nyelvekre van még szükség, akkor az angol nyelvű osztály lefordításával és „.class” állománnyá generálásával van rá lehetőség Az új nyelvi erőforrás létrehozásán kívül az adminisztrátornak a WapRouteServlet.java osztályban is regisztrálnia kell az új nyelvet „AvailableLanguages” osztály változó tartalmának megfelelő bővítésével. Jelenleg két nyelven érhetek el az alkalmazás szolgáltatásai: Angolul és Magyarul. Ezek implementációját a "WapRoute/ WapRouteResources en EN.java" és "WapRoute/ WapRouteResources hu HUjava" állományok tartalmazzák. 32. oldal 7 Program továbbfejlesztései és más objektum modell absztrakciók A program

továbbfejlesztésénél mindenek előtt azt kell figyelembe venni, hogy a jelenlegi implementáció csak egy lehetséges megvalósítást ad. A jelenlegi megvalósítás az jelenleg tárolt adatmennyiség mellett sem túl gyors Viszont egy valóságos üzleti rendszerben számolni kell az adatok olyan nagyságrendű növekedésével amelyet ez a megvalósítás már nem tud valós időben kezelni. Ezért első sorban a szakdolgozat részét nem szervesen képző saját útvonal adatbázis implementációt kellene valamelyik multinacionális óriás agyonreklámozott kellően drága szoftverére lecserélni. Hiszen azok megfelelő paraméterezések mellet nagyobb mennyiségű adatokat tudnak kezelni. A második fontos módosítás a GIS motor lecserélése lenne. Erre is a gyorsaság és hatékonyság növelése érdekében van szükség. A használható alternatívák nagyon széles skálája lehet megfelelő egy üzleti felhasználás számára Ílyen például a Siemens SICAD, vagy

az ESRI ArcInfo nevű terméke. A szakdolgozatban azért nem használtam ilyen terméket, hogy azt mindenki számára elérhetővé és felhasználhatóvá tegyem az Interneten. Ezáltal a leendő felhasználóknak nem kell a fent említett drága példányaira drága licenceket vásárolniuk. 7.1 WapRoute útvonal adatbázis készítő továbbfejlesztése Mentéseknél megjelenő kérdés ablak az automatikus exportálásról, permanensé tehető legyen. Azaz, a felhasználó megkérdezése nélkül az alkalmazás nyújtson lehetőséget a mentéssel párhuzamos exportálásra. Legyen lehetőség a rajzban levő előre elkészített objektumok alaptulajdonságainak visszaállítására. Azaz ha a felhasználó egy réteg színét megváltoztatja, akkor az alkalmazással azt vissza lehessen állítani. Egy konfigurációs menüpont létrehozása a fent említett újabb tulajdonságok felhasználóbarát eléréséhez. 7.2 Attribútumok számának tartalmának bővítése Az

attribútumokat annak megfelelően kell bővíteni, hogy milyen lekérdezésekre kíváncsiak felhasználók. Itt csak néhány kérdést sorolok fel, ami egy átlagos felhasználót érdekelhet a program használatánál. • Fizetni kell-e az úton? Mennyit kell fizetni? Olyan úton akarok menni, ahol nem kell fizetni! • Városon keresztül kell menni, vagy van elkerülő út? A program használja az elkerülő utakat, de „xy”-ban a városon keresztül menjen – mert ott lakik a nagymama. • Hegyen keresztül vezet az út? Hegynek fölfele többet fogyaszt az autó, és a városokban is. • Kirándulásokhoz: A legtöbb nevezetességet tartalmazó útvonal kiválasztása. • Vasúti kereszteződésen keresztül megy-e az út? • Útelzárások, elterelések kezelése – útinform adatbázis használata gyorsan változó információk kezelésére. Az előbb felsorolt kérdésekre a jelenlegi adatbázis nem tud választ adni, de a program bővíthető újabb attribútumok

használatára, azok szerinti lekérdezésekre. 7.21 Háromdimenziós ábrázolás Egy repülőgép útvonal adatbázis nyilvántartásánál célszerű lehet a háromdimenziós ábrázolás, hiszen egy repülővel akár a földet is körbe lehet repülni. Ekkor jobban oda kell figyelni a súlyozásra, mert egyik irány gyorsabb lehet, mint a másik. 7.22 Hipertér bevezetése Ezáltal lehetővé válna űrhajók útvonalának tervezése a hipertérben. 7.3 Hibák a programban Az adatbázis készítő kiegészítés importáló funkciója nem felel meg az ASN.1 szabványnak Ugyanis a szabvány szerint az újsor karakter a vesszővel egyenrangú karakter, azaz a csak egy sort tartalmazó állomány is érvényes input lenne. Ezt viszont a beolvasó rosszul értelmezi 33. oldal 8 Irodalom jegyzék 8.1 Elektronikus irodalom Elektronikus formában létező irodalmak listája. Zárójelben az elektronikus dokumentum szerző által adott nevét találhatja. Az Interneten

valószínűleg ezen a néven található meg valamelyik kereső segítségével Autodesk: AutoCAD 2000 ObjectArx™ developer’s guide, January 19, 1999 arxdev.pdf Bódis Katalin: Geometriai transzformációk, transzformációs egyenletek és alkalmazásuk a geoinformatikában http://www.geou-szegedhu/~bodis/maths/szakdolgozat Dr. Sárközi Ferenc: Térinformaikai elméleti oktató anyag http://bme-geod.agtbmehu/tutor h/terinfor/tbevhtm Larmouth Open Systems Solutions: ASN.1 Complete by Prof John, 1999 larmouth.pdf Nokia Corporation: WAP Service Designers Guide To Nokia Handsets, 2000 http://www.forumnokiacom/ OpenGIS Consortium: http://www.opengisorg RSA Data Security, Inc: A Laymans Guide to a Subset of ASN.1, BER, and DER - June 3, 1991 layman.pdf Sun Micosystems: JavaServlet Development Kit, 1999 http://www.javasoftcom/products/servlet/ 8.2 Irodalom Figyelő, 2000/14. szám Nyékiné Gaizler Judit: Java 2 útikalauz programozóknak, 1999 ELTE TTK Hallgatiói Alapítvány Andrew

S. Tandenbaum: Számítógép hálózatok, 1999 Panem Prentice Hall 8.3 Mobil alkalmazások listája Az általam elkészített szoftverhez hasonló útvonal információt és térképi adatokat mobil terminálon megjelenítő alkalmazások (nem teljes) listája: Environmental Systems Research Institute, Inc: RouteMap, 2000 http://www.esricom/software/routemapims/indexhtml IONIC: Location service http://www.ionicsoftcom/wap/imswml 34. oldal I. Forrás melléklet: Adatbázis készítő indító programja Database designer/sources/Main.cpp /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - AutoCAD indító program * * @@ @@@ @@ @@@@@@ @@@@@@ - Regisztrációs program * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ /* * Includes. * */ #include #include #include #include #include #include #include #include <io.h> <fcntl.h> <stdio.h>

<stdlib.h> <string.h> <windows.h> <process.h> "shlobj.h" /* * Defines. * */ /* A következö struktúrákat a WapRoute program használja a registryben / #define HKLM WAPROUTE "SOFTWARE\Szakdolgozat 2000\WapRoute\1.0" #define HKLM UTVONALK HKLM WAPROUTE"\Database Designer" #define APPLICATION NAME "WapRoute" /* A következö strukturákat az AutoCAD definiálja a registryben / #define HKLM AUTODESK "Software\Autodesk" #define PRODLIST KEY "ProdList" #define HKLM AUTOCAD "Software\Autodesk\AutoCAD" #define CURVER KEY "CurVer" #define HKLM ACADVER "Software\Autodesk\AutoCAD\R15.0" #define AUTOCAD LOCATION "AcadLocation" /* A következö értékeket kell ellenörizni a registry-ben, hogy * biztosan a megfelelő verziójú AutoCAD is installálva legyen a * rendszerben. #define CHECK PRODUCT "ACADR15" #define CHECK VERSION "R15.0" * * */ /* Az

AutoCAD indító ámmományának a neve. */ #define AUTOCAD EXE "Acad.exe" /* Menüvel kapcsolatos konstansok / #define WAPROUTE MENU FILE "WapRoute" #define WAPROUTE ARX "WapRoute.arx" /* Az új menü állományának a neve / /* AutoCAD parancsállomány / /* A WapRoute profillal kapcsolatos konstansok / #define WAPROUTE PROFILE "WapRoute" /* Az új profil registry-beli neve / #define WAPROUTE PROFILE TEMP WAPROUTE PROFILE"-Temporary" /* Egy temp profil neve / #define WAPROUTE PROFILE FILE "WapRoute.arg" /* Az új profil állományának a neve / #define WAPROUTE PROFILE DESCR "WapRoute útvonal adatbázis készítő AutoCAD kiterjesztés profilja - " "Dovák István - Programozó Matatemetikus Szakdolgozat 2000" /* Néhány álltalános definició / #ifndef TRUE #define TRUE (1==1) #endif #ifndef FALSE #define FALSE (1!=1) #endif #define BUFFLEN 1024 #define HEXL(b)

((((b)&0x0f)==0)?"0":((((b)&0x0f)==1)?"1":((((b)&0x0f)==2)?" 2":((((b)&0x0f)==3)?"3":((((b)&0x0f)==4)?"4":((((b)&0x0f)==5 )?"5":((((b)&0x0f)==6)?"6":((((b)&0x0f)==7)?"7":((((b)&0x0f) ==8)?"8":((((b)&0x0f)==9)?"9":((((b)&0x0f)==10)?"A":((((b)&0 x0f)==11)?"B":((((b)&0x0f)==12)?"C":((((b)&0x0f)==13)?"D":(( ((b)&0x0f)==14)?"E":"F"))))))))))))))) #define HEXH(b) HEXL((((b)&0xf0)>>4)) 35. oldal #define ELEMENTS(o) (sizeof((o))/sizeof((o)[0])) /* * Globals. * */ struct { char *cpDir; char *cpKey; char *cpNew; int type; bool append; } ProfileSettingsToChange[] = { { "Command Line Windows", "TextWindow.ForeColor", { "Command Line Windows", "TextWindow.BackColor", { "Command Line Windows",

"TextWindow.FontFace", { "Command Line Windows", "TextWindow.FontHeight", { "Command Line Windows", "TextWindow.FontWeight", { "Command Line Windows", "TextWindow.FontPitchAndFamily", { "Command Line Windows", "TextWindow.FontItalic", { "Command Line Windows", "CmdLine.ForeColor", { "Command Line Windows", "CmdLine.BackColor", { "Command Line Windows", "CmdLine.FontFace", { "Command Line Windows", "CmdLine.FontHeight", { "Command Line Windows", "CmdLine.FontWeight", { "Command Line Windows", "CmdLine.FontItalic", { "Command Line Windows", "CmdLine.FontPitchAndFamily", { "Drawing Window", "BackColor", { "Drawing Window", "Background", { "General", "NoStartUpDialog", { "General",

"CustomColors", { "", "", }; struct { char *cpDir; char *cpKey; char *cpNew; int type; } RegisterUnderWapRoute[] = { { "Name", APPLICATION NAME, { "Commands", "WRCREATENODE", { "Commands", "WRCREATETRACE", { "Commands", "WRMODIFYNODE", { "Commands", "WRMODIFYTRACE", { "Commands", "WRFINDNODE", { "Commands", "WRFINDTRACE", { "Commands", "WRSHOWHIDE", { "Commands", "WRCHECK1", { "Commands", "WRCHECK2", { "Commands", "WRIMPORT", { "Commands", "WREXPORT", { "Groups", "WAPROUTE", }; APPLICATION NAME, "WRCREATENODE", "WRCREATETRACE", "WRMODIFYNODE", "WRMODIFYTRACE", "WRFINDNODE", "WRFINDTRACE", "WRSHOWHIDE", "WRCHECK1",

"WRCHECK2", "WRIMPORT", "WREXPORT", "WAPROUTE", REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ REG SZ "x04 "x04 "x0b "x04 "x04 "x04 "x04 "x04 "x04 "x0b "x04 "x04 "x04 "x04 "x04 "x04 "x04 "x04 "x7D x00x00xffx00", REG DWORD, false }, x00xbfxffx00", REG DWORD, false }, Courier New", REG SZ, false }, x0ax00x00x00", REG DWORD, false }, x90x01x00x00", REG DWORD, false }, x31x00x00x00", REG DWORD, false }, x00x00x00x00", REG DWORD, false }, x00x00xffx00", REG DWORD, false }, x00xbfxffx00", REG DWORD, false }, Courier New", REG SZ, false }, x0ax00x00x00", REG DWORD, false }, x90x01x00x00", REG DWORD, false }, x00x00x00x00", REG DWORD, false }, x31x00x00x00", REG DWORD, false }, xd8xd0xc8x00", REG DWORD, false }, x84x84x84x00", REG DWORD, false

}, x01x00x00x00", REG DWORD, false }, x01x00x00x00", REG DWORD, false }, "WAPROUTE PROFILE DESCR, REG SZ, false } }, }, }, }, }, }, }, }, }, }, }, }, } /* * Functions. * */ // A windows regitryből megállapítja hogy a megfelelő AutoCAD van-e // a rendszerbe telepítve és ha igen akkor vissza adja az AutoCAD // Registry beli fökönyvtárának nevét. Ha nem a megfelelő van telepítve // vagy nincs a rendszeren AutoCAD telepítve akkor NULL-lal tér vissza. char *GetAcadRegistryRoot( void ){ HKEY hKey; DWORD Type; DWORD Length = BUFFLEN; char buffer[BUFFLEN]; static char AcadKey[BUFFLEN]; long stat; // AutoDESK meglétének ellenörzése if( RegOpenKeyEx( HKEY LOCAL MACHINE, HKLM AUTODESK, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return NULL; Length = BUFFLEN; stat = RegQueryValueEx( hKey, PRODLIST KEY, NULL, &Type, (unsigned char *)&buffer, &Length ); RegCloseKey( hKey ); if(( stat != ERROR SUCCESS ) || ( strstr(buffer, CHECK PRODUCT) == NULL ))

return NULL; // AutoCAD meglétének ellenörzése if( RegOpenKeyEx( HKEY LOCAL MACHINE, HKLM AUTOCAD, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return NULL; 36. oldal Length = BUFFLEN; stat = RegQueryValueEx( hKey, CURVER KEY, NULL, &Type, (unsigned char *)&buffer, &Length ); RegCloseKey( hKey ); if(( stat != ERROR SUCCESS ) || ( strstr(buffer, CHECK VERSION) == NULL )) return NULL; // AutoCAD R15.0 alverziójának verziojénak lekérdezése if( RegOpenKeyEx( HKEY LOCAL MACHINE, HKLM ACADVER, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return NULL; Length = BUFFLEN; stat = RegQueryValueEx( hKey, CURVER KEY, NULL, &Type, (unsigned char *)&buffer, &Length ); RegCloseKey( hKey ); if( stat != ERROR SUCCESS ) return NULL; strcpy( AcadKey, HKLM ACADVER ); strcat( AcadKey, "\" ); strcat( AcadKey, buffer ); return AcadKey; } // WindowsNT-ben nem lehet RegDeleteKey funkciót egy olyan kulcsra // alkalmazni ami további könyvtárakat tartalmaz ezért

egy rekuziv // funkciót kell megvalósítani ami törli az összes alatta levő kul// csot mely önmagát is. Ez a funkció töröl egy megadott könyvtárat // a registryben. DWORD RegDeleteKeyNT(HKEY hStartKey , LPTSTR pKeyName ){ DWORD dwRtn, dwSubKeyLength; LPTSTR pSubKey = NULL; TCHAR szSubKey[BUFFLEN]; HKEY hKey; // Do not allow NULL or empty key name if ( pKeyName && lstrlen(pKeyName)){ if( (dwRtn=RegOpenKeyEx(hStartKey,pKeyName, 0, KEY ENUMERATE SUB KEYS | DELETE, &hKey )) == ERROR SUCCESS){ while (dwRtn == ERROR SUCCESS ){ dwSubKeyLength = BUFFLEN; dwRtn=RegEnumKeyEx( hKey, 0, szSubKey, &dwSubKeyLength, NULL, NULL, NULL, NULL ); if(dwRtn == ERROR NO MORE ITEMS){ dwRtn = RegDeleteKey(hStartKey, pKeyName); break; } else if(dwRtn == ERROR SUCCESS) dwRtn=RegDeleteKeyNT(hKey, szSubKey); } RegCloseKey(hKey); } } else dwRtn = ERROR BADKEY; return dwRtn; } // WindowsNT-ben nem lehet RegDeleteKey funkciót egy könyvtárra // alkalmazni. Ezért egy könyvtár

törléséhez irtam ezt a funkciót DWORD RegDeleteLeafNT(HKEY hStartKey , LPTSTR pKeyName ){ DWORD dwRtn, dwSubKeyLength, dwNameLength; LPTSTR pSubKey = NULL; TCHAR szSubKey[BUFFLEN]; TCHAR szValueName[BUFFLEN]; HKEY hKey; // Do not allow NULL or empty key name if ( pKeyName && lstrlen(pKeyName)){ if( (dwRtn=RegOpenKeyEx(hStartKey,pKeyName, 0, KEY ALL ACCESS, &hKey )) == ERROR SUCCESS){ // Az értékkel rendelkező kulcsok törlése while ( dwRtn == ERROR SUCCESS ){ dwNameLength = BUFFLEN; dwRtn = RegEnumValue( hKey, 0, szValueName, &dwNameLength, NULL, NULL, NULL, NULL ); if(dwRtn == ERROR NO MORE ITEMS){ dwRtn = ERROR SUCCESS; break; } else if( dwRtn == ERROR SUCCESS ) { dwRtn = RegDeleteValue( hKey, szValueName ); } } // Könyvtárak törlése while (dwRtn == ERROR SUCCESS ){ dwSubKeyLength = BUFFLEN; dwRtn=RegEnumKeyEx( hKey, 0, szSubKey, &dwSubKeyLength, NULL, NULL, NULL, NULL ); if(dwRtn == ERROR NO MORE ITEMS){ 37. oldal dwRtn = ERROR SUCCESS; break; }

else if(dwRtn == ERROR SUCCESS) dwRtn = RegDeleteKeyNT(hKey, szSubKey); } RegCloseKey(hKey); } } else dwRtn = ERROR BADKEY; return dwRtn; } // A windows registryben tárolt levél kiirása egy megadott állományba // Ugy, hogy a kiirt levelbol a root level cimkejet a hivasnal kell // megadni. A funkcio minden csucsot kiir az állományba, még a VOLATILE // tipusuakat is. DWORD ExportRegistryLeaf( FILE *hFile, HKEY hStartKey, LPTSTR pKeyName, LPTSTR pKeyNewName ){ DWORD dwRtn, dwSubKeyLength, dwIndex = 0, dwIndexValues = 0; LPTSTR pSubKey = NULL; TCHAR szSubKey[BUFFLEN]; HKEY hKey; DWORD dwNameLength, dwType, dwValueLength; char newKeyName[BUFFLEN]; char szValueName[BUFFLEN]; char szData[BUFFLEN]; char szDataReplaced[BUFFLEN]; char *cp, ck; // Do not allow NULL or empty key name if( pKeyName && lstrlen(pKeyName)){ if( (dwRtn=RegOpenKeyEx(hStartKey,pKeyName, 0, KEY ENUMERATE SUB KEYS | KEY EXECUTE, &hKey )) == ERROR SUCCESS){ fprintf( hFile, " [%s]",

pKeyNewName ); // Az értékkel rendelkező kulcsok kiirása while ( dwRtn == ERROR SUCCESS ){ dwNameLength = BUFFLEN; dwValueLength = BUFFLEN; dwRtn = RegEnumValue( hKey, dwIndexValues++, szValueName, &dwNameLength, NULL, &dwType, (unsigned char *)szData, &dwValueLength ); if(dwRtn == ERROR NO MORE ITEMS){ dwRtn = ERROR SUCCESS; break; } else if( dwRtn == ERROR SUCCESS ) { // A kapott érték irása a fájlba. switch(dwType){ case REG DWORD: fprintf( hFile, " "%s"=dword:%s%s%s%s%s%s%s%s", szValueName, HEXH(*(szData+3)), HEXL(*(szData+3)), HEXH((szData+2)), HEXL((szData+2)), HEXH(*(szData+1)), HEXL((szData+1)), HEXH((szData+0)), HEXL(*(szData+0)) ); break; case REG SZ: for( cp=szData,ck=szDataReplaced; ((cp != NULL) && (*cp != 0x0)); ){ if( *cp == \ ) *ck++ = \; *ck++ = cp++; } *ck = 0x0; fprintf( hFile, " "%s"="%s"", szValueName, szDataReplaced ); break; } } } // Az alkönyvtárak végig olvasása. while ( dwRtn ==

ERROR SUCCESS ){ dwSubKeyLength = BUFFLEN; dwRtn = RegEnumKeyEx( hKey, dwIndex++, szSubKey, &dwSubKeyLength, NULL, NULL, NULL, NULL ); if(dwRtn == ERROR NO MORE ITEMS){ dwRtn = ERROR SUCCESS; break; } else if( dwRtn == ERROR SUCCESS ) { sprintf( newKeyName, "%s\%s", pKeyNewName, szSubKey ); dwRtn = ExportRegistryLeaf( hFile, hKey, szSubKey, newKeyName ); } } RegCloseKey(hKey); } } else dwRtn = ERROR BADKEY; return dwRtn; } DWORD ExportRegisty( char *fileName, HKEY hStartKey, LPTSTR pKeyName, LPTSTR pKeyNewName ){ 38. oldal FILE *hFile; // Az állomány létrehozása és kezdeti irása. if( (hFile = fopen( fileName, "w+" )) == NULL ) return -1; // A kulcsok rekurzív olvasása és kiirása a fileba. fprintf( hFile, "REGEDIT4" ); // A kezdö kulcs megnyítása. ExportRegistryLeaf( hFile, hStartKey, pKeyName, pKeyNewName ); // Az állomány lezárása. fprintf( hFile, " " ); fclose( hFile ); return 0; } // A Windows registrijéból egy

megadott csúcstól lefele // minden csomópontban levő érték másolása egy másik // windos registry beli csucspontba. Ha az új csúcsok // nem léteznek akkor újakat hoz létre ha már léteznek akkor // az ottani értékek közül csak az azonos kulcsúakat irja felul // funkció a többit változatlanul hagyja. DWORD CopyRegistryLeaf( HKEY hStartKey, LPTSTR pKeyName, HKEY hTargetKey, LPTSTR pTargetKeyName ){ DWORD dwRtn, dwSubKeyLength, dwIndex = 0, dwIndexValues = 0, dwDisposition; LPTSTR pSubKey = NULL; TCHAR szSubKey[BUFFLEN]; HKEY hKey; HKEY hTKey; DWORD dwNameLength, dwType, dwValueLength; char szValueName[BUFFLEN]; char szData[BUFFLEN]; // Do not allow NULL or empty key name if( pKeyName && lstrlen(pKeyName) && pTargetKeyName && lstrlen(pTargetKeyName) ){ if(( (dwRtn=RegOpenKeyEx(hStartKey, pKeyName, 0, KEY ENUMERATE SUB KEYS | KEY EXECUTE, &hKey )) == ERROR SUCCESS) && ( (dwRtn=RegCreateKeyEx(hTargetKey,pTargetKeyName, 0, "REG

SZ", REG OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hTKey, &dwDisposition )) == ERROR SUCCESS)){ // Az értékkel rendelkező kulcsok kiirása while ( dwRtn == ERROR SUCCESS ){ dwNameLength = BUFFLEN; dwValueLength = BUFFLEN; dwRtn = RegEnumValue( hKey, dwIndexValues++, szValueName, &dwNameLength, NULL, &dwType, (unsigned char *)szData, &dwValueLength ); if(dwRtn == ERROR NO MORE ITEMS){ dwRtn = ERROR SUCCESS; break; } else if( dwRtn == ERROR SUCCESS ) { dwRtn = RegSetValueEx( hTKey, szValueName, 0, dwType, (unsigned char *)szData, dwValueLength ); } } // Az alkönyvtárak végig olvasása. while ( dwRtn == ERROR SUCCESS ){ dwSubKeyLength = BUFFLEN; dwRtn = RegEnumKeyEx( hKey, dwIndex++, szSubKey, &dwSubKeyLength, NULL, NULL, NULL, NULL ); if(dwRtn == ERROR NO MORE ITEMS){ dwRtn = ERROR SUCCESS; break; } else if( dwRtn == ERROR SUCCESS ) { dwRtn = CopyRegistryLeaf( hKey, szSubKey, hTKey, szSubKey ); } } RegCloseKey(hKey); } } else dwRtn = ERROR BADKEY;

return dwRtn; } // A Registry alapján a Default AutoCAD profilt lemásolja és a // és létrehozza a WapRoute profilt amit ugy módosít, hogy az adatbázis // készítéshez szükséges információkat hozzáadja a profilhoz és az igy // kapott strukturát a PalceAndNameOfTheFile név alatt és helyre menti. // Visszatérési értéke nincs, az állományt mindenképen létrehozza. void CreateWapRouteArgProfilFile( char *PalceAndNameOfTheFile ) { HKEY hKey, hKeyRoot; DWORD Type, i, dwDisposition; DWORD Length = BUFFLEN, dwLength; char buffer[BUFFLEN]; char bufferRes[BUFFLEN]; char AcadNewWapProfile[BUFFLEN]; 39. oldal char char char char long FILE AcadProfiles[BUFFLEN]; AcadCurrentProfile[BUFFLEN]; AcadWapRouteProfile[BUFFLEN]; *AcadKey = NULL, cp = NULL; stat; *hFile = NULL; // Az AutoCAD intallálásának ellenörzése. if( (AcadKey = GetAcadRegistryRoot()) == NULL ) return; strcpy( AcadProfiles, AcadKey ); strcat( AcadProfiles, "\" ); strcat( AcadProfiles,

"Profiles" ); // Az AutoCAD Profiles könyvtár lekérdezése a defult user profilhoz. if( RegOpenKeyEx( HKEY CURRENT USER, AcadProfiles, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return; Length = BUFFLEN; stat = RegQueryValueEx( hKey, "", NULL, &Type, (unsigned char *)&buffer, &Length ); RegCloseKey( hKey ); if( stat != ERROR SUCCESS ) return; sprintf( AcadCurrentProfile, "%s\Profiles\%s", AcadKey, buffer ); sprintf( AcadNewWapProfile, "%s\Profiles\%s", AcadKey, WAPROUTE PROFILE TEMP ); sprintf( AcadWapRouteProfile, "HKEY CURRENT USER\%s\Profiles\%s", AcadKey, WAPROUTE PROFILE ); // Copy the current user to the WapProfile CopyRegistryLeaf( HKEY CURRENT USER, AcadCurrentProfile, HKEY CURRENT USER, AcadNewWapProfile ); // Az Temporaris registry bejegyzés módosítása. if( RegOpenKeyEx( HKEY CURRENT USER, AcadNewWapProfile, 0, KEY ALL ACCESS, &hKeyRoot ) == ERROR SUCCESS ) { for( i=0;

i<ELEMENTS(ProfileSettingsToChange); i++ ){ dwLength = *(ProfileSettingsToChange[i].cpNew) & 0xff; if( !ProfileSettingsToChange[i].append ){ if( strlen(ProfileSettingsToChange[i].cpDir) != 0 ){ if( RegOpenKeyEx( hKeyRoot, ProfileSettingsToChange[i].cpDir, 0, KEY ALL ACCESS, &hKey ) != ERROR SUCCESS ) continue; RegSetValueEx( hKey, ProfileSettingsToChange[i].cpKey, 0, ProfileSettingsToChange[i]type, (unsigned char *)(ProfileSettingsToChange[i].cpNew+2), dwLength ); if( hKeyRoot ) RegCloseKey( hKey ); } else { RegSetValueEx( hKeyRoot, ProfileSettingsToChange[i].cpKey, 0, ProfileSettingsToChange[i]type, (unsigned char *)(ProfileSettingsToChange[i].cpNew+2), dwLength ); } } } // Supprot könyvtár hozzáadása if( RegOpenKeyEx( hKeyRoot, "General", 0, KEY ALL ACCESS, &hKey ) == ERROR SUCCESS ) { dwLength = BUFFLEN; if( RegQueryValueEx( hKey, "ACAD", 0, &Type, (unsigned char *)&buffer, &dwLength ) == ERROR SUCCESS ){ strcpy( bufferRes,

PalceAndNameOfTheFile ); if( (cp = strrchr(bufferRes,\)) != NULL ) *cp = 0x0; strcat( buffer, bufferRes ); strcat( buffer, ";" ); if( strstr(buffer, bufferRes) == NULL ) RegSetValueEx( hKey, "ACAD", 0, Type, (unsigned char *)buffer, strlen(buffer) ); } RegSetValueEx( hKey, "ObjectARXSupportPath", 0, REG SZ, (unsigned char *)bufferRes, strlen(bufferRes) ); RegCloseKey( hKey ); } // Menü felülírása if( RegOpenKeyEx( hKeyRoot, "General Configuration", 0, KEY ALL ACCESS, &hKey ) == ERROR SUCCESS ) { dwLength = BUFFLEN; if( RegQueryValueEx( hKey, "MenuFile", 0, &Type, (unsigned char *)&buffer, &dwLength ) == ERROR SUCCESS ){ strcpy( bufferRes, PalceAndNameOfTheFile ); if( (cp = strrchr(bufferRes,\)) != NULL ) *cp = 0x0; strcat( bufferRes, "\" ); strcat( bufferRes, WAPROUTE MENU FILE ); RegSetValueEx( hKey, "MenuFile", 0, Type, (unsigned char *)bufferRes, strlen(bufferRes) ); } RegCloseKey( hKey ); } //

Menü könyvtár törlése és új értékek beírása RegDeleteKeyNT( hKeyRoot, "Menus" ); 40. oldal if( RegCreateKeyEx( hKeyRoot, "Menus", 0, "REG SZ", REG OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hKey, &dwDisposition ) == ERROR SUCCESS){ strcpy( buffer, "WAPROUTE " ); strcpy( bufferRes, PalceAndNameOfTheFile ); if( (cp = strrchr(bufferRes,\)) != NULL ) *cp = 0x0; strcat( bufferRes, "\" ); strcat( bufferRes, WAPROUTE MENU FILE ); strcat( buffer, bufferRes ); RegSetValueEx( hKey, "Group1", 0, Type, (unsigned char *)buffer, strlen(buffer) ); strcpy( buffer, "WAPROUTE pop1" ); RegSetValueEx( hKey, "Pop1", 0, Type, (unsigned char *)buffer, strlen(buffer) ); RegCloseKey( hKey ); } // Eszköztár könyvtár törlése és új értékek beírása RegDeleteKeyNT( hKeyRoot, "Toolbars" ); if( RegCreateKeyEx( hKeyRoot, "Toolbars", 0, "REG SZ", REG OPTION NON VOLATILE, KEY

ALL ACCESS, NULL, &hKey, &dwDisposition ) == ERROR SUCCESS){ strcpy( buffer, "no" ); RegSetValueEx( hKey, "LargeButtons", 0, Type, (unsigned char *)buffer, strlen(buffer) ); strcpy( buffer, "yes" ); RegSetValueEx( hKey, "ToolTips", 0, Type, (unsigned char *)buffer, strlen(buffer) ); strcpy( buffer, "show left 0 0" ); RegSetValueEx( hKey, "WAPROUTE.TB WAPROUTE STANDARD TOOLBAR", 0, Type, (unsigned char *)buffer, strlen(buffer) ); RegCloseKey( hKey ); } RegCloseKey( hKeyRoot ); } // Export the modified registry to a file. ExportRegisty( PalceAndNameOfTheFile, HKEY CURRENT USER, AcadNewWapProfile, AcadWapRouteProfile ); // Delete the temporary WapProfile RegDeleteKeyNT( HKEY CURRENT USER, AcadNewWapProfile ); return; } // Ez a funkcó a registry alapján ellenörzi a rendszert hogy a meg// felelő verziójú AutoCAD telepítve van-e. És a telepített AutoCAD // futtatható állománya tényleg a rendszer része-e. Ha

igen akkor a // funkció a futtatható "ACAD.EXE" útvonalával tér vissza Ha valami // hiba történik, nincs AutoCAD telepítve, vagy az indító állomány // nem elérhető akkor NULL-lal tér vissza. char *GetAutoCadExecutable( void ){ HKEY hKey; DWORD Type; DWORD Length = BUFFLEN; static char buffer[BUFFLEN]; char *AcadKey; long stat; int fh; // Az AutoCAD intallálásának ellenörzése. if( (AcadKey = GetAcadRegistryRoot()) == NULL ) return NULL; // Az AutoCAD könyvtár lekérdezése if( RegOpenKeyEx( HKEY LOCAL MACHINE, AcadKey, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return NULL; Length = BUFFLEN; stat = RegQueryValueEx( hKey, AUTOCAD LOCATION, NULL, &Type, (unsigned char *)&buffer, &Length ); RegCloseKey( hKey ); if( stat != ERROR SUCCESS ) return NULL; strcat( buffer, "\" ); strcat( buffer, AUTOCAD EXE ); // A futató állomány meglétének ellenörzése. if( (fh = open( buffer, O RDONLY )) == -1 ) return NULL; close(fh); return

buffer; } // Az aktuális AutoCAD profil lekérdezése, hogy később lehetőség // legyen ennek a visszaállítására, a program elindulása után két // másodpercel. char *GetCurrentAcadProfile( void ){ HKEY hKey; DWORD Length = BUFFLEN, dwType; char AcadProfiles[BUFFLEN]; static char AcadCurrentProfileName[BUFFLEN]; char *AcadKey = NULL; 41. oldal char *RetVal = NULL; // Az AutoCAD intallálásának ellenörzése. if( (AcadKey = GetAcadRegistryRoot()) == NULL ) return NULL; strcpy( AcadProfiles, AcadKey ); strcat( AcadProfiles, "\" ); strcat( AcadProfiles, "Profiles" ); // Az AutoCAD ProfilesWapRoute könyvtár lekérdezése if( RegOpenKeyEx( HKEY CURRENT USER, AcadProfiles, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return NULL; // A WapRoute profile lekérdezése Length = BUFFLEN; if( RegQueryValueEx( hKey, "", 0, &dwType, (unsigned char *)&AcadCurrentProfileName, &Length ) == ERROR SUCCESS ) RetVal = (char

*)&AcadCurrentProfileName; // A kulcs bezárása RegCloseKey( hKey ); return RetVal; } // Az aktuális AutoCAD profil beállítása, hogy akésőbbi indításokat // ne befolyasolja a WapRoute elindítása. void SetCurrentAcadProfile( char *AcadCurrentProfileName ){ HKEY hKey; DWORD Length = BUFFLEN; char AcadProfiles[BUFFLEN]; char *AcadKey = NULL; char *RetVal = NULL; // Az AutoCAD intallálásának ellenörzése. if( (AcadKey = GetAcadRegistryRoot()) == NULL ) return; strcpy( AcadProfiles, AcadKey ); strcat( AcadProfiles, "\" ); strcat( AcadProfiles, "Profiles" ); // Az AutoCAD ProfilesWapRoute könyvtár lekérdezése if( RegOpenKeyEx( HKEY CURRENT USER, AcadProfiles, 0, KEY ALL ACCESS, &hKey ) != ERROR SUCCESS ) return; // A WapRoute profile lekérdezése RegSetValueEx( hKey, "", 0, REG SZ, (unsigned char *)AcadCurrentProfileName, strlen(AcadCurrentProfileName) ); // A kulcs bezárása RegCloseKey( hKey ); return; } // Az ARX alkalmazás

beregisztrálása az AutoCAD alá. Megkeresi az // AutoCADet ott az Applications könyvtárba új kulcsokat hoz létre // valamint a WapRoute registry-jében is elvégzi a megfelelő // bejegyzések létrehozását. void RegisterWapRouteUnderAutoCAD( char *WapRouteArx ){ HKEY hKey; HKEY hAKey; char *AcadKey = NULL; char AcadApplications[BUFFLEN]; char buffer[BUFFLEN]; DWORD dwRtn, dwDisposition; int i; // Az AutoCAD intallálásának ellenörzése. if( (AcadKey = GetAcadRegistryRoot()) == NULL ) return; strcpy( AcadApplications, AcadKey ); strcat( AcadApplications, "\" ); strcat( AcadApplications, "Applications" ); // Az AutoCAD ApplicationsWapRoute könyvtár lekérdezése if( RegOpenKeyEx( HKEY LOCAL MACHINE, AcadApplications, 0, KEY ALL ACCESS, &hKey ) != ERROR SUCCESS ) return; dwRtn = RegCreateKeyEx( hKey, APPLICATION NAME, 0, "REG SZ", REG OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hAKey, &dwDisposition ); RegCloseKey( hKey ); if( dwRtn

!= ERROR SUCCESS ) return; // Új ertékek beállítása az AutoCAD alkalmazások között 42. oldal buffer[0] = 0xd; buffer[1] = 0x0; buffer[2] = 0x0; buffer[3] = 0x0; RegSetValueEx( hAKey, "LoadCtrls", 0, REG DWORD, (unsigned char *)buffer, 4 ); sprintf( buffer, "\\HKEY LOCAL MACHINE\%s", HKLM UTVONALK ); RegSetValueEx( hAKey, "RegPath", 0, REG SZ, (unsigned char *)buffer, strlen(buffer) ); RegCloseKey( hAKey ); // Az új WapRoute registry bejegyzések létrehozása dwRtn = RegCreateKeyEx( HKEY LOCAL MACHINE, HKLM UTVONALK"\Loader", 0, "REG SZ", REG OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hKey, &dwDisposition ); if( dwRtn != ERROR SUCCESS ) return; RegSetValueEx( hKey, "MODULE", 0, REG SZ, (unsigned char *)WapRouteArx, strlen(WapRouteArx) ); RegCloseKey( hKey ); // A tömbböl olvasható állandó bejegyzések létrehozása dwRtn = RegCreateKeyEx( HKEY LOCAL MACHINE, HKLM UTVONALK, 0, "REG SZ", REG

OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hKey, &dwDisposition ); if( dwRtn != ERROR SUCCESS ) return; for( i=0; i<ELEMENTS(RegisterUnderWapRoute); i++ ){ if( strlen(RegisterUnderWapRoute[i].cpDir) != 0 ){ if( RegCreateKeyEx( hKey, RegisterUnderWapRoute[i].cpDir, 0, "REG SZ", REG OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hAKey, &dwDisposition ) == ERROR SUCCESS ){ RegSetValueEx( hAKey, RegisterUnderWapRoute[i].cpKey, 0, RegisterUnderWapRoute[i]type, (unsigned char *)(RegisterUnderWapRoute[i].cpNew), strlen(RegisterUnderWapRoute[i].cpNew) ); RegCloseKey( hAKey ); } } else { RegSetValueEx( hKey, RegisterUnderWapRoute[i].cpKey, 0, RegisterUnderWapRoute[i]type, (unsigned char *)(RegisterUnderWapRoute[i].cpNew), strlen(RegisterUnderWapRoute[i].cpNew) ); } } RegCloseKey( hKey ); } // Megkeresi a telepített AutoCAD profiles könyvtárát a registryben // ha a megfelelő verziószámú AutoCAD telepítve van a rendszerben. // Ha a profilok között talál

"WapRoute" nevűt akkor azt törli a // rendszerből. Erre azért van szükség, hogy mindig a megfelelő // környezeti beállításokkel induljon az útvonal készítő. Visszatérési // érték nincs, mert vagy van mit törölni, vagy nincs, és ha van mit // törölni akkor azt biztosan törli is a funkció. void ClearWapPofileFromAcadProfiles( void ){ HKEY hKey; DWORD Length = BUFFLEN; char AcadProfiles[BUFFLEN]; char *AcadKey = NULL; long stat; // Az AutoCAD intallálásának ellenörzése. if( (AcadKey = GetAcadRegistryRoot()) == NULL ) return; strcpy( AcadProfiles, AcadKey ); strcat( AcadProfiles, "\" ); strcat( AcadProfiles, "Profiles" ); // Az AutoCAD ProfilesWapRoute könyvtár lekérdezése if( RegOpenKeyEx( HKEY CURRENT USER, AcadProfiles, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return; // A WapRoute profile törlése stat = RegDeleteKeyNT( hKey, WAPROUTE PROFILE ); RegCloseKey( hKey ); return; } // A windows Startmenüjében található

Programokmenü helyének // lekérdezése. A visszaadott ponter egy statikus karakter // tömbre mutat igy nem szabad felszabadítani ha az értékre // már nincs szükség valamint az értéket csak lekérdezni szabad // innen mert a buffert más funkciók is használhatják érték // lekérdezésre char *GetStartMenuFolder( void ){ static char buffer[MAX PATH]; LPITEMIDLIST pidl; // Startmenü könyvtárának lekérdezése SHGetSpecialFolderLocation( NULL, CSIDL PROGRAMS, &pidl ); SHGetPathFromIDList( pidl, buffer ); return buffer; 43. oldal } // A windows aktuális felhasználójának Desktop könyvtárának // lekérdezése. A visszaadott ponter egy statikus karakter // tömbre mutat igy nem szabad felszabadítani ha az értékre // már nincs szükség valamint az értéket csak lekérdezni szabad // innen mert a buffert más funkciók is használhatják érték // lekérdezésre char *GetDesktopFolder( void ){ static char buffer[MAX PATH]; LPITEMIDLIST pidl; // Desktop

könyvtárának lekérdezése SHGetSpecialFolderLocation( NULL, CSIDL DESKTOP, &pidl ); SHGetPathFromIDList( pidl, buffer ); return buffer; } // A registryböl kiolvassa hogy milyen néven hozták létre a // StartMenu csoportot a "Programok" folderben. Ha ilyen csoport // még nincs akkor a registryben bejegyez egy default-ot, és // létrehozza a könyvtárat. char *CreateWapRouteStartMenuFolder( void ){ HKEY hKey; DWORD dwLength, dwDisposition, dwType, dwRtn; static char buffer[BUFFLEN]; static char WapFolder[BUFFLEN]; // Az új WapRoute registry bejegyzések létrehozása strcpy( buffer, APPLICATION NAME ); dwRtn = RegCreateKeyEx( HKEY LOCAL MACHINE, HKLM WAPROUTE, 0, "REG SZ", REG OPTION NON VOLATILE, KEY ALL ACCESS, NULL, &hKey, &dwDisposition ); if( dwRtn == ERROR SUCCESS ){ dwLength = BUFFLEN; if( RegQueryValueEx( hKey, "StartMenuFolder", 0, &dwType, (unsigned char *)&buffer, &dwLength ) != ERROR SUCCESS ){ strcpy( buffer,

APPLICATION NAME ); RegSetValueEx( hKey, "StartMenuFolder", 0, REG SZ, (unsigned char *)buffer, strlen(buffer) ); } } RegCloseKey( hKey ); sprintf( WapFolder, "%s\%s", GetStartMenuFolder(), buffer ); CreateDirectory( WapFolder, NULL ); return WapFolder; } // Ez a funkció a paraméterek alapján a PlaceAndNameOfTheLink // könyvtárban és néven létrehoz egy linket (sortcut-ot) a // FilenameToCreateLink állományra, és beállítja a link ikonját // munka könyvtárát és a megjelenítő ablak stillusát ugy mint // SW MINIMIZED, SW RESTORED. // PlaceAndNameOfTheLink paraméter a link nevét és kiterjesztését // is tartalmazza, ahol a kiterjesztésnek ".lnk"-nak kell lennie void CreateShortCut( char *PlaceAndNameOfTheLink, char FilenameToCreateLink, char *IconFile, char WorkingDirectory, int ShowStyle ) { HRESULT hres; IShellLink *psl = NULL; IPersistFile *pPf = NULL; WORD wsz[MAX PATH]; TCHAR buf[MAX PATH]; int id; // COM objektumok

inicializálása hres = CoInitialize( NULL ); if( FAILED(hres) ) goto cleanup; // IShellLink lekérdezése hres = CoCreateInstance( CLSID ShellLink, NULL, CLSCTX INPROC SERVER, IID IShellLink, (LPVOID*)&psl ); if( FAILED(hres) ) goto cleanup; // IPersistFile interface lekérdezése a IShellLink-től. hres = psl->QueryInterface( IID IPersistFile, (LPVOID*)&pPf ); if( FAILED(hres) ) goto cleanup; // Cél állomány kijelölése hres = psl->SetPath( FilenameToCreateLink ); if( FAILED(hres) ) goto cleanup; // Link nevének megadása majd mentés strcpy( buf, PlaceAndNameOfTheLink ); MultiByteToWideChar( CP ACP, 0, buf, -1, wsz, MAX PATH ); 44. oldal hres = pPf->Save( wsz, TRUE ); if( FAILED(hres) ) goto cleanup; // Az ikon módosítása és visszakérdezés, majd mentés hres = psl->SetIconLocation( IconFile, 0 ); if( FAILED(hres) ) goto cleanup; hres = psl->GetIconLocation( buf, 256, &id ); if( FAILED(hres) ) goto cleanup; pPf->Save( wsz, TRUE ); // A

munka könyvtár beállítása visszakérdezés, majd mentés hres = psl->SetWorkingDirectory( WorkingDirectory ); if( FAILED(hres) ) goto cleanup; hres = psl->GetWorkingDirectory( buf, MAX PATH ); if( FAILED(hres) ) goto cleanup; pPf->Save( wsz, TRUE ); // Az ablak megjelenitésének beállítása hres = psl->SetShowCmd( ShowStyle ); if( FAILED(hres) ) goto cleanup; hres = psl->GetShowCmd( &id ); if( FAILED(hres) ) goto cleanup; pPf->Save( wsz, TRUE ); cleanup: if(pPf) if(psl) } pPf->Release(); psl->Release(); // Main funkció - leirását lásd a fejlécben. int main( int argc, char *argv[], char envp[] ){ char *StartMenuFolder = NULL; char *AcadExecutable = NULL; char *DesktopFolder = NULL; int retVal; char RunningExecutabeDir[MAX PATH]; char WapRouteProfile[MAX PATH]; char AcadExecutableName[MAX PATH]; char WapRouteArxExecutable[MAX PATH]; char errorMessage[2048]; char *cp, CurrentProfile = NULL; // A registry olvasása, és az AutoCAD indító

állomány meglétének // ellenörzése. AcadExecutable = GetAutoCadExecutable(); if( argc == 1 ){ // Paraméter nélküli esetben a program elindítja az AutoCAD-et // a megfelelő paraméterekkel, könyvtár beállításokkal, úgy // hogy az adatbázis szekesztő kiegészítés betöltödjön az // induláskor. retVal = (AcadExecutable == NULL) ? 1 : 0; if(retVal == 0){ // Az AutoCAD helyes elindításához szükséges paraméterek kiszámítása // A Support dirctoryban keresi például az ARX és DIALOG fájlokat. strcpy( RunningExecutabeDir, argv[0] ); if( (cp = strrchr(RunningExecutabeDir, \)) != NULL ) *cp = 0x0; // A Profile állomány helye, ez által definiálom a menu és egyéb // állományok helyét valamint a felület megjelenését. sprintf( WapRouteProfile, ""%s\%s"", RunningExecutabeDir, WAPROUTE PROFILE FILE ); // A mésodik paraméterben macskakörmöt kell használni hosszú állománynevek esetén. sprintf( AcadExecutableName,

""%s"", AcadExecutable ); // A jó beállítások használatához a régi profile törlése ClearWapPofileFromAcadProfiles(); RegFlushKey( HKEY CURRENT USER ); // Az AutoCAD új processének elindítása CurrentProfile = GetCurrentAcadProfile(); if( spawnl( P NOWAIT, AcadExecutable, AcadExecutableName, "/p", WapRouteProfile, NULL ) <= 0 ){ sprintf( errorMessage, "WapRoute útvonal adatbázis készítő AutoCAD " "kiterjesztés indító programja. Dovák István - WapRoute " "alkalmazás - Programozó Matatemetikus Szakdolgozat 2000 " "!!!ERROR: %s nem indítható! ", AcadExecutable ); MessageBox( NULL, errorMessage, "AutoCAD nem található!", 0 ); retVal = 1; } else { Sleep(3000); SetCurrentAcadProfile( CurrentProfile ); } } else { 45. oldal sprintf( errorMessage, "WapRoute útvonal adatbázis készítő AutoCAD " "kiterjesztés indító programja. Dovák István - WapRoute "

"alkalmazás - Programozó Matatemetikus Szakdolgozat 2000 " "!!!ERROR: AutoCAD 2000 nincs a rendszerre telepítve. " ); MessageBox( NULL, errorMessage, "AutoCAD nem található!", 0 ); } } else if(( argc == 2 ) && (stricmp(argv[1],"CHECK") == 0)){ // Ha csak egy paraméter van és az "CHECK" akkor ellenőrzi hogy // az AutoCAD része-e a rendszernek. Ha igen 0-val, ha nem 1// gyel terminál a program retVal = (AcadExecutable == NULL) ? 1 : 0; } else if(( argc == 2 ) && (stricmp(argv[1],"CREATE") == 0)){ // A WapRoute program indito csoprtban létrehoz egy indító menüt // ami önmagára mutat és az aktuális könyvtára az exe könyvtára lesz. StartMenuFolder = CreateWapRouteStartMenuFolder(); strcat( StartMenuFolder, "\Útvonalkészítés AutoCAD 2000-rel.lnk" ); strcpy( RunningExecutabeDir, argv[0] ); if( (cp = strrchr(RunningExecutabeDir, \)) != NULL ) *cp = 0x0; CreateShortCut(

StartMenuFolder, argv[0], argv[0], RunningExecutabeDir, SW MINIMIZE ); } else if(( argc == 2 ) && (stricmp(argv[1],"DESKTOP") == 0)){ // A WapRoute programra létrehoz egy ikont az aktuális felhasználó // desktopján. DesktopFolder = GetDesktopFolder(); strcat( DesktopFolder, "\Útvonalkészítés AutoCAD 2000-rel.lnk" ); strcpy( RunningExecutabeDir, argv[0] ); if( (cp = strrchr(RunningExecutabeDir, \)) != NULL ) *cp = 0x0; CreateShortCut( DesktopFolder, argv[0], argv[0], RunningExecutabeDir, SW MINIMIZE ); } else if(( argc == 2 ) && (stricmp(argv[1],"PROFILE") == 0)){ // A default AutoCAD felhasználói profil alapján létrehoz egy // WapRoute felhasználói profilt (amiben beállítja a futtatáshoz // szükséges paramétereket is) a futatott program könyvtárában. strcpy( RunningExecutabeDir, argv[0] ); if( (cp = strrchr(RunningExecutabeDir, \)) != NULL ) *cp = 0x0; sprintf( WapRouteProfile, "%s\%s", RunningExecutabeDir,

WAPROUTE PROFILE FILE ); CreateWapRouteArgProfilFile( WapRouteProfile ); } else if(( argc == 2 ) && (stricmp(argv[1],"REGISTER") == 0)){ // A default AutoCAD felhasználói profil alapján létrehoz egy // WapRoute felhasználói profilt (amiben beállítja a futtatáshoz // szükséges paramétereket is) a futatott program könyvtárában. retVal = (AcadExecutable == NULL) ? 1 : 0; if(retVal == 0){ strcpy( RunningExecutabeDir, argv[0] ); if( (cp = strrchr(RunningExecutabeDir, \)) != NULL ) *cp = 0x0; sprintf( WapRouteArxExecutable, "%s\%s", RunningExecutabeDir, WAPROUTE ARX ); RegisterWapRouteUnderAutoCAD( WapRouteArxExecutable ); } else { sprintf( errorMessage, "WapRoute útvonal adatbázis készítő AutoCAD " "kiterjesztés indító programja. Dovák István - WapRoute " "alkalmazás - Programozó Matatemetikus Szakdolgozat 2000 " "!!!ERROR: AutoCAD 2000 nincs a rendszerre telepítve. " ); MessageBox( NULL,

errorMessage, "AutoCAD nem található!", 0 ); } } else { // Egyéb paraméterezés esetén a felhasználói instrukciók kiir// ása a képernyőre. sprintf( errorMessage, "WapRoute útvonal adatbázis készítő AutoCAD " "kiterjesztés indító programja. Dovák István - WapRoute " "alkalmazás - Programozó Matatemetikus Szakdolgozat 2000 " "!!!ERROR: Hibás paraméterek! " " %s [CHECK|CREATE|DESKTOP] " "Paraméter nélküli indítás esetén az AutoCAD megfelelő elindítása. " " CHECK - Az AutoCAD 2000 ellenörzése. " " CREATE - Menüpont létrehozása a WapRoute program csoportban. " " DESKTOP - Egy ikon létrehozása az aktuális felhasználó desktopján. " " PROFILE - A "WAPROUTE PROFILE FILE" profil fállomány létrehozása. " " REGISTER - A útvonal készítő alkalmazás regisztrálása az AutoCAD-be. " , argv[0] ); MessageBox( NULL,

errorMessage, "Rossz paraméter(ek)!", 0 ); } return retVal; } 46. oldal II. Forrás melléklet: Jáva futtató alkalmazás WapRoute-Java-Source/Main.cpp /* * * * @@ @@ @@ @@ @@ @@@@@@ Útvonaladatbázis nézegető * * @@ @@@@ @@ @@@ @@ @@ alkalmazás indító program * * @@ @@ @@ @@ @@ @@ @@ * * @@ @@@ @@ @@@@@@ @@@@@@ * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ /* * Includes. * */ #include #include #include #include #include #include #include #include <io.h> <fcntl.h> <stdio.h> <stdlib.h> <string.h> <windows.h> <process.h> "shlobj.h" /* * Defines. * */ /* Az aktuális jáva verzió lekérdezése a rendszeren / #define HKLM JAVASOFT1 "SOFTWARE\JavaSoft\Java Runtime Environment" #define HKLM JAVASOFT2 "SOFTWARE\JavaSoft\Java Development Kit" #define CURVER KEY "CurrentVersion" #define JAVA LOCATION "JavaHome" /* Az indító állomány

neve / #define JAVA EXE "bin\java.exe" /* Amit el kell indítani / #define WAPROUTE JAR "WapRoute.jar" /* Néhány álltalános definició / #ifndef TRUE #define TRUE (1==1) #endif #ifndef FALSE #define FALSE (1!=1) #endif #define BUFFLEN 1024 #define HEXL(b) ((((b)&0x0f)==0)?"0":((((b)&0x0f)==1)?"1":((((b)&0x0f)==2)?" 2":((((b)&0x0f)==3)?"3":((((b)&0x0f)==4)?"4":((((b)&0x0f)==5 )?"5":((((b)&0x0f)==6)?"6":((((b)&0x0f)==7)?"7":((((b)&0x0f) ==8)?"8":((((b)&0x0f)==9)?"9":((((b)&0x0f)==10)?"A":((((b)&0 x0f)==11)?"B":((((b)&0x0f)==12)?"C":((((b)&0x0f)==13)?"D":(( ((b)&0x0f)==14)?"E":"F"))))))))))))))) #define HEXH(b) HEXL((((b)&0xf0)>>4)) #define ELEMENTS(o) (sizeof((o))/sizeof((o)[0])) /* * Globals. * */ /* * Functions. * */ // A windows

regitryből megállapítja hogy a megfelelő Java van-e // a rendszerbe telepítve és ha igen akkor vissza adja a Java // Registry beli fökönyvtárának nevét. Ha nem a megfelelő van telepítve // vagy nincs a rendszeren Java telepítve akkor NULL-lal tér vissza. char *GetJavaRegistryRoot( void ){ HKEY hKey; DWORD Type; 47. oldal DWORD Length = BUFFLEN; char buffer[BUFFLEN]; static char JavaRoot[BUFFLEN]; long stat; // Java meglétének ellenörzése if( RegOpenKeyEx( HKEY LOCAL MACHINE, HKLM JAVASOFT1, 0, KEY READ, &hKey ) == ERROR SUCCESS ){ strcpy( JavaRoot, HKLM JAVASOFT1 ); } else if( RegOpenKeyEx( HKEY LOCAL MACHINE, HKLM JAVASOFT2, 0, KEY READ, &hKey ) != ERROR SUCCESS ) { strcpy( JavaRoot, HKLM JAVASOFT2 ); } else { return NULL; } Length = BUFFLEN; stat = RegQueryValueEx( hKey, CURVER KEY, NULL, &Type, (unsigned char *)&buffer, &Length ); RegCloseKey( hKey ); if(( stat != ERROR SUCCESS ) || ( atof(buffer)<1.2 )) return NULL; strcat( JavaRoot,

"\" ); strcat( JavaRoot, buffer ); return JavaRoot; } // Ez a funkcó a registry alapján ellenörzi a rendszert hogy a meg// felelő verziójú Java telepítve van-e. És a telepített Java // futtatható állománya tényleg a rendszer része-e. Ha igen akkor a // funkció a futtatható "Java.exe" útvonalával tér vissza Ha valami // hiba történik, nincs Java telepítve, vagy az indító állomány // nem elérhető akkor NULL-lal tér vissza. char *GetJavaExecutable( void ){ HKEY hKey; DWORD Type; DWORD Length = BUFFLEN; static char buffer[BUFFLEN]; char *JavaRoot; long stat; int fh; // Az Java intallálásának ellenörzése. if( (JavaRoot = GetJavaRegistryRoot()) == NULL ) return NULL; // Az Java könyvtár lekérdezése if( RegOpenKeyEx( HKEY LOCAL MACHINE, JavaRoot, 0, KEY READ, &hKey ) != ERROR SUCCESS ) return NULL; Length = BUFFLEN; stat = RegQueryValueEx( hKey, JAVA LOCATION, NULL, &Type, (unsigned char *)&buffer, &Length );

RegCloseKey( hKey ); if( stat != ERROR SUCCESS ) return NULL; strcat( buffer, "\" ); strcat( buffer, JAVA EXE ); // A futató állomány meglétének ellenörzése. if( (fh = open( buffer, O RDONLY )) == -1 ) return NULL; close(fh); return buffer; } // Main funkció - leirását lásd a fejlécben. void main( int argc, char *argv[], char envp[] ){ char *JavaExecutable = NULL; char errorMessage[1024]; char buffer[1024]; char buffer2[1024]; // A registry olvasása, és az Java indító állomány meglétének // ellenörzése. JavaExecutable = GetJavaExecutable(); sprintf( buffer, ""%s"", JavaExecutable ); // A maradék paraméterek beállítása char *args[7]; args[0] = buffer; args[1] = "-classpath"; args[2] = "WapRoute.jar"; 48. oldal args[3] = "WapRoute.PathDatabaseViewer"; if( argc >= 2 ) { sprintf( buffer2, ""%s"", argv[1] ); args[4] = strdup( buffer2 ); } else { args[4] = NULL; } if( argc

>= 3 ) args[5] = strdup( argv[2] ); else args[5] = NULL; args[6] = NULL; // Ha az indító állomány nem létezik akkor hibaüzenetet ír ki. if( JavaExecutable == NULL ) { sprintf( errorMessage, "A rendszeren nincs telepítve Java futtató környezet " "vagy a futtató környezet verziója nem megfelelő! WapRoute " "útvonal adatbázis nézegető alkalmazás indító program " "Dovák István - Programozó Matatemetikus Szakdolgozat 2000" ); MessageBox( NULL, errorMessage, "Nincs Java futtató környezet!", 0 ); } // Jáva elindítása spawnv( P NOWAIT, JavaExecutable, args ); return; } 49. oldal 50. oldal III. Forrás melléklet: Adatbázis tervező alkalmazás Database designer/arxsources/AcadPlus.h /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - AutoCAD szolgáltatások * * @@ @@@ @@ @@@@@@ @@@@@@ bővítése * * @@@ @@@ @@ @@

@@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ #ifndef WAPROUTE ACADPLUS H #define WAPROUTE ACADPLUS H 1 #define acdbPointEqual(pt1, pt2) (pt1[0]==pt2[0] && pt1[1]==pt2[1] && pt1[2]==pt2[2]) /* * Funkciók elöre deklarálása. * */ AcDbSymbolTable* openSymbolTable(AcRxClass symTblClass, AcDb::OpenMode mode, AcDbDatabase db); BOOL addToSymbolTableAndClose(AcDbSymbolTableRecord* symRec); BOOL setSymbolName(AcDbSymbolTableRecord* newRec, LPCTSTR newName); Acad::ErrorStatus nameToSymbolId(AcRxClass* symTblClass, LPCTSTR name, AcDbObjectId& recordId, AcDbDatabase db); Acad::ErrorStatus defineNewBlock(LPCTSTR blkName, AcDbBlockTableRecord*& newBlkRec, AcDbObjectId& newBlkRecId, AcDbDatabase* db); Acad::ErrorStatus defineNewBlock(LPCTSTR blkName, AcDbBlockTableRecord*& newBlkRec, AcDbDatabase db); Acad::ErrorStatus defineNewBlock(LPCTSTR blkName, AcDbObjectId& newBlkRecId, AcDbDatabase* db); bool symbolExists(AcRxClass* symTblClass,

LPCTSTR name, AcDbDatabase db); Acad::ErrorStatus objIdToEname(const AcDbObjectId& objId, ads name& ent); Acad::ErrorStatus enameToObjId(ads name ent, AcDbObjectId& objId); Acad::ErrorStatus createPolyline( AcGePoint2dArray ptArray, AcDbObjectId& objId ); Acad::ErrorStatus createText( AcGePoint3d pt, double height, double angle, const char *text, AcDbObjectId& idStandardTextStyle, AcDbObjectId& objId ); char *getWrdFileLoation( const char cpTitle, const char cpDefaultFileName, int method ); AcGePoint3d midpoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2); AcGePoint3d midpoint(const AcGePoint2d& pt1, const AcGePoint2d& pt2); struct resbuf *entitem(struct resbuf rchain, int gcode); char *enttype( ads name ent ); Acad::ErrorStatus entpoints( ads name ent, AcGePoint3dArray &ptArray ); int asciiStringToOctetString( char *from, char to ); int octetStringToAsciiString( char *from, char to ); struct resbuf *entlastitem(struct resbuf rchain);

struct resbuf *getXDataPointer( struct resbuf rchain, char appidstr, int gcode ); char *GetApplicationData( AcDbObjectId idEnt ); char *GetApplicationData( ads name ent ); Acad::ErrorStatus SetApplicationData( AcDbObjectId idEnt, char *cpData ); Acad::ErrorStatus SetApplicationData( ads name ent, char *cpData ); Acad::ErrorStatus createInsertWithAttributes( AcDbObjectId& objId, const char *cpBlockName, AcGePoint3d basePoint, AcGeScale3d *scaleFactor = NULL, double dRotation = 0.0, CString strAttribValues = ""); int GetUtvonalTipus( AcDbObjectId idEnt ); int GetUtvonalTipus( ads name ent ); void SetUtvonalTipus( ads name ent, int newType ); void SetUtvonalTipus( AcDbObjectId idEnt, int newType ); void changeObjectsColor( ads name ent, AcCmColor newColor ); void changeObjectsColor( AcDbObjectId idEnt, AcCmColor newColor ); void startPrograssIndicator( CString strTitle = "" ); bool setProgressIndicator( double percent ); void endProgressIndicator( void ); #endif

Database designer/arxsources/AcadPlus.cpp /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - AutoCAD szolgáltatások * * @@ @@@ @@ @@@@@@ @@@@@@ bővítése * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * 51. oldal * * */ /* * Include-k. * */ #include "StdAfx.h" #include "Default.h" #include "WapRoute.h" #include #include #include #include // Alkalmazas globalis valtozoi, define-ok "AcadStr.h" "Error.h" // Hibakezelés "AcadPlus.h" // AutoCAD szolgáltatások bövítése "WRUiProgressDialog.h" /* * openSymbolTable: * * ~~~~~~~~~~~~~~~~ * * Egy általános szimbolum tábla mutató menyitása egy * * szimbólum táblához. Hasonló az: ArxDbgUtils::open * * SymbolTable funkciójához. * * * */ AcDbSymbolTable* openSymbolTable(AcRxClass symTblClass, AcDb::OpenMode mode, AcDbDatabase db) {

ASSERT(symTblClass != NULL); ASSERT(db != NULL); AcDbSymbolTable* symTbl = NULL; Acad::ErrorStatus es; if (symTblClass == AcDbBlockTableRecord::desc()) { AcDbBlockTable* blkTbl; es = db->getBlockTable(blkTbl, mode); symTbl = blkTbl; } else if (symTblClass == AcDbDimStyleTableRecord::desc()) { AcDbDimStyleTable* dimTbl; es = db->getDimStyleTable(dimTbl, mode); symTbl = dimTbl; } else if (symTblClass == AcDbLayerTableRecord::desc()) { AcDbLayerTable* layerTbl; es = db->getLayerTable(layerTbl, mode); symTbl = layerTbl; } else if (symTblClass == AcDbLinetypeTableRecord::desc()) { AcDbLinetypeTable* ltypeTbl; es = db->getLinetypeTable(ltypeTbl, mode); symTbl = ltypeTbl; } else if (symTblClass == AcDbTextStyleTableRecord::desc()) { AcDbTextStyleTable* textTbl; es = db->getTextStyleTable(textTbl, mode); symTbl = textTbl; } else if (symTblClass == AcDbRegAppTableRecord::desc()) { AcDbRegAppTable* appTbl; es = db->getRegAppTable(appTbl, mode); symTbl = appTbl; } else if

(symTblClass == AcDbUCSTableRecord::desc()) { AcDbUCSTable* ucsTbl; es = db->getUCSTable(ucsTbl, mode); symTbl = ucsTbl; } else if (symTblClass == AcDbViewTableRecord::desc()) { AcDbViewTable* viewTbl; es = db->getViewTable(viewTbl, mode); symTbl = viewTbl; } else if (symTblClass == AcDbViewportTableRecord::desc()) { AcDbViewportTable* vportTbl; es = db->getViewportTable(vportTbl, mode); symTbl = vportTbl; } else es = Acad::eInvalidInput; // Illegális class tipus a paraméter ASSERT(es == Acad::eOk); // ennek a funkciónak sohan nem szabadna rosszul végződnie if (es != Acad::eOk) { rxErrorAlert(es, FILE , LINE ); return NULL; } else return symTbl; } /* * addToSymbolTableAndClose: * * ~~~~~~~~~~~~~~~~~~~~~~~~~ * * A paraméterben megadott szimbolum tabla rekordot a * * szimbolum tablához hozzáadja, ha lehetséges és lezárja * 52. oldal * a rekordot. Ha nem lehetséges akkor törli a rekordot * * és hibaüzenettel illetve false értékkel tér vissza. * * * */

BOOL addToSymbolTableAndClose(AcDbSymbolTableRecord* symRec) { BOOL stat = FALSE; AcDbSymbolTable* symTbl = openSymbolTable(symRec->isA(), AcDb::kForWrite, acdbHostApplicationServices()>workingDatabase() ); if (symTbl) { Acad::ErrorStatus es = symTbl->add(symRec); if (es == Acad::eOk) { stat = TRUE; symRec->close(); } else { rxErrorAlert(es, FILE , LINE ); delete symRec; } symTbl->close(); } return(stat); } /* * setSymbolName: * * ~~~~~~~~~~~~~~ * * A paraméterben megadott szimbolum tabla rekordo nevét * * azaz ASCII azonosítóját állítja be. Layer esetén ez a * * layer neve, vonaltipus esetén ez a vonaltipus neve. * * Helyes lefutás esetén a név beállítódik, különben hiba * * üzenettel és false értékkel tér vissza a függvény. * * * */ BOOL setSymbolName(AcDbSymbolTableRecord* newRec, LPCTSTR newName){ Acad::ErrorStatus es; CString str; es = newRec->setName(newName); if (es != Acad::eOk) { rxErrorAlert(es, FILE , LINE );

newRec->close(); str.Format( T("Invalid Symbol Name: "%s""), newName); acedAlert(str); } return(es); } /* * nameToSymbolId: * * ~~~~~~~~~~~~~~~ * * A paraméterben megadott szimbolum tablában megkeresi * * az adott nevű rekordot és annak azonosítóját a harmadik* * paraméterben adja vissza. Ha a keresett elem nem talál-* * ható akkor ezt a visszatérési értékben jelzi. * * * */ Acad::ErrorStatus nameToSymbolId(AcRxClass* symTblClass, LPCTSTR name, AcDbObjectId& recordId, AcDbDatabase db){ ASSERT(symTblClass != NULL); ASSERT(db != NULL); AcDbSymbolTable* symTbl; if ((symTbl = openSymbolTable(symTblClass, AcDb::kForRead, db)) == NULL) return Acad::eInvalidInput; Acad::ErrorStatus es; es = symTbl->getAt(name, recordId); symTbl->close(); return es; } /* * defineNewBlock: * * ~~~~~~~~~~~~~~~ * * Akkor használható ha egy új blokkot akarunk létrehozni * * vagy egy meglevőt felüldefiniálni. Amikor új blokkot * * hozunk létre egy új rekordot

fog a BlokkTablához adni * * és a rekordot irásra megnyitva adja vissza a második * * paraméterben. * * * */ Acad::ErrorStatus defineNewBlock(LPCTSTR blkName, AcDbBlockTableRecord*& newBlkRec, AcDbObjectId& newBlkRecId, AcDbDatabase* db) { ASSERT(db != NULL); 53. oldal AcDbBlockTable* blkTbl; Acad::ErrorStatus es = db->getSymbolTable(blkTbl, AcDb::kForWrite); if (es != Acad::eOk) return es; if (blkTbl->getAt(blkName, newBlkRec, AcDb::kForWrite) == Acad::eOk) { // Ha a blokk már létezik töröni kell a tartalmát előszőr. newBlkRecId = newBlkRec->objectId(); AcDbBlockTableRecordIterator* iter; es = newBlkRec->newIterator(iter); if (es != Acad::eOk) { rxErrorAlert(es, FILE , LINE ); newBlkRec->close(); } else { AcDbEntity* ent; for (; !iter->done(); iter->step()) { if (iter->getEntity(ent, AcDb::kForWrite) == Acad::eOk) { ent->erase(); ent->close(); } } delete iter; } } else { // Ha a blokk még nem létezik akkor egy új

BlokkRekord létrehozésa // és hozzáadása a blokk táblához. newBlkRec = new AcDbBlockTableRecord; newBlkRec->setPathName(AcadString::nullStr); es = newBlkRec->setName(blkName); if (es == Acad::eOk) es = blkTbl->add(newBlkRecId, newBlkRec); if (es != Acad::eOk) { rxErrorAlert(es, FILE , LINE ); delete newBlkRec; } } // A blokk tábla bezárása. blkTbl->close(); return es; } /* * defineNewBlock: * * ~~~~~~~~~~~~~~~ * * Akkor használható ez a fajtája a funkciónak ha a blokk * * rekord azonosítójára nincs szükségünk. * * * */ Acad::ErrorStatus defineNewBlock(LPCTSTR blkName, AcDbBlockTableRecord*& newBlkRec, AcDbDatabase db) { AcDbObjectId newBlkRecId; return defineNewBlock(blkName, newBlkRec, newBlkRecId, db); } /* * defineNewBlock: * * ~~~~~~~~~~~~~~~ * * Akkor használható ez a fajtája a funkciónak ha a blokk * * rekord mutatóra nincs szükségünk. * * * */ Acad::ErrorStatus defineNewBlock(LPCTSTR blkName, AcDbObjectId& newBlkRecId,

AcDbDatabase* db){ AcDbBlockTableRecord* newBlkRec; Acad::ErrorStatus es = defineNewBlock(blkName, newBlkRec, newBlkRecId, db); if (es == Acad::eOk) newBlkRec->close(); return es; } /* * symbolExists: * * ~~~~~~~~~~~~~ * * Egy szimbolum névről megmondja hogy az létezik-e már a * * megadott szimbólum táblában. * * * */ bool symbolExists(AcRxClass* symTblClass, LPCTSTR name, AcDbDatabase db){ ASSERT(symTblClass != NULL); ASSERT(db != NULL); AcDbSymbolTable* symTbl; if ((symTbl = openSymbolTable(symTblClass, AcDb::kForRead, db)) == NULL) return false; 54. oldal bool symExists = symTbl->has(name); symTbl->close(); return symExists; } /* * objIdToEname: * * ~~~~~~~~~~~~~ * * Egy objektum azonosítójából előállítja annak Entity * * nevét, vagy hibával tér vissza ha nincs objektum. * * * */ Acad::ErrorStatus objIdToEname(const AcDbObjectId& objId, ads name& ent){ Acad::ErrorStatus es = acdbGetAdsName(ent, objId); ASSERT(es == Acad::eOk); if (es ==

Acad::eOk) rxErrorAlert(es, FILE , LINE ); return es; } /* * enameToObjId: * * ~~~~~~~~~~~~~ * * Egy objektum Entity nevéből előállítja annak Objektum * * azonosítóját, vagy hibával tér vissza ha nincs entity. * * * */ Acad::ErrorStatus enameToObjId(ads name ent, AcDbObjectId& objId){ Acad::ErrorStatus es = acdbGetObjectId(objId, ent); ASSERT(es == Acad::eOk); if (es != Acad::eOk) rxErrorAlert(es, FILE , LINE ); return es; } /* * createPolyline: * * ~~~~~~~~~~~~~~~ * * Egy LWPOLYLINE létrehozása a megadott pont tömbből. A * * sikeres létrehozás után objId tartalmazza az azonosítót* * * */ Acad::ErrorStatus createPolyline( AcGePoint2dArray ptArray, AcDbObjectId& objId ){ AcDbPolyline* pNewPline; AcGePoint2d pt( 0.0, 00 ); int i; pNewPline = new AcDbPolyline( ptArray.length() ); pNewPline->setClosed( Adesk::kFalse ); pNewPline->setConstantWidth( 0.0 ); for( i=0; i<ptArray.length(); i++ ){ pt.set( ptArrayat(i)x, ptArrayat(i)y );

pNewPline->addVertexAt( i, pt ); } AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB MODEL SPACE, pBlockTableRecord,AcDb::kForWrite); pBlockTable->close(); pBlockTableRecord->appendAcDbEntity(objId, pNewPline); pBlockTableRecord->close(); pNewPline->close(); return Acad::eOk; } /* * createText: * * ~~~~~~~~~~~ * * Egy TEXT létrehozása a megadott tulajdonságokkal. A si-* * keres létrehozás után objId tartalmazza az azonosítót. * * * */ Acad::ErrorStatus createText( AcGePoint3d pt, double height, double angle, const char *text, AcDbObjectId& idStandardTextStyle, AcDbObjectId& objId ){ AcDbText* pNewText; pNewText = new AcDbText( pt, text, idStandardTextStyle, height, angle ); AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead);

AcDbBlockTableRecord *pBlockTableRecord; 55. oldal pBlockTable->getAt(ACDB MODEL SPACE, pBlockTableRecord,AcDb::kForWrite); pBlockTable->close(); pBlockTableRecord->appendAcDbEntity(objId, pNewText); pBlockTableRecord->close(); pNewText->close(); return Acad::eOk; } /* * getWrdFileLoation: * * ~~~~~~~~~~~~~~~~~~ * * Egy WRD kiterjesztésű állomány nevének és útvonalának * * bekérése a felhasználótól. A AutoCAD nyujtotta standard* * GetFileD funkción keresztül. * * * */ static struct resbuf *resVal = NULL; char *getWrdFileLoation( const char cpTitle, const char cpDefaultFileName, int method ){ // Régebbi területek felszabaditása if( resVal != NULL ){ acutRelRb( resVal ); resVal = NULL; } // Új területek lefoglalása és a WRD állomány nevének bekérése resVal = acutNewRb( RTSTR ); if( acedGetFileD( cpTitle, cpDefaultFileName, "wrd", (method|8|2)&(~4), resVal) == RTNORM ){ return resVal->resval.rstring; } else { return NULL; } }

/* * midpoint: * * ~~~~~~~~~ * * Két három dimenziós pont közötti középsö pont meghatá- * * rozása. (Számtani közép) * * * */ AcGePoint3d midpoint(const AcGePoint3d& pt1, const AcGePoint3d& pt2){ AcGePoint3d newPt; newPt.x =(pt1x + pt2x) / 20; newPt.y =(pt1y + pt2y) / 20; newPt.z =(pt1z + pt2z) / 20; return newPt; } AcGePoint3d midpoint(const AcGePoint2d& pt1, const AcGePoint2d& pt2){ AcGePoint3d newPt1( pt1.x, pt1y, 00 ), newPt2( pt2x, pt2y, 00 ); return midpoint( newPt1, newPt2 ); } /* * entitem: * * ~~~~~~~~ * * Az acdbEntGet fuggvény által vissza adott láncban meg- * * keresi a megadott group code-u elemet és arra mutató * * pointerrel tér vissza vagy NULL-lal. * * * */ struct resbuf *entitem(struct resbuf rchain, int gcode){ while ((rchain != NULL) && (rchain->restype != gcode)) rchain = rchain->rbnext; return rchain; } /* * enttype: * * ~~~~~~~~ * * A paraméterben megadott entitás 0-ás group kódjának * * értékével tér

vissza. Ez az entitás tipusa Ha nem * * lehet megynitni az entitást akkor ""-t ad vissza. * * * */ char *enttype( ads name ent ){ struct resbuf *ebuf,rb; static char buff[128]; strcpy( buff, "" ); if((ebuf = acdbEntGet(ent)) != NULL){ if( (rb = entitem(ebuf,0)) != NULL ){ strcpy( buff, rb->resval.rstring ); } acutRelRb(ebuf); 56. oldal } return buff; } /* * entpoints: * * ~~~~~~~~~~ * * A paraméterben megadott entitás lekért láncában meg* * keresi a az elem pontjait és hozzáfüzi a paraméterben * * megadott tömbhoz. Egyenlöre csak LWPOLYLINE-ra mükönik * * rendesen. * * * */ Acad::ErrorStatus entpoints( ads name ent, AcGePoint3dArray &ptArray ){ struct resbuf *rb, ebuf; if((rb = ebuf = acdbEntGet(ent)) != NULL){ while( (rb = entitem(rb,10)) != NULL ){ AcGePoint3d newPt( rb->resval.rpoint[X], rb->resvalrpoint[Y], 00 ); ptArray.append( newPt ); rb = rb->rbnext; } acutRelRb(ebuf); } return Acad::eOk; } /* * asciiStringToOctetString: *

* ~~~~~~~~~~~~~~~~~~~~~~~~~ * * A paraméterben megadott 0x0-val lezart karakter soro- * * zatot átalakítja az ASN1 szerinti octet sztringgé. Ha * * a második paraméter NULL akkor csak tároláshoz szüksé- * * ges buffermáretet adja vissza. Különben az átalakított * * karkterek számát. * * * */ int asciiStringToOctetString( char *from, char to ){ int retVal = 0; if( to != NULL ) { for( ; *from!=0x0; from++ ){ *to++ = HEXH( from ); *to++ = HEXL( from ); retVal++; } *to = 0x0; } else { retVal = strlen(from)*2; } return retVal; } /* * octetStringToAsciiString: * * ~~~~~~~~~~~~~~~~~~~~~~~~~ * * A paraméterben megadott 0x0-val lezart karakter soro- * * zatot átalakítja az ASN1 szerinti octet sztringgé. Ha * * a második paraméter NULL akkor csak tároláshoz szüksé- * * ges buffermáretet adja vissza. Különben az átalakított * * karkterek számát. * * * */ int octetStringToAsciiString( char *from, char to ){ int retVal = 0; if( to != NULL ) { for( ; *from!=0x0;

from=from+2 ){ *to++ = ASCII(from); retVal++; } *to = 0x0; } else { retVal = (int)floor(strlen(from)/2); } return retVal; } /* * entlastitem: * * ~~~~~~~~~~~~ * * Az acdbEntGet fuggvény által vissza adott láncban meg- * * keresi a legutolso elemet aminek a next-je NULL. * * * */ 57. oldal struct resbuf *entlastitem(struct resbuf rchain){ while ((rchain != NULL) && (rchain->rbnext != NULL)) rchain = rchain->rbnext; return rchain; } /* * getXDataPointer: * * ~~~~~~~~~~~~~~~~ * * Az acdbEntGetX fuggvény által vissza adott láncban meg-* * keresi az "appidstr" nevu alkalmazas hoz tartozo elso * * gcode azonostoju elemet. Ha nem talal ilyet akkor NULL * * értékkel tér vissza. * * * */ struct resbuf *getXDataPointer( struct resbuf rchain, char appidstr, int gcode ){ bool kilep = false; // Alkalmazások XDATA-janak keresése a listában rchain = entitem(rchain,-3); // Ha mar van XDATA az entitashoz regisztralva // megkeresem az alkalmazas XDATAjat es azt

kell // modositani. while( !kilep && (rchain != NULL) && ((rchain = entitem(rchain,1001)) != NULL ) ){ if( strcmp(rchain->resval.rstring,local appname) != 0 ){ rchain = rchain->rbnext; continue; } rchain = rchain->rbnext; for( ; ( !kilep && (rchain != NULL) && (rchain->restype != 1001)); rchain=rchain->rbnext ){ if( rchain->restype == gcode ){ kilep = true; break; } } } return rchain; } /* * GetApplicationData: * * ~~~~~~~~~~~~~~~~~~~ * * A paraméterben megadott entitásnak lekérdezi a nevét. * * Amit a program XDATA ként tárol az entitásban. * * * */ char *GetApplicationData( AcDbObjectId idEnt ){ ads name ent; objIdToEname( idEnt, ent ); return GetApplicationData( ent ); } char *GetApplicationData( ads name ent ){ struct resbuf *rb, ebuf, app; static char buff[128]; // Applikáció regisztrációs sztringje app.rbnext = NULL; app.restype = RTSTR; app.resvalrstring = local appname; strcpy( buff, "???" ); if((rb = ebuf =

acdbEntGetX(ent, &app)) != NULL){ if(( rb = getXDataPointer(rb, local appname, 1000) ) != NULL ){ strcpy( buff, rb->resval.rstring ); } acutRelRb(ebuf); } return buff; } /* * GetUtvonalTipus: * * ~~~~~~~~~~~~~~~~ * * A paraméterben megadott entitásnak lekérdezi az utvonal* * tipusat amit a vonatipusbol allapit meg. Ha a vonalti- * * pus BJ-Egy. akkor DWG TRACE ONEWAY LR, ha JB-Egy * * akkor DWG TRACE ONEWAY RL kulonben DWG TRACE TWOWAY a * * visszateresi erteke. * * * */ int GetUtvonalTipus( ads name ent ){ AcDbObjectId idEnt; enameToObjId( ent, idEnt ); return GetUtvonalTipus(idEnt); 58. oldal } int GetUtvonalTipus( AcDbObjectId idEnt ){ AcDbEntity *pEnt = NULL; AcDbObjectId idBJ, idJB, idObj; Acad::ErrorStatus es; // A BJ-Egyirányú útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "BJ-Egyirányú útvonal", idBJ, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){

rxErrorAlert(es, FILE , LINE ); return -1; } // A JB-Egyirányú útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "JB-Egyirányú útvonal", idJB, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return -1; } acdbOpenObject( pEnt, idEnt, AcDb::kForRead ); idObj = pEnt->linetypeId(); pEnt->close(); if( idObj == idBJ ){ return DWG TRACE ONEWAY LR; } else if( idObj == idJB ){ return DWG TRACE ONEWAY RL; } else { return DWG TRACE TWOWAY; } } /* * SetUtvonalTipus: * * ~~~~~~~~~~~~~~~~ * * A paraméterben megadott entitásnak beállítja az utvonal* * tipusat amit a vonatipusmegváltoztatásával ér el. A vo-* * naltipus BJ-Egy. akkor ha DWG TRACE ONEWAY LR, JB-Egy* * ha DWG TRACE ONEWAY RL kulonben CONTINUOUS lesz. * * * */ void SetUtvonalTipus( ads name ent, int newType ){ AcDbObjectId idEnt; enameToObjId( ent, idEnt ); SetUtvonalTipus(idEnt,

newType); return; } void SetUtvonalTipus( AcDbObjectId idEnt, int newType ){ AcDbEntity *pEnt = NULL; AcDbObjectId idBJ, idJB, idCONT, idObj; Acad::ErrorStatus es; // A CONTINUOUS útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "CONTINUOUS", idCONT, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return; } // A BJ-Egyirányú útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "BJ-Egyirányú útvonal", idBJ, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return; } // A JB-Egyirányú útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "JB-Egyirányú útvonal", idJB, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE

, LINE ); return; } acdbOpenObject( pEnt, idEnt, AcDb::kForWrite ); switch( newType ){ case DWG TRACE ONEWAY LR: pEnt->setLinetype( idBJ ); break; case DWG TRACE ONEWAY RL: pEnt->setLinetype( idJB ); 59. oldal break; default: pEnt->setLinetype( idCONT ); break; } pEnt->close(); } /* * SetApplicationData: * * ~~~~~~~~~~~~~~~~~~~ * * A paraméterben megadott entitásnak lekérdezi a nevét. * * Amit a program XDATA ként tárol az entitásban. * * * */ Acad::ErrorStatus SetApplicationData( AcDbObjectId idEnt, char *cpData ){ ads name ent; objIdToEname( idEnt, ent ); return SetApplicationData( ent, cpData ); } Acad::ErrorStatus SetApplicationData( ads name ent, char *cpData ){ struct resbuf *rb, ebuf, app, rbLast; char *oldValue; Acad::ErrorStatus es = Acad::eOk; static struct resbuf buf1000 = { NULL,1000 }, buf1001 = { &buf1000,1001 }, bufneg3 = { &buf1001,-3 }; // Applikáció regisztrációs sztringje app.rbnext = NULL; app.restype = RTSTR; app.resvalrstring

= local appname; if((rb = ebuf = acdbEntGetX(ent, &app)) != NULL){ if(( rb = getXDataPointer(rb, local appname, 1000) ) != NULL ){ oldValue = rb->resval.rstring; rb->resval.rstring = cpData; acdbEntMod( ebuf ); rb->resval.rstring = oldValue; } else { if( (rbLast = entlastitem(ebuf)) != NULL ){ buf1001.resvalrstring = local appname; buf1000.resvalrstring = cpData; rbLast->rbnext = &bufneg3; acdbEntMod( ebuf ); rbLast->rbnext = NULL; } else { es = Acad::eInvalidInput; } } acutRelRb(ebuf); } else { debugOutput("WAPROUTE - Hatelse"); } return es; } /* * createInsertWithAttributes: * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~ * * Egy INSRET létrehozása a megadott tulajdonságok alapján* * Az INSERT-et a neve alapján azonosítja, az ATTRIButum * * okat pedig egy stringben kell megadni a következö for- * * mában: "kulcs-1 ertek-1 kulcs-2 ertek-2 ." * * * */ Acad::ErrorStatus createInsertWithAttributes( AcDbObjectId& objId, const char *cpBlockName,

AcGePoint3d basePoint, AcGeScale3d *scaleFactor, double dRotation, CString strAttribValues){ AcGeScale3d defaultSacleFactor( 1.0, 10, 10 ); AcGeScale3d *internalScaleFactor = NULL; AcGeVector3d normal(0.0, 00, 10); AcDbObjectId blockId; struct resbuf to, from; CString strFind; CString strValue; Acad::ErrorStatus es = Acad::eOk; // Nagyitási faktor és normálvektor ( UCS->WCS ) kiszánítása internalScaleFactor = ((scaleFactor == NULL) ? &defaultSacleFactor : scaleFactor); from.restype = RTSHORT; from.resvalrint = 1; // UCS to.restype = RTSHORT; to.resvalrint = 0; // WCS 60. oldal acedTrans(&(normal.x), &from, &to, Adesk::kTrue, &(normalx)); // A beszúrandó blokk azonosítójának lekérdezése if( (es = nameToSymbolId( AcDbBlockTableRecord::desc(), cpBlockName, blockId, acdbHostApplicationServices()>workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return es; } // Blokk referencia allokálása és az azonosító és más

tulajdonságok beállítása AcDbBlockReference *pBlkRef = new AcDbBlockReference; pBlkRef->setBlockTableRecord(blockId); pBlkRef->setPosition(basePoint); pBlkRef->setRotation(dRotation); pBlkRef->setNormal(normal); // A blokk hozzáadása a ModelSpace-hez AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable, AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB MODEL SPACE, pBlockTableRecord, AcDb::kForWrite); pBlockTable->close(); AcDbObjectId newEntId; pBlockTableRecord->appendAcDbEntity(objId, pBlkRef); pBlockTableRecord->close(); // A blokk definició megnyitása olvasásra iterátor beállítása AcDbBlockTableRecord *pBlockDef; acdbOpenObject(pBlockDef, blockId, AcDb::kForRead); AcDbBlockTableRecordIterator *pIterator; pBlockDef->newIterator(pIterator); AcDbEntity *pEnt; AcDbAttributeDefinition *pAttdef; // A blokk definició végig olvasása és ATTRIB-ok

létrehozása for (pIterator->start(); !pIterator->done(); pIterator->step()) { // Következö elem olvasása pIterator->getEntity(pEnt, AcDb::kForRead); // Ha az elem attributum definició nem konstans akkor az értékét // be kell állítani, egy új attributum entitást kell léttrhozni. pAttdef = AcDbAttributeDefinition::cast(pEnt); if (pAttdef != NULL && !pAttdef->isConstant()) { // Entitás létrehozása AcDbAttribute *pAtt = new AcDbAttribute(); pAtt->setPropertiesFrom(pAttdef); pAtt->setInvisible(pAttdef->isInvisible()); // A blokk referencia másolása basePoint = pAttdef->position(); basePoint += pBlkRef->position().asVector(); pAtt->setAlignmentPoint(basePoint); pAtt->setHeight(pAttdef->height()); pAtt->setHorizontalMode(pAttdef->horizontalMode()); pAtt->setVerticalMode(pAttdef->verticalMode()); pAtt->setAlignmentPoint(basePoint); pAtt->setRotation(pAttdef->rotation()); pAtt->setTag("Tag");

pAtt->setFieldLength(25); char *pStr = pAttdef->tag(); pAtt->setTag(pStr); pAtt->setFieldLength(pAttdef->fieldLength()); // A megjelenítendő érték értékadása strValue = "Un-Assigned Attribute Value"; strFind.Format( "%s ", pStr ); if( strAttribValues.Find(strFind) == 0 ){ strFind = strAttribValues; if( strFind.Find(" ") != -1 ) strFind = strFind.Left( strFindFind(" ") ); if( strFind.Find(" ") != -1 ){ strValue = strFind.Mid( strFindFind(" ")+1 ); } else { strValue = ""; } } strFind.Format( " %s ", pStr ); if ( strAttribValues.Find(strFind) != -1 ) { strFind = strAttribValues.Mid( strAttribValuesFind(strFind)+1 ); if( strFind.Find(" ") != -1 ) strFind = strFind.Left( strFindFind(" ") ); if( strFind.Find(" ") != -1 ){ 61. oldal strValue = strFind.Mid( strFindFind(" ")+1 ); } else { strValue = ""; } } free(pStr);

pAtt->setTextString(strValue); AcDbObjectId attId; pBlkRef->appendAttribute(attId, pAtt); pAtt->close(); } pEnt->close(); // pEnt-et kell hasznalni mert pAttDef NULL is lehet } delete pIterator; pBlockDef->close(); pBlkRef->close(); return es; } /* * changeObjectsColor: * * ~~~~~~~~~~~~~~~~~~~ * * A paraméterben kapott objektum színét megváltoztatja a * * a második paraméterben megadott szinre. * * * */ void changeObjectsColor( ads name ent, AcCmColor newColor ){ AcDbObjectId objId; enameToObjId( ent, objId ); changeObjectsColor( objId, newColor ); } void changeObjectsColor( AcDbObjectId idEnt, AcCmColor newColor ){ AcDbEntity *pEnt; acdbOpenObject( pEnt, idEnt, AcDb::kForWrite ); if( pEnt ){ pEnt->setColor( newColor ); pEnt->close(); } return; } /* * changeObjectsName: * * ~~~~~~~~~~~~~~~~~~ * * A paraméterben kapott objektumok nevét megváltoztatja * * a második paraméterben megadott névre. (A 1001gc-t * * értékét változtatja meg. * * * */ void

changeObjectsName( AcDbObjectIdArray &arrayOfWapObjects, CString newName ){ return; } bool canceledDialog = false; WRUiProgressDialog *progressDialog = NULL; void startPrograssIndicator( CString strTitle ){ canceledDialog = false; progressDialog = new WRUiProgressDialog; progressDialog->strTitle = strTitle; progressDialog->GetProgressHWND( &canceledDialog ); progressDialog->Create( MAKEINTRESOURCE(IDD PROGRESS), CWnd::FromHandle(adsw acadMainWnd()) ); progressDialog->ShowWindow( SW SHOWNORMAL ); progressDialog->ShowWindow( SW SHOW ); progressDialog->RedrawWindow(); } bool setProgressIndicator( double percent ){ if(( progressDialog != NULL ) && !canceledDialog ){ progressDialog->SetProgressIndicator( percent ); } return canceledDialog; } void endProgressIndicator( void ){ if( progressDialog != NULL ) { if( !canceledDialog ) progressDialog->SetProgressIndicator( -1 ); delete progressDialog; } } Database designer/arxsources/Commands.h /* * * 62.

oldal * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - WapRoute parancsok * * @@ @@@ @@ @@@@@@ @@@@@@ megvalósítása * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ #ifndef WAPROUTE COMMANDS H #define WAPROUTE COMMANDS H 1 /* * Funkciók elöre deklarálása. * */ /* Az aktuális rajz objektum inicializálását végzi / void initDwg(void); /* Új csomópont létrehozása - MODÁLIS PARANCS / void runCreateNode( void ); /* Új útvonal létrehozása - MODÁLIS PARANCS / void runCreateTrace( void ); /* Egy csomópont tulajdonságainak megváltoztatása - MODÁLIS PARANCS / void runModifyNode( void ); /* Egy útvonal tulajdonságainak megváltoztatása - MODÁLIS PARANCS / void runModifyTrace( void ); /* Egy csomópont keresése a rajzban - TRANSZPARENS PARANCS / void runFindNode( void ); /* Egy útvonal keresése a rajzban - TRANSZPARENS PARANCS / void

runFindTrace( void ); /* Egy feliratok rétegének ki/be kapcsolása - TRANSZPARENS PARANCS / void runShowHide( void ); /* Azonos nevü útvonalak összefüggöségének ellenörzése - MODÁLIS PARANCS / void runCheck1( void ); /* Útvonal kereső algoritmus két csomópont között - MODÁLIS PARANCS / void runCheck2( void ); /* Útvonal adatbázis importálása a rajzba - MODÁLIS PARANCS / void runImport( void ); /* Útvonal adatbázis exportálása a rajz alapján - MODÁLIS PARANCS / void runExport( void ); #endif Database designer/arxsources/Commands.cpp /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - WapRoute parancsok * * @@ @@@ @@ @@@@@@ @@@@@@ megvalósítása * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ /* * Include-k. * */ #include "StdAfx.h" #include "Default.h" #include "WapRoute.h" // Alkalmazas globalis

valtozoi, define-ok #include #include #include #include // Hibakezelés // AutoCAD szolgáltatások bövítése // WapRoute parancsok megvalósítása "AcadStr.h" "Error.h" "AcadPlus.h" "Commands.h" #include "WRUiCheck1Dialog.h" // Check1 funkció ablaka 63. oldal #include #include #include #include #include #include "WRUiCheck2Dialog.h" "WRUiGetString.h" "WRUiModifyTraceDialog.h" "WRUiNewTraceDialog.h" "WRUiFindNodeDialog.h" "WRUiFindTraceDialog.h" // // // // // // Check2 funkció ablaka Egy stringet bekérö ablak Útvonal módosító ablak Új útvonal létrehozásához tartozó ablak Csomópont kereső ablak Útvonal kereső ablak /* * createNewLinetypes: * * ~~~~~~~~~~~~~~~~~~~ * * A WapRoute sablonhoz tartozó vonaltipusok generálása * * az aktuális rajzba. Ez nem külső vonaltipus állomány- * * ból történik hanem az AutoCAD vonaltipus objektumain

* * keresztül. * * * */ bool createNewLinetypes( void ){ AcDbLinetypeTableRecord *pNewLinetype = NULL; Acad::ErrorStatus es; AcGeVector2d offset(0.0, -20); AcDbObjectId idStandardTextStyle, ltId; bool createBJ, createJB; bool retCode = false; createBJ = !symbolExists( AcDbLinetypeTableRecord::desc(), "BJ-Egyirányú útvonal", acdbHostApplicationServices()->workingDatabase() ); createJB = !symbolExists( AcDbLinetypeTableRecord::desc(), "JB-Egyirányú útvonal", acdbHostApplicationServices()->workingDatabase() ); // A STANDARD szöveg tipus azonosítojanak lekérdezése if( (es = nameToSymbolId( AcDbTextStyleTableRecord::desc(), "STANDARD", idStandardTextStyle, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return retCode; } // *BJ-Egyirányú útvonal,BJ-Egyirányú --- > --- > --- > --// A,20.0,-25,[">",STANDARD,S=10,R=0,X=0,Y=-50],-100 // // ((0 . "LTYPE")

(2 "BJ-Egyirányú útvonal") (70 0) // (3 . "BJ-Egyirányú --- > --- > --- > ---") (72 65) // (73 . 3) (40 275) (49 200) (49 -25) // (74 . 2) (75 0) (340 11) (46 40) (50 00) (44 00) // (45 . -20) (9 ">") (49 -50) (74 0)) if( createBJ ){ pNewLinetype = new AcDbLinetypeTableRecord; if( setSymbolName( pNewLinetype, "BJ-Egyirányú útvonal" ) == pNewLinetype->setComments( "BJ-Egyirányú --- > --- > --pNewLinetype->setIsScaledToFit( false ); pNewLinetype->setNumDashes( 3 ); pNewLinetype->setPatternLength( 27.5 ); pNewLinetype->setDashLengthAt( 0, 20.0 ); pNewLinetype->setDashLengthAt( 1, -2.5 ); pNewLinetype->setShapeIsUcsOrientedAt( 1, false ); pNewLinetype->setShapeNumberAt( 1, 0 ); pNewLinetype->setShapeStyleAt( 1, idStandardTextStyle ); pNewLinetype->setShapeScaleAt( 1, 4.0 ); pNewLinetype->setShapeRotationAt( 1, 0.0 ); pNewLinetype->setShapeOffsetAt( 1, offset );

pNewLinetype->setTextAt( 1, ">" ); pNewLinetype->setDashLengthAt( 2, -5.0 ); pNewLinetype->setShapeIsUcsOrientedAt( 2, false ); addToSymbolTableAndClose( pNewLinetype ); retCode = true; } else { delete pNewLinetype; } } // *JB-Egyirányú útvonal,JB-Egyirányú --- < --- < --- < --// A,20.0,-25,["<",STANDARD,S=10,R=0,X=0,Y=-50],-100 // // ((0 . "LTYPE") (2 "JB-Egyirányú útvonal") (70 0) // (3 . "JB-Egyirányú --- < --- < --- < ---") (72 65) // (73 . 3) (40 275) (49 200) (49 -25) // (74 . 2) (75 0) (340 11) (46 40) (50 00) (44 00) // (45 . -20) (9 "<") (49 -50) (74 0)) if( createJB ){ pNewLinetype = new AcDbLinetypeTableRecord; if( setSymbolName( pNewLinetype, "JB-Egyirányú útvonal" ) == pNewLinetype->setComments( "JB-Egyirányú --- < --- < --pNewLinetype->setIsScaledToFit( false ); pNewLinetype->setNumDashes( 3 ); 64. oldal Acad::eOk ){

> ---" ); // GC 3 // GC 72 (A betű) // GC 73 // GC 40 // GC 49 // GC 49 // GC 74 // GC 75 // GC 340 // GC 46 // GC 50 // GC 44, 45 // GC 9 // GC 49 // GC 74 Acad::eOk ){ < ---" ); // GC 3 // GC 72 (A betű) // GC 73 pNewLinetype->setPatternLength( 27.5 ); // GC 40 pNewLinetype->setDashLengthAt( 0, 20.0 ); // GC 49 pNewLinetype->setDashLengthAt( 1, -2.5 ); // GC 49 pNewLinetype->setShapeIsUcsOrientedAt( 1, false ); // GC 74 pNewLinetype->setShapeNumberAt( 1, 0 ); // GC 75 pNewLinetype->setShapeStyleAt( 1, idStandardTextStyle ); // GC 340 pNewLinetype->setShapeScaleAt( 1, 4.0 ); // GC 46 pNewLinetype->setShapeRotationAt( 1, 0.0 ); // GC 50 pNewLinetype->setShapeOffsetAt( 1, offset ); // GC 44, 45 pNewLinetype->setTextAt( 1, "<" ); // GC 9 pNewLinetype->setDashLengthAt( 2, -5.0 ); // GC 49 pNewLinetype->setShapeIsUcsOrientedAt( 2, false ); // GC 74 addToSymbolTableAndClose( pNewLinetype ); retCode = true; } else {

delete pNewLinetype; } } return retCode; } /* * createNewLayers: * * ~~~~~~~~~~~~~~~~ * * A WapRoute sablonhoz tartozó rétegek generálása az ak- * * tuális rajzba. A layerek letrehozasaval egyutt azok * * vonaltipusat es szinet is beallitja a funkcio. * * * */ bool createNewLayers( void ) { AcDbLayerTableRecord *pLayerTableRecord; Acad::ErrorStatus es; AcDbObjectId ltId; AcCmColor color; bool createVaros, createUt, createFelirat; bool retCode = false; createVaros = !symbolExists( AcDbLayerTableRecord::desc(), "WR VAROS", acdbHostApplicationServices()>workingDatabase() ); createUt = !symbolExists( AcDbLayerTableRecord::desc(), "WR UT", acdbHostApplicationServices()>workingDatabase() ); createFelirat = !symbolExists( AcDbLayerTableRecord::desc(), "WR FELIRAT", acdbHostApplicationServices()>workingDatabase() ); // A CONTINUOUS vonaltipus azonosítójának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(),

"CONTINUOUS", ltId, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return retCode; } /* Csomopontok rétegének létrehozása / if( createVaros ){ pLayerTableRecord = new AcDbLayerTableRecord; if( setSymbolName( pLayerTableRecord, "WR VAROS" ) == Acad::eOk ){ pLayerTableRecord->setIsFrozen(0); // Réteg nem fagyasztott pLayerTableRecord->setIsOff(0); // Réteg látható pLayerTableRecord->setVPDFLT(0); // Réteg minden viewportban látható pLayerTableRecord->setIsLocked(0); // Réteg nincs lezárva color.setColorIndex( 5 ); pLayerTableRecord->setColor(color); // Réteg színe kék pLayerTableRecord->setLinetypeObjectId(ltId); // Réteg vonaltipusa folytonos addToSymbolTableAndClose( pLayerTableRecord ); retCode = true; } else { delete pLayerTableRecord; } } /* Útvonalak layere / if( createUt ){ pLayerTableRecord = new AcDbLayerTableRecord; if( setSymbolName( pLayerTableRecord, "WR

UT" ) == Acad::eOk ){ pLayerTableRecord->setIsFrozen(0); // Réteg nem fagyasztott pLayerTableRecord->setIsOff(0); // Réteg látható pLayerTableRecord->setVPDFLT(0); // Réteg minden viewportban látható pLayerTableRecord->setIsLocked(0); // Réteg nincs lezárva color.setColorIndex( 2 ); pLayerTableRecord->setColor(color); // Réteg színe sárga pLayerTableRecord->setLinetypeObjectId(ltId); // Réteg vonaltipusa folytonos addToSymbolTableAndClose( pLayerTableRecord ); retCode = true; } else { 65. oldal delete pLayerTableRecord; } } /* Ellenőrző felirtok layere / pLayerTableRecord = new AcDbLayerTableRecord; if( createFelirat ){ if( setSymbolName( pLayerTableRecord, "WR FELIRAT" ) pLayerTableRecord->setIsFrozen(0); // pLayerTableRecord->setIsOff(1); // pLayerTableRecord->setVPDFLT(0); // pLayerTableRecord->setIsLocked(0); // color.setColorIndex( 3 ); pLayerTableRecord->setColor(color); //

pLayerTableRecord->setLinetypeObjectId(ltId); // addToSymbolTableAndClose( pLayerTableRecord ); retCode = true; } else { delete pLayerTableRecord; } } == Acad::eOk ){ Réteg nem fagyasztott Réteg nem látható Réteg minden viewportban látható Réteg nincs lezárva Réteg színe zöld Réteg vonaltipusa folytonos return retCode; } /* * createNewBlocks: * * ~~~~~~~~~~~~~~~~ * * A WapRoute sablonhoz tartozó blokkok generálása az ak- * * tuális rajzba. Azok szinének beállitása BYLAYER-re * * * */ bool createNewBlocks( void ){ bool retCode = false; bool createNode; AcGePoint3d basePoint(0.0, 00, 00); AcGePoint3d textInsertPoint(0.0, 60, 00); AcDbObjectId newBlockRecId, entityId, idLy; Acad::ErrorStatus es; AcDbBlockTableRecord *pBlockRecord; AcDbAttributeDefinition *pAttdef = NULL; createNode = !symbolExists( AcDbBlockTableRecord::desc(), "WAPROUTE-NODE", acdbHostApplicationServices()>workingDatabase() ); // A WR FELIRAT nevű réteg azonosítójának

lekérdezése if( (es = nameToSymbolId( AcDbLayerTableRecord::desc(), "WR FELIRAT", idLy, acdbHostApplicationServices()>workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return retCode; } if( createNode && (defineNewBlock("WAPROUTE-NODE", pBlockRecord, acdbHostApplicationServices()>workingDatabase()) == Acad::eOk) ){ // A blokk tulajdonságainak beállítása. pBlockRecord->setOrigin(basePoint); // DONUT készítése és hozzáadása a blokk definicióhoz // // (0 . "LWPOLYLINE") (100 "AcDbEntity") (67 0) (410 "Model") (8 "0") // (6 . "Continuous") (100 "AcDbPolyline") (90 2) (70 1) (43 50) (38 00) // (39 . 00) (10 -25 00) (40 50) (41 50) (42 10) (10 25 00) (40 50) // (41 . 50) (42 10) (210 00 00 10)) AcDbPolyline* pNewPline; AcGePoint2d pt1( -2.5, 00 ); AcGePoint2d pt2( 2.5, 00 ); pNewPline = new AcDbPolyline( 2 ); pNewPline->setClosed( Adesk::kTrue

); pNewPline->setConstantWidth( 5.0 ); pNewPline->addVertexAt( 0, pt1, 1.0 ); pNewPline->addVertexAt( 1, pt2, 1.0 ); pNewPline->setColorIndex( 0 ); pBlockRecord->appendAcDbEntity(entityId, pNewPline); pNewPline->close(); // Egy attributum hozzáadása a blokk definicióhoz. pAttdef = new AcDbAttributeDefinition; pAttdef->setAlignmentPoint(textInsertPoint); pAttdef->setHeight(5.0); pAttdef->setRotation(0.0); pAttdef->setHorizontalMode(AcDb::kTextCenter); pAttdef->setVerticalMode(AcDb::kTextBase); pAttdef->setAlignmentPoint(textInsertPoint); 66. oldal pAttdef->setPrompt("Csomópont neve"); pAttdef->setTextString("???"); pAttdef->setTag("VÁROS"); pAttdef->setInvisible(Adesk::kFalse); pAttdef->setVerifiable(Adesk::kFalse); pAttdef->setPreset(Adesk::kFalse); pAttdef->setConstant(Adesk::kFalse); pAttdef->setFieldLength(3); pAttdef->setLayer(idLy); pBlockRecord->appendAcDbEntity(entityId,

pAttdef); pAttdef->close(); // A blokk definició hozzáadása a blokk táblához pBlockRecord->close(); retCode = true; } return retCode; } /* * registerApplication: * * ~~~~~~~~~~~~~~~~~~~~ * * Az aktualis rajzba az alkalmazás regisztrálása, az ex- * * tended tulajdonságok tárolása érdekében. Az neveket * * és utvonal számokat fogja a program itt tárolni. * * * */ bool registerApplication( void ){ bool retCode = false; struct resbuf *rbp; if ((rbp = acdbTblSearch("APPID", local appname, 0)) == NULL) { if (acdbRegApp(ACAD APPNAME) != RTNORM) { acutPrintf("XDATA regisztrálása nem lehetséges a %s alkalmazásnak. ", local appname); } else { retCode = true; } } else { acutRelRb(rbp); } return retCode; } /* * initDwg: * * ~~~~~~~~ * * Az aktualis rajz inicializalasa, vonaltipusok betolte- * * se, retegek letrehozasa, ikonok, ablakok betoltese. * * * */ void initDwg( void ) { bool crlt, crly, crbl, rgap; CString strMsg = ""; /* A crlt crly

crbl rgap rajz nem inicializált részeinek inicializálása */ = createNewLinetypes(); = createNewLayers(); = createNewBlocks(); = registerApplication(); /* Az inicializalas kesz / if( crlt ){ if( strMsg.GetLength() == else } if( crly ){ if( strMsg.GetLength() == else } if( crbl ){ if( strMsg.GetLength() == else } if( rgap ){ if( strMsg.GetLength() == else } 0 ) strMsg = "(Vonaltipusok"; strMsg += ",Vonaltipusok"; 0 ) strMsg = "(Rétegek"; strMsg += ",Rétegek"; 0 ) strMsg = "(Blokkok"; strMsg += ",Blokkok"; 0 ) strMsg = "(Regisztráció"; strMsg += ",Regisztráció"; if( strMsg.GetLength() ) acutPrintf("WapRoute - Rajz sablon "+strMsg+") inicializálva. "); return; } 67. oldal /* * createNode: * * ~~~~~~~~~~~ * * A bejövö paraméterek alapján egy csomópont objektumot * * készit. * * * */ Acad::ErrorStatus createNode( AcDbObjectId &objId, AcGePoint3d basePoint,

CString strName ){ AcDbEntity *pEnt = NULL; CString strAttribValue; Acad::ErrorStatus es = Acad::eOk; // Az attributum értékének beállításához spec tárolási forma strAttribValue.Format( "%s %s", "VÁROS", strName ); // Blokk elkészítése es = createInsertWithAttributes( objId, "WAPROUTE-NODE", basePoint, NULL, 0.0, strAttribValue ); // Az elkészítés után plussz tulajdonságok beállítása acdbOpenObject( pEnt, objId, AcDb::kForWrite ); if( pEnt ){ pEnt->setLayer( "WR VAROS" ); pEnt->close(); } // XData keszitese SetApplicationData( objId, (char*)((LPCTSTR)strName) ); return es; } /* * createTrace: * * ~~~~~~~~~~~~ * * A bejövö paraméterek alapján egy útvonal objektumot * * készit. * * * */ Acad::ErrorStatus createTrace( AcDbObjectId &objId, AcGePoint2dArray ptArray, CString strName, int iUtTipus ){ AcDbObjectId idStandardTextStyle, idLast; AcDbObjectId idBJ, idJB; AcDbEntity *pEnt = NULL; AcDbText *pTxt = NULL; ads

point ptOld; ads point pt; int i; double dRotation; AcGePoint3d textInsertPoint(0.0, 00, 00); Acad::ErrorStatus es = Acad::eOk; // A STANDARD szöveg tipus azonosítojanak lekérdezése if( (es = nameToSymbolId( AcDbTextStyleTableRecord::desc(), "STANDARD", idStandardTextStyle, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return es; } // A BJ-Egyirányú útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "BJ-Egyirányú útvonal", idBJ, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return es; } // A JB-Egyirányú útvonal vonal tipus azonosítojának lekérdezése if( (es = nameToSymbolId( AcDbLinetypeTableRecord::desc(), "JB-Egyirányú útvonal", idJB, acdbHostApplicationServices()->workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return es; } //

A vonal létrehozása createPolyline( ptArray, objId ); // A layer megváltoztatása acdbOpenObject( pEnt, objId, AcDb::kForWrite ); pEnt->setLayer( "WR UT" ); if( iUtTipus == DWG TRACE ONEWAY LR ){ pEnt->setLinetype( idBJ ); } else if ( iUtTipus == DWG TRACE ONEWAY RL ){ pEnt->setLinetype( idJB ); } else { pEnt->setLinetype( "CONTINUOUS" ); 68. oldal } pEnt->close(); // XData keszitese SetApplicationData( objId, (char*)((LPCTSTR)strName) ); // Feliratok feltétele az egyes elég hoszzú szegmensek közepére. for( i=0; i<ptArray.length()-1; i++ ){ ptOld[X] = ((ptArray.at(i)x > ptArrayat(i+1)x) ? ptArrayat(i+1)x : ptArrayat(i)x ); ptOld[Y] = ((ptArray.at(i)x > ptArrayat(i+1)x) ? ptArrayat(i+1)y : ptArrayat(i)y ); ptOld[Z] = 0.0; pt[X] = ((ptArray.at(i)x > ptArrayat(i+1)x) ? ptArrayat(i)x : ptArrayat(i+1)x ); pt[Y] = ((ptArray.at(i)x > ptArrayat(i+1)x) ? ptArrayat(i)y : ptArrayat(i+1)y ); pt[Z] = 0.0; if( acutDistance( pt, ptOld )

> 10.0 ){ // Számolások dRotation = asin( (pt[Y]-ptOld[Y]) / acutDistance( pt, ptOld ) ); textInsertPoint = midpoint( ptArray.at(i), ptArrayat(i+1) ); textInsertPoint.x = textInsertPointx-sin(dRotation)*2.0; textInsertPoint.y = textInsertPointy+cos(dRotation)*2.0; createText( textInsertPoint, 5.0, dRotation, (LPCTSTR)strName, idStandardTextStyle, idLast ); // Az értékek beállítása acdbOpenObject( pTxt, idLast, AcDb::kForWrite ); pTxt->setLayer( "WR FELIRAT" ); pTxt->setHorizontalMode(AcDb::kTextCenter); pTxt->setVerticalMode(AcDb::kTextBase); pTxt->setAlignmentPoint(textInsertPoint); pTxt->setRotation( dRotation ); pTxt->close(); } } return es; } /* * freadline: * * ~~~~~~~~~~ * * Egy sort olvas a megadott állományból az aktuális fájl * * poziciótól. A beolvastott sort egy CStringben adja * * vissza,ha nem sikerült olvasnia üres stringet ad visza,* * a visszatérési érték nem tartalmazza az újsor karaktert* * A beolvasott sort

előfeldolgozza is, hiszen az első # * * karaktertől kezdődően a sor további részét levágja. * * valamint a karakter sorozatban található szóközöket * * kihagyja. Ha egy üres sort olvas akkor a feldolgozást * * a következö sorral folytatja. * * * */ void freadline( FILE *fp, CString& strLine, long countRows ){ char buffer[1024]; char *cp = buffer; memset( buffer, 0x0, 1024 ); strLine = ""; while( !feof(fp) && (strLine.GetLength() == 0) ){ memset( buffer, 0x0, 1024 ); while( ( !feof(fp) ) && ((*cp++=fgetc( fp )) != )) if(( *(cp-1) == ) || ( (cp-1) == ) || ( (cp-1) == )) cp--; if( *(cp-1) == ) *(cp-1) = 0x0; *cp = 0x0; strLine = buffer; if( strLine.Find("#") != -1 ) strLine = strLine.Left( strLineFind("#") ); (*countRows)++; cp = buffer; } } /* * runCreateNode: * * ~~~~~~~~~~~~~~ * * WRCREATENODE parancs megvalósítása. A felhasználótól * * bekéri a szükséges adatokat és elkészíti az objktumot. * * *

*/ static long lNextNodeNumber = 0; void runCreateNode( void ) { CString strNev; AcGePoint3d basePoint; AcDbObjectId idLast = 0; initDwg(); // A város nevének bekérése, ha CANCEL-lel zárta le az 69. oldal // ablakot akkor kilépés a funkcióból. WRUiGetString dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.m strTitle = "Új város létrehozása"; dlg.m strDescription = "Adja meg az új város nevét:"; dlg.m strDefaultValueFormat( "Város-%d", lNextNodeNumber ); if( dlg.DoModal() != 1 ) return; strNev = dlg.m strReturnValue; // Pont bekérése után az objktum létrehozása if( acedGetPoint(NULL, " Adja meg az új város beszúrási pontját: ", asDblArray(basePoint)) == RTNORM ) { createNode( idLast, basePoint, strNev ); lNextNodeNumber++; } return; } /* * runCreateTrace: * * ~~~~~~~~~~~~~~~ * * WRCREATETRACE parancs megvalósítása. A felhasználótól * * bekéri a szükséges adatokat és elkészíti az objktumot. * * * */ static

long lNextTraceNumber = 0; static int iLastType = DWG TRACE TWOWAY; void runCreateTrace( void ) { CString strNev; int iUtType = 0; bool AcDbObjectId ads name ads point ads point AcGePoint2d AcGePoint2dArray int char kilep = false; idLast = 0; ename; ptOld; pt; ptRes; ptArray; resVal; answer[132]; initDwg(); // Az út nevének bekérése, ha CANCEL-lel zárta le az // ablakot akkor kilépés a funkcióból. WRUiNewTraceDialog dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.m strTitle = "Új út létrehozása"; dlg.m strDescription = "Adja meg az új út tulajdonságait:"; dlg.m strDefaultNameFormat( "Út-%d", lNextTraceNumber ); dlg.m iDefaultType = iLastType; if( dlg.DoModal() != 1 ) return; strNev = dlg.m strName; iUtType = dlg.m iType; while( !kilep ){ // Az egyes pontok alapján a kiirt felirat is változik switch( ptArray.length() ){ case 0: acedInitGet( RSG NOLIM|RSG NONULL, "" ); resVal = acedGetPoint(NULL, " Adja meg az útvonal

első pontját: ", pt); break; case 1: acedInitGet( RSG NOLIM, "Vissza" ); resVal = acedGetPoint(ptOld, " Adja meg az útvonal második pontját: <Vissza>", pt); break; default: acedInitGet( RSG NOLIM, "Vissza véGe" ); resVal = acedGetPoint(ptOld, " Adja meg az útvonal további pontjait: Vissza,<véGe>", pt); break; } // A kapott paraméterek analizálása if( resVal == RTNORM ) { ptRes.set( pt[X], pt[Y] ); ptArray.append( ptRes ); ptOld[X] = pt[X]; ptOld[Y] = pt[Y]; ptOld[Z] = 0.0; } else if(( resVal == RTKWORD ) || ( resVal == RTNONE )){ if( resVal == RTKWORD ){ acedGetInput(answer); } else if(( resVal == RTNONE ) && ( ptArray.length() == 1 )){ strcpy( answer, "Vissza" ); } else if(( resVal == RTNONE ) && ( ptArray.length() > 1 )){ strcpy( answer, "véGe" ); 70. oldal } // A válasz "Vissza" akkor törölni kell az utolsó értéket if( stricmp(answer, "Vissza")

== 0 ){ if( !ptArray.isEmpty() ) ptArray.removeLast(); if( !ptArray.isEmpty() ){ ptRes = ptArray.last(); ptOld[X] = ptRes.x; ptOld[Y] = ptRes.y; ptOld[Z] = 0.0; } } // Ha a válasz "véGe" akkor ki kell lépni és minden jó // csak a layert, szöveget és vonaltipust kell beállitani. else if( stricmp(answer, "véGe") == 0 ){ kilep = true; // Ha volt régi objektum akkor letörli azt. if( idLast != 0 ) { objIdToEname( idLast, ename ); acdbEntDel( ename ); idLast = 0; } createTrace( idLast, ptArray, strNev, iUtType ); iLastType = iUtType; lNextTraceNumber++; continue; } } else if( resVal == RTCAN ) { kilep = true; } // Ha volt régi objektum akkor letörli azt. if( idLast != 0 ) { objIdToEname( idLast, ename ); acdbEntDel( ename ); idLast = 0; } // Ha lehet akkor megjeleníti az megadott vonalat. if(( resVal != RTCAN ) && ( ptArray.length() >= 2 )){ createPolyline( ptArray, idLast ); } } } /* * runShowHide: * * ~~~~~~~~~~~~ * * WRSHOWHIDE parancs

megvalósítása. Leellenörzi, hogy a * * WR FELIRAT réteg látható vagy nem, ha látható akkor * * nemláthatóvá, nam nem látható akkor láthatóvá teszi. * * Valamint a menü jó megjelenítéséhez állítja az USERS2 * * változót ON illetve OFF értéküre. * * * */ void runShowHide( void ) { AcDbLayerTableRecord *pEnt = NULL; Acad::ErrorStatus es; struct resbuf rb; AcDbObjectId lyId; bool bVisible; initDwg(); // A WR FELIRAT layer azonosítójának lekérdezése if( (es = nameToSymbolId( AcDbLayerTableRecord::desc(), "WR FELIRAT", lyId, acdbHostApplicationServices()>workingDatabase() )) != Acad::eOk ){ rxErrorAlert(es, FILE , LINE ); return; } // A layer lathatosaganak lekerdezese es ellentetesre allitasa acdbOpenObject( pEnt, lyId, AcDb::kForWrite ); bVisible = !pEnt->isOff(); pEnt->setIsOff( bVisible ); pEnt->close(); // Beállitom az AutoCAD környezetet hogy a menüt jól jelenítse meg. rb.restype = RTSTR; rb.resvalrstring = ((bVisible) ?

"OFF" : "ON"); acedSetVar( "USERS2", &rb ); return; 71. oldal } /* * runImport: * * ~~~~~~~~~~ * * WRIMPORT parancs megvalósítása. A felhasználótól bekér * * egy WRD kiterjesztésü állomány nevet, amit megnyit és * * megpróbál útvonal adatbázisként értelmezni. Az impor- * * tált adatok statisztikáját jeleníti meg az olvasás * * végeztével. * * * */ void runImport( void ) { struct resbuf rb; char *cpFileName; char *cp; char *ck; char cbFileName[1024]; char cbFilePath[1024]; char cbFileNameAndPath[1024]; char strDisplay[1024]; char bufferT[1024]; FILE *fp; long iMaxLength; long readBytes = 0; long nrOfReadLines = 0; long nrOfReadElements = 0; long nrOfElementErrors = 0; AcGePoint2dArray ptArray; AcDbObjectId idLast = 0; int iType = 0, iUtType = 0; double x = 0.0, y = 00; CString currentLine; CString currentWord; CString nextPart; CString strName; initDwg(); // A rajz állomány nevének lekérdezése és kiterjesztés

levágása acedGetVar( "DWGPREFIX", &rb ); strcpy( cbFileNameAndPath, rb.resvalrstring ); free( rb.resvalrstring ); acedGetVar( "DWGNAME", &rb ); strcat( cbFileNameAndPath, rb.resvalrstring ); free( rb.resvalrstring ); if(( (cp=strrchr(cbFileNameAndPath,.))!=NULL ) && ( ! (( (ck=strrchr(cbFileNameAndPath,\))!=NULL ) && (ck>cp)) )){ *cp = 0x0; } // Új állománynév bekérése. if( (cpFileName = getWrdFileLoation( "Útvonal adatbázis importálása", cbFileNameAndPath, 32 )) == NULL ) return; strcpy(cbFileNameAndPath, cpFileName); if( ( cp = strrchr( cbFileNameAndPath, \ ) ) == NULL ){ strcpy( cbFileName, cbFileNameAndPath ); strcpy( cbFilePath, "" ); } else { *cp = 0x0; strcpy( cbFilePath, cbFileNameAndPath ); strcpy( cbFileName, cp+1 ); *cp = \; } //debugOutput("WAPROUTE - Import-Finename: %s WAPROUTE - Import-Filepath: %s", cbFileName, cbFilePath ); // Az állomány megnyitása és az adatok importálása

if( (fp = fopen( cbFileNameAndPath, "r" )) == NULL ){ sprintf( strDisplay, "A megadott állományt (%s) nem lehet olvasásra megynitni!", cbFileNameAndPath ); acedAlert( strDisplay ); return; } // A progress indikátor felmutatása maximális hossz meghatározása startPrograssIndicator( "Elemek importálása." ); fseek( fp, 0, SEEK END ); iMaxLength = ftell( fp ); fseek( fp, 0, SEEK SET ); // Indikator olvasasa freadline( fp, currentLine, &nrOfReadLines ); currentWord = currentLine.Left( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")) ); 72. oldal nextPart = currentLine.Mid( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")+1) ); iType = atoi(currentWord); // Az állomény olvasása objektumonként while( !feof(fp) && !ads usrbrk() ){ // Az indikátor növelése ha szükséges setProgressIndicator( (((double)ftell(fp))/iMaxLength)*100.0 );

// Ha nem ures a tömb akkor törli minden elemét AcGePoint3d pt( 0.0, 00, 00 ); AcGePoint2d pt2d( 0.0, 00 ); if( !ptArray.isEmpty() ) ptArray.removeSubArray( 0, ptArraylength()-1 ); switch( iType ){ case ASN CONFIG: //sprintf( strDisplay, "WAPROUTE - ASN CONFIG" ); //acedAlert( strDisplay ); // Config sor maradek részét figyelmenkívül hagyhatjuk freadline( fp, currentLine, &nrOfReadLines ); currentWord = currentLine.Left( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")) ); nextPart = currentLine.Mid( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")+1) ); iType = atoi(currentWord); break; case ASN NODE: nrOfReadElements++; //sprintf( strDisplay, "WAPROUTE - ASN NODE" ); //acedAlert( strDisplay ); currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid(

((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); octetStringToAsciiString( (char*)(LPCTSTR)currentWord, bufferT ); strName = bufferT; currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); pt.x = atof(currentWord); currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); pt.y = atof(currentWord); //sprintf( strDisplay, "WAPROUTE - ASN NODE - %s,%.4f,%4f", strName, ptx, pty ); //acedAlert( strDisplay ); createNode( idLast, pt, strName ); // Következö sor olvasása freadline( fp, currentLine, &nrOfReadLines ); currentWord = currentLine.Left(

((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")) ); nextPart = currentLine.Mid( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")+1) ); iType = atoi(currentWord); break; case ASN TRACE: nrOfReadElements++; //sprintf( strDisplay, "WAPROUTE - ASN TRACE" ); //acedAlert( strDisplay ); currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); octetStringToAsciiString( (char*)(LPCTSTR)currentWord, bufferT ); strName = bufferT; currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); iUtType = atoi(currentWord); iType = ASN

POINT; while( !feof(fp) && (iType == ASN POINT) ){ 73. oldal // Következö sor olvasása freadline( fp, currentLine, &nrOfReadLines ); currentWord = currentLine.Left( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")) ); nextPart = currentLine.Mid( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")+1) ); iType = atoi(currentWord); if( iType == ASN POINT ){ currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); pt2d.x = atof(currentWord); currentWord = nextPart.Left( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")) ); nextPart = nextPart.Mid( ((nextPartFind(",") == -1)? nextPartGetLength() : nextPart.Find(",")+1) ); pt2d.y =

atof(currentWord); ptArray.append( pt2d ); //sprintf( strDisplay, "WAPROUTE - ASN POINT - %.4f,%4f", pt2dx, pt2dy ); //acedAlert( strDisplay ); } } //sprintf( strDisplay, "WAPROUTE - ASN TRACE - %s,%d,%d", strName, ptArray.length(),iUtType ); //acedAlert( strDisplay ); if( ptArray.length() > 1 ) createTrace( idLast, ptArray, bufferT, iUtType ); break; default: nrOfElementErrors++; //sprintf( strDisplay, "WAPROUTE - default" ); //acedAlert( strDisplay ); // Config sor maradek részét figyelmenkívül hagyhatjuk freadline( fp, currentLine, &nrOfReadLines ); currentWord = currentLine.Left( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")) ); nextPart = currentLine.Mid( ((currentLineFind(",") == -1)? currentLineGetLength() : currentLine.Find(",")+1) ); iType = atoi(currentWord); break; } } readBytes = ftell(fp); fclose(fp); endProgressIndicator(); // Statisztikai információk

megjelenítése sprintf( strDisplay, "Útvonal adatbázis importálása megtörtént! A "%s" " "állományból olvasott adatok statisztikája: Importált elemek száma : %d darab Hibás elemek száma : %d darab Sorok száma : %d darab Állomány olvasott hossza : %d byte", cbFileNameAndPath, nrOfReadElements, nrOfElementErrors, nrOfReadLines, readBytes ); acedAlert( strDisplay ); return; } /* * runExport: * * ~~~~~~~~~~ * * WREXPORT parancs megvalósítása. A felhasználótól bekér * * egy WRD kiterjesztésü állomány nevet, amibe a rajzon * * található WapRoute objketumokat elmenti. Ha a felhasz- * * náló már létezö állományt váklaszt ki akkor erre fi* * gyelmezteti. * * * */ void runExport( void ) { struct resbuf rb, *filter; char *cpFileName, cp, ck; char cbFileName[1024]; char cbFilePath[1024]; char cbFileNameAndPath[1024]; char strDisplay[1024]; long iLast, i, j, iUtType= 0, writtenBytes = 0, nrOfLines = 0, nrOfElements = 0; FILE

*fp; ads name ent,sset; AcGePoint3dArray ptArray; initDwg(); // A rajz állomány nevének lekérdezése és kiterjesztés levágása 74. oldal acedGetVar( "DWGPREFIX", &rb ); strcpy( cbFileNameAndPath, rb.resvalrstring ); free( rb.resvalrstring ); acedGetVar( "DWGNAME", &rb ); strcat( cbFileNameAndPath, rb.resvalrstring ); free( rb.resvalrstring ); if(( (cp=strrchr(cbFileNameAndPath,.))!=NULL ) && ( ! (( (ck=strrchr(cbFileNameAndPath,\))!=NULL ) && (ck>cp)) )){ *cp = 0x0; } // Új állománynév bekérése. if( (cpFileName = getWrdFileLoation( "Útvonal adatbázis mentése", cbFileNameAndPath, 1 )) == NULL ) return; strcpy(cbFileNameAndPath, cpFileName); if( ( cp = strrchr( cbFileNameAndPath, \ ) ) == NULL ){ strcpy( cbFileName, cbFileNameAndPath ); strcpy( cbFilePath, "" ); } else { *cp = 0x0; strcpy( cbFilePath, cbFileNameAndPath ); strcpy( cbFileName, cp+1 ); *cp = \; } //debugOutput("WAPROUTE -

Export-Finename: %s WAPROUTE - Export-Filepath: %s", cbFileName, cbFilePath ); // Az állomány megnyitása és az export elkészítése if( (fp = fopen( cbFileNameAndPath, "w+" )) == NULL ){ sprintf( strDisplay, "A megadott állományt (%s) nem lehet irásra megynitni!", cbFileNameAndPath ); acedAlert( strDisplay ); return; } // A progress indikátor felmutatása startPrograssIndicator( "Elemek exportálása." ); // Config sor kiirasa fprintf( fp, "%d,%d", ASN CONFIG, 1000 ); // Adatok legyújtése a rajzról. filter = acutBuildList( -4, "<OR", -4, "<AND", RTDXF0, "INSERT", 2, "WAPROUTE-NODE", 8, "WR VAROS", -4, "AND>", -4, "<AND", RTDXF0, "LWPOLYLINE", 8, "WR UT", -4, "AND>", -4, "OR>", 0 ); acedSSGet( T("X"), NULL, NULL, filter, sset ); acutRelRb(filter); if(acedSSLength(sset, &iLast) == RTNORM){

for( i=iLast; i-->0; ){ setProgressIndicator( ((double)(iLast-i)/iLast)*100.0 ); if( acedSSName(sset, i, ent) == RTNORM ){ // Ha nem ures a tömb akkor törli minden elemét if( !ptArray.isEmpty() ) ptArray.removeSubArray( 0, ptArraylength()-1 ); // A különbözö entitások különbözö kiiró funkciókat kívánnak. cp = enttype( ent ); //debugOutput( " %dth element %s type", i, cp ); ck = GetApplicationData( ent ); //debugOutput( " %dth element %s application data", i, ck ); entpoints( ent, ptArray ); //debugOutput( " %dth element %d array length", i, ptArray.length() ); asciiStringToOctetString( ck, strDisplay ); //debugOutput( " %dth element %s application data coded", i, strDisplay ); // Csomopontok exportálása if( stricmp( cp, "INSERT" ) == 0 ){ nrOfElements++; if( ptArray.length() == 1 ){ fprintf( fp, " %d,%s,%.4f,%4f", ASN NODE, strDisplay, ptArrayat(0)x, ptArrayat(0)y ); nrOfLines++; } else { debugOutput(

" %dth element (%s) is invalid: pointArray-length: %d", i, cp, ptArray.length ); } // Az utak exportálása } else if( stricmp( cp, "LWPOLYLINE" ) == 0 ) { nrOfElements++; iUtType = GetUtvonalTipus( ent ); if( ptArray.length() > 1 ){ nrOfLines++; fprintf( fp, " %d,%s,%d", ASN TRACE, strDisplay, ((iUtType == DWG TRACE TWOWAY) ? ASN TRACE TWOWAY : ASN TRACE ONEWAY) ); 75. oldal if( iUtType != DWG TRACE ONEWAY RL ){ for( j=0; j<ptArray.length(); j++ ){ fprintf( fp, " %d,%.4f,%4f", ASN POINT, ptArrayat(j)x, ptArrayat(j)y ); nrOfLines++; } } else { for( j=ptArray.length()-1; j>=0; j-- ){ fprintf( fp, " %d,%.4f,%4f", ASN POINT, ptArrayat(j)x, ptArrayat(j)y ); nrOfLines++; } } } else { debugOutput( " %dth element (%s) is invalid: pointArray-length: %d", i, cp, ptArray.length ); } } } } } acedSSFree(sset); writtenBytes = ftell(fp); fclose(fp); endProgressIndicator(); // Statisztikai információk kiirása a képernyőre

sprintf( strDisplay, "Útvonal adatbázis exportálása megtörtént! A "%s" " "állomány elkészült: Elemek száma : %d darab Sorok száma : %d darab Hossza : byte", cbFileNameAndPath, nrOfElements, nrOfLines, writtenBytes ); acedAlert( strDisplay ); return; } /* * runModifyNode: * * ~~~~~~~~~~~~~~ * * WRMODIFYNODE parancs megvalosítása. A felhasználótól * * egy csomópont objektum kiválasztását kéri a rajzon majd* * az objektum nevével egy ablakot hoz fel. Az ablakban * * a város név található amit módosítani lehet. * * * */ void runModifyNode( void ) { bool bEntInsert; CString newValue; ads name entName; ads point selPoint; initDwg(); // Egy elem kiválasztásának kérése a felhasználótól while( true ){ if (acedEntSel(" Válasszon ki egy csomópontot: ", entName, selPoint) == RTNORM) { // Kapott adatok ellenörzése. (réteg, XData) bEntInsert = (strcmp( enttype( entName ), "INSERT" ) == 0); newValue =

GetApplicationData( entName ); if( !bEntInsert || ( newValue.GetLength() == 0 )){ acutPrintf(" A kiválasztott elem nem csomópont. Válasszon újra!"); continue; } // Ha jó elemet választott ki akkor a módosítás folytatása break; } else { // Különben a parancs Cancel-olása, vissza az Acad-hoz return; } } // A város nevének bekérése, ha CANCEL-lel zárta le az // ablakot akkor kilépés a funkcióból. WRUiGetString dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.m strTitle = "Város tulajdonságainak módosítása"; dlg.m strDescription = "Adja meg az város új nevét:"; dlg.m strDefaultValue = GetApplicationData( entName ); if( dlg.DoModal() != 1 ) return; SetApplicationData( entName, (char*)(LPCTSTR)dlg.m strReturnValue ); // A város INSERT ATTRIB-jának módosítása az új névre. AcDbObjectId blkId; AcDbBlockReference *pBlock; AcDbObjectIterator *pIterator; enameToObjId( entName, blkId ); acdbOpenObject( pBlock, blkId, AcDb::kForWrite

); 76. oldal %d pIterator = pBlock->attributeIterator(); // A blokk definició végig olvasása és ATTRIB-ok létrehozása for (pIterator->start(); !pIterator->done(); pIterator->step()) { AcDbEntity *pEnt; // Következö elem olvasása AcDbObjectId idEnt = pIterator->objectId(); acdbOpenObject( pEnt, idEnt, AcDb::kForWrite ); // Ha az elem attributum akkor az értékét lehet hogy be kell állítani az új értékre AcDbAttribute *pAtt = AcDbAttribute::cast(pEnt); if (pAtt != NULL && !pAtt->isConstant()) { // Ha az Attributum neve "VÁROS" akkor m=dostani kell. if( strcmp( pAtt->tag(), "VÁROS" ) == 0 ){ pAtt->setTextString( (LPCTSTR)dlg.m strReturnValue ); } } pEnt->close(); } delete pIterator; pBlock->close(); return; } /* * runModifyNode: * * ~~~~~~~~~~~~~~ * * WRMODIFYNODE parancs megvalosítása. A felhasználótól * * egy csomópont objektum kiválasztását kéri a rajzon majd* * az objektum nevével egy ablakot

hoz fel. Az ablakban * * a város név található amit módosítani lehet. * * * */ void runModifyTrace( void ) { struct resbuf *filter; bool bDiffName = false; bool bDiffType = false; CString strOldName; int iOldType; ads name sset; ads name ent; long i, iLast; int status; initDwg(); // Módosítandó útvonal elemek kiválasztása filter = acutBuildList( -4, "<AND", RTDXF0, "LWPOLYLINE", 8, "WR UT", -4, "AND>", 0 ); status = acedSSGet( NULL, NULL, NULL, filter, sset ); acutRelRb(filter); // Ha cancel-olta a felhasználó akkor kilépés if( status != RTNORM ) return; // Módosítanó elemek adatainak legyújtése a rajzról if(acedSSLength(sset, &iLast) == RTNORM){ if( iLast == 0 ){ acedAlert("Nem választott ki egyetlen útvonalat sem! A funkció nem hajtható végre."); acedSSFree(sset); return; } for( i=0; (i<iLast && ( !bDiffName || !bDiffType )); i++ ){ if( acedSSName(sset, i, ent) == RTNORM ){ if( i == 0 ){

strOldName = GetApplicationData( ent ); iOldType = GetUtvonalTipus( ent ); } else { bDiffName = bDiffName || (strcmp( strOldName, GetApplicationData( ent ) ) != 0); bDiffType = bDiffType || (iOldType != GetUtvonalTipus( ent )); } } } } // Az ablak megjelenítése a legyüjtött értékekkel WRUiModifyTraceDialog dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.m iDefaultType = ((bDiffType) ? 3 : iOldType); dlg.m strDefaultName = ((bDiffName) ? "" : strOldName); if( dlg.DoModal() != 1 ){ acedSSFree(sset); return; } // A szelekcióban levő útvonalak módosítása ott ahol szükséges if(acedSSLength(sset, &iLast) == RTNORM){ 77. oldal for( i=0; i<iLast; i++ ){ if( acedSSName(sset, i, ent) == RTNORM ){ if( dlg.m strNameGetLength() != 0 ) SetApplicationData( ent, (char*)(LPCTSTR)dlg.m strName ); if( dlg.m iType != 3 ) SetUtvonalTipus( ent, dlg.m iType ); } } } // A módosítások után a szelekciós szet felszabaditása acedSSFree(sset); } void runFindNode( void ) {

initDwg(); WRUiFindNodeDialog dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.DoModal(); } void runFindTrace( void ) { initDwg(); WRUiFindTraceDialog dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.DoModal(); } void runCheck1( void ) { initDwg(); WRUiCheck1Dialog dlg(CWnd::FromHandle(adsw acadMainWnd())); dlg.CheckTraceElements(); dlg.DoModal(); } void runCheck2( void ) { initDwg(); WRUiCheck2Dialog dlg(CWnd::FromHandle(adsw acadMainWnd())); int nReturnValue = dlg.DoModal(); } Database designer/arxsources/default.h #ifndef WAPROUTE DEFAULT H #define WAPROUTE DEFAULT H 1 #define kPi #define kHalfPi #define kTwoPi 3.14159265358979323846 (3.14159265358979323846 / 20) (3.14159265358979323846 * 2.0) #define radiansToDegrees(rads) (rads*(180.0/kPi)) #define degreesToRadians(degrees) (degrees*(kPi/180.0)) #define HEXL(b) ((((b)&0x0f)==0)?0:((((b)&0x0f)==1)?1:((((b)&0x0f)==2)? 2:((((b)&0x0f)==3)?3:((((b)&0x0f)==4)?4:((((b)&0x0f)==5

)?5:((((b)&0x0f)==6)?6:((((b)&0x0f)==7)?7:((((b)&0x0f) ==8)?8:((((b)&0x0f)==9)?9:((((b)&0x0f)==10)?A:((((b)&0 x0f)==11)?B:((((b)&0x0f)==12)?C:((((b)&0x0f)==13)?D:(( ((b)&0x0f)==14)?E:F))))))))))))))) #define HEXH(b) #define ASCIIC(b) #define ASCII(cp) HEXL((((b)&0xf0)>>4)) ((((b)>=0)&&((b)<=9))?((b)-0):(((b)>=A)&&((b)<=Z))?((b)A+10):(((b)>=a)&&((b)<=z))?((b)-a+10):0) ASCIIC(*cp)16+ASCIIC((cp+1)) #endif Database designer/arxsources/Error.h /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - Hibakezelés * * @@ @@@ @@ @@@@@@ @@@@@@ * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ #ifndef WAPROUTE ERROR H #define WAPROUTE ERROR H 1 /* 78. oldal * Include-k. * */ #include <acadstrc.h> /* * Define-k. * */ #ifdef DEBUG #define debugOutput acutPrintf #else #define

debugOutput TRACE #endif /* * Funkciók elöre deklarálása. * */ void rxErrorAlert( Acad::ErrorStatus es, char *cpSource, int iLineNr ); #endif Database designer/arxsources/Error.cpp /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ - Hibakezelés * * @@ @@@ @@ @@@@@@ @@@@@@ * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ /* * Include-k. * */ #include "StdAfx.h" #include "Default.h" #include "WapRoute.h" // Alkalmazas globalis valtozoi, define-ok /* * rxErrorAlert: * * ~~~~~~~~~~~~~ * * Egy általános hiba felderítö rutin, amely fatalis áll- * * talában nem elöforduló hibák megjelenítésére szolgál. * * Az ablak ahol megjelenik az üzenet rendszer modális. * * * */ void rxErrorAlert( Acad::ErrorStatus es, char *cpSource, int iLineNr ){ char errorStr[2048]; sprintf( errorStr, "Nem lekezelt hiba (%s) a WapRoute

alkalmazásban a következő helyen: %s:%d", acadErrorStatusText( es ), cpSource, iLineNr ); if( es != Acad::eOk ){ acedAlert( errorStr ); } } Database designer/arxsources/WapRoute.cpp /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ * * @@ @@@ @@ @@@@@@ @@@@@@ * * @@@ @@@ @@ @@ @@ * * @@ @@ @@ @@ @@ Dovák István * * Szakdolgozat 2000 * * * */ /* * Include-k. * */ 79. oldal #include "StdAfx.h" #include "Default.h" #define WAPROUTE MAIN FILE 1 #include "WapRoute.h" // Alkalmazas globalis valtozoi, define-ok #include "AcExtensionModule.h" #include #include #include #include "AcadStr.h" "Error.h" "AcadPlus.h" "Commands.h" // Hibakezelés // AutoCAD szolgáltatások bövítése // WapRoute parancsok megvalósítása /* * Globális változók, konstansok. * */ extern "C" HWND adsw acadMainWnd();

// AutoCAD föablak HWND-je AC IMPLEMENT EXTENSION MODULE(arxWapRoute); // Kiterjesztés definiálása /* * Funkciók elöre deklarálása. * */ void initApp( void ); void unloadApp( void ); /* * initApp: * * ~~~~~~~~ * * WapRoute ObjectARX alkalmazás inicializálása. Új paran-* * csok regisztrálása az "AutoCAD command stack"-jére. * * * */ #define REGISTER COMMAD( command, function, modal ) acedRegCmds->addCommand ("WAPROUTE","WAPROUTE "command,"WR"command,ACRX CMD ##modal,function) #define REGISTER COMMADRES( command, function, modal ) acedRegCmds->addCommand ("WAPROUTE","WAPROUTE "command,"WR"command,ACRX CMD ##modal,function,NULL,1,arxWapRoute.ModuleResourceInstance()) void initApp( void ) { // Normál parancsok regisztrálása (MDI ablak nélküliek) REGISTER COMMAD( "SHOWHIDE", runShowHide, TRANSPARENT ); REGISTER COMMAD( "IMPORT", runImport, MODAL ); REGISTER COMMAD(

"EXPORT", runExport, MODAL ); // MDI ablakos parancsok regisztrálása. (Saját eröforrások // használatához az aktuálisat el kell menteni és a sajátra // állítani a mutatót. Ezt automatikusan elvégzi az AutoCADes // CAcModuleResourceOverride osztály kon- és destruktora) CAcModuleResourceOverride resOverride; REGISTER COMMADRES( "CREATENODE", runCreateNode, MODAL ); REGISTER COMMADRES( "CREATETRACE", runCreateTrace, MODAL ); REGISTER COMMADRES( "MODIFYNODE", runModifyNode, MODAL ); REGISTER COMMADRES( "MODIFYTRACE", runModifyTrace, MODAL ); REGISTER COMMADRES( "FINDNODE", runFindNode, TRANSPARENT ); REGISTER COMMADRES( "FINDTRACE", runFindTrace, TRANSPARENT ); REGISTER COMMADRES( "CHECK1", runCheck1, MODAL ); REGISTER COMMADRES( "CHECK2", runCheck2, MODAL ); acutPrintf("WapRoute - Alkalmazás inicializálva. "); } #undef REGISTER COMMADRES #undef REGISTER COMMAD /* *

unloadApp: * * ~~~~~~~~~~ * * WapRoute ObjectARX alkalmazás parancsainak kivétele az * * AutoCADbe beregisztralt parancsok közül. A lefoglalt * * erőforrások felszabadítása. * * * */ void unloadApp( void ) { acedRegCmds->removeGroup("WAPROUTE"); acutPrintf("WapRoute - Alkalmazás törölve a memoriából. "); } /* * initApp: * * ~~~~~~~~ * * WapRoute ObjectARX alkalmazás inicializálása. Új paran-* * csok regisztrálása az "AutoCAD command stack"-jére. * * * */ 80. oldal void saveApp( void ) { CString str = "kSaveMsg Message is sent."; acedAlert( str ); } /* * DllMain: * * ~~~~~~~~ * * Windows belépési pont. A DLL-eket a rendszer ezen a * * ponton keresztül inicializálja a rendszer ha van ilyen * * függvény. Itt kell az alkalmazás könyvtárait erőforrá- * * sokat inicializálni illetve felszabadítani. * * * */ extern "C" int APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {

UNREFERENCED PARAMETER(lpReserved); if (dwReason == DLL PROCESS ATTACH) { arxWapRoute.AttachInstance(hInstance); hWapRouteInstance = hInstance; } else if (dwReason == DLL PROCESS DETACH) { arxWapRoute.DetachInstance(); } return 1; // Minden OK } /* * acrxEntryPoint: * * ~~~~~~~~~~~~~~~ * * AutoCAD belépési pont. Az AutoCAD ezen a fuggvenyen ke-* * resztül kommunikál az ObjectARX alkalmazással. Az al- * * kalmazást itt inicializáljuk, a parancsokat beregiszt- * * ráljuk és a végén felszabadítjuk a lefoglalt erőfor* * rásokat. * * * */ extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* appId) { /* Globális MESSAGE-loop. Az alkalmazás bejegyzi a hozzá tar- * * tozó parancsokat, és a kész inicializálást egy szöveggel * * jelzi a parancs sorban. */ switch (msg) { /* Applikació inicializálása, erőforrások lefoglalása / case AcRx::kInitAppMsg: acrxDynamicLinker->unlockApplication(appId);

acrxDynamicLinker->registerAppMDIAware(appId); initApp(); break; /* Applikáció által lefoglalt erőforrások felszabadítása / case AcRx::kUnloadAppMsg: unloadApp(); break; /* Aktuális rajzot a felhasználó el akarja menteni / case AcRx::kSaveMsg: saveApp(); break; } return AcRx::kRetOK; } Database designer/arxsources/WapRoute.def LIBRARY WapRoute DESCRIPTION WapRoute útvonal adatbázis készítő alkalmazás ; Dovák István 2000 Szakdolgozat EXPORTS acrxEntryPoint acrxGetApiVersion PRIVATE PRIVATE Database designer/arxsources/WapRoute.h /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázis készítő * * @@ @@@@ @@ @@@ @@ @@ ObjectARX alkalmazás. * * @@ @@ @@ @@ @@ @@ @@ * * @@ @@@ @@ @@@@@@ @@@@@@ Dovák István * * @@@ @@@ @@ @@ @@ Szakdolgozat 2000 * * @@ @@ @@ @@ @@ * * * */ 81. oldal /* * Define-k. * */ #define ACAD APPNAME "WapROUTE-Szakdolgozat-2000" #define #define #define #define ASN CONFIG ASN NODE ASN TRACE ASN POINT 0 1 2 3 #define ASN TRACE

ONEWAY 1 #define ASN TRACE TWOWAY 0 #define DWG TRACE TWOWAY 0 #define DWG TRACE ONEWAY LR 1 #define DWG TRACE ONEWAY RL 2 /* * Tupusdefiniciók. * */ // // // // A GIS lekérdezéseknél általában az objektumoknak csak speciális tulajdonságár vagyunk kiváncsiak pl: az útvonalnál csak a kezdő és végpont érdekel, de a közbölsö sarokpontok nem. Ez tulajdonképpen a rajz egy speciális indexeléseként fogható fel #define WAPNAME LEN 8 // Útvonal index typedef struct { ads name ent; // Útvonal entitás azonosítója ads point pt1; // Kezdöpont ads point pt2; // Végpont int dir; // Irányítottság DWG ??? char name[8]; // Útvonal WapRoute szöveges azonosítója } t traceDef; // Csomópont index typedef struct { ads name ent; ads point pt; } t nodeDef; // Csomópont entitás azonosítója // Beszúrási pont /* * Globális konstans változók. * */ #ifdef WAPROUTE MAIN FILE char *local appname = ACAD APPNAME; HINSTANCE hWapRouteInstance = NULL; #else extern

char *local appname; extern HINSTANCE hWapRouteInstance; #endif Database designer/arxsources/WRUiCheck1Dialog.h #if !defined(AFX WRUiCheck1Dialog H 31987283 BD60 11D4 908D 0020AF3672E3 INCLUDED ) #define AFX WRUiCheck1Dialog H 31987283 BD60 11D4 908D 0020AF3672E3 INCLUDED #include #include #include #include #include #include "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiCheck1Dialog : public CAcUiDialog { public: WRUiCheck1Dialog(CWnd* pParent = NULL); ~WRUiCheck1Dialog(); void LoadNewSegments( void ); void ColorizeObjects( int newColor ); void RefreshSelection( void ); int CheckTraceElements( void ); //{{AFX DATA(WRUiCheck1Dialog) enum { IDD = IDD CHECK1 }; CStatic m staText2; 82. oldal // standard constructor CComboBox m cmbTrace; CListCtrl m cmbTraceSegs; //}}AFX DATA //{{AFX VIRTUAL(WRUiCheck1Dialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL protected: long t

traceDef int AcDbObjectIdArray CImageList bool // DDX/DDV support m lNrOfTraceEnts; *m pTraceEnts; m iOldCmdEcho; m aColoredObjects; m oImageList; m bPrevZoomAvailable; //{{AFX MSG(WRUiCheck1Dialog) afx msg void OnDestroy(); virtual BOOL OnInitDialog(); virtual void OnOK(); virtual void OnCancel(); afx msg void OnSelchangeFtTrace(); afx msg void OnClickFtList(NMHDR* pNMHDR, LRESULT pResult); afx msg void OnKeydownFtList(NMHDR* pNMHDR, LRESULT pResult); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiCheck1Dialog.cpp #include #include #include #include "stdafx.h" "waproute.h" "AcadPlus.h" "WRUiCheck1Dialog.h" WRUiCheck1Dialog::WRUiCheck1Dialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiCheck1Dialog::IDD, pParent){ //{{AFX DATA INIT(WRUiCheck1Dialog) //}}AFX DATA INIT m lNrOfTraceEnts = 0; m pTraceEnts = NULL; m bPrevZoomAvailable = false; } int WRUiCheck1Dialog::CheckTraceElements( void ){

struct resbuf *filter; ads name sset, ent; long j,i,iLast; CString strName; ads point pt1, pt2; // A útvonalak tömbjének feltöltése filter = acutBuildList( -4, "<AND", RTDXF0, "LWPOLYLINE", 8, "WR UT", -4, "AND>", 0 ); acedSSGet( T("X"), NULL, NULL, filter, sset ); acutRelRb(filter); if(acedSSLength(sset, &iLast) == RTNORM){ if( iLast != 0 ){ if( (m pTraceEnts = (t traceDef *)malloc( (iLast+1)(sizeof(t traceDef)) )) != NULL ){ for( i=0; i<iLast; i++ ){ if( acedSSName(sset, i, ent) == RTNORM ){ AcGePoint3dArray ptArray; entpoints( ent, ptArray ); strName = GetApplicationData( ent ); int dir = GetUtvonalTipus( ent ); if((strName != "???") && (strName.GetLength() != 0) && (ptArraylength() >= 2)){ t traceDef *nextStore = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); acdbNameSet( ent, (*nextStore).ent ); pt1[X] = ptArray.at(0)x; pt1[Y] = ptArray.at(0)y; pt1[Z] = ptArray.at(0)z;

pt2[X] = ptArray.at(ptArraylength()-1)x; pt2[Y] = ptArray.at(ptArraylength()-1)y; pt2[Z] = ptArray.at(ptArraylength()-1)z; acdbPointSet( pt1, (*nextStore).pt1 ); acdbPointSet( pt2, (*nextStore).pt2 ); (*nextStore).dir = dir; strncpy( (*nextStore).name, (LPCTSTR)strName, WAPNAME LEN ); 83. oldal (*nextStore).name[WAPNAME LEN-1] = 0x0; m lNrOfTraceEnts++; } } } } } } acedSSFree(sset); // A tömb rendezése név szerint, (buborék rendezés) t traceDef sav; for( i=0; i<m lNrOfTraceEnts;i++ ){ for( j=i+1; j<m lNrOfTraceEnts; j++ ){ t traceDef *trI = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); t traceDef *trJ = (t traceDef )(((char )m pTraceEnts)+jsizeof(t traceDef)); if( strcmp((*trI).name,(*trJ).name) > 0 ){ memcpy( &sav, trI, sizeof(t traceDef) ); memcpy( trI, trJ, sizeof(t traceDef) ); memcpy( trJ, &sav, sizeof(t traceDef) ); } } } // A rendezésen kell végigmenni úgy hogy néha kidobok // belőle elemeket néha nem. Kidobás=ent-ek NULLra ál//

lításával Majd a végén a tömböt Packolom int nextIter; for( nextIter=i=0; i<m lNrOfTraceEnts; ){ // nextIter-rel megkeresem az azonos nevüek utánni első elemet. nextIter = i+1; t traceDef *trI = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); t traceDef *trJ = (t traceDef )(((char )m pTraceEnts)+nextItersizeof(t traceDef)); while( ( nextIter<m lNrOfTraceEnts ) && (strcmp((*trI).name,(*trJ).name) == 0 ) ){ trJ = (t traceDef *)(((char )m pTraceEnts)+(nextIter+1)sizeof(t traceDef)); nextIter++; } ////////////////////////////////////////////////// // A sorozat összefüggöségének eldöntése. START // ////////////////////////////////////////////////// bool bOsszefuggo = true; // Az elemeket összefüggö részhalmazokba rendezem, // a tömb eleje mindig egy összefüggö gráfot fog // tartalmazni, vagy ha a belsö ciklus a tömb végére // ér akkor nem összefüggö az adott nevű út. j számolja // az aktuális összefüggö gráf tömmbeli

hosszát. for( j=1; (bOsszefuggo && (i+j<nextIter)); j++ ){ int cik = 0, cak = 0; bool bFoundEqual = false; t traceDef *trCik = NULL; t traceDef *trCak = NULL; for( cik=i; ((cik<i+j) && !bFoundEqual); cik++ ){ for( cak=i+j; ((cak<nextIter) && !bFoundEqual); cak++ ){ trCik = (t traceDef *)(((char )m pTraceEnts)+ciksizeof(t traceDef)); trCak = (t traceDef *)(((char )m pTraceEnts)+caksizeof(t traceDef)); bFoundEqual =(( acdbPointEqual( (*trCik).pt1, (*trCak).pt1 ) ) ||( acdbPointEqual( (*trCik).pt1, (*trCak).pt2 ) ) ||( acdbPointEqual( (*trCik).pt2, (*trCak).pt1 ) ) ||( acdbPointEqual( (*trCik).pt2, (*trCak).pt2 ) )); } } // Ha talált két egyezöt akkor a továbbiakban nem // vagyok kivancsi semmire csak másolok, különben // pedig a gráf nem összefüggö. if( bFoundEqual && trCak ){ if( i+j<nextIter ){ t traceDef *trNewCik = (t traceDef )(((char )m pTraceEnts)+(i+j)sizeof(t traceDef)); memcpy( &sav, trNewCik, sizeof(t traceDef) );

memcpy( trNewCik, trCak, sizeof(t traceDef) ); memcpy( trCak, &sav, sizeof(t traceDef) ); } } else { bOsszefuggo = false; } } ////////////////////////////////////////////////// // A sorozat összefüggöségének eldöntése. END // ////////////////////////////////////////////////// // A végén elemek torlése ha bOsszefuggo if( bOsszefuggo ) 84. oldal memset( trI, 0x0, (nextIter-i)*sizeof(t traceDef)); // A ciklus invariáns növelése a következö vonalcsoport vizsgálatához. i = nextIter; } // A tömb packolása, i-ig már packolva van utánna levő részt kell mozgatni. for( i=0; i<m lNrOfTraceEnts;i++ ){ t traceDef *trI = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); if( acdbNameNil((*trI).ent) ){ t traceDef *trIPL = (t traceDef )(((char )m pTraceEnts)+(i+1)sizeof(t traceDef)); if(m lNrOfTraceEnts-i-1 != 0) memmove( trI, trIPL, (m lNrOfTraceEnts-i-1)*sizeof(t traceDef) ); m lNrOfTraceEnts--; i--; } } return 0; } WRUiCheck1Dialog::~WRUiCheck1Dialog(){

if(m pTraceEnts != NULL) free(m pTraceEnts); } void WRUiCheck1Dialog::DoDataExchange(CDataExchange* pDX) { CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiCheck1Dialog) DDX Control(pDX, IDC C1 TX2, m staText2); DDX Control(pDX, IDC C1 TRACE, m cmbTrace); DDX Control(pDX, IDC C1 LIST, m cmbTraceSegs); //}}AFX DATA MAP } BEGIN MESSAGE MAP(WRUiCheck1Dialog, CAcUiDialog) //{{AFX MSG MAP(WRUiCheck1Dialog) ON WM DESTROY() ON CBN SELCHANGE(IDC C1 TRACE, OnSelchangeFtTrace) ON NOTIFY(NM CLICK, IDC C1 LIST, OnClickFtList) ON NOTIFY(LVN KEYDOWN, IDC C1 LIST, OnKeydownFtList) //}}AFX MSG MAP END MESSAGE MAP() void WRUiCheck1Dialog::OnDestroy(){ // A kiszinezett elemek normális szinüvé tétele ColorizeObjects( 256 ); // A CMDECHO változó visszaállítása struct resbuf rb; rb.restype = RTSHORT; rb.resvalrint = m iOldCmdEcho; acedSetVar( "CMDECHO", &rb ); CAcUiDialog::OnDestroy(); } BOOL WRUiCheck1Dialog::OnInitDialog(){ // Az ablak nevének beállítása, hogy a

registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiCheck1Dialog"); CAcUiDialog::OnInitDialog(); // Az ablak átméretezésének beállítása DLGCTLINFO dlgSizeInfo[]= { { IDOK, MOVEX, 50 }, { IDCANCEL, MOVEX, 50 }, { IDOK, MOVEY, 100 }, { IDCANCEL, MOVEY, 100 }, { IDC C1 TRACE, ELASTICX, 100 }, { IDC C1 LIST, ELASTICXY, 100 }, }; const DWORD numberofentries = sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries); // A combo boxban megjelenö értékek feltöltése int i, ind; CString strName; if( m lNrOfTraceEnts == 0 ){ ind = m cmbTrace.AddString( "Nincsennek nem összefüggő utak a rajzon" ); m cmbTrace.SetItemDataPtr( ind, NULL ); } else { ind = m cmbTrace.AddString( "*Kezdetkor aktuális nézet" ); m cmbTrace.SetItemDataPtr( ind, NULL ); CString strData = " "; 85. oldal for( i=0; i<m lNrOfTraceEnts; i++ ){ t traceDef *pNextEnt = (t traceDef )(((char )m pTraceEnts)+isizeof(t

traceDef)); CString strName = GetApplicationData( (*pNextEnt).ent ); if(( strName != "???" ) && (strName.GetLength() != 0)){ if(strData.Find(" "+strName+" ") == -1){ strData += strName+" 1 "; } else { CString strOldValue = strData.Mid( strDataFind(" "+strName+" ")+1 ); strOldValue = strOldValue.Left( strOldValueFind(" ") ); int newValue = atoi( strOldValue.Mid(strOldValueFind(" ")+1) ); CString strNewValue; strNewValue.Format( " %s %d ", strName, newValue+1 ); strData.Replace( " "+strOldValue+" ", strNewValue ); } } } CString strValues = " "; for( i=0; i<m lNrOfTraceEnts; i++ ){ t traceDef *pNextEnt = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); CString strName = GetApplicationData( (*pNextEnt).ent ); if(( strName != "???" ) && (strName.GetLength() != 0) && (strValuesFind(" "+strName+" ") == -1)){

if(strData.Find(" "+strName+" ") != -1){ strValues += strName+" "; CString strComboValue; strComboValue = strData.Mid( strDataFind(" "+strName+" ")+1 ); strComboValue = strComboValue.Left( strComboValueFind(" ") ); int newValue = atoi( strComboValue.Mid(strComboValueFind(" ")+1) ); CString strCmbValue; strCmbValue.Format( "%s - (%ddb)", strName, newValue ); ind = m cmbTrace.AddString( strCmbValue ); m cmbTrace.SetItemDataPtr( ind, pNextEnt ); } } } } // A megjelenítendő képek feltöltése egy listába m oImageList.Create(32, 32, TRUE, 4, 4); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE TWOWAY) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY LR) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY RL) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE TWOWAY SELECTED) )); m

oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY LR SELECTED) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY RL SELECTED) )); m cmbTraceSegs.SetImageList(&m oImageList, LVSIL NORMAL); // A kezdeti értékek beállítása m cmbTrace.SetFocus(); m cmbTrace.SetCurSel( 0 ); LoadNewSegments(); // A CMDECHO változó mentése struct resbuf rb; acedGetVar( "CMDECHO", &rb ); m iOldCmdEcho = rb.resvalrint; rb.resvalrint = 0; acedSetVar( "CMDECHO", &rb ); return FALSE; } // Az objektum id tömbben levö elemeket a megadtott // színüre változtatja 256-bylayer. void WRUiCheck1Dialog::ColorizeObjects( int newColor ){ AcCmColor cm; cm.setColorIndex( newColor ); while( !m aColoredObjects.isEmpty() ){ changeObjectsColor( m aColoredObjects.at(0), cm ); m aColoredObjects.removeSubArray( 0, 0 ); } } void WRUiCheck1Dialog::LoadNewSegments( void ){ t traceDef *pEnt = (t traceDef)m cmbTrace.GetItemDataPtr( m

cmbTraceGetCurSel() ); if( !pEnt ){ m cmbTraceSegs.EnableWindow( false ); m staText2.EnableWindow( false ); m cmbTraceSegs.DeleteAllItems(); ColorizeObjects( 256 ); } else { m cmbTraceSegs.EnableWindow( true ); m staText2.EnableWindow( true ); m cmbTraceSegs.DeleteAllItems(); ColorizeObjects( 256 ); 86. oldal int i; CString strName = GetApplicationData( (*pEnt).ent ); for( i=0; i<m lNrOfTraceEnts; i++ ){ t traceDef *pNextEnt = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); CString strSegName = GetApplicationData( (*pNextEnt).ent ); if( strName == strSegName ){ LV ITEM lvItem; ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF TEXT | LVIF STATE | LVIF IMAGE; lvItem.state = LVIS SELECTED; lvItem.iItem = 0; lvItem.iImage = (*pNextEnt).dir; lvItem.pszText = (char*)(LPCTSTR)strSegName; int ind = m cmbTraceSegs.InsertItem(&lvItem); m cmbTraceSegs.SetItemData( ind, (LPARAM)(void *)pNextEnt ); } } } } void WRUiCheck1Dialog::RefreshSelection( void ){ int i;

AcDbObjectIdArray idArray; AcGePoint3dArray ptArray; ads point minPt, maxPt; for( i=0; i<m cmbTraceSegs.GetItemCount(); i++ ){ t traceDef *pEnt = (t traceDef)(void)m cmbTraceSegs.GetItemData(i); int state = m cmbTraceSegs.GetItemState(i, LVIS SELECTED); if( pEnt ){ // Az utvonal tipus lekerdezése es ebbol ikon megallapitasa LV ITEM lvItem; ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF IMAGE; lvItem.iItem = i; lvItem.iImage = (*pEnt).dir; if( state == LVIS SELECTED ){ // Az aktuális elem Id-jének mentése AcDbObjectId entId; enameToObjId( (*pEnt).ent, entId ); idArray.append( entId ); // A zoomoláshoz a koordináták lekérdezése entpoints( (*pEnt).ent, ptArray ); lvItem.iImage += 3; } m cmbTraceSegs.SetItem( &lvItem ); } } ColorizeObjects( 256 ); m aColoredObjects = idArray; ColorizeObjects( 1 ); m aColoredObjects = idArray; // Ha volt elözö zoom pozició akkor azt vissza kell csinálni if( m bPrevZoomAvailable ){ acedCommand( RTSTR, " ZOOM",

RTSTR, "P", 0 ); m bPrevZoomAvailable = false; } // Új zoom pozició kiszámolása if( ptArray.length()>=2 ){ minPt[X] = ptArray.at(0)x; minPt[Y] = ptArray.at(0)y; maxPt[X] = ptArray.at(0)x; maxPt[Y] = ptArray.at(0)y; for( i=1; i<ptArray.length(); i++ ){ minPt[X] = min( ptArray.at(i)x, minPt[X] ); minPt[Y] = min( ptArray.at(i)y, minPt[Y] ); maxPt[X] = max( ptArray.at(i)x, maxPt[X] ); maxPt[Y] = max( ptArray.at(i)y, maxPt[Y] ); } minPt[X] -= 100; minPt[Y] -= 100; maxPt[X] += 100; maxPt[Y] += 100; acedCommand( RTSTR, " ZOOM", RTSTR, " W", RTPOINT, minPt, RTPOINT, maxPt, 0 ); m bPrevZoomAvailable = true; } } void WRUiCheck1Dialog::OnOK(){ StorePixelData(); CAcUiDialog::OnOK(); } void WRUiCheck1Dialog::OnCancel(){ // Ha volt elözö zoom pozició akkor azt vissza kell csinálni if( m bPrevZoomAvailable ){ 87. oldal acedCommand( RTSTR, " ZOOM", RTSTR, "P", 0 ); m bPrevZoomAvailable = false; } CAcUiDialog::OnCancel(); } void

WRUiCheck1Dialog::OnSelchangeFtTrace(){ LoadNewSegments(); RefreshSelection(); } void WRUiCheck1Dialog::OnClickFtList(NMHDR* pNMHDR, LRESULT pResult){ RefreshSelection(); *pResult = 0; } // Néhány billentyü kombináció ami biztosan nem változtatja meg // ListCtrl értékét ezért nem is kell ilyenkor újraszámolni // a zoomolási koordinátákat, és kiszinezést. void WRUiCheck1Dialog::OnKeydownFtList(NMHDR* pNMHDR, LRESULT pResult) { LV KEYDOWN* pLVKeyDow = (LV KEYDOWN)pNMHDR; if( (pLVKeyDow->wVKey == VK CONTROL) || (pLVKeyDow->wVKey == VK SHIFT) || (pLVKeyDow->wVKey == VK MENU) || (pLVKeyDow->wVKey == VK CAPITAL) || (pLVKeyDow->wVKey == VK PAUSE) ){ } else { RefreshSelection(); } *pResult = 0; } Database designer/arxsources/WRUiCheck2Dialog.h #if !defined(AFX WRUiCheck2Dialog H DEC77186 BAE6 11D4 A058 0000C076DBD5 INCLUDED ) #define AFX WRUiCheck2Dialog H DEC77186 BAE6 11D4 A058 0000C076DBD5 INCLUDED #include #include #include #include #include #include

"resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiCheck2Dialog : public CAcUiDialog { public: WRUiCheck2Dialog(CWnd* pParent = NULL); ~WRUiCheck2Dialog(); // // // standard constructor CString getNodeNameFromMap( void ); void changeObjectsName( AcDbObjectIdArray &arrayOfNodes, CString newName ); CString CString CString m strStartNode; m strAcrossNode; m strEndNode; CString CString CString m strNode1Name; m strTraceName; m strNode2Name; //{{AFX DATA(WRUiCheck2Dialog) enum { IDD = IDD CHECK2 }; CButton m staGroup2; CStatic m staTextNode1; CStatic m staTextNode2; CStatic m staTextTrace; CStatic m staFoundPathNr; CButton m btnFromMap1; CButton m btnFromMap2; CButton m btnFromMap3; CButton m btnCheckSortcut; CButton m btnShowOnMap; CButton m btnPathFinder; CListBox m lstPathDetails; CEdit m edtTrace; CEdit m edtNode2; CEdit m edtNode1; CComboBox m cmbNodeStart; CComboBox m cmbNodeEnd; CComboBox m cmbNodeAcross;

CComboBox m cmbFoundPaths; //}}AFX DATA 88. oldal //{{AFX VIRTUAL(WRUiCheck2Dialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL protected: int int int t nodeDef t traceDef long long // DDX/DDV support m iLastCalculatedStart; m iLastCalculatedEnd; m iLastCalculatedAcross; *m pNodeEnts; *m pTraceEnts; m lNrOfNodeEnts; m lNrOfTraceEnts; int GetIndexFromEname( CComboBox *cmb, ads name entName ); bool GetNodeFromMap( CString &newValue, ads name &entName ); void DisableUnavailableControls( void ); //{{AFX MSG(WRUiCheck2Dialog) virtual BOOL OnInitDialog(); afx msg void OnButtonFromMap1(); afx msg void OnButtonFromMap2(); afx msg void OnButtonFromMap3(); afx msg void OnCheckSortcut(); afx msg void OnKillfocusComboFoundPaths(); afx msg void OnKillfocusEditNode1(); afx msg void OnKillfocusEditNode2(); afx msg void OnKillfocusEditTrace(); afx msg void OnSelchangeFoundPath(); afx msg void OnPathFinder(); afx msg void OnShowOnMap(); afx msg void

OnBezar(); afx msg void OnSelchangeComboNodeAcross(); afx msg void OnSelchangeComboNodeEnd(); afx msg void OnSelchangeComboNodeStart(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiCheck2Dialog.cpp #include #include #include #include #include "stdafx.h" "waproute.h" "AcadPlus.h" "Error.h" "WRUiCheck2Dialog.h" /* * Konstruktor, MESSAGE MAP * */ WRUiCheck2Dialog::WRUiCheck2Dialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiCheck2Dialog::IDD, pParent) { //{{AFX DATA INIT(WRUiCheck2Dialog) //}}AFX DATA INIT m iLastCalculatedStart = -1; m iLastCalculatedEnd = -1; m iLastCalculatedAcross = -1; m pNodeEnts = NULL; m lNrOfNodeEnts = 0; m pTraceEnts = NULL; m lNrOfTraceEnts = 0; // A csomópontok tömbjének feltöltése struct resbuf *filter; ads name sset; ads name ent; long i, iLast; CString strName; filter = acutBuildList( -4, "<AND", RTDXF0, "INSERT", 8,

"WR VAROS", -4, "AND>", 0 ); acedSSGet( T("X"), NULL, NULL, filter, sset ); acutRelRb(filter); if(acedSSLength(sset, &iLast) == RTNORM){ if( iLast != 0 ){ if( (m pNodeEnts = (t nodeDef *)malloc( iLast(sizeof(t nodeDef)+7) )) != NULL ){ for( i=0; i<iLast; i++ ){ if( acedSSName(sset, i, ent) == RTNORM ){ 89. oldal strName = GetApplicationData( ent ); if(( strName != "???" ) && (strName.GetLength() != 0)){ AcGePoint3dArray ptArray; entpoints( ent, ptArray ); t nodeDef *nextStore = (t nodeDef )(((char )m pNodeEnts)+isizeof(t nodeDef)); nextStore->pt[X] = ptArray.at(0)x; nextStore->pt[Y] = ptArray.at(0)y; nextStore->pt[Z] = ptArray.at(0)z; acdbNameSet( ent, nextStore->ent ); m lNrOfNodeEnts++; } } } } } } acedSSFree(sset); // A útvonalak tömbjének feltöltése filter = acutBuildList( -4, "<AND", RTDXF0, "LWPOLYLINE", 8, "WR UT", -4, "AND>", 0 ); acedSSGet(

T("X"), NULL, NULL, filter, sset ); acutRelRb(filter); if(acedSSLength(sset, &iLast) == RTNORM){ if( iLast != 0 ){ if( (m pTraceEnts = (t traceDef *)malloc( iLast(sizeof(t traceDef)+7) )) != NULL ){ for( i=0; i<iLast; i++ ){ if( acedSSName(sset, i, ent) == RTNORM ){ strName = GetApplicationData( ent ); if(( strName != "???" ) && (strName.GetLength() != 0)){ AcGePoint3dArray ptArray; entpoints( ent, ptArray ); t traceDef *nextStore = (t traceDef )(((char )m pTraceEnts)+isizeof(t traceDef)); nextStore->pt1[X] = ptArray.at(0)x; nextStore->pt1[Y] = ptArray.at(0)y; nextStore->pt1[Z] = ptArray.at(0)z; nextStore->pt2[X] = ptArray.at(ptArraylength()-1)x; nextStore->pt2[Y] = ptArray.at(ptArraylength()-1)y; nextStore->pt2[Z] = ptArray.at(ptArraylength()-1)z; acdbNameSet( ent, nextStore->ent ); m lNrOfTraceEnts++; } } } } } } acedSSFree(sset); } WRUiCheck2Dialog::~WRUiCheck2Dialog(){ if(m pNodeEnts != NULL) free(m pNodeEnts); if(m pTraceEnts

!= NULL) free(m pTraceEnts); } void WRUiCheck2Dialog::DoDataExchange(CDataExchange* pDX){ CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiCheck2Dialog) DDX Control(pDX, IDC STATIC GRP2, m staGroup2); DDX Control(pDX, IDC STATIC ND1, m staTextNode1); DDX Control(pDX, IDC STATIC ND2, m staTextNode2); DDX Control(pDX, IDC STATIC TR, m staTextTrace); DDX Control(pDX, IDC STATIC TXT4, m staFoundPathNr); DDX Control(pDX, IDC BUTTON FROM MAP1, m btnFromMap1); DDX Control(pDX, IDC BUTTON FROM MAP2, m btnFromMap2); DDX Control(pDX, IDC BUTTON FROM MAP3, m btnFromMap3); DDX Control(pDX, IDC CHECK SORTCUT, m btnCheckSortcut); DDX Control(pDX, IDC SHOW ON MAP, m btnShowOnMap); DDX Control(pDX, IDC PATH FINDER, m btnPathFinder); DDX Control(pDX, IDC FOUND PATH, m lstPathDetails); DDX Control(pDX, IDC EDIT TRACE, m edtTrace); DDX Control(pDX, IDC EDIT NODE2, m edtNode2); DDX Control(pDX, IDC EDIT NODE1, m edtNode1); DDX Control(pDX, IDC COMBO NODE START, m cmbNodeStart); DDX Control(pDX, IDC

COMBO NODE END, m cmbNodeEnd); DDX Control(pDX, IDC COMBO NODE ACROSS, m cmbNodeAcross); DDX Control(pDX, IDC COMBO FOUND PATHS, m cmbFoundPaths); //}}AFX DATA MAP } BEGIN MESSAGE MAP(WRUiCheck2Dialog, CAcUiDialog) //{{AFX MSG MAP(WRUiCheck2Dialog) ON BN CLICKED(IDC BUTTON FROM MAP1, OnButtonFromMap1) ON BN CLICKED(IDC BUTTON FROM MAP2, OnButtonFromMap2) 90. oldal ON BN CLICKED(IDC BUTTON FROM MAP3, OnButtonFromMap3) ON BN CLICKED(IDC CHECK SORTCUT, OnCheckSortcut) ON CBN KILLFOCUS(IDC COMBO FOUND PATHS, OnKillfocusComboFoundPaths) ON EN KILLFOCUS(IDC EDIT NODE1, OnKillfocusEditNode1) ON EN KILLFOCUS(IDC EDIT NODE2, OnKillfocusEditNode2) ON EN KILLFOCUS(IDC EDIT TRACE, OnKillfocusEditTrace) ON LBN SELCHANGE(IDC FOUND PATH, OnSelchangeFoundPath) ON BN CLICKED(IDC PATH FINDER, OnPathFinder) ON BN CLICKED(IDC SHOW ON MAP, OnShowOnMap) ON BN CLICKED(IDCANCEL, OnBezar) ON WM SIZE() ON WM GETMINMAXINFO() ON CBN SELCHANGE(IDC COMBO NODE ACROSS, OnSelchangeComboNodeAcross) ON CBN

SELCHANGE(IDC COMBO NODE END, OnSelchangeComboNodeEnd) ON CBN SELCHANGE(IDC COMBO NODE START, OnSelchangeComboNodeStart) //}}AFX MSG MAP END MESSAGE MAP() /* * Privát funkciók * */ bool WRUiCheck2Dialog::GetNodeFromMap( CString &newValue, ads name &entName ){ ads point selPoint; bool bEntInsert; // Az ablak elrejtése és a vezélés átadása az AcadEditor-nak BeginEditorCommand(); // Felhasználó csak irányítottan tud kiélpni az input ciklusból while( true ){ // Elem kiválasztásának kérése a felhasználótól if (acedEntSel(" Válasszon ki egy csomópontot: ", entName, selPoint) == RTNORM) { // Kapott adatok ellenörzése. (réteg, XData) bEntInsert = (strcmp( enttype( entName ), "INSERT" ) == 0); newValue = GetApplicationData( entName ); if( !bEntInsert || ( newValue.GetLength() == 0 )){ acutPrintf(" A kiválasztott elem nem csomópont. Válasszon újra!"); continue; } // Ha jó elemet választott ki a felhaszontalan // akkor

visszatérés az Acad-hoz CompleteEditorCommand(); return true; } else { // Különben az AcadEditor Cancel-olása, ablak visszahozása CompleteEditorCommand(); return false; } } } int WRUiCheck2Dialog::GetIndexFromEname( CComboBox *cmb, ads name entName ){ int i; t nodeDef *pEnt; for( i=0; i<cmb->GetCount(); i++ ){ pEnt = (t nodeDef*)cmb->GetItemDataPtr(i); if(( pEnt != NULL ) && (entName[0] == (*pEnt).ent[0]) && (entName[1] == (*pEnt).ent[1]) ){ return i; } } return -1; } void WRUiCheck2Dialog::DisableUnavailableControls( void ){ if(( m iLastCalculatedStart != m cmbNodeStart.GetCurSel() ) || ( m iLastCalculatedEnd != m cmbNodeEnd.GetCurSel() ) || ( m iLastCalculatedAcross != m cmbNodeAcross.GetCurSel() )){ m btnCheckSortcut.EnableWindow( false ); m btnShowOnMap.EnableWindow( false ); m lstPathDetails.EnableWindow( false ); m edtTrace.EnableWindow( false ); m edtNode2.EnableWindow( false ); m edtNode1.EnableWindow( false ); m cmbFoundPaths.EnableWindow( false

); m staGroup2.EnableWindow( false ); m staTextNode1.EnableWindow( false ); m staTextNode2.EnableWindow( false ); m staTextTrace.EnableWindow( false ); m staFoundPathNr.EnableWindow( false ); } else { m btnCheckSortcut.EnableWindow( true ); m btnShowOnMap.EnableWindow( true ); 91. oldal m lstPathDetails.EnableWindow( true ); m edtTrace.EnableWindow( true ); m edtNode2.EnableWindow( true ); m edtNode1.EnableWindow( true ); m cmbFoundPaths.EnableWindow( true ); m staGroup2.EnableWindow( true ); m staTextNode1.EnableWindow( true ); m staTextNode2.EnableWindow( true ); m staTextTrace.EnableWindow( true ); m staFoundPathNr.EnableWindow( true ); } t nodeDef *pStart = (t nodeDef )m cmbNodeStart.GetItemDataPtr(m cmbNodeStartGetCurSel()); t nodeDef *pEnd = (t nodeDef )m cmbNodeEnd.GetItemDataPtr(m cmbNodeEndGetCurSel()); t nodeDef *pAcross = (t nodeDef )m cmbNodeAcross.GetItemDataPtr(m cmbNodeAcrossGetCurSel()); if( !pStart || !pEnd || ( acdbNameEqual((*pStart).ent, (*pEnd).ent ) ) ){ m

btnPathFinder.EnableWindow( false ); } else { m btnPathFinder.EnableWindow( true ); } if( !pStart || !pEnd || !pAcross || (acdbNameEqual((*pStart).ent,(*pAcross).ent )) || (acdbNameEqual((*pEnd).ent,(*pAcross).ent )) ){ m cmbNodeAcross.SetCurSel( 0 ); } return; } /* * Üzenet kezelö funkciók * */ BOOL WRUiCheck2Dialog::OnInitDialog(){ // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiCheck2Dialog"); CAcUiDialog::OnInitDialog(); DLGCTLINFO dlgSizeInfo[]= { { IDC PATH FINDER, MOVEX, 100 }, { IDCANCEL, MOVEX, 100 }, { IDC CHECK SORTCUT, MOVEX, 100 }, { IDC SHOW ON MAP, MOVEX, 100 }, { IDC BUTTON FROM MAP1, MOVEX, 100 }, { IDC BUTTON FROM MAP2, MOVEX, 100 }, { IDC BUTTON FROM MAP3, MOVEX, 100 }, { IDC STATIC ND1, MOVEX, 50 }, { IDC STATIC TR, MOVEX, 50 }, { IDC STATIC ND2, MOVEX, 50 }, { IDC STATIC GRP1, ELASTICX, 100 }, { IDC COMBO NODE START, ELASTICX, 100 }, { IDC COMBO NODE END, ELASTICX, 100 }, { IDC COMBO NODE

ACROSS, ELASTICX, 100 }, { IDC STATIC TXT4, ELASTICX, 50 }, { IDC COMBO FOUND PATHS, ELASTICX, 50 }, { IDC FOUND PATH, ELASTICX, 50 }, { IDC STATIC GRP2, ELASTICX | MOVEX, 50 }, { IDC EDIT NODE1, ELASTICX | MOVEX, 50 }, { IDC EDIT TRACE, ELASTICX | MOVEX, 50 }, { IDC EDIT NODE2, ELASTICX | MOVEX, 50 }, { IDC FOUND PATH, ELASTICY, 100 }, }; const DWORD numberofentries = sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries); int i; CString strName; if( m lNrOfNodeEnts == 0 ){ int ind1 = m cmbNodeStart.AddString( "??? nincsennek városok" ); int ind2 = m cmbNodeEnd.AddString( "??? nincsennek városok" ); int ind3 = m cmbNodeAcross.AddString( "??? nincsennek városok" ); m cmbNodeAcross.SetItemDataPtr( ind1, NULL ); m cmbNodeAcross.SetItemDataPtr( ind2, NULL ); m cmbNodeAcross.SetItemDataPtr( ind3, NULL ); } else { int ind = m cmbNodeAcross.AddString(""); m cmbNodeAcross.SetItemDataPtr( ind, NULL ); for( i=0; i<m

lNrOfNodeEnts; i++ ){ t nodeDef *pNextEnt = (t nodeDef )(((char )m pNodeEnts)+isizeof(t nodeDef)); strName = GetApplicationData( pNextEnt->ent ); if( strName != "" ){ int ind1 = m cmbNodeStart.AddString( strName ); int ind2 = m cmbNodeEnd.AddString( strName ); int ind3 = m cmbNodeAcross.AddString( strName ); m cmbNodeStart.SetItemDataPtr( ind1, pNextEnt ); m cmbNodeEnd.SetItemDataPtr( ind2, pNextEnt ); m cmbNodeAcross.SetItemDataPtr( ind3, pNextEnt ); } 92. oldal } } // A kezdeti értékek beállítása m cmbNodeStart.SetFocus(); m cmbNodeStart.SetCurSel( 0 ); m cmbNodeEnd.SetCurSel( 0 ); m cmbNodeAcross.SetCurSel( 0 ); DisableUnavailableControls(); return FALSE; } // Ablak bezárásakor az adatainak elmentése void WRUiCheck2Dialog::OnBezar(){ StorePixelData(); CAcUiDialog::OnOK(); } // Gomb lenyomására egy csomópont név bekérése a Start mezö feltöltéséhez void WRUiCheck2Dialog::OnButtonFromMap1(){ CString newValue; ads name ename; if( GetNodeFromMap(

newValue, ename ) ) m cmbNodeStart.SetCurSel( GetIndexFromEname(&m cmbNodeStart, ename) ); DisableUnavailableControls(); } // Gomb lenyomására egy csomópont név bekérése a Vége mezö feltöltéséhez void WRUiCheck2Dialog::OnButtonFromMap2(){ CString newValue; ads name ename; if( GetNodeFromMap( newValue, ename ) ) m cmbNodeEnd.SetCurSel( GetIndexFromEname(&m cmbNodeEnd, ename) ); DisableUnavailableControls(); } // Gomb lenyomására egy csomópont név bekérése a Keresztül mezö feltöltéséhez // ha rossz helyre kattint nem változik az értéke, ha olyan várost választ ki // ami a kezdö vagy végpont akkor az értéke üre lesz, különben az a város amire // kattintott a felhasználó. void WRUiCheck2Dialog::OnButtonFromMap3(){ CString newValue; ads name ename; if( GetNodeFromMap( newValue, ename ) ){ int i = GetIndexFromEname(&m cmbNodeAcross, ename); if( i != -1 ){ m cmbNodeAcross.SetCurSel( i ); } else { m cmbNodeAcross.SetCurSel( 0 ); } }

DisableUnavailableControls(); } // Ha megváltozik az érték a legördülő menüben akkor // a számolt adatok érvényességüket veszítik. void WRUiCheck2Dialog::OnSelchangeComboNodeAcross(){ DisableUnavailableControls(); } // Ha megváltozik az érték a legördülő menüben akkor // a számolt adatok érvényességüket veszítik. void WRUiCheck2Dialog::OnSelchangeComboNodeEnd(){ DisableUnavailableControls(); } // Ha megváltozik az érték a legördülő menüben akkor // a számolt adatok érvényességüket veszítik. void WRUiCheck2Dialog::OnSelchangeComboNodeStart(){ DisableUnavailableControls(); } void WRUiCheck2Dialog::OnCheckSortcut(){ } void WRUiCheck2Dialog::OnKillfocusComboFoundPaths(){ } void WRUiCheck2Dialog::OnKillfocusEditNode1(){ } void WRUiCheck2Dialog::OnKillfocusEditNode2(){ } 93. oldal void WRUiCheck2Dialog::OnKillfocusEditTrace(){ } void WRUiCheck2Dialog::OnSelchangeFoundPath(){ } void WRUiCheck2Dialog::OnPathFinder(){ } void

WRUiCheck2Dialog::OnShowOnMap(){ } Database designer/arxsources/WRUiFindNodeDialog.h #if !defined(AFX WRUIFINDNODEDIALOG H 0B6BDD63 BC8E 11D4 A05B 0000C076DBD5 INCLUDED ) #define AFX WRUIFINDNODEDIALOG H 0B6BDD63 BC8E 11D4 A05B 0000C076DBD5 INCLUDED #include #include #include #include #include #include "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiFindNodeDialog : public CAcUiDialog { public: WRUiFindNodeDialog(CWnd* pParent = NULL); ~WRUiFindNodeDialog(); // standard constructor //{{AFX DATA(WRUiFindNodeDialog) enum { IDD = IDD FND NODE }; CComboBox m cmbNode; //}}AFX DATA //{{AFX VIRTUAL(WRUiFindNodeDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL protected: t nodeDef t nodeDef long // DDX/DDV support *m prevNodeAvailable; *m pNodeEnts; m lNrOfNodeEnts; int m iOldCmdEcho; // A kezdeti képernyö beállítások elmentésére használt változók bool m bValidCenter;

AcGePoint2d m agpCenter; double m dWidth; double m dHeight; //{{AFX MSG(WRUiFindNodeDialog) virtual void OnOK(); afx msg void OnSelchangeFnNode(); virtual void OnCancel(); virtual BOOL OnInitDialog(); afx msg void OnDestroy(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiFindNodeDialog.cpp #include #include #include #include #include "stdafx.h" "waproute.h" "Error.h" "AcadPlus.h" "WRUiFindNodeDialog.h" WRUiFindNodeDialog::WRUiFindNodeDialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiFindNodeDialog::IDD, pParent){ //{{AFX DATA INIT(WRUiFindNodeDialog) //}}AFX DATA INIT startPrograssIndicator( "Elemek adatainak legyüjtése a rajzról." ); m prevNodeAvailable = NULL; m lNrOfNodeEnts = 0; m pNodeEnts = NULL; 94. oldal // A csomópontok tömbjének feltöltése struct resbuf *filter; ads name sset; ads name ent; long i, iLast; CString strName; filter = acutBuildList(

-4, "<AND", RTDXF0, "INSERT", 8, "WR VAROS", -4, "AND>", 0 ); acedSSGet( T("X"), NULL, NULL, filter, sset ); acutRelRb(filter); if(acedSSLength(sset, &iLast) == RTNORM){ if( iLast != 0 ){ if( (m pNodeEnts = (t nodeDef *)malloc( iLastsizeof(t nodeDef)+7 )) != NULL ){ for( i=0; i<iLast; i++ ){ setProgressIndicator( ((double)i/iLast)*100.0 ); if( acedSSName(sset, i, ent) == RTNORM ){ strName = GetApplicationData( ent ); if(( strName != "???" ) && (strName.GetLength() != 0)){ AcGePoint3dArray ptArray; entpoints( ent, ptArray ); t nodeDef *nextStore = (t nodeDef )(((char )m pNodeEnts)+isizeof(t nodeDef)); nextStore->pt[X] = ptArray.at(0)x; nextStore->pt[Y] = ptArray.at(0)y; nextStore->pt[Z] = ptArray.at(0)z; acdbNameSet( ent, nextStore->ent ); m lNrOfNodeEnts++; } } } } } } acedSSFree(sset); endProgressIndicator(); } WRUiFindNodeDialog::~WRUiFindNodeDialog(){ if(m pNodeEnts != NULL) free(m

pNodeEnts); } void WRUiFindNodeDialog::DoDataExchange(CDataExchange* pDX){ CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiFindNodeDialog) DDX Control(pDX, IDC FN NODE, m cmbNode); //}}AFX DATA MAP } BEGIN MESSAGE MAP(WRUiFindNodeDialog, CAcUiDialog) //{{AFX MSG MAP(WRUiFindNodeDialog) ON CBN SELCHANGE(IDC FN NODE, OnSelchangeFnNode) ON WM DESTROY() //}}AFX MSG MAP END MESSAGE MAP() void WRUiFindNodeDialog::OnOK(){ StorePixelData(); CAcUiDialog::OnOK(); } // Cancel esetén a képernyö közepét vissza // kell állítani az eredeti pozicióra. void WRUiFindNodeDialog::OnCancel(){ // Ha nem az eredeti pozició van kiválasztva akkor visszaállítás if( m prevNodeAvailable != NULL ){ acedCommand( RTSTR, " ZOOM", RTSTR, "P", 0 ); } CAcUiDialog::OnCancel(); } // Ha a felhasználó változtat a kiválasztott // város nevén akkor oda kell zoomolni a városra. void WRUiFindNodeDialog::OnSelchangeFnNode(){ if( m prevNodeAvailable != NULL ){ AcCmColor cm;

cm.setColorIndex(256); changeObjectsColor( m prevNodeAvailable->ent, cm ); acedCommand( RTSTR, " ZOOM", RTSTR, "P", 0 ); m prevNodeAvailable = NULL; } t nodeDef *pNextEnt = (t nodeDef)m cmbNode.GetItemDataPtr( m cmbNodeGetCurSel() ); if( pNextEnt != NULL ){ AcCmColor cm; cm.setColorIndex(1); changeObjectsColor( pNextEnt->ent, cm ); acedCommand( RTSTR, " ZOOM", RTSTR, " C", RTPOINT, pNextEnt->pt, RTSHORT, 300, 0 ); 95. oldal m prevNodeAvailable = pNextEnt; } } BOOL WRUiFindNodeDialog::OnInitDialog(){ // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiFindNodeDialog"); CAcUiDialog::OnInitDialog(); // Az ablak átméretezésének beállítása DLGCTLINFO dlgSizeInfo[]= { { IDOK, MOVEX, 50 }, { IDCANCEL, MOVEX, 50 }, { IDC FN NODE, ELASTICX, 100 }, }; const DWORD numberofentries = sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries);

LockDialogHeight(); // A combo boxban megjelenö értékek feltöltése int i, ind; CString strName; if( m lNrOfNodeEnts == 0 ){ ind = m cmbNode.AddString( "??? Még nincsennek városok" ); m cmbNode.SetItemDataPtr( ind, NULL ); } else { ind = m cmbNode.AddString( "*Kezdetkor aktuális nézet" ); m cmbNode.SetItemDataPtr( ind, NULL ); for( i=0; i<m lNrOfNodeEnts; i++ ){ t nodeDef *pNextEnt = (t nodeDef )(((char )m pNodeEnts)+isizeof(t nodeDef)); CString strName = GetApplicationData( pNextEnt->ent ); if(( strName != "???" ) && (strName.GetLength() != 0)){ ind = m cmbNode.AddString( strName ); m cmbNode.SetItemDataPtr( ind, pNextEnt ); } } } // A kezdeti értékek beállítása m cmbNode.SetFocus(); m cmbNode.SetCurSel( 0 ); // A CMDECHO változó mentése struct resbuf rb; acedGetVar( "CMDECHO", &rb ); m iOldCmdEcho = rb.resvalrint; rb.resvalrint = 0; acedSetVar( "CMDECHO", &rb ); m prevNodeAvailable = NULL; return

FALSE; } // Az on InitDialogban mentett CMDECHO visszaállítása void WRUiFindNodeDialog::OnDestroy() { // A kiválasztott elem színét vissza kell állítani ha volt ilyen if( m prevNodeAvailable != NULL ){ AcCmColor cm; cm.setColorIndex(256); changeObjectsColor( m prevNodeAvailable->ent, cm ); m prevNodeAvailable = NULL; } // A CMDECHO változó visszaállítása struct resbuf rb; rb.restype = RTSHORT; rb.resvalrint = m iOldCmdEcho; acedSetVar( "CMDECHO", &rb ); CAcUiDialog::OnDestroy(); } Database designer/arxsources/WRUiFindTraceDialog.h #if !defined(AFX WRUIFINDTRACEDIALOG H 31987283 BD60 11D4 908D 0020AF3672E3 INCLUDED ) #define AFX WRUIFINDTRACEDIALOG H 31987283 BD60 11D4 908D 0020AF3672E3 INCLUDED #include #include #include #include #include 96. oldal "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> #include <acui.h> class WRUiFindTraceDialog : public CAcUiDialog { public: WRUiFindTraceDialog(CWnd*

pParent = NULL); ~WRUiFindTraceDialog(); // standard constructor void LoadNewSegments( void ); void ColorizeObjects( int newColor ); void RefreshSelection( void ); //{{AFX DATA(WRUiFindTraceDialog) enum { IDD = IDD FND TRACE }; CStatic m staText2; CComboBox m cmbTrace; CListCtrl m cmbTraceSegs; //}}AFX DATA CString m strData; //{{AFX VIRTUAL(WRUiFindTraceDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL protected: long ads name int AcDbObjectIdArray CImageList bool // DDX/DDV support m lNrOfTraceEnts; *m pTraceEnts; m iOldCmdEcho; m aColoredObjects; m oImageList; m bPrevZoomAvailable; //{{AFX MSG(WRUiFindTraceDialog) afx msg void OnDestroy(); virtual BOOL OnInitDialog(); virtual void OnOK(); virtual void OnCancel(); afx msg void OnSelchangeFtTrace(); afx msg void OnClickFtList(NMHDR* pNMHDR, LRESULT pResult); afx msg void OnKeydownFtList(NMHDR* pNMHDR, LRESULT pResult); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif

Database designer/arxsources/WRUiFindTraceDialog.cpp #include #include #include #include "stdafx.h" "waproute.h" "AcadPlus.h" "WRUiFindTraceDialog.h" WRUiFindTraceDialog::WRUiFindTraceDialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiFindTraceDialog::IDD, pParent){ //{{AFX DATA INIT(WRUiFindTraceDialog) //}}AFX DATA INIT startPrograssIndicator( "Elemek adatainak legyüjtése a rajzról." ); m lNrOfTraceEnts = 0; m pTraceEnts = NULL; m bPrevZoomAvailable = false; // A útvonalak tömbjének feltöltése struct resbuf *filter; ads name sset, ent; long i,iLast; CString strName; filter = acutBuildList( -4, "<AND", RTDXF0, "LWPOLYLINE", 8, "WR UT", -4, "AND>", 0 ); acedSSGet( T("X"), NULL, NULL, filter, sset ); acutRelRb(filter); if(acedSSLength(sset, &iLast) == RTNORM){ if( iLast != 0 ){ if( (m pTraceEnts = (ads name *)malloc( iLast(sizeof(ads name)+7) )) != NULL ){ for( i=0;

i<iLast; i++ ){ setProgressIndicator( ((double)i/iLast)*50.0 ); if( acedSSName(sset, i, ent) == RTNORM ){ strName = GetApplicationData( ent ); if(( strName != "???" ) && (strName.GetLength() != 0)){ AcGePoint3dArray ptArray; 97. oldal ads name *nextStore = (ads name )(((char )m pTraceEnts)+isizeof(ads name)); acdbNameSet( ent, *nextStore ); m lNrOfTraceEnts++; } } } } } } acedSSFree(sset); // Az elemek darabszámának kiszámítása m strData = " "; for( i=0; i<m lNrOfTraceEnts; i++ ){ setProgressIndicator( 50.0+((double)i/m lNrOfTraceEnts)*50.0 ); ads name *pNextEnt = (ads name )(((char )m pTraceEnts)+isizeof(ads name)); CString strName = GetApplicationData( *pNextEnt ); if(( strName != "???" ) && (strName.GetLength() != 0)){ if(m strData.Find(" "+strName+" ") == -1){ m strData += strName+" 1 "; } else { CString strOldValue = m strData.Mid( m strDataFind(" "+strName+" ")+1 );

strOldValue = strOldValue.Left( strOldValueFind(" ") ); int newValue = atoi( strOldValue.Mid(strOldValueFind(" ")+1) ); CString strNewValue; strNewValue.Format( " %s %d ", strName, newValue+1 ); m strData.Replace( " "+strOldValue+" ", strNewValue ); } } } endProgressIndicator(); } WRUiFindTraceDialog::~WRUiFindTraceDialog(){ if(m pTraceEnts != NULL) free(m pTraceEnts); } void WRUiFindTraceDialog::DoDataExchange(CDataExchange* pDX) { CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiFindTraceDialog) DDX Control(pDX, IDC FT TX2, m staText2); DDX Control(pDX, IDC FT TRACE, m cmbTrace); DDX Control(pDX, IDC FT LIST, m cmbTraceSegs); //}}AFX DATA MAP } BEGIN MESSAGE MAP(WRUiFindTraceDialog, CAcUiDialog) //{{AFX MSG MAP(WRUiFindTraceDialog) ON WM DESTROY() ON CBN SELCHANGE(IDC FT TRACE, OnSelchangeFtTrace) ON NOTIFY(NM CLICK, IDC FT LIST, OnClickFtList) ON NOTIFY(LVN KEYDOWN, IDC FT LIST, OnKeydownFtList) //}}AFX MSG MAP END MESSAGE

MAP() void WRUiFindTraceDialog::OnDestroy(){ // A kiszinezett elemek normális szinüvé tétele ColorizeObjects( 256 ); // A CMDECHO változó visszaállítása struct resbuf rb; rb.restype = RTSHORT; rb.resvalrint = m iOldCmdEcho; acedSetVar( "CMDECHO", &rb ); CAcUiDialog::OnDestroy(); } BOOL WRUiFindTraceDialog::OnInitDialog(){ // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiFindT"); CAcUiDialog::OnInitDialog(); // Az ablak átméretezésének beállítása DLGCTLINFO dlgSizeInfo[]= { { IDOK, MOVEX, 50 }, { IDCANCEL, MOVEX, 50 }, { IDOK, MOVEY, 100 }, { IDCANCEL, MOVEY, 100 }, { IDC FT TRACE, ELASTICX, 100 }, { IDC FT LIST, ELASTICXY, 100 }, }; const DWORD numberofentries = sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries); 98. oldal // A combo boxban megjelenö értékek feltöltése int i, ind; CString strName; if( m lNrOfTraceEnts == 0 ){ ind = m

cmbTrace.AddString( "??? Még nincsennek utak" ); m cmbTrace.SetItemDataPtr( ind, NULL ); } else { ind = m cmbTrace.AddString( "*Kezdetkor aktuális nézet" ); m cmbTrace.SetItemDataPtr( ind, NULL ); CString strData = m strData; CString strValues = " "; for( i=0; i<m lNrOfTraceEnts; i++ ){ ads name *pNextEnt = (ads name )(((char )m pTraceEnts)+isizeof(ads name)); CString strName = GetApplicationData( *pNextEnt ); if(( strName != "???" ) && (strName.GetLength() != 0) && (strValuesFind(" "+strName+" ") == -1)){ if(strData.Find(" "+strName+" ") != -1){ strValues += strName+" "; CString strComboValue; strComboValue = strData.Mid( strDataFind(" "+strName+" ")+1 ); strComboValue = strComboValue.Left( strComboValueFind(" ") ); int newValue = atoi( strComboValue.Mid(strComboValueFind(" ")+1) ); CString strCmbValue; strCmbValue.Format( "%s -

(%ddb)", strName, newValue ); ind = m cmbTrace.AddString( strCmbValue ); m cmbTrace.SetItemDataPtr( ind, pNextEnt ); } } } } // A megjelenítendő képek feltöltése egy listába m oImageList.Create(32, 32, TRUE, 4, 4); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE TWOWAY) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY LR) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY RL) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE TWOWAY SELECTED) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY LR SELECTED) )); m oImageList.Add(LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY RL SELECTED) )); m cmbTraceSegs.SetImageList(&m oImageList, LVSIL NORMAL); // A kezdeti értékek beállítása m cmbTrace.SetFocus(); m cmbTrace.SetCurSel( 0 ); LoadNewSegments(); // A CMDECHO változó mentése struct resbuf rb; acedGetVar(

"CMDECHO", &rb ); m iOldCmdEcho = rb.resvalrint; rb.resvalrint = 0; acedSetVar( "CMDECHO", &rb ); return FALSE; } // Az objektum id tömbben levö elemeket a megadtott // színüre változtatja 256-bylayer. void WRUiFindTraceDialog::ColorizeObjects( int newColor ){ AcCmColor cm; cm.setColorIndex( newColor ); while( !m aColoredObjects.isEmpty() ){ changeObjectsColor( m aColoredObjects.at(0), cm ); m aColoredObjects.removeSubArray( 0, 0 ); } } void WRUiFindTraceDialog::LoadNewSegments( void ){ ads name *pEnt = (ads name)m cmbTrace.GetItemDataPtr( m cmbTraceGetCurSel() ); if( !pEnt ){ m cmbTraceSegs.EnableWindow( false ); m staText2.EnableWindow( false ); m cmbTraceSegs.DeleteAllItems(); ColorizeObjects( 256 ); } else { m cmbTraceSegs.EnableWindow( true ); m staText2.EnableWindow( true ); m cmbTraceSegs.DeleteAllItems(); ColorizeObjects( 256 ); int i; CString strName = GetApplicationData( *pEnt ); for( i=0; i<m lNrOfTraceEnts; i++ ){ ads name *pNextEnt =

(ads name )(((char )m pTraceEnts)+isizeof(ads name)); CString strSegName = GetApplicationData( *pNextEnt ); if( strName == strSegName ){ 99. oldal LV ITEM lvItem; ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF TEXT | LVIF STATE | LVIF IMAGE; lvItem.state = LVIS SELECTED; lvItem.iItem = 0; lvItem.iImage = GetUtvonalTipus(*pNextEnt); lvItem.pszText = (char*)(LPCTSTR)strSegName; int ind = m cmbTraceSegs.InsertItem(&lvItem); m cmbTraceSegs.SetItemData( ind, (LPARAM)(void *)pNextEnt ); } } } } void WRUiFindTraceDialog::RefreshSelection( void ){ int i; AcDbObjectIdArray idArray; AcGePoint3dArray ptArray; ads point minPt, maxPt; for( i=0; i<m cmbTraceSegs.GetItemCount(); i++ ){ ads name *pEnt = (ads name)(void)m cmbTraceSegs.GetItemData(i); int state = m cmbTraceSegs.GetItemState(i, LVIS SELECTED); if( pEnt ){ // Az utvonal tipus lekerdezése es ebbol ikon megallapitasa LV ITEM lvItem; ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF IMAGE; lvItem.iItem =

i; lvItem.iImage = GetUtvonalTipus(*pEnt); if( state == LVIS SELECTED ){ // Az aktuális elem Id-jének mentése AcDbObjectId entId; enameToObjId( *pEnt, entId ); idArray.append( entId ); // A zoomoláshoz a koordináták lekérdezése entpoints( *pEnt, ptArray ); lvItem.iImage += 3; } m cmbTraceSegs.SetItem( &lvItem ); } } ColorizeObjects( 256 ); m aColoredObjects = idArray; ColorizeObjects( 1 ); m aColoredObjects = idArray; // Ha volt elözö zoom pozició akkor azt vissza kell csinálni if( m bPrevZoomAvailable ){ acedCommand( RTSTR, " ZOOM", RTSTR, "P", 0 ); m bPrevZoomAvailable = false; } // Új zoom pozició kiszámolása if( ptArray.length()>=2 ){ minPt[X] = ptArray.at(0)x; minPt[Y] = ptArray.at(0)y; maxPt[X] = ptArray.at(0)x; maxPt[Y] = ptArray.at(0)y; for( i=1; i<ptArray.length(); i++ ){ minPt[X] = min( ptArray.at(i)x, minPt[X] ); minPt[Y] = min( ptArray.at(i)y, minPt[Y] ); maxPt[X] = max( ptArray.at(i)x, maxPt[X] ); maxPt[Y] = max(

ptArray.at(i)y, maxPt[Y] ); } minPt[X] -= 100; minPt[Y] -= 100; maxPt[X] += 100; maxPt[Y] += 100; acedCommand( RTSTR, " ZOOM", RTSTR, " W", RTPOINT, minPt, RTPOINT, maxPt, 0 ); m bPrevZoomAvailable = true; } } void WRUiFindTraceDialog::OnOK(){ StorePixelData(); CAcUiDialog::OnOK(); } void WRUiFindTraceDialog::OnCancel(){ // Ha volt elözö zoom pozició akkor azt vissza kell csinálni if( m bPrevZoomAvailable ){ acedCommand( RTSTR, " ZOOM", RTSTR, "P", 0 ); m bPrevZoomAvailable = false; } CAcUiDialog::OnCancel(); } 100. oldal void WRUiFindTraceDialog::OnSelchangeFtTrace(){ LoadNewSegments(); RefreshSelection(); } void WRUiFindTraceDialog::OnClickFtList(NMHDR* pNMHDR, LRESULT pResult){ RefreshSelection(); *pResult = 0; } // Néhány billentyü kombináció ami biztosan nem változtatja meg // ListCtrl értékét ezért nem is kell ilyenkor újraszámolni // a zoomolási koordinátákat, és kiszinezést. void

WRUiFindTraceDialog::OnKeydownFtList(NMHDR* pNMHDR, LRESULT pResult) { LV KEYDOWN* pLVKeyDow = (LV KEYDOWN)pNMHDR; if( (pLVKeyDow->wVKey == VK CONTROL) || (pLVKeyDow->wVKey == VK SHIFT) || (pLVKeyDow->wVKey == VK MENU) || (pLVKeyDow->wVKey == VK CAPITAL) || (pLVKeyDow->wVKey == VK PAUSE) ){ } else { RefreshSelection(); } *pResult = 0; } Database designer/arxsources/WRUiGetString.h #if !defined(AFX WRUIGETSTRING H 57CB4E66 BBA8 11D4 A05A 0000C076DBD5 INCLUDED ) #define AFX WRUIGETSTRING H 57CB4E66 BBA8 11D4 A05A 0000C076DBD5 INCLUDED #include #include #include #include #include #include "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiGetString : public CAcUiDialog { public: WRUiGetString(CWnd* pParent = NULL); CString CString CString CString m strTitle; m strDescription; m strDefaultValue; m strReturnValue; // // // // Az ablak feliratát tartalmazza A edit mezö feliratát tartalmazza A edit

mezö kezdö értékét tartalmazza Az ablak visszatérési értéke, ha OK gombbal lett bezárva //{{AFX DATA(WRUiGetString) enum { IDD = IDD GETNAME }; CStatic m staDescription; CEdit m edtString; //}}AFX DATA //{{AFX VIRTUAL(WRUiGetString) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL // DDX/DDV support protected: //{{AFX MSG(WRUiGetString) virtual BOOL OnInitDialog(); virtual void OnOK(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiGetString.cpp #include "stdafx.h" #include "waproute.h" #include "WRUiGetString.h" WRUiGetString::WRUiGetString(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiGetString::IDD, pParent){ //{{AFX DATA INIT(WRUiGetString) //}}AFX DATA INIT m strTitle = ""; m strDescription = ""; 101. oldal m strDefaultValue = ""; m strReturnValue = ""; } void WRUiGetString::DoDataExchange(CDataExchange* pDX){

CDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiGetString) DDX Control(pDX, IDC STATIC GETNAME TX, m staDescription); DDX Control(pDX, IDC GETSTRING, m edtString); //}}AFX DATA MAP } BEGIN MESSAGE MAP(WRUiGetString, CAcUiDialog) //{{AFX MSG MAP(WRUiGetString) //}}AFX MSG MAP END MESSAGE MAP() /* * Üzenet kezelö funkciók * */ BOOL WRUiGetString::OnInitDialog(){ // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiGetString"); CAcUiDialog::OnInitDialog(); DLGCTLINFO dlgSizeInfo[]= { { IDC GETSTRING, ELASTICX, 100 }, { IDCANCEL, MOVEX, 50 }, { IDOK, MOVEX, 50 }, }; const DWORD numberofentries = sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries); LockDialogHeight(); // Ablak feliratainak beállítása if( m strTitle.GetLength() != 0 ) SetWindowText( m strTitle ); if( m strDescription.GetLength() != 0 ) m staDescription.SetWindowText( m strDescription ); if( m

strDefaultValue.GetLength() != 0 ) m edtString.SetWindowText( m strDefaultValue ); // Az aktuális kontrol megadása m edtString.SetFocus(); m edtString.SetSel( 0, -1 ); return FALSE; } // Ha az anlakot ay OK gombbal végezték ki akkor a // méret és pozició adatok mentése a Registrybe, // és a viszzatérési értékek beállítása void WRUiGetString::OnOK(){ m edtString.GetWindowText( m strReturnValue ); m strReturnValue.TrimLeft(); m strReturnValue.TrimRight(); if( m strReturnValue.GetLength() == 0 ){ MessageBox( "A megadott karakter sorozat üres vagy csak white-space karaktereket tartalmaz.", "Hibás érték!" ); m edtString.SetFocus(); m edtString.SetSel( 0, -1 ); return; } StorePixelData(); CAcUiDialog::OnOK(); } Database designer/arxsources/WRUiModifyTraceDialog.h #if !defined(AFX WRUiModifyTraceDialog H 72C92D97 BBB3 11D4 A05A 0000C076DBD5 INCLUDED ) #define AFX WRUiModifyTraceDialog H 72C92D97 BBB3 11D4 A05A 0000C076DBD5 INCLUDED #include

#include #include #include #include #include "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiModifyTraceDialog : public CAcUiDialog { public: WRUiModifyTraceDialog(CWnd* pParent = NULL); 102. oldal // Az Type változó értékei a DWG ??? konstansok értékeit veszik fel // attól függöen, hogy melyik tipusú utvonalakat kell létrehozni, // illetve mi legyen a kezdő érték az blakba való belépéskor. Ha több // különbözö útvonal is szerepel a módosítandó elemek között akkor a // Type a 3 értéket kell hogy felvegye a m iDefaultType változóban // az ablak megjelenítése előtt. Ha az ablakból való visszatéréskor // az iType valtozóban ugyanez az érték található akkor a felhasználó // nem akrja, az útvonalak tipusát megváltoztatni. Ez az ablak képes // m strName paraméterben üres stringet viszzaadni ekkor különbözö // útvonal nevek esetén a felhasználó nem akrja az

útvonal neveket // módosítani, ha különbözö nevü útvonalak szerepelnek a szelekcióban // akkor m strDefaultName-nek ""-et kell megadni. CString m strTitle; // Az ablak feliratát tartalmazza CString m strDescription; // A edit mezö feliratát tartalmazza CString m strDefaultName; // A edit mezö kezdö értékét tartalmazza int m iDefaultType; // A combo kezdö értékét tartalmazza CString m strName; // Az új út nevét tartalmazza int m iType; // Az új út irányát tartalmazza DWG ??? kód szerint //{{AFX DATA(WRUiModifyTraceDialog) enum { IDD = IDD MOD TRACE }; CStatic m staIkon; CStatic m staDescription; CComboBox m cmbType; CEdit m edtName; //}}AFX DATA //{{AFX VIRTUAL(WRUiModifyTraceDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL // DDX/DDV support protected: void RefreshIcon( int index ); //{{AFX MSG(WRUiModifyTraceDialog) virtual void OnOK(); virtual BOOL OnInitDialog(); afx msg void OnSelchangeMtType(); //}}AFX

MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiModifyTraceDialog.cpp #include "stdafx.h" #include "waproute.h" #include "WRUiModifyTraceDialog.h" WRUiModifyTraceDialog::WRUiModifyTraceDialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiModifyTraceDialog::IDD, pParent){ //{{AFX DATA INIT(WRUiModifyTraceDialog) //}}AFX DATA INIT m strTitle = ""; m strDescription = ""; m strDefaultName = ""; m iDefaultType = 0; m strName = ""; m iType = -1; } void WRUiModifyTraceDialog::DoDataExchange(CDataExchange* pDX){ CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiModifyTraceDialog) DDX Control(pDX, IDC MT ICON, m staIkon); DDX Control(pDX, IDC STATIC MT DESCRIPTION, m staDescription); DDX Control(pDX, IDC MT TYPE, m cmbType); DDX Control(pDX, IDC MT NAME, m edtName); //}}AFX DATA MAP } BEGIN MESSAGE MAP(WRUiModifyTraceDialog, CAcUiDialog) //{{AFX MSG MAP(WRUiModifyTraceDialog)

ON CBN SELCHANGE(IDC MT TYPE, OnSelchangeMtType) //}}AFX MSG MAP END MESSAGE MAP() 103. oldal BOOL WRUiModifyTraceDialog::OnInitDialog(){ // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiNewTraceDialog"); CAcUiDialog::OnInitDialog(); DLGCTLINFO dlgSizeInfo[]= { { IDC MT NAME, ELASTICX, 100 }, { IDC MT TYPE, ELASTICX, 100 }, { IDCANCEL, MOVEX, 50 }, { IDOK, MOVEX, 50 }, }; const DWORD numberofentries = sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries); LockDialogHeight(); // Combo box feltoltese az ikonokkal es szöveggel m cmbType.AddString( "Kétirányú útvonal" ); m cmbType.AddString( "BJ Egyirányú útvonal" ); m cmbType.AddString( "JB Egyirányú útvonal" ); m cmbType.AddString( "--> Különböző irányú útak <--" ); // Ablak feliratainak beállítása if( m strTitle.GetLength() != 0 ) SetWindowText( m strTitle ); if(

m strDescription.GetLength() != 0 ) m staDescription.SetWindowText( m strDescription ); if( m strDefaultName.GetLength() != 0 ) m edtName.SetWindowText( m strDefaultName ); if( m iDefaultType != 3 ){ // Ha minden útnak azonos a tipusa akkor nem kell // a "Különbözö tipusú útak" elem a combo boxba. m cmbType.DeleteString( 3 ); if(( m iDefaultType >= 0 ) && ( m iDefaultType<= 2 )) m cmbType.SetCurSel( m iDefaultType ); else m cmbType.SetCurSel( 0 ); } else { m cmbType.SetCurSel( 3 ); } RefreshIcon( m cmbType.GetCurSel() ); return TRUE; } // Az indexnek megfelelő ikon beállítása a bal alsó sarokban void WRUiModifyTraceDialog::RefreshIcon( int index ){ if( index == 0 ) m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE TWOWAY) ) ); else if( index == 1 ) m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY LR) ) ); else if( index == 2 ) m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI

TRACE ONEWAY RL) ) ); else m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE DIFFERENT) ) ); } // Ha több különbözö útvonal tipus van a szelekcióban azaz // a combo még tartalmazza a "Különbözö tipusú útak"-feliratot // és a felhasználó most egy másikat választ akkor ennek az // elemnek ki kell kerülnie a combo boxból. void WRUiModifyTraceDialog::OnSelchangeMtType(){ if( m cmbType.GetCount() == 4 ) m cmbType.DeleteString( 3 ); RefreshIcon( m cmbType.GetCurSel() ); } void WRUiModifyTraceDialog::OnOK(){ m iType = m cmbType.GetCurSel(); m edtName.GetWindowText( m strName ); if( m strName.GetLength() != 0 ){ m strName.TrimLeft(); m strName.TrimRight(); if( m strName.GetLength() == 0 ){ MessageBox( "A megadott karakter sorozat üres vagy csak white-space karaktereket tartalmaz.", "Hibás érték!" ); return; } } StorePixelData(); CAcUiDialog::OnOK(); } 104. oldal Database designer/arxsources/WRUiNewTraceDialog.h

#if !defined(AFX WRUINEWTRACEDIALOG H 72C92D93 BBB3 11D4 A05A 0000C076DBD5 INCLUDED ) #define AFX WRUINEWTRACEDIALOG H 72C92D93 BBB3 11D4 A05A 0000C076DBD5 INCLUDED #include #include #include #include #include #include "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiNewTraceDialog : public CAcUiDialog { public: WRUiNewTraceDialog(CWnd* pParent = NULL); // Az Type változó értékei a DWG ??? konstansok értékeit veszik fel // attól függöen, hogy melyik tipusú utvonalakat kell létrehozni, // illetve mi legyen a kezdő érték az blakba való belépéskor. CString m strTitle; // Az ablak feliratát tartalmazza CString m strDescription; // A edit mezö feliratát tartalmazza CString m strDefaultName; // A edit mezö kezdö értékét tartalmazza int m iDefaultType; // A combo kezdö értékét tartalmazza CString m strName; // Az új út nevét tartalmazza int m iType; // Az új út irányát tartalmazza

DWG ??? kód szerint //{{AFX DATA(WRUiNewTraceDialog) enum { IDD = IDD NEW TRACE }; CStatic m staIkon; CStatic m staDescription; CComboBox m cmbType; CEdit m edtName; //}}AFX DATA //{{AFX VIRTUAL(WRUiNewTraceDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL // DDX/DDV support protected: void RefreshIcon( int index ); //{{AFX MSG(WRUiNewTraceDialog) virtual BOOL OnInitDialog(); virtual void OnOK(); afx msg void OnSelchangeNtType(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiNewTraceDialog.cpp #include #include #include #include "stdafx.h" "waproute.h" "WRUiNewTraceDialog.h" "AcExtensionModule.h" WRUiNewTraceDialog::WRUiNewTraceDialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiNewTraceDialog::IDD, pParent){ //{{AFX DATA INIT(WRUiNewTraceDialog) //}}AFX DATA INIT m strTitle = ""; m strDescription = ""; m strDefaultName = "";

m iDefaultType = 0; m strName = ""; m iType = -1; } void WRUiNewTraceDialog::DoDataExchange(CDataExchange* pDX){ CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiNewTraceDialog) DDX Control(pDX, IDC NT IKON, m staIkon); DDX Control(pDX, IDC STATIC NT DESCRIPTION, m staDescription); DDX Control(pDX, IDC NT TYPE, m cmbType); DDX Control(pDX, IDC NT NAME, m edtName); //}}AFX DATA MAP } 105. oldal BEGIN MESSAGE MAP(WRUiNewTraceDialog, CAcUiDialog) //{{AFX MSG MAP(WRUiNewTraceDialog) ON CBN SELCHANGE(IDC NT TYPE, OnSelchangeNtType) //}}AFX MSG MAP END MESSAGE MAP() BOOL WRUiNewTraceDialog::OnInitDialog(){ // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiNewTraceDialog"); CAcUiDialog::OnInitDialog(); DLGCTLINFO dlgSizeInfo[]= { { IDC NT NAME, ELASTICX, 100 }, { IDC NT TYPE, ELASTICX, 100 }, { IDCANCEL, MOVEX, 50 }, { IDOK, MOVEX, 50 }, }; const DWORD numberofentries =

sizeof(dlgSizeInfo)/sizeof(DLGCTLINFO); SetControlProperty(dlgSizeInfo, numberofentries); LockDialogHeight(); // Combo box feltoltese az ikonokkal es szöveggel m cmbType.AddString( "Kétirányú útvonal" ); m cmbType.AddString( "BJ Egyirányú útvonal" ); m cmbType.AddString( "JB Egyirányú útvonal" ); // Ablak feliratainak beállítása if( m strTitle.GetLength() != 0 ) SetWindowText( m strTitle ); if( m strDescription.GetLength() != 0 ) m staDescription.SetWindowText( m strDescription ); if( m strDefaultName.GetLength() != 0 ) m edtName.SetWindowText( m strDefaultName ); if(( m iDefaultType >= 0 ) && ( m iDefaultType<= 2 )) m cmbType.SetCurSel( m iDefaultType ); else m cmbType.SetCurSel( 0 ); // Fokusz átállítása az egyik controllra. m edtName.SetFocus(); m edtName.SetSel( 0, -1 ); RefreshIcon( m cmbType.GetCurSel() ); return FALSE; } // Ha az anlakot ay OK gombbal végezték ki akkor a // méret és pozició adatok mentése a

Registrybe, // és a viszzatérési értékek beállítása void WRUiNewTraceDialog::OnOK(){ m iType = m cmbType.GetCurSel(); m edtName.GetWindowText( m strName ); m strName.TrimLeft(); m strName.TrimRight(); if( m strName.GetLength() == 0 ){ MessageBox( "A megadott karakter sorozat üres vagy csak white-space karaktereket tartalmaz.", "Hibás érték!" ); m edtName.SetFocus(); m edtName.SetSel( 0, -1 ); return; } StorePixelData(); CAcUiDialog::OnOK(); } // Az indexnek megfelelő ikon beállítása a bal alsó sarokban void WRUiNewTraceDialog::RefreshIcon( int index ){ if( index == 0 ) m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE TWOWAY) ) ); else if( index == 1 ) m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY LR) ) ); else if( index == 2 ) m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI TRACE ONEWAY RL) ) ); else m staIkon.SetIcon( LoadIcon( hWapRouteInstance, MAKEINTRESOURCE(IDI

TRACE DIFFERENT) ) ); } // Amikor a felhasználó új irányt választ akkor // az ikont a bal alsó sarokban meg kell változtatni void WRUiNewTraceDialog::OnSelchangeNtType() { RefreshIcon( m cmbType.GetCurSel() ); } 106. oldal Database designer/arxsources/WRUiProgressDialog.h #if !defined(AFX WRUIPROGRESSDIALOG H 07C28CB3 BFB6 11D4 A05D 0000C076DBD5 INCLUDED ) #define AFX WRUIPROGRESSDIALOG H 07C28CB3 BFB6 11D4 A05D 0000C076DBD5 INCLUDED #include #include #include #include #include #include "resource.h" <dbsymtb.h> <dbapserv.h> <adslib.h> <adui.h> <acui.h> class WRUiProgressDialog : public CAcUiDialog { public: WRUiProgressDialog(CWnd* pParent = NULL); // standard constructor void GetProgressHWND( bool *bCanceled ); bool SetProgressIndicator( double percent ); CString strTitle; //{{AFX DATA(WRUiProgressDialog) enum { IDD = IDD PROGRESS }; CStatic m ctrlTitle; CButton m ctrlCancel; CProgressCtrl m ctrlProgress; //}}AFX DATA //{{AFX

VIRTUAL(WRUiProgressDialog) protected: virtual void DoDataExchange(CDataExchange* pDX); //}}AFX VIRTUAL protected: bool // DDX/DDV support *m setCanceled; //{{AFX MSG(WRUiProgressDialog) virtual BOOL OnInitDialog(); afx msg void OnDestroy(); virtual void OnCancel(); //}}AFX MSG DECLARE MESSAGE MAP() }; //{{AFX INSERT LOCATION}} #endif Database designer/arxsources/WRUiProgressDialog.cpp #include "stdafx.h" #include "waproute.h" #include "WRUiProgressDialog.h" WRUiProgressDialog::WRUiProgressDialog(CWnd* pParent /=NULL/) : CAcUiDialog(WRUiProgressDialog::IDD, pParent) { //{{AFX DATA INIT(WRUiProgressDialog) //}}AFX DATA INIT strTitle = ""; m setCanceled = NULL; } void WRUiProgressDialog::DoDataExchange(CDataExchange* pDX) { CAcUiDialog::DoDataExchange(pDX); //{{AFX DATA MAP(WRUiProgressDialog) DDX Control(pDX, IDC PR TX1, m ctrlTitle); DDX Control(pDX, IDCANCEL, m ctrlCancel); DDX Control(pDX, IDC PR PROGRESS, m ctrlProgress); //}}AFX DATA MAP

} BEGIN MESSAGE MAP(WRUiProgressDialog, CAcUiDialog) //{{AFX MSG MAP(WRUiProgressDialog) ON WM DESTROY() //}}AFX MSG MAP END MESSAGE MAP() void WRUiProgressDialog::GetProgressHWND( bool *bCanceled ) { m setCanceled = bCanceled; } bool WRUiProgressDialog::SetProgressIndicator( double percent ) { if(( percent >= 0 ) && ( percent <= 100 )){ m ctrlProgress.SetPos( (int)percent ); 107. oldal m ctrlProgress.RedrawWindow( NULL, NULL, RDW INTERNALPAINT ); Default(); return false; } else if( percent == -1 ) { DestroyWindow(); return true; } return false; } BOOL WRUiProgressDialog::OnInitDialog() { // Az ablak nevének beállítása, hogy a registyböl elöbányászható legyen SetDialogName("WapRoute:WRUiProgressDialog"); CAcUiDialog::OnInitDialog(); // A cím beállítása if( strTitle.GetLength() != 0 ) m ctrlTitle.SetWindowText( (LPCTSTR)strTitle ); // A progress bar kezdeti értékének beállítása m ctrlProgress.SetRange( 0, 100 ); m ctrlProgress.SetPos( 0 );

return FALSE; } void WRUiProgressDialog::OnDestroy() { if( m setCanceled != NULL ) *m setCanceled = true; CAcUiDialog::OnDestroy(); } void WRUiProgressDialog::OnCancel() { if( m setCanceled != NULL ) *m setCanceled = true; CAcUiDialog::OnCancel(); } 108. oldal IV. Forrás melléklet: WapRoute alkalmazás osztályai WapRoute/Database/Point.java // :WapRoute/Database/Point.java ----------------------------------------STARTpackage WapRouteDatabase; /* Point osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * Egy dupla pontosságú kétdimenziós pontot megvalósító osztály. */ public class Point { // AZ osztály változók double X; double Y; // A pont konstruktora public Point( double X, double Y ) { this.X = X; this.Y = Y; } // Az X koordináta lekérdezése public double getX() { return X; } // Az Y koordináta lekérdezése public double getY() { return Y; } // Az X koordináta beállítása public void setX( double X ) { this.X = X; } //

Az Y koordináta beállítása public void setY( double Y ) { this.Y = Y; } // Az X,Y koordináták együttes beállítása public void set( double X, double Y ) { this.X = X; this.Y = Y; } // Két pont objektumból elkészít egy olyan pont objektumot // amelynek mindkét koordinátája a pontok koordinátái közül // a minimális. static public Point min( Point pt1, Point pt2 ) { return new Point( Math.min(pt1X, pt2X), Mathmin(pt1Y, pt2Y) ); } // Két pont objektumból elkészít egy olyan pont objektumot // amelynek mindkét koordinátája a pontok koordinátái közül // a maximális. static public Point max( Point pt1, Point pt2 ) { return new Point( Math.max(pt1X, pt2X), Mathmax(pt1Y, pt2Y) ); } public String toString() { return "Point-X:"+X+",Y:"+Y; } } // :WapRoute/Database/Point.java ------------------------------------------ENDWapRoute/Database/Nodejava // :WapRoute/Database/Node.java -----------------------------------------START- 109. oldal

package WapRoute.Database; import java.awt*; import java.awtgeom*; import WapRoute.DatabasePoint; /* Node osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * Egy duplapontosságú koordinátarendszerben megadott gráf ábrázolásához * szükséges csomópont objektumot ad meg ez az osztály. Ez a csomópont * annyiban speciális, hogy a névvel vagyis cimkével is rendelkezik. Ezzel * az osztállyal fogja az útvonal adatbázis osztály a nevesített * csomópontokat implementálni. */ public class Node { // Az egyedre jellemző változók long Id; String Name; Point Pt; // Konstruktor public Node( long id, String Name, double X, double Y ) { this.Id = id; this.Name = Name; Pt = new Point( X, Y ); } // Az egyed azonosítóját lekérdező metódus public long getId() { return Id; } // Az egyed szöveges azonosítóját lekérdező metódus public String getName() { return Name; } // Az egyed grafikus koordinátáit lekérdező metódusok public

Point getPoint() { return Pt; } public double getX() { return Pt.X; } public double getY() { return Pt.Y; } // Két egyed összehasonlítását (nem névszerinti lexikális // rendezéshez) elvégző metódusok static public int compare( Node n1, Node n2 ) { if( n1.Id < n2.Id ) return -1; if( n1.Id > n2.Id ) return 1; if( n1.NamecompareTo(n2Name) < 0 ) return -1; if( n1.NamecompareTo(n2Name) > 0 ) return 1; if( n1.PtX < n2PtX ) return -1; if( n1.PtX > n2PtX ) return 1; if( n1.PtY < n2PtY ) return -1; if( n1.PtY > n2PtY ) return 1; return 0; } public int compareTo( Node n2 ) { return Node.compare( this, n2 ); } /* A csomópontot grafikusan megjelenítő metódusok. * A paraméterben megadott grafikus objektumra kirajzolják a * csompópontot reprezentáló telített kört vagy a csomópont * szövegét. A csomópont megjelenítéséhez szükség van a csomópontot * reprezentáló kör átmérőjére. 110. oldal * @param Graphics2D A kirajzoló obejktumot

adja meg. * @param double A csomópont méretét adja meg a dupla pontosságú * koordináta rendszerben. */ public void paint( Graphics2D g2, double drawRadius ) { g2.fillOval( (int)(PtX-drawRadius/20), (int)(Pt.Y-drawRadius/20), (int)drawRadius, (int)drawRadius ); } public void paintText( Graphics2D g2, double drawRadius ) { Font fontBase = new Font("Times New Roman", 0, 6); FontMetrics fontBaseMetrics = g2.getFontMetrics( fontBase ); double fWidth = (double)fontBaseMetrics.stringWidth( thisName ); AffineTransform atrOrdinata = new AffineTransform(); atrOrdinata.setToScale( 10, -10 ); atrOrdinata.translate( -(int)(fWidth/20), -(int)((drawRadius/20)+1) ); Font fontOrdinata = fontBase.deriveFont(atrOrdinata); g2.setFont( fontOrdinata ); g2.drawString( thisName, (int)PtX, (int)PtY ); } /* Láthatóság ellenőrzése. * Ez a metódus azt dönti el hogy egy adott nézetben a csomópont objektum * látható-e? A nézet megadásához a nézet bal alsó és jobb felső *

koordinátáira van szükség. Azt hogy az objektum látható-e úgy dönti el * a metódus, hogy a csomópont koordinátáit összeveti a megadtott * területtel. Ha a pont a területen belül van akkor látható különben nem * Azaz ez a metódus az obejktum feliratát nem tekinti az objektum részének * így előfordulhat, hogy az objektumnek láható a feliratából valami, de * ez a metódus mégis hamis eredményt ad. */ public boolean isVisibleFrom( Point ll, Point ur ) { return ( (Math.min(llX,urX) <= thisPtX) && (Math.max(llX,urX) >= thisPtX) && (Math.min(llY,urY) <= thisPtY) && (Math.max(llY,urY) >= thisPtY) ); } } // :WapRoute/Database/Node.java -------------------------------------------END- WapRoute/Database/Trace.java /* * * * @@ @@ @@ @@ @@ @@@@@@ * * @@ @@@@ @@ @@@ @@ @@ * * @@ @@ @@ @@ @@ @@ @@ * * @@ @@@ @@ @@@@@@ @@@@@@ Dovák István * * @@@ @@@ @@ @@ @@ Szakdolgozat 2000 * * @@ @@ @@ @@ @@ * * * */ package WapRoute.Database;

import import import import WapRoute.DatabasePoint; java.util*; java.awt*; java.awtgeom*; public class Trace { final static boolean TWO WAY = true; final static boolean ONE WAY = false; long Id; String Name; boolean Direction; private ArrayList Segs; private double length; public Trace( long Id, String Name, boolean Direction ) { this.Id = Id; this.Name = Name; this.Direction = Direction; this.Segs = new ArrayList(0); this.length = -10; } 111. oldal public Trace( long Id, String Name, boolean Direction, Point[] Segs ) { this( Id, Name, Direction ); Collection c = Arrays.asList( Segs ); this.Segs = new ArrayList( c ); } public void addVertex( Point pt ) { Segs.add( pt ); length = -1.0; } public void addVertex( double x, double y ) { Point pt = new Point( x, y ); addVertex( pt ); } public long getId() { return Id; } public String getName() { return Name; } public boolean getDirection() { return Direction; } public Point getPointAt( int index ) { return (Point)Segs.get(index); }

public Point getEndPoint() { if( Segs.size() > 0 ) return (Point)Segs.get(Segssize()-1); else return null; } public Point getStartPoint() { if( Segs.size() > 0 ) return (Point)Segs.get(0); else return null; } public double getXAt( int index ) { return getPointAt(index).X; } public double getYAt( int index ) { return getPointAt(index).Y; } public int getLength() { return Segs.size(); } public double getSegsLength() { double retVal = 0.0; if( length != -1.0 ) return length; for( int i=1; i<Segs.size(); i++ ){ retVal += Math.sqrt( Math.pow( (getXAt(i)-getXAt(i-1)), 2 )+ Math.pow( (getYAt(i)-getYAt(i-1)), 2 )); } length = retVal; 112. oldal return retVal; } public Point getLowerLeft() { Point retVal = getPointAt(0); for( int i=1; i<Segs.size(); i++ ){ retVal = Point.min( retVal, getPointAt(1) ); } return retVal; } public Point getUpperRight() { Point retVal = getPointAt(0); for( int i=1; i<Segs.size(); i++ ){ retVal = Point.max( retVal, getPointAt(1) ); } return retVal;

} public void paint( Graphics2D g2 ) { for( int i=1; i<Segs.size(); i++ ){ // A szegmens kirajzolása g2.drawLine( (int)getXAt(i-1), (int)getYAt(i-1), (int)getXAt(i), (int)getYAt(i) ); } } /* public void paintText( Graphics2D g2 ) { Font fontBase = new Font("Times New Roman", 0, 6); FontMetrics fontBaseMetrics = g2.getFontMetrics( fontBase ); double fWidth = (double)fontBaseMetrics.stringWidth( thisName ); double fHeight = (double)fontBaseMetrics.getHeight( thisName ); for( int i=1; i<Segs.size(); i++ ){ // A felirat kiirása double centerX = (getXAt(i-1)+getXAt(i))/2.0; double centerY = (getYAt(i-1)+getYAt(i))/2.0; AffineTransform atrOrdinata = new AffineTransform(); atrOrdinata.setToScale( 10, -10 ); atrOrdinata.translate( -(int)(fWidth/20), -(int)((drawRadius/20)+1) ); Font fontOrdinata = fontBase.deriveFont(atrOrdinata); g2.setFont( fontOrdinata ); g2.drawString( thisName, (int)centerX, (int)centerY ); } }*/ public boolean isVisibleFrom( Point LL, Point UR ) {

boolean retVal = false; Point ll = new Point( Math.min(LLX,URX), Mathmin(LLY,URY) Point lr = new Point( Math.max(LLX,URX), Mathmin(LLY,URY) Point ur = new Point( Math.max(LLX,URX), Mathmax(LLY,URY) Point ul = new Point( Math.min(LLX,URX), Mathmax(LLY,URY) for( int i=1; i<Segs.size() && !retVal; i++ ) { // A láthatóság eldőntéséhez néhány rövidítést // kell bevezetnem. Point sp = new Point(getXAt(i-1), getYAt(i-1)); Point ep = new Point(getXAt(i), getYAt(i)); ); ); ); ); // Ha a kezdő vagy a végpont benne van a // téglalapban akkor kész vagyunk. retVal = ( (ll.X <= spX) && (ur.X >= spX) && (ll.Y <= spY) && (ur.Y >= spY) ) || ( (ll.X <= epX) && (ur.X >= epX) && (ll.Y <= epY) && (ur.Y >= epY) ); if( retVal ) continue; // Ha az sp-ep egyenes függöleges akkor csak a // vizszintes oldalát metszheti a téglalapnak. if( sp.X == epX ) { retVal = ( ((ll.X <= spX) && (urX >= spX))

&& !( Math.max(spY,epY)<llY || Mathmin(spY,epY)>urY ) ); continue; } // Ha az sp-ep egyenes vizszintes akkor csak a // függöleges oldalát metszheti a téglalapnak. 113. oldal if( sp.Y == epY ) { retVal = ( ((ll.Y <= spY) && (urY >= spY)) && !( Math.max(spX,epX)<llX || Mathmin(spX,epX)>urX ) ); continue; } // Ha a sp-ep által meghatározott egyenes keresztez |-4-| // leaglább egy oldalt akkor látható a téglalapból. 1 2 // (mivel sp-ep nem függöleges sp.X-epX soha nem nulla) |-3-| Point m1 = new Point( ll.X, ((epY-spY)/(epX-spX))*(ll.X-spX)+spY Point m2 = new Point( ur.X, ((epY-spY)/(epX-spX))*(ur.X-spX)+spY Point m3 = new Point( ((ep.X-spX)/(epY-spY))*(ll.Y-spY)+spX, llY Point m4 = new Point( ((ep.X-spX)/(epY-spY))*(ur.Y-spY)+spX, urY ); ); ); ); // Azt kell eldönteni, hogy a metszés pontok a // téglalap oldalain helyezkednek-e el. retVal = ((m1.Y == llY) || (m2Y == urY) || (m3X == llX) || (m4X == urX)); } return retVal; } }

WapRoute/Database/Path.java // :WapRoute/Database/Path.java -----------------------------------------STARTpackage WapRouteDatabase; import java.util*; import WapRoute.DatabasePoint; import WapRoute.DatabaseNode; import WapRoute.DatabaseTrace; /* Path osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * Egy útvonal reprezentációját megvalósító osztály. Az osztály path * változójába csomópontokat és útakat lehet rakni. Az osztály által * ellenörzötten. Azaz az új elemet nem lehet hozzáadni a halmazhoz * ha az nincs kapcsolatban az előzö elemmel. Azaz az útvonalnak * összefüggönek kell maradnia és nem lehet benne kör. */ public class Path { // Az osztály változó private ArrayList path; private double length; private Point lastPoint; // Az utvonal konstruktora public Path() { path = new ArrayList(0); length = 0.0; lastPoint = null; } public Path( Path pt ) { this.path = new ArrayList( ptpath ); this.lastPoint =

ptgetLastPoint(); this.length = ptlength; } public Path( Node nd ) { path = new ArrayList(0); length = 0.0; lastPoint = null; add( nd ); } public Point getLastPoint() { return lastPoint; } // Az utvonal bővítése egy objektummal private boolean add( Object ob ) { boolean retVal = true; // Az utolsó pont megkeresése if( lastPoint == null && (path.size() != 0) ) { // Ha csomópontot kell hozzáadni akkor biztosan annak a pontja lesz az utolsó pont if( ob instanceof Node ) lastPoint = ((Node)ob).getPoint(); 114. oldal // Ha egyirányú útvonalat adok hozzá akkor biztosan annak a végpontja lesz az utolsó pont // Ha kétirányút és csak egy útvonal van benne akkor is annak az utolsó pontját tekintem // az utolsó pontnak. if( ob instanceof Trace ) lastPoint = ((Trace)ob).getEndPoint(); // Ha kétirányú utvonalat adok hozzá akkor visszafelel meg kell keresni az elözö elemet // és a két elem pontjaiböl kell kisakkozni a helyzetet. if( ob instanceof Trace

&& ((Trace)ob).Direction == TraceTWO WAY && (pathsize()>=2) ) { Object lastButOneObj = path.get( pathsize()-2 ); Point ptStTr = ((Trace)ob).getStartPoint(); Point ptEnTr = ((Trace)ob).getEndPoint(); if( lastButOneObj instanceof Node ) { Point ptNd = ((Node)lastButOneObj).getPoint(); if(( ptNd.X == ptStTrX ) && ( ptNdY == ptStTrY )) lastPoint = ptEnTr; else lastPoint = ptStTr; } else if( lastButOneObj instanceof Trace ) { Point ptTr1 = ((Trace)lastButOneObj).getStartPoint(); Point ptTr2 = ((Trace)lastButOneObj).getEndPoint(); if(( ptTr1.X == ptStTrX && ptTr1Y == ptStTrY ) || ( ptTr2X == ptStTrX && ptTr2Y == ptStTr.Y )) lastPoint = ptEnTr; else lastPoint = ptStTr; } } // Ha még mindig null a lastPoint akkor valami nagy gáz van if( lastPoint == null ) System.outprint("Not implemented"); } // Ha már benne van az útvonalban akkor nem adom hozzá if( retVal && (path.size() > 0) && pathindexOf(ob) != -1 ) retVal =

false; // Ellenőrzöm hogy összefüggö legyen az útvonal if( retVal && path.size() > 0 ) { Point endPoint = null; Point startPoint = null; if( ob instanceof Node ) startPoint = endPoint = ((Node)ob).getPoint(); if( ob instanceof Trace ) startPoint = ((Trace)ob).getStartPoint(); if( ob instanceof Trace ) endPoint = ((Trace)ob).getEndPoint(); if( startPoint==null || endPoint==null || lastPoint==null ) { if( ( ( startPoint.X!=lastPointX || startPointY!=lastPointY ) && ( endPointX!=lastPointX || endPoint.Y!=lastPointY ) ) ) retVal = false; } } // Ha jó az elem akkor hozzáadom a listához és a hossz // változót is karban tartom. if( retVal ) { // A végpont változót is updatélnem kell Point endPoint = null; Point startPoint = null; if( ob instanceof Node ) startPoint = endPoint = ((Node)ob).getPoint(); if( ob instanceof Trace ) startPoint = ((Trace)ob).getStartPoint(); if( ob instanceof Trace ) endPoint = ((Trace)ob).getEndPoint(); if( endPoint == null ||

startPoint == null || lastPoint == null || (endPoint.X==lastPointX && endPoint.Y==lastPointY) ) lastPoint = startPoint; else lastPoint = endPoint; // Ha útat adok hozzá akkor növelni kell az útvonal hosszát is if( ob instanceof Trace ) length += ((Trace)ob).getSegsLength(); path.add( ob ); } return retVal; } // Az ábrázolt útvonal hossza public double getLength() { return this.length; } // Az utvonal bővítése egy csomóponttal 115. oldal public boolean add( Node nd ) { return this.add( (Object)nd ); } // Az utvonal bővítése egy út szegmenssel public boolean add( Trace tr ) { return this.add( (Object)tr ); } // Az útvonal lekérdezése elemenként public Iterator iterator() { return path.listIterator(); } // Stringgé alakítása public String toString() { String retVal = ""; for( int i=0; i<path.size(); i++ ) { Object ob = path.get(i); retVal += ((retVal=="")?"":","); if( ob instanceof Node ) retVal +=

((Node)ob).getName()/*+"("+((Node)ob).getId()+")"*/; if( ob instanceof Trace ) retVal += ((Trace)ob).getName()/*+"("+((Trace)ob).getId()+")"*/; } return "Path-p:"+retVal+/*"-lp:"+lastPoint+/"-l:"+(int)length; } } // :WapRoute/Database/Path.java -------------------------------------------END- WapRoute/Database/PathDatabase.java /* * * * @@ @@ @@ @@ @@ @@@@@@ útvonal adatbázist megva- * * @@ @@@@ @@ @@@ @@ @@ lósító osztaly. * * @@ @@ @@ @@ @@ @@ @@ * * @@ @@@ @@ @@@@@@ @@@@@@ Dovák István * * @@@ @@@ @@ @@ @@ Szakdolgozat 2000 * * @@ @@ @@ @@ @@ * * * */ // ------- PACKAGE -----------------------------------------------------package WapRoute.Database; // ------- IMPORTED PACKAGES -------------------------------------------import import import import import import import import WapRoute.Database*; java.io*; java.util*; java.awt*; java.awtevent*; java.awtimage*; java.awtcolor*; java.awtgeom*; // -------

IMPLEMENTATION ----------------------------------------------public class PathDatabase { // A felhasználói interfészt is befolyásoló konstansok. final long NumberOfMaxLinksOnACard = 16; // Minden elemet tartalmazó név szerint rendezett lista, ebből történik a rajzolás private ArrayList Entities = new ArrayList(0); // Az objektumok tulajdonságainak lekérdezését gyorsító tagok. private HashMap NodeIDToObject = new HashMap(0); private HashMap TraceIDToObject = new HashMap(0); // A keresési müvelet gyorsításához használt objektumok // A nevek részhalmazainak képzése már a konstruktorban megtörténik // igy nem kell külön idöt tölteni a névhalmaz "NumberOfMaxLinksOnACard" // darabos egységekre bontásával private SortedMap NodePileNames = new TreeMap(); private SortedMap TracePileNames = new TreeMap(); private ArrayList NodePileIds = new ArrayList(0); private ArrayList TracePileIds = new ArrayList(0); // Statisztikai információk tárolására

szolgáló változók public final long readObjects; 116. oldal public public public public final final final final long long long long readErrors; readLines; readWords; readChars; // Az adatbázis maximális méreteinek tárolására használt változók private Point LowerLeft = null; private Point UpperRight = null; final Comparator lexicalOrder = new Comparator() { public int compare( Object o1, Object o2 ) { String s1 = ""; String s2 = ""; String nodeClass = (new Node(0, "", 0, 0)).getClass()toString(); String traceClass =(new Trace(0, "", true)).getClass()toString(); if( o1.getClass()toString()equals( nodeClass ) ) s1 = ((Node)o1).Name; if( o2.getClass()toString()equals( nodeClass ) ) s2 = ((Node)o2).Name; if( o1.getClass()toString()equals( traceClass ) ) s1 = ((Trace)o1).Name; if( o2.getClass()toString()equals( traceClass ) ) s2 = ((Trace)o2).Name; return s1.compareTo(s2); } }; final Comparator lexicalOrderNodeName = new

Comparator() { public int compare( Object o1, Object o2 ) { Node nd1 = (Node)NodeIDToObject.get( (Long)o1 ); Node nd2 = (Node)NodeIDToObject.get( (Long)o2 ); return nd1.NamecompareTo(nd2Name); } }; final Comparator lexicalOrderTraceName = new Comparator() { public int compare( Object o1, Object o2 ) { Trace tr1 = (Trace)TraceIDToObject.get( (Long)o1 ); Trace tr2 = (Trace)TraceIDToObject.get( (Long)o2 ); return tr1.NamecompareTo(tr2Name); } }; public PathDatabase( String DatabaseFile ) throws FileNotFoundException { // Az final final final final final final final útvonal adatbázisban használt konstansok definiciója. int ASN CONFIG = 0; int ASN NODE = 1; int ASN TRACE = 2; int ASN POINT = 3; int ASN TRACE ONEWAY = 1; int ASN TRACE TWOWAY = 0; long startId = 1000; // Az adatbázis olvasót csak itt használom nem akarom, hogy // bárki használhassa ezt a kódrészletet ezért beágyazott osztály. // Ez az osztály feldolgozza a bejövö állományt és ASN1 furmátumúvá //

alakítja. Azaz kommenteket kihagyja új sor karaktereket ,-vel // helyettesíti. Azaz ez megfelel egy ASN1 olvasónak class DatabaseReader { final FileReader inf; private String currentWord; private char currentChar; private boolean eof; // Statisztikai információk long readLines; long readWords; long readChars; //-----------------------------------------------Publikus metódusok // Konstruktor az olvasando állomány nevével. // A privát változók kezdeti értékadása. public DatabaseReader( String DatabaseFile ) throws FileNotFoundException { 117. oldal inf = new FileReader(DatabaseFile); currentWord = ""; readLines = 0; readWords = 0; eof = false; } // Az állományban megkeresi a következö karaktert ami érvényes // az ASN szabvány szerint. Azaz white space karaktereket kihagyja // újsor karaktert ,-vel helyettesíti a komment után levő karaktereket // átolvassa és az újsor karaktert ,-vel helyettesíti ha van ilyen. // Ha az állomány végére ér

akkor egy kivátelt dob. public char readNextValidChar() throws IOException { int icharus = inf.read(); readChars++; // Szokoz karakterek atolvasasa while(( " ".indexOf((char)icharus) != -1 ) && (icharus != -1)){ icharus = inf.read(); readChars++; } // Komment atolvasasa if( (char)icharus == # ) { while(( (char)icharus != ) && (icharus != -1)) { icharus = inf.read(); readChars++; } } // ENTER helyettesítése if( (char)icharus == ) { currentChar = ,; readLines++; } else { currentChar = (char)icharus; } // Állomány vége esetén IOException dobása if( icharus == -1 ) { readChars--; throw new IOException(); } return currentChar; } // Az állományban a vesszökkel határolt szavakat olvassa be a // currentWord változóba. A vesszök nem külön egységek ezek nem // kerülnek bele a visszaadott szóba. A szót úgy képezi hogy // A karakter olvasó által meg szürt és érvényes karaktereket // összekonkatenálja. public String readNextValidWord()

throws IOException { // Az első karakter olvasásakor keletkező IOExceptiont // továbbítja kifelé mert ez az állomány végét jelezi. currentWord = ""; try { currentWord += readNextValidChar(); } catch (IOException e) { eof = true; throw e; } try { while( readNextValidChar() != , ) currentWord += currentChar; } catch( IOException e ) { // Ekkor elérkezett az állomány vége de a bufferelt // szót még vissza kell adni. A következö híváskor // úgyis IOException lesz de már az első karakternél. } readWords++; return currentWord; } // A currentWord privát változót lekérdezó metódus, ha már // elértük az állomány végét akkor ez is IOExceptiont dob. public String getCurrentWord() throws IOException { if( eof ) throw new IOException(); return currentWord; } // Az aktuális szó OKTET SRING-ként értelmezve. public int getCurrentWordAsInteger() throws IOException,NumberFormatException { return wordAsInteger(getCurrentWord()); } // Az aktuális szó

INTEGER-ként értelmezve. public Double getCurrentWordAsFloat() throws IOException,NumberFormatException { return wordAsFloat(getCurrentWord()); } 118. oldal // Az aktuális szó FLOAT-ként értelmezve. public String getCurrentWordAsOctetString() throws IOException,NumberFormatException { return wordAsOctetString(getCurrentWord()); } // Annak ellenörzése hogy az állomány végére értünk-e. public boolean eof() { return eof; } // Egy szó értelmezése OKTET STRING-ként. public String wordAsOctetString( String word ) throws NumberFormatException { String myWord = word; String decodedWord = ""; String currentWord = ""; // A szó páros számú karaktert kell hogy tartalmazzon. if( myWord.length() % 2 != 0 ) throw new NumberFormatException(); myWord = myWord.toUpperCase(); // A szóban csak 0-9A-Fa-fkarakterek szerepelhetnek ha igy // van akkor exception, küönben dekódolás ASCII szerint. for( int i=0; i<myWord.length(); i++ ) { char currentChar =

myWord.charAt(i); if( i%2 == 0 ) currentWord = ""+currentChar; else { currentWord += currentChar; byte[] value = { (byte)Integer.parseInt( currentWord, 16 ) }; decodedWord += new String( value ); } } return decodedWord; } // Egy szó értelmezése INTEGER-ként. public int wordAsInteger( String word ) throws NumberFormatException { return Integer.parseInt(word); } // Egy szó értelmezése FLOAT-ként. public Double wordAsFloat( String word ) throws NumberFormatException { return new Double(word); } } // END OF DatabaseReader class // A konstrukció elkészítése, az állomány megnyitása. Ha // nem megnyitható akkor kivétel dobása a példányosítónak. long myReadObjects = 0; long myReadErrors = 0; DatabaseReader dr = new DatabaseReader(DatabaseFile); // Az állomány olvasása szavanként szemantikai értelmezése // és az Utvonal adatbázis struktúráinak létrehozása. try { dr.readNextValidWord(); } catch( IOException e ) {} while( !dr.eof() ) { try { int iType =

-1; iType = dr.getCurrentWordAsInteger(); /*try { System.outprint(" CurrentWord: "+drgetCurrentWord()+" Type: "+iType); } catch( IOException e) { System.outprint(" IOException"); }*/ switch( iType ) { case ASN CONFIG: try { String Scale = dr.readNextValidWord(); // Méretarány olvasása myReadObjects++; } catch (IOException e) { myReadErrors++; } // Előre olvasás: Ha előre olvasás közben van // állomány vége az nem hiba try { dr.readNextValidWord(); } catch( IOException e ) {} break; case ASN NODE: try { String Name = dr.readNextValidWord(); // Név olvasása String X = dr.readNextValidWord(); // X koordináta String Y = dr.readNextValidWord(); // Y koordináta myReadObjects++; long newNodeId = startId+myReadObjects; 119. oldal try { String strName = dr.wordAsOctetString(Name); double dX = dr.wordAsFloat(X)doubleValue(); double dY = dr.wordAsFloat(Y)doubleValue(); Node ndEntity = new Node( newNodeId, strName, dX, dY ); LowerLeft = ((LowerLeft

== null) ? new Point(dX, dY) : Point.min(LowerLeft, new Point(dX, dY))); UpperRight = ((UpperRight == null) ? new Point(dX, dY) : Point.max(UpperRight, new Point(dX, dY))); Entities.add( ndEntity ); NodeIDToObject.put( new Long(newNodeId), ndEntity ); } catch (NumberFormatException e) { myReadErrors++; } } catch (IOException e) { myReadErrors++; } // Előre olvasás: Ha előre olvasás közben van // állomány vége az nem hiba try { dr.readNextValidWord(); } catch( IOException e ) {} break; case ASN TRACE: try { String Name = dr.readNextValidWord(); // Név olvasása String UtType = dr.readNextValidWord(); // Ut irányítottságának olvasása myReadObjects++; long newTraceId = startId+myReadObjects; ArrayList pts = new ArrayList(0); // Pontok beolvasása: legalább két pontnak kell követnie egy ut fejet try { dr.readNextValidWord(); iType = dr.getCurrentWordAsInteger(); while( !dr.eof() && iType == ASN POINT ){ try { String X = dr.readNextValidWord(); // X koordináta

String Y = dr.readNextValidWord(); // Y koordináta try { Point pt = new Point( dr.wordAsFloat(X)doubleValue(), dr.wordAsFloat(Y)doubleValue() ); pts.add( pt ); } catch (NumberFormatException e) { myReadErrors++; } } catch (IOException e) { myReadErrors++; } // Előre olvasásnál nem számít az IOException mert az EOFot jelent. try { dr.readNextValidWord(); iType = dr.getCurrentWordAsInteger(); } catch(IOException e) {}; } } catch ( IOException e ) { myReadErrors++; } catch ( NumberFormatException e ) { myReadErrors++; } // Ha a pontok beolvasása után elég szegmens gyült össze (legalább // 2) akkor az utat hozzá lehet adni az elem adatbázishoz. if( pts.size() >= 2 ){ try { String strName = dr.wordAsOctetString(Name); boolean bUtType = (dr.wordAsInteger(UtType) == ASN TRACE TWOWAY); Trace trEntity = new Trace( newTraceId, strName, bUtType ); Iterator it = pts.iterator(); while( it.hasNext() ){ Point pt = (Point)it.next(); trEntity.addVertex( pt ); } LowerLeft = ((LowerLeft

== null) ? trEntity.getLowerLeft() : Point.min(LowerLeft, trEntitygetLowerLeft())); UpperRight = ((UpperRight == null) ? trEntity.getUpperRight() : Point.max(UpperRight, trEntitygetUpperRight())); Entities.add( trEntity ); TraceIDToObject.put( new Long(newTraceId), trEntity ); } catch ( NumberFormatException e ){} } } catch (IOException e) { // Elöreolvasás kell, ha a név vagy irányítottság // olvasása közben történt hiba. try { dr.readNextValidWord(); } catch( IOException e2 ) {} myReadErrors++; } break; // Ha nem megengedett tipust olvasok akkor hiba az adatbázisban. default: // Előre olvasás try { dr.readNextValidWord(); } catch( IOException e ) {} myReadErrors++; break; 120. oldal } } catch (Exception e) { System.outprint( " WAPROUTE unexpected exception: "+e ); // Előre olvasás try { dr.readNextValidWord(); } catch( IOException e2 ) {} myReadErrors++; } } // Ha az elem adatbázis üres akkor valami nagyon rossz történhetett // kivételt küldök a

hívonak, hogy tudjon róla. if( Entities.size() == 0 ) { throw new FileNotFoundException(); } // Az elemek névsorszerinti rendezése, hogy később ne ezzel // teljen az id. A TraceIDToObject és NodeIDToObject névsorszerint // van a természetes rendezés miatt. Collections.sort( Entities, lexicalOrder ); // Az entitásokon végigmenve mindig megjegyzem az első és az utolsó elemét // az adott tipusnak, és ha a számláló nagyon megnő akkor a megfelelő // Pilébe beszúrok egy elemet. Az azonos nevű elemeket minden képpen egy Pilébe // kell rakni! long lengthOfCurrentNodePile = 0; long lengthOfCurrentTracePile = 0; String startNameOfCurrentNodePile = ""; String startNameOfCurrentTracePile = ""; String endNameOfCurrentNodePile = ""; String endNameOfCurrentTracePile = ""; Iterator it = Entities.iterator(); ArrayList currentNodePile = null; ArrayList currentTracePile = null; Set includedTraceNames = new TreeSet(); while( it.hasNext() )

{ Object ob = it.next(); if( ob.getClass()toString()equals( (new Node(0, "", 0, 0))getClass()toString()) ) { Node nd = (Node)ob; if( lengthOfCurrentNodePile == 0 ) { startNameOfCurrentNodePile = nd.Name; endNameOfCurrentNodePile = nd.Name; currentNodePile = new ArrayList(0); currentNodePile.add( new Long(ndId) ); lengthOfCurrentNodePile++; } else if(( lengthOfCurrentNodePile >= NumberOfMaxLinksOnACard ) && !endNameOfCurrentNodePile.equals(ndName) ){ /*System.outprint( " Node - Start: "+startNameOfCurrentNodePile+" End: "+endNameOfCurrentNodePile+" " );*/ NodePileNames.put( startNameOfCurrentNodePile, endNameOfCurrentNodePile ); NodePileIds.add(currentNodePile); startNameOfCurrentNodePile = ""; endNameOfCurrentNodePile = ""; lengthOfCurrentNodePile = 0; currentNodePile = null; } else { endNameOfCurrentNodePile = nd.Name; currentNodePile.add( new Long(ndId) ); lengthOfCurrentNodePile++; } } if(

ob.getClass()toString()equals( (new Trace( 0, "", true ))getClass()toString()) ) { Trace tr = (Trace)ob; if( !includedTraceNames.contains(trName) ){ // Az utvonal neveket csak egyszer kell felvenni a // halmokba mert azoknak a nevei csak egyediek lehetnek // itt egy út több szegmensből állhat, de azok összefüggöek // és tulajdonképpen egy objektumot reprezentálnak. includedTraceNames.add(trName); if( lengthOfCurrentTracePile == 0 ) { startNameOfCurrentTracePile = tr.Name; endNameOfCurrentTracePile = tr.Name; currentTracePile = new ArrayList(0); currentTracePile.add( new Long(trId) ); lengthOfCurrentTracePile++; } else if(( lengthOfCurrentTracePile >= NumberOfMaxLinksOnACard ) && !endNameOfCurrentTracePile.equals(trName) ){ TracePileNames.put( startNameOfCurrentTracePile, endNameOfCurrentTracePile ); TracePileIds.add(currentTracePile); /*System.outprint( " Trace - Start: "+startNameOfCurrentTracePile+" End:

"+endNameOfCurrentTracePile+" " );*/ startNameOfCurrentTracePile = ""; endNameOfCurrentTracePile = ""; lengthOfCurrentTracePile = 0; currentTracePile = null; } else { 121. oldal endNameOfCurrentTracePile = tr.Name; currentTracePile.add( new Long(trId) ); lengthOfCurrentTracePile++; } } } } if( lengthOfCurrentNodePile != 0 ){ /*System.outprint( " Node - Start: "+startNameOfCurrentNodePile+" End: "+endNameOfCurrentNodePile+" " );*/ NodePileNames.put( startNameOfCurrentNodePile, endNameOfCurrentNodePile ); NodePileIds.add(currentNodePile); lengthOfCurrentNodePile = 0; } if( lengthOfCurrentTracePile != 0 ){ TracePileNames.put( startNameOfCurrentTracePile, endNameOfCurrentTracePile ); TracePileIds.add(currentTracePile); /*System.outprint( " Trace - Start: "+startNameOfCurrentTracePile+" End: "+endNameOfCurrentTracePile+" " );*/ lengthOfCurrentTracePile = 0; } // A négyzet alakú teljesnézet

kiszámítása double dCenterX = Math.ceil((LowerLeftX+UpperRightX)/20); double dCenterY = Math.ceil((LowerLeftY+UpperRightY)/20); double dWidth = Math.abs(LowerLeftX-UpperRightX); double dHeight = Math.abs(LowerLeftY-UpperRightY); dHeight = dWidth = Math.ceil(Mathmax( dWidth, dHeight )); LowerLeft = new Point( dCenterX-dWidth/2.0, dCenterY-dHeight/20 ); UpperRight = new Point( dCenterX+dWidth/2.0, dCenterY+dHeight/20 ); // Publikus konstansok értékadása readObjects = myReadObjects; readErrors = myReadErrors; readLines = dr.readLines; readWords = dr.readWords; readChars = dr.readChars; } // Az elem adatbázisra vonatkozó lekérdezések megvalósítása. // Szöveges információk lekérdezése public SortedMap getListOfNodeNames( int pile ) { /*System.outprint(" Helloka belloka: "+NodePileIdssize()+" ");*/ if( pile == -1 ){ return NodePileNames; } else if( NodePileIds.size() > pile ) { SortedMap retVal = new TreeMap(lexicalOrderNodeName); ArrayList am =

(ArrayList)NodePileIds.get(pile); Iterator it = am.iterator(); while( it.hasNext() ) { Long Id = (Long)it.next(); Node nd = (Node)NodeIDToObject.get( Id ); /*System.outprint(" - "+Id+" ");*/ if( nd != null ) retVal.put( Id, ndName ); else retVal.put( Id, "???" ); } return retVal; } else { return null; } } public SortedMap getListOfNodeNames( String substr ) { SortedMap retVal = new TreeMap(lexicalOrderNodeName); Iterator it = NodeIDToObject.keySet()iterator(); while( it.hasNext() ) { Long Id = (Long)it.next(); Node nd = (Node)NodeIDToObject.get( Id ); if( nd != null ){ if( nd.NametoUpperCase()indexOf(substrtoUpperCase()) != -1 ){ retVal.put( Id, ndName ); } } } return retVal; } public SortedMap getListOfTraceNames( int pile ) { if( pile == -1 ){ return TracePileNames; } else if( TracePileIds.size() > pile ) { SortedMap retVal = new TreeMap(lexicalOrderTraceName); ArrayList am = (ArrayList)TracePileIds.get(pile); 122. oldal Iterator it =

am.iterator(); while( it.hasNext() ) { Long Id = (Long)it.next(); Trace tr = (Trace)TraceIDToObject.get( Id ); if( tr != null ) retVal.put( Id, trName ); else retVal.put( Id, "???" ); } return retVal; } else { return null; } } public SortedMap getListOfTraceNames( String substr ) { SortedMap retVal = new TreeMap(lexicalOrderTraceName); ArrayList am = new ArrayList(0); Iterator it = TraceIDToObject.keySet()iterator(); while( it.hasNext() ) { Long Id = (Long)it.next(); Trace tr = (Trace)TraceIDToObject.get( Id ); if( tr != null ){ if( am.indexOf(trName) == -1 ){ if( tr.NametoUpperCase()indexOf(substrtoUpperCase()) != -1 ){ retVal.put( Id, trName ); am.add( trName ); } } } } return retVal; } public Collection getTraceElementsByName( String Name ){ Collection retVal = new TreeSet(); Iterator it = TraceIDToObject.keySet()iterator(); while( it.hasNext() ) { Long Id = (Long)it.next(); Trace tr = (Trace)TraceIDToObject.get( Id ); if( tr != null ){ if( tr.Nameequals(Name) )

retVal.add( Id ); } } return retVal; } public Node getNodeElement( Long id ) { Object ob = NodeIDToObject.get( id ); /*System.outprint(" "+id+": "+ob+" ");*/ if( ob != null ){ return (Node)ob; } else { return null; } } public Trace getTraceElement( Long id ) { Object ob = TraceIDToObject.get( id ); /*System.outprint(" "+id+": "+ob+" ");*/ if( ob != null ){ return (Trace)ob; } else { return null; } } public ArrayList getElementSet( Collection IdSet ) { ArrayList retVal = new ArrayList(); Iterator it = IdSet.iterator(); while( it.hasNext() ) { Long l = (Long)it.next(); if( getNodeElement(l) != null ) retVal.add( getNodeElement(l) ); if( getTraceElement(l) != null ) retVal.add( getTraceElement(l) ); } return retVal; } public ArrayList getElementSet( Point LowerLeft, Point UpperRight ) { ArrayList retVal = new ArrayList(); Iterator it = Entities.iterator(); 123. oldal while( it.hasNext() ) { Object ob = it.next(); if((ob

instanceof Node) && ((Node)ob).isVisibleFrom(LowerLeft,UpperRight)) { retVal.add( (Node)ob ); } if((ob instanceof Trace) && ((Trace)ob).isVisibleFrom(LowerLeft,UpperRight)) { retVal.add( (Trace)ob ); } } return retVal; } public BufferedImage double llx1, double urx1, { return getImage( } getImage( double lly1, double ury1 ) llx1, lly1, urx1, ury1, 96, 96 /*44/ ); public BufferedImage getImage( double llx1, double lly1, double urx1, double ury1, int imgWidth, int imgHeight ) { // Átmeneti változok létrehozása double llx = Math.min( llx1, urx1 ); double lly = Math.min( lly1, ury1 ); double urx = Math.max( llx1, urx1 ); double ury = Math.max( lly1, ury1 ); double lrx = Math.max( llx1, urx1 ); double lry = Math.min( lly1, ury1 ); double ulx = Math.min( llx1, urx1 ); double uly = Math.max( lly1, ury1 ); double width = Math.abs( lrx-ulx ); double height = Math.abs( lry-uly ); BufferedImage bi = new BufferedImage( imgWidth, imgHeight, BufferedImage.TYPE INT ARGB );

Graphics2D gbi = (Graphics2D)bi.createGraphics(); // A grafikus objektum törlése tulajdonságainak beállítása gbi.setColor( Colorwhite ); gbi.fillRect( 0, 0, imgWidth, imgHeight ); gbi.scale( ((double)imgWidth)/width, -((double)imgHeight)/height ); gbi.translate( -llx, -lly-height ); // Koordináta rendszer rajzolása a könnyebb navigálás // érdekében. (Csak teszjelleggel, de lépték vonalzónak // is használható lenne) Font fontBase = new Font("Times New Roman", Font.BOLD, 12); FontMetrics fontBaseMetrics = gbi.getFontMetrics( fontBase ); double fHeight = (double)fontBaseMetrics.getHeight(); gbi.setColor( Colorblack ); gbi.drawLine( 0,0,1000,0 ); gbi.drawLine( 0,0,0,1000 ); for( int i=0; i<1001; i=i+10 ){ gbi.drawLine( i,3,i,-3 ); gbi.drawLine( 3,i,-3,i ); if(( i % 100 == 0 ) && (i != 0)){ String strDisplay = ""+i; double fWidth = (double)fontBaseMetrics.stringWidth( strDisplay ); // Kicsivel nagyobb rovátka rajzolása gbi.drawLine(

i,7,i,-7 ); gbi.drawLine( 7,i,-7,i ); // Vizszintes // Negatív értékek a vonal alá, pozitívak a vonal fölé kerülnek. AffineTransform atrAbcissza = new AffineTransform(); atrAbcissza.setToScale( 10, -10 ); atrAbcissza.translate( -(int)(fWidth/20), -10 ); Font fontAbcissza = fontBase.deriveFont(atrAbcissza); gbi.setFont( fontAbcissza ); gbi.drawString(strDisplay, i, 0 ); // Függöleges // Negatív értékek a vonal bal oldalára, pozitívak a jobb oldalára kerülnek. AffineTransform atrOrdinata = new AffineTransform(); atrOrdinata.setToScale( 10, -10 ); atrOrdinata.translate( 10, (int)(fHeight/20)-3 ); Font fontOrdinata = fontBase.deriveFont(atrOrdinata); gbi.setFont( fontOrdinata ); gbi.drawString(strDisplay, 0, i ); 124. oldal } } // Az objektum listán iterálva kirajzolom az elemeket // a BufferedImage-re. Amit előbb beállítottam hogy // megfelelően legyenek kirajzolva az elemek. String strTraceClassName = (new Trace( 0, "", true )).getClass()toString();

String strNodeClassName = (new Node(0, "", 0, 0)).getClass()toString(); Iterator it = Entities.iterator(); while( it.hasNext() ) { Object ob = it.next(); if( ob.getClass()toString()equals( strNodeClassName ) ) { gbi.setColor( Colorblack ); Node nd = (Node)ob; nd.paint( gbi, 40 ); } if( ob.getClass()toString()equals( strTraceClassName ) ) { gbi.setColor( Colorblack ); Trace tr = (Trace)ob; tr.paint( gbi ); } } // Az objektum listán iterálva kirajzolom az elemek // feliratait a BufferedImage-re. A szinekkel operálva // a megfelelő kitakarások lesznek megoldhatóak. Iterator it2 = Entities.iterator(); while( it2.hasNext() ) { Object ob = it2.next(); if( ob.getClass()toString()equals( strNodeClassName ) ) { gbi.setColor( Colorblue ); Node nd = (Node)ob; nd.paintText( gbi, 40 ); } if( ob.getClass()toString()equals( strTraceClassName ) ) { gbi.setColor( Colorblue ); Trace tr = (Trace)ob; tr.paintText( gbi ); }*/ } gbi.dispose(); /* return bi; } // Egy WBMP állomány

készítése a paraméterben megadott BufferedImage-ről // az állomány egy temporáris állomány lesz. Ennek törléséről az operációs // rendszerben müködő mechanizmusok gondoskodnak. Ez a hibát kivételek // kiváltásával tudatja a hívóval. Illetve a törlés akkor is megtörténik // ha a virtuális gépet rendesen állították le. public static String writeWBMP( BufferedImage bi ) throws Exception { return writeWBMP( bi, null ); } public static String writeWBMP( BufferedImage bi, String strTempDir ) throws Exception { int Width = bi.getWidth(); int Height = bi.getHeight(); String retVal = null; if(( Width <= 127 ) && ( Height <= 127 ) && ( Width > 0 ) && ( Height > 0 )) { File fp = File.createTempFile("WapRoute-", "wbmp"); fp.deleteOnExit(); if( strTempDir != null ) { try { File fpNew = new File( strTempDir+"/"+fp.getName() ); fpNew.createNewFile(); fpNew.deleteOnExit(); fp = fpNew; } catch

(Exception e) {} } FileOutputStream fos = new FileOutputStream( fp ); int fileLength = (int)Math.ceil((((double)Width*(double)Height)/8.0)+40); byte[] HB = new byte[] { 0, 0, (byte)Width, (byte)Height }; byte[] pixelBuffer = new byte[fileLength]; fos.write( HB ); for( int counter=0; counter<Width*Height; counter++ ) { int pixAt = (int)Math.floor((double)counter/80); int X = (int)(counter%Width); int Y = (int)Math.floor((double)counter/(double)Width); int color = bi.getRGB( X, Y ); boolean bitAt = (color == -1); if( counter % 8 == 0 ) { pixelBuffer[pixAt] = 0; } if( bitAt ) { pixelBuffer[pixAt] = (byte)(pixelBuffer[pixAt] + (byte)Math.pow(2, 7-counter%8)); } 125. oldal } fos.write( pixelBuffer ); fos.close(); retVal = fp.getPath(); } else { throw new Exception("writeWBMP accepts only images smaller then 127x127 pixels"); } return retVal; } public double getLLX() { return LowerLeft.X; } public double getLLY() { return LowerLeft.Y; } public double getURX() { return

UpperRight.X; } public double getURY() { return UpperRight.Y; } public Path getShortestPath( Node ndStart, Node ndEnd ) { final Comparator orderByLength = new Comparator() { public int compare( Object o1, Object o2 ) { double l1 = getTraceElement((Long)o1).getSegsLength(); double l2 = getTraceElement((Long)o2).getSegsLength(); return ((l1<l2)?-1:((l1==l2)?0:1)); } }; HashMap paths = new HashMap(0); ArrayList notusedTraces = new ArrayList(0); Collection c = (Collection)TraceIDToObject.keySet(); notusedTraces.addAll( c ); Collections.sort( notusedTraces, orderByLength ); boolean extended; Point startPoint = ndStart.getPoint(); Point endPoint = ndEnd.getPoint(); // A fa gyökerének hozzáadása a fában levő utakat // tartalmazó végponttal indexelt halmazhoz. extended = true; paths.put( startPointtoString(), new Path( ndStart ) ); //PrintWriter fos = null; //try { //fos = new PrintWriter( new FileOutputStream( new File("D:\xxx.txt") ) ); //} catch( Exception e ){} //

Addig iterálunk amig minden lehetséges út el nem tünik a // listából vagy amig meg nem találjuk a keresett utat. while( notusedTraces.size() != 0 ) { // A még nem használt útak közül ki kell választani azt // a legrövidebbet amelyik csatlakozik a paths változóban // tárolt gráfhoz. (Mivel a notUsedTraces már hossz szerint // rendezve van csak elölről végig kell menni az elemeken) Iterator it = notusedTraces.listIterator(); extended = false; while( it.hasNext() && !extended ) { Long nextId = (Long)it.next(); Trace tr = getTraceElement( nextId ); Point ptS = tr.getStartPoint(); Point ptE = tr.getEndPoint(); // Ha az aktuális vonal olyan, hogy a kezdőpontja benne // van a halmazban, de a végpontja kimutat onnan akkor // megvan a következő elem. extended = (paths.containsKey( ptStoString() ) && !pathscontainsKey( ptEtoString() )); if( extended ) { Path p = (Path)paths.get( ptStoString() ); Path pp = new Path( p ); pp.add( tr ); // A végpontban

szereplő nevesített csomópontok hozzáadása az útvonalhoz 126. oldal Iterator itNodes = ((Collection)NodeIDToObject.keySet())iterator(); while( itNodes.hasNext() ) { Node nd = getNodeElement( (Long)itNodes.next() ); if( nd.getPoint()toString()equals(ptEtoString()) ){ pp.add( nd ); } } paths.put( ptEtoString(), pp ); } else if (tr.Direction == TraceTWO WAY ) { extended = (paths.containsKey( ptEtoString() ) && !pathscontainsKey( ptStoString() )); if( extended ) { Path p = (Path)paths.get( ptEtoString() ); Path pp = new Path( p ); pp.add( tr ); // A végpontban szereplő nevesített csomópontok hozzáadása az útvonalhoz Iterator itNodes = ((Collection)NodeIDToObject.keySet())iterator(); while( itNodes.hasNext() ) { Node nd = getNodeElement( (Long)itNodes.next() ); if( nd.getPoint()toString()equals(ptStoString()) ){ pp.add( nd ); } } paths.put( ptStoString(), pp ); } } // Ha az aktuális vonal egy belső élet határoz meg akkor // lehet hogy egy két útvonalat

lerövidít. A rövídítéseket // ki kell cserélni. if( !extended && paths.containsKey( ptStoString() ) && pathscontainsKey( ptEtoString() ) ) { extended = true; double l1 = ((Path)paths.get(ptStoString()))getLength(); double l2 = ((Path)paths.get(ptEtoString()))getLength(); double l3 = tr.getSegsLength(); //fos.print(" --------------------------------------------------------------------------------------------------"); //fos.print(" l1:"+(int)l1+" l2:"+(int)l2+" l3:"+(int)l3); if( l1+l3 < l2 ) { // Ha az így keletkezett út rövidebb akkor a régi útat le kell cserélni Path p = (Path)paths.get( ptStoString() ); Path pp = new Path( p ); pp.add( tr ); // A végpontban szereplő nevesített csomópontok hozzáadása az útvonalhoz //fos.print(" oldPath: "+(Path)pathsget(ptEtoString())); Iterator itNodes = ((Collection)NodeIDToObject.keySet())iterator(); while( itNodes.hasNext() ) { Node nd = getNodeElement(

(Long)itNodes.next() ); if( nd.getPoint()toString()equals(ptEtoString()) ){ pp.add( nd ); } } paths.remove( ptEtoString() ); paths.put( ptEtoString(), pp ); //fos.print(" newPath: "+pp); //fos.print(" >>>>>>>>>>>>>>>>>>>>>>>>>>"); // Meg kell keresni azokat az utakat emelyeknek az így keletkezett út része // és le kell cserélni azoknak az elejét úgy hogy ezt a rész utat tartalmazza. Iterator itp = ((Collection)paths.keySet())iterator(); while( itp.hasNext() ) { String spid = (String)itp.next(); if( spid.equals(ptEtoString()) ) { continue; } Path sp = (Path)paths.get( spid ); // Meg kell keresni a rész útvonal végét amelynek az elején // az utolsó pont van. Iterator itsp = sp.iterator(); boolean bFound = false; while( itsp.hasNext() && !bFound ) { Object ob = itsp.next(); if(( ob instanceof Trace ) && ( ((Trace)ob).getEndPoint()toString()equals( ptEtoString()

) || ((Trace)ob).getStartPoint()toString()equals( ptEtoString() ) )) { bFound = true; } } // Az útvonal maradék részét hozzá kell adogatni if( bFound ){ Path ppNew = new Path( pp ); while( itsp.hasNext() ){ Object ob = itsp.next(); if( ob instanceof Trace ) ppNew.add( (Trace)ob ); 127. oldal if( ob instanceof Node ) ppNew.add( (Node)ob ); } paths.put( spid, ppNew ); oldPath: "+sp); newPath: "+ppNew); } } } if( l2+l3 < l1 ) { // Ha az így keletkezett út rövidebb akkor a régi útat le kell cserélni Path p = (Path)paths.get( ptEtoString() ); Path pp = new Path( p ); pp.add( tr ); // A végpontban szereplő nevesített csomópontok hozzáadása az útvonalhoz oldPath: "+(Path)paths.get(ptStoString())); Iterator itNodes = ((Collection)NodeIDToObject.keySet())iterator(); while( itNodes.hasNext() ) { Node nd = getNodeElement( (Long)itNodes.next() ); if( nd.getPoint()toString()equals(ptStoString()) ){ pp.add( nd ); } } paths.remove( ptStoString() ); paths.put(

ptStoString(), pp ); newPath: "+pp); >>>>>>>>>>>>>>>>>>>>>>>>>>"); // Meg kell keresni azokat az utakat emelyeknek az így keletkezett út része // és le kell cserélni azoknak az elejét úgy hogy ezt a rész utat tartalmazza. Iterator itp = ((Collection)paths.keySet())iterator(); while( itp.hasNext() ) { String spid = (String)itp.next(); if( spid.equals(ptStoString()) ) { continue; } Path sp = (Path)paths.get( spid ); // Meg kell keresni a rész útvonal végét amelynek az elején // az utolsó pont van. Iterator itsp = sp.iterator(); boolean bFound = false; while( itsp.hasNext() && !bFound ) { Object ob = itsp.next(); if(( ob instanceof Trace ) && ( ((Trace)ob).getEndPoint()toString()equals( ptStoString() ) || ((Trace)ob).getStartPoint()toString()equals( ptStoString() ) )) { bFound = true; } } // Az útvonal maradék részét hozzá kell adogatni if( bFound ){ Path ppNew = new

Path( pp ); while( itsp.hasNext() ){ Object ob = itsp.next(); if( ob instanceof Trace ) ppNew.add( (Trace)ob ); if( ob instanceof Node ) ppNew.add( (Node)ob ); } paths.put( spid, ppNew ); oldPath: "+sp); newPath: "+ppNew); } } } //fos.print(" //fos.print(" //fos.print(" //fos.print(" //fos.print(" //fos.print(" //fos.print(" } // Ha találtam ilyen utat akkor azt az utat ki kell venni // a még felhasználható elemek listájából. if( extended ) { notusedTraces.remove( nextId ); } } } //fos.print(" <><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><><

><><><><><><><><><><><><><><><><><><><><><><><><><><><><><>< ><><><><><><><><><><><><><>"); //Iterator iti = ((Collection)paths.keySet())iterator(); //while( iti.hasNext() ) { // fos.print( " "+(Path)paths.get((String)itinext()) ); //} //fos.close(); Path foundPath = (Path)paths.get( endPointtoString() ); 128. oldal return foundPath; } } WapRoute/PathDatabaseViewer.java // :WapRoute/PathDatabaseViewer.java ------------------------------------STARTpackage WapRoute; import import import import import import import import import import import java.io*; java.awt*; java.util*; java.awtevent*; java.awtimage*; java.awtcolor*; javax.swing*; java.utilEnumeration; WapRoute.Database*; java.net*; java.security*; /*

PathDatabaseViewer osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * @see javax.swingJFrame * Az alkalmazás az első paraméterben megadott WRD adatbázist betölti és * megjeleníti egy ablakban. Az alkamazás második paramétere egy nyelvet * hatátroz meg amely a grafikus interfészen illetve a konzolon megjelenített * üzenetek nyelvét adja meg. Jelenleg ez kétféle lehet, en vagy hu * <BR> * Az alkamazás egy egyszerü felület biztosít a WAP szerver adminisztrátorának * hogy a WapRouteServlet osztályhoz érkező kérések eredményeképpen generált * WBMP képeket megnézze ellenőrízze. Ennek a programnak a futtatásához nincs * szükség speciális alkalmazásra. (Nem úgy mint a Database Designer-nél) * <BR> * Az adminisztrátor az alkalmazás indításakor egy két részből álló ablakot * lát. A bal oldalon található az útvonal adatbázisról készített kép a jobb * oldalon pedig egy irényító pult. Az

irányító pult segítségével a felhasználó * kiléphet a programból, vagy a megjelenített képet mozgathatja illetve a * méretarányt növelheti illetve csökkentheti. A használatot a gombokon * megjelenő "tooltip"-ek segítik amelyek a gomb megnyomásakor végrehalytott * funkciót írják le néhány szóban. * <BR> * A bal oldalon látható kép alapállapotban nagyított formában jelenik meg. * Hogy a mobil terinálon látható nagyítás is ellenőrízhető legyen a * megjelenített képet mobil terminál méretüre lehet zsugorítani az írányító * pult középső gombjával. Ennek a gombnak az ismételt lenyomásával a kép * ismét a régi formájában látható. * <BR> * Az alkalmazás a generált képekkel együtt egy WML oldalt is készít amely * egy hivatkozást tartalmaz egy WBMP képre. Ez a WML oldal a lokális gépen * futó WAP böngészövel is megtekinthető, vagy a megfelelő könyvtárba helyezve * egy mobil terminálról is

lekérdezhető. (És a kismókusok kenyérre is * kenhetik :-) Az előbb említett két állományt az alaklmazás a rendszer * ideiglenes állományokat tartalmazó könyvtárában helyezi el * "WapRoute-test.wml" valamint "WapRoute-nnnnwbmp" néven (Ahol az nnnn egy) * négyjegyű számot jelent. */ public class PathDatabaseViewer extends JFrame { // Nyelvfüggő stringek deklarációja. static String MSG2000 = "Image is not available!"; static String MSG2001 = "Close"; static String MSG2002 = "ZA"; static String MSG2003 = "Out"; static String MSG2004 = "In"; static String MSG2005 = "Change the image "; static String MSG2006 = "to mobile terminal size"; static String MSG2007 = "to scaled image size"; static String MSG2008 = " (WBMP file created)"; static String MSG2009 = "WBMP viewer"; static String MSG2010 = "Loading."; static String MSG2011 = "

-> WBMP can not be created!"; static String MSG2012 = "llx:"; static String MSG2013 = " - lly:"; static String MSG2014 = " - urx:"; static String MSG2015 = " - ury:"; static String MSG2016 = "Current database:"; static String MSG2017 = "Move image North-East"; static String MSG2018 = "Move image North"; static String MSG2019 = "Move image North-West"; static String MSG2020 = "Move image East"; 129. oldal static static static static static static static static static static String String String String String String String String String String MSG2021 MSG2022 MSG2023 MSG2024 MSG2025 MSG2026 MSG2027 MSG2028 MSG2029 MSG2030 = = = = = = = = = = "Move image West"; "Move image South-East"; "Move image South"; "Move image South-West"; "Zoom out"; "Zoom in"; "Zoom all"; "Quit the application"; "Path

database viewer"; "!!! The specified file can not be found or "+ "not in valid format."; static String MSG2031 = "!!! Usage: WapRoute.jar <path-database> "+ "[<language>] "+ " <path-database> - The database to view "+ "in the application "+ " <language> - The language to use "+ "in the application"; // A megjelenített kép tulajdonságait leíró változók deklarációja. double llx = 0.0; // Bal alsó sarok double lly = 0.0; double urx = 250.0; // Jobb felső sarok double ury = 250.0; PathDatabase pdb = null; // Aktuálisan betöltött útvonal adatbázis private boolean scaled = true; // A megjelenített kép nagyításának be // illetve ki kapcsolása // A grafikus felület elemeinek deklarációja. private JPanel southPanel; private JPanel westPanel; private JLabel CurrentView = new JLabel(MSG2000, JLabel.CENTER); private JLabel CurrentKoordinates = new JLabel(MSG2000,

JLabel.CENTER); private JButton CloseButton = new JButton(MSG2001); private JButton ZoomAll = new JButton(MSG2002); private JButton ZoomOut = new JButton(MSG2003); private JButton ZoomIn = new JButton(MSG2004); private JButton Zoom11 = new JButton("11"); private JButton Zoom12 = new JButton("12"); private JButton Zoom13 = new JButton("13"); private JButton Zoom21 = new JButton("21"); private JButton Zoom22 = new JButton("22"); private JButton Zoom23 = new JButton("23"); private JButton Zoom31 = new JButton("31"); private JButton Zoom32 = new JButton("32"); private JButton Zoom33 = new JButton("33"); // A gomokhoz tartozó eseménykezelö oszrályok implementálása class OkListener implements ActionListener { public void actionPerformed(ActionEvent e) { System.exit(0); } } class myAllListener implements ActionListener { public void actionPerformed(ActionEvent e) { llx = pdb.getLLX(); urx =

pdb.getURX(); lly = pdb.getLLY(); ury = pdb.getURY(); repaintView(); } } class myOutListener implements ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; double height = ury-lly; llx -= width/2.0; urx += width/2.0; lly -= height/2.0; ury += height/2.0; repaintView(); } } class myInListener implements ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; double height = ury-lly; llx += width/4.0; urx -= width/4.0; lly += height/4.0; ury -= height/4.0; repaintView(); } } class my11Listener implements ActionListener { public void actionPerformed(ActionEvent e) { 130. oldal double width = urx-llx; double height = ury-lly; llx -= width/2.0; urx -= width/2.0; lly += height/2.0; ury += height/2.0; repaintView(); } } class my12Listener implements ActionListener { public void actionPerformed(ActionEvent e) { double height = ury-lly; lly += height/2.0; ury += height/2.0; repaintView(); } } class my13Listener implements

ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; double height = ury-lly; llx += width/2.0; urx += width/2.0; lly += height/2.0; ury += height/2.0; repaintView(); } } class my21Listener implements ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; llx -= width/2.0; urx -= width/2.0; repaintView(); } } class my22Listener implements ActionListener { public void actionPerformed(ActionEvent e) { scaled = !scaled; Zoom22.setToolTipText( MSG2005+((scaled)?MSG2006:MSG2007) ); repaintView(); } } class my23Listener implements ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; llx += width/2.0; urx += width/2.0; repaintView(); } } class my31Listener implements ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; double height = ury-lly; llx -= width/2.0; urx -= width/2.0; lly -= height/2.0; ury -= height/2.0; repaintView(); } } class my32Listener implements

ActionListener { public void actionPerformed(ActionEvent e) { double height = ury-lly; lly -= height/2.0; ury -= height/2.0; repaintView(); } } class my33Listener implements ActionListener { public void actionPerformed(ActionEvent e) { double width = urx-llx; double height = ury-lly; llx += width/2.0; urx += width/2.0; lly -= height/2.0; ury -= height/2.0; repaintView(); } } class Closing extends WindowAdapter { public void windowClosing(WindowEvent e) { System.exit(0); } 131. oldal } // Az egyes események után a képernyőnm látható kép tartalmát frissíteni // kell. Ezt végzi el ez a metódus az ablakon található kép objektumának // lecserélésével. A kép készítésekor egy WML állomány is készül amely // hivatkozást tartalmaz az elkészült WBMP állományra. Ezeket az // állományokat az alkalmazás a rendszer ideiglenes állományokat tartalazó // könyvtárában hozza létre. public void repaintView() { BufferedImage bi = pdb.getImage(llx,lly,urx,ury);

try { String fn = PathDatabase.writeWBMP( bi ); System.outprintln( "PathDatabaseViewer: "+fn+MSG2008); String dir = fn.substring( 0, fnlastIndexOf(FileseparatorChar) ); File fpWml = new File( dir, "WapRoute-test.wml" ); fpWml.createNewFile(); fpWml.deleteOnExit(); PrintStream prt = new PrintStream( new FileOutputStream( fpWml ) ); prt.println("<?xml version="10"?>"); prt.println("<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 11"+ "//EN" "http://www.wapforumorg/DTD/wml 11xml">"); prt.println("<wml>"); prt.println("<card id="Test" title=""+MSG2009+"">"); prt.println(MSG2009+":<br/>"); prt.println("<p><img src=""+(new File(fn))getName()+"" "+ "alt=""+MSG2010+"" /></p>"); prt.println("</card>"); prt.println("</wml>");

prt.close(); } catch( Exception e) { System.outprintln( "PathDatabaseViewer: "+e+MSG2011 ); } String dbName = CurrentView.getToolTipText(); getContentPane().remove( CurrentView ); getContentPane().remove( CurrentKoordinates ); Image ii = null; ImageIcon ij = null; if( bi != null && scaled ){ setSize( 493, 385 ); ii = bi.getScaledInstance(340, 340, ImageSCALE FAST); } else { setSize( 254, 172 ); ii = bi; } if( ii != null ) ij = new ImageIcon(ii); if( ij != null ) { CurrentView = new JLabel( ij, JLabel.CENTER ); CurrentKoordinates = new JLabel( MSG2012+llx+MSG2013+lly+ MSG2014+urx+MSG2015+ury, JLabel.LEFT); } else { CurrentView = new JLabel(MSG2000, JLabel.CENTER); CurrentKoordinates = new JLabel(MSG2000, JLabel.LEFT); } CurrentView.setToolTipText(dbName); getContentPane().add("Center", CurrentView ); getContentPane().add("South", CurrentKoordinates ); show(); } // A gombokon megjelenítendő képek betöltését végző metóduus public ImageIcon

getImage( String name ) { URL url = ClassLoader.getSystemResource(name); return new ImageIcon(url); } // Az alkalmazás konstruktora public PathDatabaseViewer( String dbName, PathDatabase pdb ) { super(); this.pdb = pdb; setTitle("PathDatabaseViewer: "+MSG2016+" "+dbName); setSize( 493, 385 ); setResizable( false ); // Ha a képek elérhetőek akkor azokat betöltöm a szövegek helyére try { setIconImage( getImage("WapRoute/appIcon.gif")getImage() ); ZoomAll = new JButton(getImage("WapRoute/ZA.gif")); ZoomOut = new JButton(getImage("WapRoute/OUT.gif")); ZoomIn = new JButton(getImage("WapRoute/IN.gif")); Zoom11 = new JButton(getImage("WapRoute/11.gif")); Zoom12 = new JButton(getImage("WapRoute/12.gif")); Zoom13 = new JButton(getImage("WapRoute/13.gif")); Zoom21 = new JButton(getImage("WapRoute/21.gif")); Zoom22 = new JButton(getImage("WapRoute/22.gif")); 132. oldal Zoom23

= new JButton(getImage("WapRoute/23.gif")); Zoom31 = new JButton(getImage("WapRoute/31.gif")); Zoom32 = new JButton(getImage("WapRoute/32.gif")); Zoom33 = new JButton(getImage("WapRoute/33.gif")); } catch (Exception e){ System.outprint(e);} // A layoutok példányosítása és beállítása BorderLayout bl1 = new BorderLayout(); BorderLayout bl2 = new BorderLayout(); GridLayout gl = new GridLayout(4,3); westPanel = new JPanel( bl2 ); southPanel = new JPanel( gl ); getContentPane().setLayout( bl1 ); // A grafikus interfész felépítése getContentPane().add("East", westPanel); westPanel.add("North", CloseButton); westPanel.add("South", southPanel); southPanel.add( ZoomIn ); southPanel.add( ZoomOut ); southPanel.add( ZoomAll ); southPanel.add( Zoom11 ); southPanel.add( Zoom12 ); southPanel.add( Zoom13 ); southPanel.add( Zoom21 ); southPanel.add( Zoom22 ); southPanel.add( Zoom23 ); southPanel.add( Zoom31 );

southPanel.add( Zoom32 ); southPanel.add( Zoom33 ); addWindowListener( new Closing() ); Zoom11.addActionListener( new my11Listener() ); Zoom12.addActionListener( new my12Listener() ); Zoom13.addActionListener( new my13Listener() ); Zoom21.addActionListener( new my21Listener() ); Zoom22.addActionListener( new my22Listener() ); Zoom23.addActionListener( new my23Listener() ); Zoom31.addActionListener( new my31Listener() ); Zoom32.addActionListener( new my32Listener() ); Zoom33.addActionListener( new my33Listener() ); ZoomOut.addActionListener( new myOutListener() ); ZoomIn.addActionListener( new myInListener() ); ZoomAll.addActionListener( new myAllListener() ); CloseButton.addActionListener(new OkListener()); // Tooltipek beállítása Zoom11.setToolTipText( MSG2017 ); Zoom12.setToolTipText( MSG2018 ); Zoom13.setToolTipText( MSG2019 ); Zoom21.setToolTipText( MSG2020 ); Zoom22.setToolTipText( MSG2005+((scaled)?MSG2006:MSG2007) ); Zoom23.setToolTipText( MSG2021 ); Zoom31.setToolTipText(

MSG2022 ); Zoom32.setToolTipText( MSG2023 ); Zoom33.setToolTipText( MSG2024 ); ZoomOut.setToolTipText( MSG2025 ); ZoomIn.setToolTipText( MSG2026 ); ZoomAll.setToolTipText( MSG2027 ); CloseButton.setToolTipText( MSG2028 ); CurrentView.setToolTipText( dbName ); // Az aktuális kép kirajzolása getContentPane().add("Center", CurrentView ); getContentPane().add("South", CurrentKoordinates ); repaintView(); } // A nyelvfüggő elemek betöltését végző metódus a paraméterében // szereplö kétbetűs nyelv azonosító stringgel betölt egy erőforrás // osztályt. Ha a betöltés sikertelen akkor a szövegek változatlanok // maradnak és egy kivétel váltódik ki. static private void loadStringResources( String lng ) { String resName = "WapRoute.WapRouteResources"; ResourceBundle res; String LNG = lng.toUpperCase(); res = ResourceBundle.getBundle( resName, new Locale(lng,LNG) ); MSG2029 = (String)res.getObject("MSG2029"); MSG2000 =

(String)res.getObject("MSG2000"); MSG2001 = (String)res.getObject("MSG2001"); MSG2002 = (String)res.getObject("MSG2002"); MSG2003 = (String)res.getObject("MSG2003"); MSG2004 = (String)res.getObject("MSG2004"); MSG2005 = (String)res.getObject("MSG2005"); MSG2006 = (String)res.getObject("MSG2006"); MSG2007 = (String)res.getObject("MSG2007"); 133. oldal MSG2008 MSG2009 MSG2010 MSG2011 MSG2012 MSG2013 MSG2014 MSG2015 MSG2016 MSG2017 MSG2018 MSG2019 MSG2020 MSG2021 MSG2022 MSG2023 MSG2024 MSG2025 MSG2026 MSG2027 MSG2028 MSG2030 MSG2031 = = = = = = = = = = = = = = = = = = = = = = = (String)res.getObject("MSG2008"); (String)res.getObject("MSG2009"); (String)res.getObject("MSG2010"); (String)res.getObject("MSG2011"); (String)res.getObject("MSG2012"); (String)res.getObject("MSG2013"); (String)res.getObject("MSG2014");

(String)res.getObject("MSG2015"); (String)res.getObject("MSG2016"); (String)res.getObject("MSG2017"); (String)res.getObject("MSG2018"); (String)res.getObject("MSG2019"); (String)res.getObject("MSG2020"); (String)res.getObject("MSG2021"); (String)res.getObject("MSG2022"); (String)res.getObject("MSG2023"); (String)res.getObject("MSG2024"); (String)res.getObject("MSG2025"); (String)res.getObject("MSG2026"); (String)res.getObject("MSG2027"); (String)res.getObject("MSG2028"); (String)res.getObject("MSG2030"); (String)res.getObject("MSG2031"); } // Az alkalmazás elindulásáért felelős metódus. Kezeli a paramétereket // és létrehozzal az útvonal adatbázis obejtumot. Ha a példányosítás nem // sikerül akkor hibaüzenetet ír a konzolra és terminál. public static void main( String[] argv ) { int argc = argv.length;

PathDatabase pdb = null; // Nyelvi elemek betöltése az erőforrás állományból // ha létezik a kívánt nyelvű erőforrás try { loadStringResources( argv[1] ); System.outprintln("PathDatabaseViewer: "+MSG2029); } catch( Exception e ) { System.outprintln("PathDatabaseViewer: "+MSG2029); if( argc >= 2 ) System.outprintln("PathDatabaseViewer: "+ "Language not found! ("+argv[1]+")"); } // A megadott útvonal adatbázis betöltése try { pdb = new PathDatabase( argv[0] ); } catch ( FileNotFoundException e ) { System.outprintln(MSG2030); System.exit(-1); } catch ( RuntimeException e ) { System.outprintln(MSG2031); System.exit(-1); } // Ablak megjelenítése az adatbázisból nyert képpel PathDatabaseViewer w = new PathDatabaseViewer( argv[0], pdb ); w.show(); } } // :WapRoute/PathDatabaseViewer.java --------------------------------------END- WapRoute/WapRouteResources en EN.java // :WapRoute/WapRouteResources en EN.java

-------------------------------STARTpackage WapRoute; import java.util*; /* WapRouteResources en EN osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * @see java.utilListResourceBundle * A WapRoute alkalmazásban (szervletben és a megjelenítőben) használt nyelvi * elemek listája. Az itt megadott sztringekre az alkalmazásba csak kulcs * szerinti hivatkozás van. Így könnyen más nyelvekre is lefordítható és így * más nyelvi környezetben is használhatóvá válik a program. * <BR> * Ez az osztály az angol nyelvű erőforrásokat definiálja. */ public class WapRouteResources en EN extends ListResourceBundle { 134. oldal public Object[][] getContents() { return contents; } static final Object[][] contents = { { "MSG1000", "Search city" }, { "MSG1001", "Previous page" }, { "MSG1002", "Help" }, { "MSG1003", "Search city" }, { "MSG1004",

"By a substring of the city name:" }, { "MSG1005", "Enter some characters from the city name:" }, { "MSG1006", "City name" }, { "MSG1007", "There are no cityes in the database!" }, { "MSG1008", "Help" }, { "MSG1009", "The anchors could be found on the page leads to the list "+ "of cities in the displayed range. Or a search could be "+ "done by entering one or more characters from the city "+ "name, in this case you will get the city names "+ "containing the specified substring." }, { "MSG1010", "Good luck!" }, { "MSG1011", "Search city II." }, { "MSG1012", "Choose the city from the list :" }, { "MSG1013", "By clicking on a city name you will get the details of "+ "the choosen city. If you are looking for a city that "+ "is not in the list then

you should go to the previous "+ "page and modify the search conditions!" }, { "MSG1014", "I am glad to see you in the wounder world of WapRoute. "+ "This application was developed in as a part of a thesis "+ "to surprise you. Please click on the Funcions button "+ "on the left side to join the venture. When you do not "+ "feel faliliar with a page you may get some help on the "+ "current page by clicking on the Help button." }, { "MSG1015", "Functions" }, { "MSG1016", "WapRoute 1.0" }, { "MSG1017", "Thesis 2000" }, { "MSG1018", "By " }, { "MSG1019", "Dov&#xE1;k&nbsp;Istv&#xE1;n" }, { "MSG1020", "Route finder" }, { "MSG1021", "Route" }, { "MSG1022", "between thw city" }, { "MSG1023", "City search" }, {

"MSG1024", "City" }, { "MSG1025", "by name" }, { "MSG1026", "Path finder" }, { "MSG1027", "Path" }, { "MSG1028", "by name" }, { "MSG1029", "find." }, { "MSG1030", "This page contains three links that activate "+ "searching functions:" }, { "MSG1031", "After specifying two cities your terminal will "+ "show a possible route between the cities." }, { "MSG1032", "After specifying a city the application will "+ "show a detailed decsription about the choosen city." }, { "MSG1033", "After specifying a path yuo will get a detailed "+ "description of the path." }, { "MSG1034", "Path finder" }, { "MSG1035", "Please specify some characters from the path you are "+ "looking for:" }, { "MSG1036",

"Path name" }, { "MSG1037", "There are no paths in the database!" }, { "MSG1038", "The anchors could be found on the page leads to the list "+ "of path names in the displayed range. Or a search could "+ "be done by entering one or more characters from the path "+ "name, in this case you will get the path names "+ "containing the specified substring." }, { "MSG1039", "Path search II." }, { "MSG1040", "Choose a path name form the list:" }, { "MSG1041", "By clicking on a path name you will get the details of "+ "the choosen path. If you are looking for a path that is "+ "not in the list then you should go to the previous page "+ "and modify the search conditions!" }, { "MSG1042", "City details" }, { "MSG1043", "Path details" }, { "MSG1044", "City name:"

}, { "MSG1045", "X coord.:" }, { "MSG1046", "Y coord.:" }, { "MSG1047", "Show on map" }, { "MSG1048", "Path name:" }, { "MSG1049", "Length:" }, { "MSG1050", "Average length:" }, { "MSG1051", "Total segment count:" }, { "MSG1052", "North-East" }, { "MSG1053", "North" }, { "MSG1054", "North-West" }, { "MSG1055", "East" }, 135. oldal { { { { { { { { { { { { { { { { { { { { { "MSG1056", "MSG1057", "MSG1058", "MSG1059", "MSG1060", "MSG1061", "MSG1062", "MSG1063", "MSG1064", "MSG1065", "MSG1066", "MSG1067", "MSG1068", "MSG1069", "MSG1070", "MSG1071", "MSG1072", "MSG1073", "MSG1074",

"MSG1075", "MSG1076", { "MSG1077", { "MSG1078", { "MSG1079", { { { { { { { { { { "MSG1080", "MSG1081", "MSG1082", "MSG1083", "MSG1084", "MSG1085", "MSG1086", "MSG1087", "MSG1088", "MSG1089", "West" }, "South-East" }, "South" }, "South-West" }, "Loading." }, "Zoom out" }, "Zoom in" }, "Whole map" }, "Main screen" }, "The specified area does not contain entities!" }, "s details" }, "Pathfinder" }, "Choose the start and destination city:" }, "Start city:" }, "Departure city:" }, "Start the search" }, "Change the start city" }, "Choose the start city" }, "Change the destination city" }, "Choose the destination city" }, "On the page you

can find two links with a label "+ "???. Click on them to choose a city to their place "+ "When you succesfully choosed the two city names an "+ "other link will appear which leads you to the real "+ "path finder utility. The choosed cities can be "+ "changed by clicking on the city names again." }, "Can not find a route between the two cityes!" }, "Route details" }, "The shortest path between the two choosen cities "+ "is described on this screen. When no route is found "+ "then a label will appear describing this case. "+ "The apprication will show the found route in a "+ "graphical way when you click the link on the top." }, "Elements in sight" }, "See on the map" }, "Total length of the route" }, "km" }, "" }, "" }, "" }, "" }, "" }, "" }, //

PathDatabaseViewer nyelvi elemei { "MSG2000", "Image is not available!" }, { "MSG2001", "Close" }, { "MSG2002", "ZA" }, { "MSG2003", "Out" }, { "MSG2004", "In" }, { "MSG2005", "Change the image " }, { "MSG2006", "to mobile terminal size" }, { "MSG2007", "to scaled image size" }, { "MSG2008", " (WBMP file created)" }, { "MSG2009", "WBMP viewer" }, { "MSG2010", "Loading." }, { "MSG2011", " -> WBMP can not be created!" }, { "MSG2012", "llx:" }, { "MSG2013", " - lly:" }, { "MSG2014", " - urx:" }, { "MSG2015", " - ury:" }, { "MSG2016", "Current database:" }, { "MSG2017", "Move image North-East" }, { "MSG2018", "Move

image North" }, { "MSG2019", "Move image North-West" }, { "MSG2020", "Move image East" }, { "MSG2021", "Move image West" }, { "MSG2022", "Move image South-East" }, { "MSG2023", "Move image South" }, { "MSG2024", "Move image South-West" }, { "MSG2025", "Zoom out" }, { "MSG2026", "Zoom in" }, { "MSG2027", "Zoom all" }, { "MSG2028", "Quit the application" }, { "MSG2029", "Path database viewer" }, { "MSG2030", "!!! The specified file can not be found or not in "+ "valid format." }, { "MSG2031", "!!! Usage: WapRoute.jar <path-database> [<language>] "+ " <path-database> - The database to view in the "+ "application "+ " <language> - The language to use in the "+

"application" }, 136. oldal }; } // :WapRoute/WapRouteResources en EN.java ---------------------------------END- WapRoute/WapRouteResources hu HU.java // :WapRoute/WapRouteResources hu HU.java -------------------------------STARTpackage WapRoute; import java.util*; /* WapRouteResources hu HU osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * @see java.utilListResourceBundle * A WapRoute alkalmazásban (szervletben és a megjelenítőben) használt nyelvi * elemek listája. Az itt megadott sztringekre az alkalmazásba csak kulcs * szerinti hivatkozás van. Így könnyen más nyelvekre is lefordítható és így * más nyelvi környezetben is használhatóvá válik a program. * <BR> * Ez az osztály a magyar nyelvű erőforrásokat definiálja. */ public class WapRouteResources hu HU extends ListResourceBundle { public Object[][] getContents() { return contents; } static final Object[][] contents = { { "MSG1000",

"V&#xE1;ros keresese" }, { "MSG1001", "El&#xF6;z&#xF5; lap" }, { "MSG1002", "S&#xFA;g&#xF3;" }, { "MSG1003", "V&#xE1;ros keres&#xE9;se" }, { "MSG1004", "Nev&#xE9;nek kezd&#xE9;betui alapj&#xE1;n:" }, { "MSG1005", "Adjon meg a keresett v&#xE1;ros nev&#xE9;b&#xF6;l "+ "n&#xE9;h&#xE1;ny karaktert:" }, { "MSG1006", "V&#xE1;ros n&#xE9;v" }, { "MSG1007", "Nincsennek varosok az adatbazisban!" }, { "MSG1008", "S&#xFA;g&#xF3;" }, { "MSG1009", "Az oldalon tal&#xE1;lhat&#xF3; linkek az adott "+ "intervallumba es&#xE9; v&#xE1;rosnevek "+ "list&#xE1;j&#xE1;t jelenitik meg. V&#xE1;rosok keres"+ "&#xE9;s&#xE9;re lehet&#xE9;s&#xE9;g van m&#xE9;g a "+

"v&#xE1;rosn&#xE9;v n&#xE9;h&#xE1;ny karakter&#xE9;nek "+ "beg&#xE9;pel&#xE9;s&#xE9;vel ekkor a megadott karakter "+ "sorozatot tartalmaz&#xF3; v&#xE1;rosok list&#xE1;j"+ "&#xE1;t kapja vissza." }, { "MSG1010", "Sok sikert!" }, { "MSG1011", "V&#xE1;ros keres&#xE9;se II." }, { "MSG1012", "V&#xE1;lassza ki a keresett v&#xE1;rost a "+ "list&#xE1;b&#xF3;l:" }, { "MSG1013", "A keresett v&#xE1;ros nevere kattintva megtekintheti a "+ "v&#xE1;ros adatait. Ha a keresett v&#xE1;ros nincs a "+ "list&#xE1;ban, akkor menjen az e&#xF6;z&#xF5; oldalra es "+ "m&#xF3;dositsa a kereses felteteleit!" }, { "MSG1014", "&#xDC;dv&#xF6;zl&#xF6;m &#xF6;nt a WapRoute "+ "csod&#xE1;latos

vil&#xE1;g&#xE1;ban! Ez a program egy "+ "szakdolgozat keret&#xE9;ben k&#xE9;sz&#xFC;lt, hogy "+ "&#xF6;nt kell&#xF5; k&#xE9;ppen elak&#xE1; "+ "pr&#xE1;ztassa. A bal oldalon talalhat&#xF3; "Funk- "+ "ci&#xF3;k" gombra kattintva v&#xE1;- lasszon a "+ "felsorolt lehet&#xF5;s&#xE9;- gek k&#xF6;z&#xFC;l az "+ "utaz&#xE1;s megkez- d&#xE9;s&#xE9;hez. Ha valamit nem "+ "&#xE9;rt k&#xE9;rjen seg&#xED;ts&#xE9;get a "+ ""S&#xFA;g&#xF3;" gombra kattintva." }, { "MSG1015", "Funkci&#xF3;k" }, { "MSG1016", "WapRoute 1.0" }, { "MSG1017", "Szakdolgozat 2000" }, { "MSG1018", "K&#xE9;sz&#xED;tette:" }, { "MSG1019", "Dov&#xE1;k&nbsp;Istv&#xE1;n" }, { "MSG1020",

"&#xDA;tvonal keres&#xE9;s" }, { "MSG1021", "&#xDA;tvonal" }, { "MSG1022", "k&#xE9;t v&#xE1;ros k&#xF6;z&#xF6;tti" }, { "MSG1023", "V&#xE1;ros keres&#xE9;s" }, { "MSG1024", "V&#xE1;ros" }, { "MSG1025", "n&#xE9;v szerinti" }, { "MSG1026", "&#xDA;t keres&#xE9;s" }, { "MSG1027", "&#xDA;t" }, { "MSG1028", "n&#xE9;v szerinti" }, { "MSG1029", "keres&#xE9;s." }, { "MSG1030", "Ez az oldal h&#xE1;rom linket tartalmaz, melyek k&#xFC; "+ "l&#xF6;nb&#xF6;z&#xF5; funkci&#xF3;kat "+ 137. oldal "akt&#xED;v&#xE1;lnak:" }, { "MSG1031", "K&#xE9;t v&#xE1;ros azonos&#xED;t&#xE1;sa ut&#xE1;n a "+ "terminalon megjelenik a k&#xE9;t

v&#xE1;rost "+ "&#xF6;sszek&#xF6;t&#xF5; &#xFA;tvo- nal "+ "le&#xED;r&#xE1;sa" }, { "MSG1032", "Egy v&#xE1;ros kiv&#xE1;laszt&#xE1;sa ut&#xE1;n a "+ "terminalon megjelennek a v&#xE1;ros tulajdons&#xE1;gai" }, { "MSG1033", "Egy &#xFA;t kiv&#xE1;laszt&#xE1;sa ut&#xE1;n a "+ "terminalon megjelennek az &#xFA;t tulajdons&#xE1;gai" }, { "MSG1034", "&#xDA;t keres&#xE9;se" }, { "MSG1035", "Adjon meg a keresett &#xFA;t nev&#xE9;b&#xF6;l "+ "n&#xE9;h&#xE1;ny karaktert:" }, { "MSG1036", "&#xDA;t n&#xE9;v" }, { "MSG1037", "Nincsennek utak az adatbazisban!" }, { "MSG1038", "Az oldalon tal&#xE1;lhat&#xF3; linkek az adott "+ "intervallumba es&#xE9; utnevek list&#xE1;j&#xE1;t

"+ "jelenitik meg. Utak keres&#xE9;s&#xE9;re "+ "lehet&#xE9;s&#xE9;g van m&#xE9;g az ut nev neh&#xE1;ny "+ "karakter&#xE9;nek beg&#xE9;pel&#xE9;s&#xE9;vel ekkor "+ "a megadott karakter sorozatot tartalmaz&#xF3; utak "+ "list&#xE1;j&#xE1;t kapja vissza." }, { "MSG1039", "&#xDA;t keres&#xE9;se II." }, { "MSG1040", "V&#xE1;lassza ki a keresett utat a list&#xE1;b&#xF3;l:" }, { "MSG1041", "A keresett ut nevere kattintva megtekintheti az ut adat"+ "ait. Ha a keresett ut nincs a list&#xE1;ban, akkor "+ "menjen az e&#xF6;z&#xF5; oldalra es m&#xF3;dositsa a "+ "kereses felteteleit!" }, { "MSG1042", "V&#xE1;ros tulajdonsagai" }, { "MSG1043", "&#xDA;t tulajdonságai" }, { "MSG1044", "Varos neve:" }, {

"MSG1045", "X koord.:" }, { "MSG1046", "Y koord.:" }, { "MSG1047", "Megtekintes terkepen" }, { "MSG1048", "Ut neve:" }, { "MSG1049", "Hossza:" }, { "MSG1050", "Atlagos hossza:" }, { "MSG1051", "Osszes darabszam:" }, { "MSG1052", "Eszak-Kelet" }, { "MSG1053", "Eszak" }, { "MSG1054", "Eszak-Nyugat" }, { "MSG1055", "Kelet" }, { "MSG1056", "Nyugat" }, { "MSG1057", "Del-Kelet" }, { "MSG1058", "Del" }, { "MSG1059", "Del-Nyugat" }, { "MSG1060", "Betoltes." }, { "MSG1061", "Tavolitas" }, { "MSG1062", "Kozelites" }, { "MSG1063", "Teljes térkép" }, { "MSG1064", "Főmenü" }, { "MSG1065",

"Az adott területen nincsennek objektumok!" }, { "MSG1066", " tulajdonságai" }, { "MSG1067", "Útvonal keresés" }, { "MSG1068", "Válassza ki az indúló és cél városokat:" }, { "MSG1069", "Induló város:" }, { "MSG1070", "Cél város:" }, { "MSG1071", "útkeresés indítása" }, { "MSG1072", "Induló város megváltoztatása" }, { "MSG1073", "Induló város kiválasztása" }, { "MSG1074", "Cél város megváltoztatása" }, { "MSG1075", "Cél város kiválasztása" }, { "MSG1076", "Az oldalon két link található amelynek értéke "+ "alapállapotban ???. Kattintson rájuk hogy "+ "helyükre a megfelelő városnevet tudja kiválaszatani."+ "Ha sikeresen kiválasztott két város nevet akkor a "+ "program a képernyő

alján egy újabb linket jelenít meg "+ "amelynek hatására a program megmutatja önnek a két "+ "kiválasztott város összekötő utvonalat. A kiválasztott "+ "városok helyett bármikor újabbakat választhat ki ha "+ "ismét a város névre kattint." }, { "MSG1077", "Nem található út a két megadott város között!" }, { "MSG1078", "Útvonal megjelenítése" }, { "MSG1079", "A két kiválasztott város közötti útvonal tulajdonságait "+ "láthatja ezen a képernyőn. Ha a két város között nincs "+ "utvonal akkor ezt egy felirat jelzi. Az útvonalat "+ "grafikusan is meg jelenítheti az oldalon található "+ "linkkel." }, { "MSG1080", "Látható elemek" }, { "MSG1081", "Megtekintés térképen" }, { "MSG1082", "Az út teljes hossza" }, { "MSG1083",

"km" }, { "MSG1084", "" }, { "MSG1085", "" }, { "MSG1086", "" }, 138. oldal { "MSG1087", "" }, { "MSG1088", "" }, { "MSG1089", "" }, // PathDatabaseViewer nyelvi elemei { "MSG2000", "Kép nem érvényes!" }, { "MSG2001", "Bezárás" }, { "MSG2002", "ZA" }, { "MSG2003", "Out" }, { "MSG2004", "In" }, { "MSG2005", "Kép méretének megváltoztatása: " }, { "MSG2006", "Mobil terminál méretüre" }, { "MSG2007", "Nagyíott méretüre" }, { "MSG2008", " (WBMP állomány elkészült)" }, { "MSG2009", "WBMP nézegető" }, { "MSG2010", "Betöltés." }, { "MSG2011", " -> WBMP készítése nem sikerült!" }, {

"MSG2012", "llx:" }, { "MSG2013", " - lly:" }, { "MSG2014", " - urx:" }, { "MSG2015", " - ury:" }, { "MSG2016", "Aktuális adatbázis:" }, { "MSG2017", "Kép mozgatása Észak-Keletre" }, { "MSG2018", "Kép mozgatása Északra" }, { "MSG2019", "Kép mozgatása Észak-Nyugatra" }, { "MSG2020", "Kép mozgatása Keletre" }, { "MSG2021", "Kép mozgatása Nyugatra" }, { "MSG2022", "Kép mozgatása Dél-Keletre" }, { "MSG2023", "Kép mozgatása Délre" }, { "MSG2024", "Kép mozgatása Dél-Nyugatra" }, { "MSG2025", "Távolítás" }, { "MSG2026", "Közelítés" }, { "MSG2027", "Teljes terület megtekintése" }, { "MSG2028", "Kilépés az alkalmazásból" }, {

"MSG2029", "Útvonal adatbázis megjelenítő alkalmazás" }, { "MSG2030", "! A megadott állomány nem található, vagy "+ "nem megfelelő formátumú !" }, { "MSG2031", "!!! Használat: WapRoute.jar <útvonal-adatbázis> "+ "[<nyelv>] "+ " <útvonal-adatbázis> - A megjelenítendő útvonal "+ "adatbázis specifikációja. "+ " <nyelv> - Az alaklmazás által "+ "használandó nyelv" }, }; } // :WapRoute/WapRouteResources hu HU.java ---------------------------------END- WapRoute/WapRouteServlet.java // :WapRoute/WapRouteServlet.java ---------------------------------------STARTpackage WapRoute; import import import import import import import import import import java.io*; java.util*; java.utilEnumeration; javax.servlet*; javax.servlethttp*; WapRoute.DatabasePathDatabase; WapRoute.DatabaseNode; WapRoute.DatabaseTrace;

WapRoute.DatabasePoint; WapRoute.DatabasePath; /* WapRouteServlet osztály. * @author Dovák István * @author http://ludens.eltehu/~dip * @version 1.0 * @see java.servlethttpHttpServlet * A szervletet a Nokia WAP Server alkalmazás futtatja. A helyes futtatáshoz * egy paramétert kell beállítani "database". Ezt a WAP szerver adminisztrátora * a config könyvtárban levő konfigurációs állomány * (%NOKIA WAP SERVER PATH%/config/Servlets.config) * módosításával teheti meg. * <BR> * Windows operációs rendszerre történő telepítéskor a telepítő program * automatikusan módosítja a megfelelő konfigurációs állományt és a "database" * paraméter értékének a telepített útvonal adatbázist állítja be. * <BR> * A szervlet a WAP szerver konzoljára információkat ír ki. Ezek az információk * segítik az adminisztrátort a hibák felderítésében és javításában. Minden a * szervlet által a konzolra írt üzenet a

szervlet szöveges azonosítójával * kezdődik. Ezt a szöveges azonosítót a 139. oldal * @see WapRoute.WapRouteServlet#getServletInfo getServletInfo metódus * szolgáltatja. A konzolon megjelenő információk angolul tájékoztatják az * adminisztrátort a hibákról illetve eseményekről. * <BR> * A szervlet a HTTP metódusok közül csak a @see WapRoute.WapRouteServlet#doGet * GET metódust implementálja. * Mivel: * <UL> * <LI> a cliens -&gt; szerver irányú kommunikációban átvitt adatok mennyisége * olyan csekély, hogy annak átvitelére a GET metódus is alkalmas * <LI> a GET metódus alkalmazásával az szervlet által szolgáltatott dinamikus * adatok is könnyen bookmarkolhatóak lesznek * <LI> az így szolgáltatott adatokat (például: képek megjelenítése) más * szolgáltatók is könnyen felhasználhatják az URL-ben megadott paraméterek * segítésgével. * </UL> */ public class WapRouteServlet extends

HttpServlet { // Az osztályhoz kapcsolódó saját változó. Ebben tárolom a szervlet // által megjelenített útvonal adatbázist. Az initben kap értéket private PathDatabase pdb = null; private String DefaultLanguge = null; private String TempDirectory = null; static final String[][] AvailableLanguages = { { "English", "en" }, { "Magyar", "hu" } }; /* A szervlet belső nevétnek lekérdezése. * @result String egy konstans visszaadása amivel a szervlet azonosítható, * illetve a konzolon ezzel a felirattal jelennek meg a szervlet * által kiirt üzenetek. */ public String getServletInfo() { return "WapRoute-1.0-servlet"; } /* A szervlet inicializálása. * Feladata a paraméterek belolvasása és azok alapján az útvonal adatbázis * betöltése, létrehozása. * @param ServletConfig a szervletek indításánál használt osztály a * paraméterek átadására. * @throws ServletException ha "database" paraméter egy

nem létező * állományra mutat akkor a szervlet inicializálása ezt a kivételt * fogja kiváltani, ami a szervlet használhatatlanságát jelzi a * WAP szervernek. */ public void init(ServletConfig config) throws ServletException { super.init(config); String strDatabasePath = config.getInitParameter("database"); String strDefaultLanguge = config.getInitParameter("language"); String TempDirectory = config.getInitParameter("temp"); String b = getServletInfo()+": "; String i = "Inicialisation of "+getServletInfo()+" servlet "; // Az útvonal adatbázis betöltésének megkísérlése, ha a betöltés // sikertelen akkor hibaüzenet kiirása a szerver konzoljára. if (strDatabasePath != null) { try { // A betöltés időigényes lehet ezért egy felirattal jelzem // az adminisztrátornak, hogy a müvelet elindult. System.outprintln(); System.outprint( b+i+"started " ); pdb = new PathDatabase(strDatabasePath);

System.outprintln( b+i+"successful!" ); System.outprint( b ); for( int c=0; c<(i+"successful!").length();c++ ) System.outprint( "-" ); // A művelet végén az adatbázisban található elemekről egy // statisztika kiirása a képernyőre. System.outprintln(); System.outprintln(b+" Read objects: "+pdbreadObjects); System.outprintln(b+" Read lines: "+pdb.readLines); System.outprintln(b+" Read words: "+pdb.readWords); System.outprintln(b+" Read chars: "+pdb.readChars); System.outprintln(b+" Errors: "+pdb.readErrors); } catch( FileNotFoundException e ) { // Ha az állomány nem található vagy valamilyen oknál 140. oldal // fogva nem tölthető be, pl nincs az olvasáshoz joga // a javának akkor hibaüzenetet irok a képernyőre. System.outprintln( b+i+"failed! " ); System.outprint( b ); for( int c=0; c<(i+"failed!").length();c++ ) System.outprint( "-" ); // A

hibára utaló megjegyzést is irok a képernyőre. Ez // még angolul van hiszen itt nincs lehetőség más nyelv // választására. System.outprintln(); System.outprint(b+" because the specified path database"+ " ("+strDatabasePath+") can not be found, not accessa"+ "ble or it is empty!"); // Az adatbázist érvénytelenre állítom, hogy biztosan // érvénytelen legyen. pdb = null; } System.outprintln(); } // Az alapértelmezett nyelv megállapításához leellenőrzöm, hogy a // paraméterként megadott nyelven létezik-e megfelelő erőforrás // állomány. Ha nem létezik akkor az alapértelmezés magyar lesz try { String lng = strDefaultLanguge; String LNG = lng.toUpperCase(); String resName = "WapRoute.WapRouteResources"; Locale loc = new Locale( lng, LNG ); ResourceBundle res = ResourceBundle.getBundle( resName, loc ); DefaultLanguge = strDefaultLanguge; } catch( Exception e ) { DefaultLanguge = "hu"; } //

Ideiglenes könyvtár elérési utjának leellenőrzése. Ha nem elérhető // vagy nem írható akkor az operációs rendszer ideiglenes könyvtárát // fogja használni a szervlet. Akkor is az oprendszer könyvtárát // használja ha nem adott meg értéket a felhasználó. try { if( TempDirectory.trim()length() != 0 ) { File fp = new File( TempDirectory+"/WapRoute-test.txt" ); FileOutputStream fos = new FileOutputStream( fp ); fos.write(12345678); fos.close(); fp.delete(); } else { TempDirectory = null; } } catch( Exception e ) { TempDirectory = null; } // Ha az útvonal adatbázis betöltése nem volt sikeres akkor a szervlet // sem tudott rendesen inicializálódni, azaz a szervletet nem lehet // el indítani. if( pdb == null ) throw new ServletException(); return; } /* A szervlethez érkező kéréseket kiszolgáló matódus. * A szervletet futtató WAP szerver ezt a funkciót hívja meg ha a GET * tipusú HTTP kérés érkezik a szervlethez rendelt cimen

(álltalában: * http://xxx.yyyzzz/waproute?a=b&amp;c=d formában) A szervlet * csak ezt az egy tipust implementálja. Lehetőség lenne még a POST * használatára is a feladat megoldásához, de akkor az egyes oldalakat * nem lehetne bookmarkolni a mobil terminálon. A kérések kiszolgálását * a metódus más privát metódusoknak továbbítja miután azonosította a * kéréssel azonosított funkciót. A funkciókat a metódus paraméterei és * azok értékei alapján azonosítja. * @param HttpServletRequest a kérésben érkező paraméterek és tulajdoságok * átadására szolgáló osztály. * @param HttpServletResponse a válasz megfogalmazásához használt objektum, * a szervlet ezen keresztül kommunikál a klienssel. * @see java.servlethttpHttpServlet#doGet */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String b = getServletInfo()+": "; String resName =

"WapRoute.WapRouteResources"; ResourceBundle res; 141. oldal String currentLanguegeStr = ""; // A következő oldal nyelvének beállítása az lng paraméter értéke // alapján. Ha a paraméter értéke jó (azaz létezik hozzá osztály) akkor // az adott nyelvhez tartozó resource osztályt betölti. Ha nem érvényes // az érték akkor az alapértelmezett nyelvet fogja használni a szervlet // a következő oldal generálásánál. try { String[] lngs = request.getParameterValues("lng"); String lng = lngs[0]; String LNG = lng.toUpperCase(); res = ResourceBundle.getBundle( resName, new Locale(lng,LNG) ); currentLanguegeStr = "&amp;lng="+lng; } catch( Exception e ) { res = ResourceBundle.getBundle( resName, new Locale( DefaultLanguge, DefaultLanguge.toUpperCase() ) ); } // Ha a lekérdezés keresési funkció akkor ezt a search paraméter // értéke jelzi. A helyes értékek C, L, P Ezeknél az értékeknél // további változók

értékeit kell ellenőrizni illetve azok alapján más // a keresés tárgya, illetve azok által még tovább szükített a keresés. String[] s = request.getParameterValues("search"); String[] p = request.getParameterValues("pile"); String[] n = request.getParameterValues("byname"); String[] t = request.getParameterValues("path"); // Ha a kérés egy lekérdezés akkor ezt a query paraméter értéke // jelzi. A helyes értékek alpha, gamma, image Ezeknél az // értékeknél további változók értékeit kell ellenőrizni illetve // azok alapján más a keresés tárgya, illetve azok által még tovább // szükített a keresés. String[] q = request.getParameterValues("query"); String[] o = request.getParameterValues("obj"); String[] x = request.getParameterValues("box"); // Ha van obj paraméter akkor az a kiválasztott szelektált // elemek azonosítoit tartalmazza. ArrayList alObj = new ArrayList(); if( o

!= null && o[0].length() > 0 ) { String objs = o[0]; StringTokenizer st = new StringTokenizer( objs, "," ); while( st.hasMoreTokens() ) { alObj.add( new Long( stnextToken() ) ); } } // Az útvonal keresés adatainek bekérését vissza vezetem a város // keresés néven megvelósított funkcióre. Így az itt szereplő város // kiválasztó metódus hívások csak annyiban különböznek a későbbi // hivásoktól, hogy plussz paraméterként a path=objStart,objEnd // paramétert kapják. // // - Ha search=P és path nem szerepel vagy szerepel, de az értéke // nem tartalmaz ??? rész-sztringet akkor ezen az oldalon a már // kiválasztott városokat kell megjeleníteni. így meg kell // jeleníteni két linket ahova a felhasználónak ki kell választania // a városokat valamint egyet a keresés indításához. // // - Ha egy város kiválasztási funkcióból tér vissza a felhaználó akkor // a paraméterek között kell lennie path=. tipusúnak és //

obj=. tipusúnak ekkor az előbb említett funkciót kell // végrehajtani és ahoz szimulálni a paramétereket. // // - Ha város kiválasztási funkció van akkor a plusz path=. // paraméter értékét át kell menteni a következő oldalra. Azaz ha // search=C és path=. akkor currentLanguageStr-t ki kell // bövíteni a &amp;path=.-tal // // - Ha search=P és path=???,xxx illetve path=xxx,??? akkor a // felhasználó az induló illetve cél várost akarja kiválasztani // (esetleg felülírni). Város kiválasztó ablakot kell megjeleníteni // (xxx egy objektum azonosítója). try { if( (t != null) && (t[0].length() > 0) && s != null && s[0].equals("C") ) { currentLanguegeStr += "&amp;path="+t[0]; } if( (t != null) && (t[0].length() > 0) && (alObjsize() > 0) ) { s = new String[] { "P" }; String path = t[0]; StringTokenizer st = new StringTokenizer( path, "," ); String p1 =

st.nextToken(); String p2 = st.nextToken(); t[0] = (p1.equals("???") ? alObjget(0)+"":p1 )+","+ 142. oldal (p2.equals("???") ? alObjget(0)+"":p2 ); } if( s[0].equals("P") && (t != null) && (t[0]length() > 0) ) { String path = t[0]; StringTokenizer st = new StringTokenizer( path, "," ); if( st.countTokens() >= 2 ) { // path paraméter elemzése String strObjStart = st.nextToken(); String strObjEnd = st.nextToken(); Long objStart = new Long(0); Long objEnd = new Long(0); try { objStart = new Long(strObjStart); } catch(Exception e) {} try { objEnd = new Long(strObjEnd); } catch(Exception e) {} // megfelelő funkció végrehajtása if( strObjStart.equals("???") ) { printSearchNode( response, res, currentLanguegeStr+ "&amp;path=???,"+objEnd ); } else if( strObjEnd.equals("???") ) { printSearchNode( response, res, currentLanguegeStr+

"&amp;path="+objStart+",???" ); } else { printSearchPath( objStart, objEnd, response, res, currentLanguegeStr ); } } return; } if( s[0].equals("P") ) { Long NU = new Long(0); printSearchPath( NU, NU, response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } // - Ha // // try { if( path=xxx,yyy az egyedüli paraméter akkor az útvonal kereső metódust kell meghívni, amely a két város közötti útvonalat fogja megjeleníteni a felhasználónak. s == null && q == null && t != null && t[0].length() > 0 ) { String path = t[0]; StringTokenizer st = new StringTokenizer( path, "," ); if( st.countTokens() >= 2 ) { Long objStart = new Long( st.nextToken() ); Long objEnd = new Long( st.nextToken() ); printShortestPathDetails( objStart, objEnd, response, res, currentLanguegeStr ); } return; } } catch( Exception e ){ } // - Ha // // // - Ha // // // // - Ha // // // try { if( search=C és pile helyes

értéket tartalmaz, akkor a városok közül a megadott csomag tartalmát kell kilistázni. search=C és byname változonak nem üres az értéke akkor a városok közül azokat kell listázni amelyek nevében megtalálható az byname-ben megadott rész szöveg. search=C és a fenti esetek nem teljesülnek akkor a város keresés funkció első ablakát kell megjeleníteni ahol a felhasználó kiválaszthatja a pile értékét vagy megadhat egy byname értéket. s[0].equals("C") && (IntegerparseInt(p[0]) >= 0) ) { printSearchNode( Integer.parseInt(p[0]), response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } try { if( s[0].equals("C") && (n[0]length() != 0) ) { printSearchNode( n[0], response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } try { if( s[0].equals("C") ) { printSearchNode( response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } // - Ha search=L és pile helyes értéket

tartalmaz, akkor az 143. oldal // // // - Ha // // // // - Ha // // // try { if( utak közül a megadott csomag tartalmát kell kilistázni. search=L és byname változonak nem üres az értéke akkor az utak közül azokat kell listázni amelyek nevében megtalálható az byname-ben megadott rész szöveg. search=L és a fenti esetek nem teljesülnek akkor az ut keresés funkció első ablakát kell megjeleníteni ahol a felhasználó kiválaszthatja a pile értékét vagy megadhat egy byname értéket. s[0].equals("L") && (IntegerparseInt(p[0]) >= 0) ) { printSearchTrace( Integer.parseInt(p[0]), response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } try { if( s[0].equals("L") && (n[0]length() != 0) ) { printSearchTrace( n[0], response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } try { if( s[0].equals("L") ) { printSearchTrace( response, res, currentLanguegeStr ); return; } } catch( Exception

e ){ } // - Ha // // // // - Ha // // // // try { if( query=alpha és obj helyes értéket tartalmaz, akkor az obj egy vagy több objektum azonosítója és annak (illetve azok) leírását adja vissza. query=alpha és box egy téglalapot definiál, akkor a téglalapban található objektumokat adja vissza. Minden elemet a nevével azonosít és minden név egy link: query=alpha és obj értékekkel. q[0].equals("alpha") && (alObjsize() > 0) ) { printAlphaQueryResults( alObj, response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } try { if( q[0].equals("alpha") && (x[0]length() > 0) ) { String box = x[0]; StringTokenizer st = new StringTokenizer( box, "," ); if( st.countTokens() == 4 ){ double llx = Double.parseDouble(stnextToken()); double lly = Double.parseDouble(stnextToken()); double urx = Double.parseDouble(stnextToken()); double ury = Double.parseDouble(stnextToken()); printAlphaQueryResults( llx, lly, urx,

ury, response, res, currentLanguegeStr ); return; } } } catch( Exception e ){ } // - Ha // // // // - Ha // // // // try { if( query=gamma és obj helyes értéket tartalmaz akkor egy olyan decket ad vissza ami csak egy képre való hivatkozást tartalmaz, ahol a megadott objektum(ok) van(nak) középen. query=gamma és box helyes értéket tartalmaz akkor egy olyan decket ad vissza ami csak egy képre való hivatkozást tartalmaz, aminek a bal felső és jobb alsó koordinátáit a box paraméter határozza meg. q[0].equals("gamma") && (alObjsize() > 0) ) { printGammaQueryResults( alObj, response, res, currentLanguegeStr ); return; } } catch( Exception e ){ } try { if( q[0].equals("gamma") && (x[0]length() > 0) ) { String box = x[0]; StringTokenizer st = new StringTokenizer( box, "," ); if( st.countTokens() == 4 ){ double llx = Double.parseDouble(stnextToken()); double lly = Double.parseDouble(stnextToken()); 144. oldal

double urx = Double.parseDouble(stnextToken()); double ury = Double.parseDouble(stnextToken()); printGammaQueryResults( llx, lly, urx, ury, response, res, currentLanguegeStr ); return; } } } catch( Exception e ){ } // - Ha // // try { if( query=image és box helyes értéket tartalmaz akkor egy WBMP képet ad vissza ami a box paraméterben megadott téglalap által határolt területet fogja mutatni. q[0].equals("image") && (x[0]length() > 0) ) { String box = x[0]; StringTokenizer st = new StringTokenizer( box, "," ); if( st.countTokens() == 4 ){ double llx = Double.parseDouble(stnextToken()); double lly = Double.parseDouble(stnextToken()); double urx = Double.parseDouble(stnextToken()); double ury = Double.parseDouble(stnextToken()); printImageResults( llx, lly, urx, ury, response ); return; } } } catch( Exception e ){ } // Ha a fentiek közül egyik funkció sem jön be akkor a kezdőképernyőt // mutatom a felhasználónak. Helyes müködés esetén

csak az indításkor // mutatja a program ezt a képernyőt. printStartPage( response, res, currentLanguegeStr ); return; } /* A WML oldalakhoz tartozó fejléc vissza adása. * Ezt használom az oldalak összeállításánál az oldal szövegét tartalmazó * változó inicializálására. */ private String printHeader() { return "<?xml version="1.0"?> "+ "<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "+ ""http://www.wapforumorg/DTD/wml 11xml"> "; } /* Egyes WML oldalakhoz tartozó súgó összeállítása. * A paraméterekben megadott Stringek segítségével egy WML kátryát készít. * A paramétereket általában egy @see java.utilResourceBundle -ből nyert * értékek adják amiket igy nyelvfüggően lehet megjeleníteni. * @param card A kátrya nevét adja meg. Egy Deck-en belül lehetőleg egyedi * legyen. * @param prev Az "Előző oldal" gomb feliratának megadása. * @param title A

"Súgó" oldal feliratának megadása. * @param contents A súgó oldal tartalmának megadása. Egy tartalmazhat * további WML elemeket is. * @param goodluck Az oldal alján található befejező szöveget adja meg. */ private String printHelp( String card, String prev, String title, String contents, String goodluck ) { return "<card id=""+card+"">"+ "<do type="prev" label=""+prev+""><prev/></do>"+ "<p align="center"><big><b>"+title+"</b></big><br/></p>"+ "<p align="left"><small>"+contents+"</small><br/></p>"+ "<p align="right">"+ "<b>"+goodluck+"</b></p></card>"; } private String printAlphaOnElements( ArrayList elset, ResourceBundle res, String addPar ) { // A szükséges

erőforrások betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1042 = (String)res.getObject("MSG1042"); String MSG1043 = (String)res.getObject("MSG1043"); String MSG1044 = (String)res.getObject("MSG1044"); String MSG1045 = (String)res.getObject("MSG1045"); String MSG1046 = (String)res.getObject("MSG1046"); String MSG1047 = (String)res.getObject("MSG1047"); String MSG1048 = (String)res.getObject("MSG1048"); String MSG1049 = (String)res.getObject("MSG1049"); String MSG1050 = (String)res.getObject("MSG1050"); 145. oldal String String String String MSG1051 = (String)res.getObject("MSG1051"); MSG1066 = (String)res.getObject("MSG1066"); MSG1083 = (String)res.getObject("MSG1083"); outMsg = ""; outMsg += "<card id="WRSC">"; outMsg +=

"<do type="prev" label=""+MSG1001+""><prev/></do>"; // Az kezdetben elöállított elem halmazból felépítem az oldal tartalmát // A halamz elemei vagy Node vagy Trace elemek. A két különbözö elemnél // más-más tipusú adatokat kell megjeleníteni. ArrayList alPrintedElements = new ArrayList(0); Iterator elit = elset.iterator(); while( elit.hasNext() ) { Object ob = elit.next(); Node nd = null; Trace tr = null; if( ob instanceof Node ) nd = (Node)ob; if( ob instanceof Trace ) tr = (Trace)ob; // Ha van ilyen azonosítójú oldal akkor annak // tulajdonságainak megjelenítése. if( nd != null && alPrintedElements.indexOf( new Long(ndgetId()) ) == -1 ){ if( elset.size() == 1 ) outMsg += "<p align="center"><b>"+MSG1042+"</b></p>"; else outMsg += "<p align="center"><b>"+nd.getName()+MSG1066+ "</b></p>";

outMsg += "<p align="left"><table columns="2">"; outMsg += "<tr><td>"+MSG1044+"</td><td><a title=""+ MSG1047+"" href="waproute?query=gamma&amp;obj="+ nd.getId()+addPar+"">"+ndgetName()+"</a>"+ "</td></tr>"; outMsg += "<tr><td>"+MSG1045+"</td><td>"+nd.getX()+"</td></tr>"; outMsg += "<tr><td>"+MSG1046+"</td><td>"+nd.getY()+"</td></tr>"; outMsg += "</table></p>"; outMsg += "<p align="left"><br/></p>"; alPrintedElements.add( new Long(ndgetId()) ); } else if( tr != null && alPrintedElements.indexOf( new Long(trgetId()) ) == -1 ) { if( elset.size() == 1 ) outMsg += "<p

align="center"><b>"+MSG1043+"</b></p>"; else outMsg += "<p align="center"><b>"+tr.getName()+MSG1066+ "</b></p>"; Collection trs = pdb.getTraceElementsByName( trgetName() ); Iterator it = trs.iterator(); Double sumOfLengths = new Double(0.0); String idList = ""; while( it.hasNext() ){ Long id = (Long)it.next(); Trace tr2 = pdb.getTraceElement( id ); sumOfLengths = new Double( sumOfLengths.doubleValue()+ tr2.getSegsLength()); idList += (( idList.length() == 0 ) ? "":",")+tr2getId(); } Double averageSegLength = new Double(0.0); if( trs.size() != 0 ) { averageSegLength = new Double( sumOfLengths.doubleValue()/ (double)trs.size() ); } outMsg += "<p align="left"><table columns="2">"; outMsg += "<tr><td>"+MSG1048+"</td><td><a title=""+MSG1047+ ""

href="waproute?query=gamma&amp;obj="+idList+ addPar+"">"+tr.getName()+"</a>"+ "</td></tr>"; outMsg += "<tr><td>"+MSG1049+"</td><td>"+ (Math.floor(sumOfLengthsdoubleValue()*100.0)/1000)+ " "+MSG1083+"</td></tr>"; outMsg += "<tr><td>"+MSG1050+"</td><td>"+ (Math.floor(averageSegLengthdoubleValue()*100.0)/1000)+ " "+MSG1083+"</td></tr>"; outMsg += "<tr><td>"+MSG1051+"</td><td>"+trs.size()+"</td></tr>"; outMsg += "</table></p>"; outMsg += "<p align="left"><br/></p>"; alPrintedElements.addAll( trs ); } } // A kártya befelyezése outMsg += "</card>"; return outMsg; 146. oldal } /* "Útvonal kereső fő oldal"

megjelenítése. * Ez az oldal kerül megjelenítésre ha a szervlet csak a ?search=P * paraméterezéssel kerül meghívásra vagy ha ezenkívűl szereplő a path * paraméter nem tartlmazza a ??? karakter sorozatot. Az oldalon két * linkként megjelenő felirat jeleníti meg a kiválasztott városokat. Ha * ilyen nincs akkor ??? jelenik meg a város neve helyett. Az oldal alján * található link indítja majd az útvonal keresési funkciót. * @param Long ha van már kiválasztott induló város akkor annak az * azonosítóját tartalmazza, ha nincs akkor értéke 0. * @param Long ha van már kiválasztott cél város akkor annak az * azonosítóját tartalmazza, ha nincs akkor értéke 0. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét

tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printSearchPath( Long objStart, Long objEnd, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // A megadott városok objektumának lekérdezése Node ndStart = pdb.getNodeElement( objStart ); Node ndEnd = pdb.getNodeElement( objEnd ); // Az oldalon tarálható nyelv függő elemek betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1008 =

(String)res.getObject("MSG1008"); String MSG1010 = (String)res.getObject("MSG1010"); String MSG1067 = (String)res.getObject("MSG1067"); String MSG1068 = (String)res.getObject("MSG1068"); String MSG1069 = (String)res.getObject("MSG1069"); String MSG1070 = (String)res.getObject("MSG1070"); String MSG1071 = (String)res.getObject("MSG1071"); String MSG1072 = (String)res.getObject("MSG1072"); String MSG1073 = (String)res.getObject("MSG1073"); String MSG1074 = (String)res.getObject("MSG1074"); String MSG1075 = (String)res.getObject("MSG1075"); String MSG1076 = (String)res.getObject("MSG1076"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSP">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>";

outMsg += "<do type="help" label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><big><b>"+MSG1067+"</b></big><br/></p>"; outMsg += "<p align="left"><small>"+MSG1068+"</small><br/></p>"; outMsg += "<p align="left"><small>"+MSG1069+" "+ "<a title=""+((ndStart!=null)?MSG1072:MSG1073)+ "" href="waproute?search=P&amp;path=???,"+objEnd+addPar+ "">"+( (ndStart==null) ? "???":ndStart.getName() )+ "</a></small></p>"; outMsg += "<p align="left"><small>"+MSG1070+" "+ "<a title=""+((ndEnd!=null)?MSG1074:MSG1075)+ ""

href="waproute?search=P&amp;path="+objStart+",???"+ addPar+"">"+( (ndEnd==null) ? "???":ndEnd.getName() )+ "</a></small></p>"; if( ndStart != null && ndEnd != null ) { outMsg += "<p align="right"><br/><a href="waproute?path="+ objStart+","+objEnd+addPar+"">"+MSG1071+"</a></p>"; } // Az oldal további tartalmának kiirása outMsg += "</card>"; outMsg += printHelp( "WRH", MSG1001, MSG1008, MSG1076, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); 147. oldal out.println(outMsg); out.close(); return; } /* "Útvonal megjelenítő oldal" megjelenítése. * Ez az oldal kerül megjelenítésre ha a szervlet csak a ?path=xxx,yyy *

paraméterezéssel kerül meghívásra. Ekkor a paraméterben kapott város * azonosítók a kezdő és cél városokat adják meg. Ennek a funkciónak a * feledata hogy útvonalat keressen a két város között és azt megjelenítse * a felhasználó terminálján. * @param Long ha van már kiválasztott induló város akkor annak az * azonosítóját tartalmazza, ha nincs akkor értéke 0. * @param Long ha van már kiválasztott cél város akkor annak az * azonosítóját tartalmazza, ha nincs akkor értéke 0. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. *

@throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printShortestPathDetails( Long objStart, Long objEnd, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // A megadott városok objektumának lekérdezése és akét város közötti // legrövidebb útvonal lekérdezése az adatbázistól. Node ndStart = pdb.getNodeElement( objStart ); Node ndEnd = pdb.getNodeElement( objEnd ); Path path = pdb.getShortestPath( ndStart, ndEnd ); // Az oldalon tarálható nyelv függő elemek betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1010

= (String)res.getObject("MSG1010"); String MSG1077 = (String)res.getObject("MSG1077"); String MSG1078 = (String)res.getObject("MSG1078"); String MSG1079 = (String)res.getObject("MSG1079"); String MSG1081 = (String)res.getObject("MSG1081"); String MSG1082 = (String)res.getObject("MSG1082"); String MSG1083 = (String)res.getObject("MSG1083"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSP">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help" label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><big><b>"+MSG1078+"</b></big></p>"; // A

dinamikus tartalom megjelenítése if( path == null ) { outMsg += "<p align="left"><small><b>"+MSG1077+" ("+ ((ndStart!=null)?ndStart.getName():"???")+"-"+ ((ndEnd!=null)?ndEnd.getName():"???")+")</b></small>"+ "<br/></p>"; } else { outMsg += "<p align="center"><small><b>("+ ((ndStart!=null)?ndStart.getName():"???")+"-"+ ((ndEnd!=null)?ndEnd.getName():"???")+")</b></small>"+ "<br/></p>"; // Lista összeállítása az útvonalról String pl = ""; Iterator it = path.iterator(); boolean prev = false; String prevName = ""; String strLista = ""; String objLista = ""; while( it.hasNext() ) { Object ob = it.next(); if( ob instanceof Node ) { strLista +=

pl+"<br/><b>"+((Node)ob).getName()+"</b>"; objLista += pl+((Node)ob).getId(); prev = true; 148. oldal prevName = ""; } else if ( ob instanceof Trace ) { String currName = ((Trace)ob).getName(); objLista += pl+((Trace)ob).getId(); if( !currName.equals(prevName) ) { strLista += pl+(prev?"<br/>&nbsp;":"")+ "&nbsp;<small><i>"+currName+"</i></small>"; prev = false; } prevName = currName; } pl = ","; } outMsg += "<p align="right"><a href="waproute?query=gamma&amp;obj="+ objLista+addPar+"" title=""+MSG1081+"">"+MSG1081+"</a></p>"; outMsg += "<p align="right">"+MSG1082+":"+((int)path.getLength())+ MSG1083+"</p>"; outMsg += "<p align="left">"+strLista+"</p>"; } // Az

oldal további tartalmának kiirása outMsg += "</card>"; outMsg += printHelp( "WRH", MSG1001, MSG1008, MSG1079, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* "Város kereső oldal" megjelenítése. * Ez az oldal kerül megjelenítésre ha a szervlet csak a ?search=C * paraméterezéssel kerül meghívásra. Az oldalon a városnevek csoportosítva * jelennek meg. Ezen kívül egy szövegmező kitöltésével a felhasználó saját * keresési stratégiával készíthet szükítést a város nevekre. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató

linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printSearchNode( HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Az oldalon tarálható nyelv függő elemek betöltése String MSG1000 = (String)res.getObject("MSG1000"); String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1003 = (String)res.getObject("MSG1003"); String MSG1004 = (String)res.getObject("MSG1004");

String MSG1005 = (String)res.getObject("MSG1005"); String MSG1006 = (String)res.getObject("MSG1006"); String MSG1007 = (String)res.getObject("MSG1007"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1009 = (String)res.getObject("MSG1009"); String MSG1010 = (String)res.getObject("MSG1010"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSC">"; outMsg += "<do type="accept" label=""+MSG1000+"">"; outMsg += "<go href="waproute?search=C&amp;byname=$(citych)"+addPar+ ""/></do>"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help" label=""+MSG1002+""><go

href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><b>"+MSG1003+"</b></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1004+"</small><br/>"; // Az oldalon levő dinamikus információ kiirása 149. oldal // Az egyes város csoportok kezdő és utolsó elemeit az útvonal adatbázis // egy SortedMap-ban adja vissza. Ez a megközelítés feltételezi, hogy // minimális számú azonos nevű elem van az adabázisban. SortedMap piles = pdb.getListOfNodeNames(-1); if( piles.size() != 0 ){ int counter = 0; Iterator it = piles.keySet()iterator(); while( it.hasNext() ){ String start = (String)it.next(); String end = (String)piles.get(start); outMsg += "<!-- "+counter+" -->&nbsp;<b><a title=""+start+"-"+ end+""

href="waproute?search=C&amp;pile="+counter+addPar+ "">"+start+"-"+end+"</a></b><br/>"; counter++; } } else { outMsg += MSG1007; } // Az oldal további tartalmának kiirása outMsg += "<small>"+MSG1005+"</small>"; outMsg += "<input name="citych" title=""+MSG1006+""/></p></card>"; outMsg += printHelp( "WHR", MSG1001, MSG1008, MSG1009, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* "Város keresése csomag alapján". * Ha a szervlethez "?search=C&amp;pile=n" alakú kérés érkezik akkor ezt a * metódust hajtja végre. Ez megjeleníti a kivánt csomag tartalmát úgy hogy * az egyes elemek link-ként a keresett

városra mutatnak. Ha valami miatt a * keresett csomag nem létezik akkor a Város kereső oldal kerül * megjelenítésre. (Ez a program helyes müködése során nem fordulhat elő) * @param pile a kiválasztott csomag száma. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */

private void printSearchNode( int pile, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // A kért adatok ellenörzése. Ha a kért csomag nem létezik akkor az // Város kereső oldal megjelenítése SortedMap piles = pdb.getListOfNodeNames(pile); if( piles == null || piles.size() == 0 ){ printSearchNode( response, res, addPar ); return; } // Az erőforrások betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1011 = (String)res.getObject("MSG1011"); String MSG1012 = (String)res.getObject("MSG1012"); String MSG1010 = (String)res.getObject("MSG1010"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1013 = (String)res.getObject("MSG1013"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card

id="WRSC">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help" label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><b>"+MSG1011+"</b></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1012+"</small><br/>"; 150. oldal // Dinamikus tartalom kiirása a terminálra Iterator it = piles.keySet()iterator(); while( it.hasNext() ){ Long id = (Long)it.next(); String str = (String)piles.get(id); outMsg += "<!-- "+id+" -->&nbsp;<b><a title=""+str+"" href=""+ "waproute?query=alpha&amp;obj="+id+addPar+"">"+str+

"</a></b><br/>"; } // Az oldal további tartalmának kiirása outMsg += "</p></card>"; outMsg += printHelp( "WHR", MSG1001, MSG1008, MSG1013, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* "Város keresés név alapján". * Ha a szervlethez "?search=C&amp;byname=xyz" alakú kérés érkezik akkor * ezt a metódust hajtja végre. Ez megjeleníti azoknak a városoknak a nevét * amelyekben szerepel a megadott karaktersorozat. Az összehasonlítás nem * kölönbözteti meg a kis és a nagy betüket. Ha az így végrehajtott * keresésnek egy elem sem felel meg akkor a Város kereső oldal kerül * megjelenítésre. (Ez akkor fordulhat elő ha a felhasználó az útvonal * adatbázisban nem szereplő város keres.) *

@param substr a keresett város nevének egy része. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printSearchNode( String substr, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // A kért adatok

ellenörzése. Ha a nem léteznek városok a megadott // névvel akkor a Város kereső oldal megjelenítése SortedMap piles = pdb.getListOfNodeNames(substr); if( piles == null || piles.size() == 0 ){ printSearchNode( response, res, addPar ); return; } // Az erőforrások betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1011 = (String)res.getObject("MSG1011"); String MSG1012 = (String)res.getObject("MSG1012"); String MSG1010 = (String)res.getObject("MSG1010"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1013 = (String)res.getObject("MSG1013"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSC">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>";

outMsg += "<do type="help" label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><b>"+MSG1011+"</b></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1012+"</small><br/>"; // Dinamikus tartalom kiirása a terminálra Iterator it = piles.keySet()iterator(); while( it.hasNext() ){ Long id = (Long)it.next(); String str = (String)piles.get(id); 151. oldal outMsg += "<!-- "+id+" -->&nbsp;<b><a title=""+str+"" href=""+ "waproute?query=alpha&amp;obj="+id+addPar+"">"+str+ "</a></b><br/>"; } // Az oldal további tartalmának kiirása outMsg += "</p></card>"; outMsg += printHelp( "WHR", MSG1001,

MSG1008, MSG1013, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* "Út kereső oldal" megjelenítése. * Ez az oldal kerül megjelenítésre ha a szervlet csak a ?search=L * paraméterezéssel kerül meghívásra. Az oldalon a útak nevei csoportosítva * jelennek meg. Ezen kívül egy szövegmező kitöltésével a felhasználó saját * keresési stratégiával készíthet szükítést az út nevekre. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek

az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printSearchTrace( HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Az oldalon tarálható nyelv függő elemek betöltése String MSG1034 = (String)res.getObject("MSG1034"); String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1004 = (String)res.getObject("MSG1004"); String MSG1035 = (String)res.getObject("MSG1035"); String MSG1036 = (String)res.getObject("MSG1036"); String MSG1037 = (String)res.getObject("MSG1037");

String MSG1008 = (String)res.getObject("MSG1008"); String MSG1038 = (String)res.getObject("MSG1038"); String MSG1010 = (String)res.getObject("MSG1010"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSC">"; outMsg += "<do type="accept" label=""+MSG1034+"">"; outMsg += "<go href="waproute?search=L&amp;byname=$(linech)"+addPar+ ""/></do>"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help" label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><b>"+MSG1034+"</b></p>"; outMsg += "<p

align="left">"; outMsg += "<small>"+MSG1004+"</small><br/>"; // Az oldalon levő dinamikus információ kiirása // Az egyes út csoportok kezdő és utolsó elemeit az útvonal adatbázis // egy SortedMap-ban adja vissza. Ez a megközelítés feltételezi, hogy // az azonos nevű utak egy útat azonosítnak csak az elágazásoknál // megszakadnak. SortedMap piles = pdb.getListOfTraceNames(-1); if( piles.size() != 0 ){ int counter = 0; Iterator it = piles.keySet()iterator(); while( it.hasNext() ){ String start = (String)it.next(); String end = (String)piles.get(start); outMsg += "<!-- "+counter+" -->&nbsp;<b><a title=""+start+"-"+ end+"" href="waproute?search=L&amp;pile="+counter+addPar+ "">"+start+"-"+end+"</a></b><br/>"; counter++; } } else { 152. oldal outMsg += MSG1037; } // Az oldal

további tartalmának kiirása outMsg += "<small>"+MSG1035+"</small>"; outMsg += "<input name="linech" title=""+MSG1036+""/></p></card>"; outMsg += printHelp( "WHR", MSG1001, MSG1008, MSG1038, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* "Út keresése csomag alapján". * Ha a szervlethez "?search=L&amp;pile=n" alakú kérés érkezik akkor ezt a * metódust hajtja végre. Ez megjeleníti a kivánt csomag tartalmát úgy hogy * az egyes elemek link-ként a keresett útra mutatnak. Ha valami miatt a * keresett csomag nem létezik akkor az Út kereső oldal kerül * megjelenítésre. (Ez a program helyes müködése során nem fordulhat elő) * @param pile a kiválasztott csomag

száma. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printSearchTrace( int pile, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // A kért adatok ellenörzése. Ha a kért csomag nincs a // csomagok

között akkor az Út kereső oldal megjelenítése SortedMap piles = pdb.getListOfTraceNames(pile); if( piles == null || piles.size() == 0 ){ printSearchTrace( response, res, addPar ); return; } // Az erőforrások betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1039 = (String)res.getObject("MSG1039"); String MSG1040 = (String)res.getObject("MSG1040"); String MSG1010 = (String)res.getObject("MSG1010"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1041 = (String)res.getObject("MSG1041"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSC">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help"

label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><b>"+MSG1039+"</b></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1040+"</small><br/>"; // Dinamikus tartalom kiirása a terminálra // Itt a kulcs egy út azonosítója az érték pedig az út neve. // a terminálra való kiirásjkor egy útnál az összes útvonal // objektum azonosítóját fel kell sorolni az obj listában. Iterator it = piles.keySet()iterator(); while( it.hasNext() ){ Long id = (Long)it.next(); String idList = ""; String str = (String)piles.get(id); Collection col = pdb.getTraceElementsByName( str ); Iterator it2 = col.iterator(); while( it2.hasNext() ) { Long l = (Long)it2.next(); idList += ((idList.length() != 0) ? ",":"")+l; } 153. oldal outMsg +=

"<!-- "+id+" -->&nbsp;<b><a title=""+str+"" href=""+ "waproute?query=alpha&amp;obj="+idList+addPar+"">"+str+ "</a></b><br/>"; } // Az oldal további tartalmának kiirása outMsg += "</p></card>"; outMsg += printHelp( "WHR", MSG1001, MSG1008, MSG1041, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* "Út keresés név alapján". * Ha a szervlethez "?search=L&amp;byname=xyz" alakú kérés érkezik akkor * ezt a metódust hajtja végre. Ez megjeleníti azoknak az utaknak a nevét * amelyekben szerepel a megadott karaktersorozat. Az összehasonlítás nem * kölönbözteti meg a kis és a nagy betüket. Ha az így végrehajtott *

keresésnek egy elem sem felel meg akkor az Út kereső oldal kerül * megjelenítésre. (Ez akkor fordulhat elő ha a felhasználó az útvonal * adatbázisban nem szereplő út névre keres.) * @param substr a keresett út nevének egy része. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a

kivételet váltja ki. */ private void printSearchTrace( String substr, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // A kért adatok ellenörzése. Ha nem létezik a megadott névvel // út az adatbázisban akkor az Út kereső oldal megjelenítése SortedMap piles = pdb.getListOfTraceNames(substr); if( piles == null || piles.size() == 0 ){ printSearchTrace( response, res, addPar ); return; } // Az erőforrások betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1039 = (String)res.getObject("MSG1039"); String MSG1040 = (String)res.getObject("MSG1040"); String MSG1010 = (String)res.getObject("MSG1010"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1041 = (String)res.getObject("MSG1041"); String outMsg = ""; // Az oldal tartalmának összeállítása outMsg +=

printHeader(); outMsg += "<wml><card id="WRSC">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help" label=""+MSG1002+""><go href="#WRH"/>"; outMsg += "</do>"; outMsg += "<p align="center"><b>"+MSG1039+"</b></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1040+"</small><br/>"; // Dinamikus tartalom kiirása a terminálra // Itt a kulcs egy út azonosítója az érték pedig az út neve. // a terminálra való kiirásjkor egy útnál az összes útvonal // objektum azonosítóját fel kell sorolni az obj listában. Iterator it = piles.keySet()iterator(); while( it.hasNext() ){ Long id = (Long)it.next(); String idList = ""; String str =

(String)piles.get(id); Collection col = pdb.getTraceElementsByName( str ); Iterator it2 = col.iterator(); 154. oldal while( it2.hasNext() ) { Long l = (Long)it2.next(); idList += ((idList.length() != 0) ? ",":"")+l; } outMsg += "<!-- "+id+" -->&nbsp;<b><a title=""+str+"" href=""+ "waproute?query=alpha&amp;obj="+idList+addPar+"">"+str+ "</a></b><br/>"; } // Az oldal további tartalmának kiirása outMsg += "</p></card>"; outMsg += printHelp( "WHR", MSG1001, MSG1008, MSG1041, MSG1010 ); outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* Alpha numerikus adatok megjelenítése objektumokról - azonosító alapján. * A paraméterben megadott

(alo) elem zonosítók felhasználásával a metódus * megjeleníti az elemek leírását a WAP terminálon. A különbözö tipusú * elemekről más más adatokat fog közölni ez a funkció. Valamint a * megjelenített adatokon kívül lehetőség van még az adatok mellet található * linkkel az adott objektumot a térképen megtekinteni. * @param alo Egy Long értékeket tartalmazó ArrayList amelyben szereplő * azonósítokkal rendelkező elemeket kell megjelenítenie a * funkciónak. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. * @throws IOException ha a

válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printAlphaQueryResults( ArrayList alo, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Bejövö adatok ellenőrzése, ha az adott azonosítókkal // nincsennek elemek az adatbázisban akkor a kezdeti oldal // megjelenítése, mert ilyen nem fordulhat elő. ArrayList elset = (ArrayList)pdb.getElementSet( alo ); if( elset == null || elset.size() == 0 ) { printStartPage( response, res, addPar ); return; } // Az oldal tartalmának összeállítása String outMsg = ""; outMsg += printHeader(); outMsg += "<wml>"; outMsg += printAlphaOnElements( elset, res, addPar ); outMsg += "</wml>"; // Az oldal kiírása a

kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* Alpha numerikus adatok megjelenítése objektumokról - terület alapján. * A paraméterben megadott területen elhelyezkedő objektumokból egy * listát készít. Ha a kijelölt területen vannak elemek akkor azonak * megjeleníti az alfanumerikus adatait. Ha nincsennek elemek akkor * ezt egy feliratot tartalmazó ablakban ezt tudatja a felhasználóval. * aki erröl az oldalró léphet egyet vissza vagy mehet a fömenübe is. * @param llx a megjelenítendő terület bal alsó * koordinátájának x komponense. * @param lly a megjelenítendő terület bal alsó 155. oldal * koordinátájának y komponense. * @param urx a megjelenítendő terület jobb felső * koordinátájának x komponense. * @param ury a megjelenítendő terület jobb felső * koordinátájának y komponense. * @param HttpServletResponse a kliens

terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. */ private void printAlphaQueryResults( double llx, double lly, double urx, double ury, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Az erőforrások betöltése // Az oldal tartalmának összeállítása String MSG1001 = (String)res.getObject("MSG1001"); String MSG1064 = (String)res.getObject("MSG1064"); String MSG1065 = (String)res.getObject("MSG1065"); String outMsg = ""; outMsg += printHeader(); outMsg += "<wml>"; // Bejövö adatok

ellenőrzése, ha az adott területen // nincsennek elemek akkor egy felirat megjelenítése // és a további funkciók a navigáláshoz: Vissza, Kezdőlap. ArrayList elset = (ArrayList)pdb.getElementSet( new Point(llx,lly), new Point(urx,ury) ); if( elset == null || elset.size() == 0 ) { outMsg += "<card>"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="main" label=""+MSG1064+"">"+ "<go href="waproute"+((addPar=="")?"":"?"+addPar)+ ""/></do>"; outMsg += "<p>"+MSG1065+"</p>"; outMsg += "</card>"; } else { outMsg += printAlphaOnElements( elset, res, addPar ); } outMsg += "</wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out =

response.getWriter(); out.println(outMsg); out.close(); return; } /* Az adott objektumok képének megjelenítése. * Egy Decket ír a kliens termináljára amiben egy képre van hivatkozás. * A képen az itt meghatározott elemek fognak megjelenni. A deck ezen kívül * tartalmazza még a térképen navigáláshoz szükséges funkciókat, valamint * a teljes térkép tartalmának megtekintéséhez és az aktuális nézet * elemeinek lekérdezéséhez szükséges linkeket is. Ha a bejövö adatok nem * érvényesek akkor a felhasználó a kezdőlapon találja magát. (Ez nem * fordulhat elő a program helyes müködése során.) * @param alo Egy Long értékeket tartalmazó ArrayList amelyben szereplő * azonósítokkal rendelkező elemeket kell megjelenítenie a * funkciónak. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat

tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. */ private void printGammaQueryResults( ArrayList alo, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Bejövö adatok ellenőrzése, ha az adott azonosítókkal // nincsennek elemek az adatbázisban akkor a kezdeti oldal // megjelenítése, mert ilyen nem fordulhat elő. ArrayList elset = (ArrayList)pdb.getElementSet( alo ); if( elset == null || elset.size() == 0 ) { printStartPage( response, res, addPar ); 156. oldal return; } // A befoglaló négyzet kiszámítása Point ll = null; Point ur = null; Iterator elit = elset.iterator(); while( elit.hasNext() ) { Object ob = elit.next(); if( ob instanceof Node ) { Point pt = ((Node)ob).getPoint(); ll = (( ll ==

null ) ? pt : Point.min( ll, pt ) ); ur = (( ur == null ) ? pt : Point.max( ur, pt ) ); } if( ob instanceof Trace ){ Point ptLL = ((Trace)ob).getLowerLeft(); Point ptUR = ((Trace)ob).getUpperRight(); ll = (( ll == null ) ? ptLL : Point.min( ll, ptLL ) ); ur = (( ur == null ) ? ptUR : Point.max( ur, ptUR ) ); } } // Ha még mindig nincs méret akkor tényleg gáz van // Ha van akkor egy minimális keretet kell neki adni. if( ll == null || ur == null ) { printStartPage( response, res, addPar ); return; } else { // A négyzet alakú teljesnézet kiszámítása double dCenterX = Math.ceil((llgetX()+urgetX())/20); double dCenterY = Math.ceil((llgetY()+urgetY())/20); double dWidth = Math.abs(llgetX()-urgetX()); double dHeight = Math.abs(llgetY()-urgetY()); dHeight = dWidth = Math.max(Mathceil(Mathmax(dWidth,dHeight)),40); ll = new Point( dCenterX-dWidth/2.0, dCenterY-dHeight/20 ); ur = new Point( dCenterX+dWidth/2.0, dCenterY+dHeight/20 ); } // Különben pedig meg kell jeleníteni a képet

tartalmazó oldalt printGammaQueryResults( ll.getX(), llgetY(), urgetX(), ur.getY(), response, res, addPar ); return; } /* Egy téglalap által határolt terület képének megjelenítése. * Egy Decket ír a kliens termináljára amiben egy képre van hivatkozás. * A képen az itt meghatározott terület fog megjelenni. A deck ezen kívül * tartalmazza még a térképen navigáláshoz szükséges funkciókat, valamint * a teljes térkép tartalmának megtekintéséhez és az aktuális nézet * elemeinek lekérdezéséhez szükséges linkeket is. * @param llx a megjelenítendő terület bal alsó * koordinátájának x komponense. * @param lly a megjelenítendő terület bal alsó * koordinátájának y komponense. * @param urx a megjelenítendő terület jobb felső * koordinátájának x komponense. * @param ury a megjelenítendő terület jobb felső * koordinátájának y komponense. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére

használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;" karaktersorozatot kell * tartalmaznia. */ private void printGammaQueryResults( double llx, double lly, double urx, double ury, HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Az erőforrások betöltése String MSG1001 = (String)res.getObject("MSG1001"); String MSG1052 = (String)res.getObject("MSG1052"); String MSG1053 = (String)res.getObject("MSG1053"); String MSG1054 = (String)res.getObject("MSG1054"); String MSG1055 = (String)res.getObject("MSG1055"); String MSG1056 = (String)res.getObject("MSG1056"); String MSG1057 =

(String)res.getObject("MSG1057"); String MSG1058 = (String)res.getObject("MSG1058"); String MSG1059 = (String)res.getObject("MSG1059"); String MSG1060 = (String)res.getObject("MSG1060"); String MSG1061 = (String)res.getObject("MSG1061"); String MSG1062 = (String)res.getObject("MSG1062"); 157. oldal String String String String MSG1063 = (String)res.getObject("MSG1063"); MSG1064 = (String)res.getObject("MSG1064"); MSG1080 = (String)res.getObject("MSG1080"); outMsg = ""; // Navigálás előkészítése a szélességnek és a magasságnak // meg kell egyeznie hogy jó méretarányos képet kapjunk. double width = Math.abs(urx-llx); double height = Math.abs(ury-lly); double centerx = (urx+llx)/2.0; double centery = (ury+lly)/2.0; llx = centerx-Math.max(width,height)/20; lly = centery-Math.max(width,height)/20; urx = centerx+Math.max(width,height)/20; ury =

centery+Math.max(width,height)/20; width = Math.abs(urx-llx); height = Math.abs(ury-lly); // A navigálás egysége a szélesség és a magasság negyede double navx = width/4.0; double navy = height/4.0; // A következő kiirások rövidítéséhez néhány konstans bevezetése String dt = "<do type="wr"; String la = "" label=""; String go = ""><go href="waproute?query=gamma"+addPar+"&amp;box="; String ga = ""><go href="waproute?query=alpha"+addPar+"&amp;box="; String pd = ""/></do>"; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRSC">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="main" label=""+MSG1064+"">"+ "<go

href="waproute"+((addPar=="")?"":"?"+addPar)+ ""/></do>"; outMsg += dt+"11"+la+MSG1054+go+ (llx-navx)+","+(lly+navy)+","+(urx-navx)+","+(ury+navy)+pd; outMsg += dt+"12"+la+MSG1053+go+ (llx+ 0.0)+","+(lly+navy)+","+(urx+ 00)+","+(ury+navy)+pd; outMsg += dt+"13"+la+MSG1052+go+( llx+navx)+","+(lly+navy)+","+(urx+navx)+","+(ury+navy)+pd; outMsg += dt+"21"+la+MSG1056+go+ (llx-navx)+","+(lly+ 0.0)+","+(urx-navx)+","+(ury+ 00)+pd; outMsg += dt+"23"+la+MSG1055+go+ (llx+navx)+","+(lly+ 0.0)+","+(urx+navx)+","+(ury+ 00)+pd; outMsg += dt+"31"+la+MSG1059+go+ (llx-navx)+","+(lly-navy)+","+(urx-navx)+","+(ury-navy)+pd; outMsg += dt+"32"+la+MSG1058+go+ (llx+

0.0)+","+(lly-navy)+","+(urx+ 00)+","+(ury-navy)+pd; outMsg += dt+"33"+la+MSG1057+go+ (llx+navx)+","+(lly-navy)+","+(urx+navx)+","+(ury-navy)+pd; outMsg += dt+"ot"+la+MSG1061+go+ (llx-navx)+","+(lly-navy)+","+(urx+navx)+","+(ury+navy)+pd; outMsg += dt+"in"+la+MSG1062+go+(llx+navx/2.0)+","+(lly+navy/20)+","+ (urx-navx/2.0)+","+(ury-navy/20)+pd; outMsg += dt+"al"+la+MSG1063+go+pdb.getLLX()+","+pdbgetLLY()+","+ pdb.getURX()+","+pdbgetURY()+pd; outMsg += dt+"alp"+la+MSG1080+ga+llx+","+lly+","+ urx+","+ury+pd; outMsg += "<p><img src="waproute?query=image&amp;box="+llx+","+lly+ ","+urx+","+ury+"" alt=""+MSG1060+"" /></p>"; outMsg +=

"</card></wml>"; // Az oldal kiírása a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } /* WBMP készítése az útvonal adatbázis egy részéről. * Egy olyan WBMP képet készít amelynek pozicióját és méretét a paraméterben * lehet szabályozni. Az elkészült WBMP dimenzioja automatikusan 98x98 pixel * lesz. * @param llx a megjelenítendő terület bal alsó * koordinátájának x komponense. * @param lly a megjelenítendő terület bal alsó 158. oldal * koordinátájának y komponense. * @param urx a megjelenítendő terület jobb felső * koordinátájának x komponense. * @param ury a megjelenítendő terület jobb felső * koordinátájának y komponense. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @throws IOException ha a válaszhoz tartozó kimenet

példányosítása nem * sikerült akkor generálódik ez a kivétel, vagy ha az ideiglenes * WBMP állomány nem olvasható a megadott helyen. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printImageResults(double llx, double lly, double urx, double ury, HttpServletResponse response ) throws IOException, ServletException { // Kért kép generálása String fileName = null; try { fileName = PathDatabase.writeWBMP( pdb.getImage(llx,lly,urx,ury), TempDirectory ); } catch (Exception e) { // Üzenet a szerver konzoljára, ha a kép generálása nem sikerült String msgError = getServletInfo()+": The requested image can not "+ "be created - Full storage?!"; System.outprintln(msgError); throw new ServletException(msgError); } // A kép beolvasása az elkészített állományból File fp = new File( fileName ); int flen =

(int)fp.length(); byte[] bytes = new byte[flen]; FileInputStream fis = new FileInputStream(fp); fis.read( bytes, 0, flen ); // Az oldal kiírása a kliens termináljára. response.setContentType("image/vndwapwbmp"); OutputStream out = response.getOutputStream(); out.write( bytes, 0, flen ); out.close(); return; } /* WapRoute bejelentkező oldal. * Egy olyan WML oldalt ir a kliens terminálra amin a a felhasználó * kiválaszthatja milyen nyelven szeretné igénybe venni a szolgáltatást * valamint keresési feltételek közül választhat. * @param HttpServletResponse a kliens terminálon megjelenítendő adatok * átvitelére használt osztály. * @param ResourceBundle egy osztály amelyből a metódus a szükséges nyelvi * erőforrásokat tudja előállítani. * @param String az oldalról kifele mutató linkek postfixét tartalmazza, * ilyen paraméter lehet például az "&amp;lng=en". Az itt érkező * stringnek az elején egy "&amp;"

karaktersorozatot kell * tartalmaznia. * @throws IOException ha a válaszhoz tartozó kimenet példányosítása nem * sikerült akkor generálódik ez a kivétel. * @see java.servlethttpHttpServletResponse#getWriter * @throws ServletException ha a metódus végrehajtása lehetséges akkor * a metódus ezt a kivételet váltja ki. */ private void printStartPage( HttpServletResponse response, ResourceBundle res, String addPar ) throws IOException, ServletException { // Az oldalon tarálható nyelv függő elemek betöltése String MSG1016 = (String)res.getObject("MSG1016"); String MSG1017 = (String)res.getObject("MSG1017"); String MSG1018 = (String)res.getObject("MSG1018"); String MSG1019 = (String)res.getObject("MSG1019"); String MSG1002 = (String)res.getObject("MSG1002"); String MSG1015 = (String)res.getObject("MSG1015"); String MSG1020 = (String)res.getObject("MSG1020"); String MSG1021 =

(String)res.getObject("MSG1021"); String MSG1023 = (String)res.getObject("MSG1023"); String MSG1024 = (String)res.getObject("MSG1024"); String MSG1026 = (String)res.getObject("MSG1026"); String MSG1027 = (String)res.getObject("MSG1027"); String MSG1029 = (String)res.getObject("MSG1029"); String MSG1008 = (String)res.getObject("MSG1008"); String MSG1010 = (String)res.getObject("MSG1010"); String MSG1001 = (String)res.getObject("MSG1001"); 159. oldal String String String String String String String String String MSG1030 = (String)res.getObject("MSG1030"); MSG1031 = (String)res.getObject("MSG1031"); MSG1032 = (String)res.getObject("MSG1032"); MSG1033 = (String)res.getObject("MSG1033"); MSG1022 = (String)res.getObject("MSG1022"); MSG1025 = (String)res.getObject("MSG1025"); MSG1028 = (String)res.getObject("MSG1028"); MSG1014 =

(String)res.getObject("MSG1014"); outMsg = ""; // Az oldal tartalmának összeállítása outMsg += printHeader(); outMsg += "<wml><card id="WRS" newcontext="true">"; outMsg += "<do type="functions" label=""+MSG1015+"">"; outMsg += "<go href="#WRF"/></do>"; outMsg += "<do type="help" label=""+MSG1002+"">"; outMsg += "<go href="#WRH1"/></do>"; for( int i=0; i<AvailableLanguages.length; i++ ) { outMsg += "<do type="WR"+i+"" label=""+AvailableLanguages[i][0]+ ""><go href="waproute?lng="+AvailableLanguages[i][1]+ ""/></do>"; } outMsg += "<p align="center">"; outMsg +=

"<big><b>"+MSG1016+"</b></big><br/><b>"+MSG1017+"</b>"; outMsg += "<br/>&nbsp;<br/><small>"+MSG1018+"</small>&nbsp;"; outMsg += "<b>"+MSG1019+"</b>"; outMsg += "</p></card><card id="WRF">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<do type="help" label=""+MSG1002+"">"; outMsg += "<go href="#WRH2"/></do>"; outMsg += "<p align="center"><big><b>"+MSG1015+"</b></big><br/></p>"; outMsg += "<p align="left">"; outMsg += "<b><i><a title=""+MSG1020+"" "; outMsg +=

"href="waproute?search=P"+addPar+"">"+MSG1021+"</a>"; outMsg += "</i></b>&nbsp;<small> "; outMsg += MSG1022+"</small><br/>"; outMsg += "<b><i><a title=""+MSG1023+"" "; outMsg += "href="waproute?search=C"+addPar+"">"+MSG1024+"</a>"; outMsg += "</i></b>&nbsp;<small> "; outMsg += MSG1025+"</small><br/>"; outMsg += "<b><i><a title=""+MSG1026+"" "; outMsg += "href="waproute?search=L"+addPar+"">"+MSG1027+"</a>"; outMsg += "</i></b>&nbsp;<small> "; outMsg += MSG1028+"</small><br/>"; outMsg += "</p><p

align="right"><i>"+MSG1029+"</i></p></card>"; outMsg += "<card id="WRH1">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<p align="center"><big><b>"+MSG1008+"</b></big><br/></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1014+"</small><br/></p><p align="right">"; outMsg += "<b>"+MSG1010+"</b></p></card>"; outMsg += "<card id="WRH2">"; outMsg += "<do type="prev" label=""+MSG1001+""><prev/></do>"; outMsg += "<p

align="center"><big><b>"+MSG1008+"</b></big><br/></p>"; outMsg += "<p align="left">"; outMsg += "<small>"+MSG1030+"</small>"; outMsg += "<br/><u><b><i>"+MSG1021+"</i></b></u><br/>"; outMsg += "<small>"+MSG1031+"</small>"; outMsg += "<br/><u><b><i>"+MSG1024+"</i></b></u><br/>"; outMsg += "<small>"+MSG1032+"</small>"; outMsg += "<br/><u><b><i>"+MSG1027+"</i></b></u><br/>"; outMsg += "<small>"+MSG1033+"</small>"; outMsg += "</p><p align="right"><b>"+MSG1010+"</b></p></card></wml>"; // Az oldal kiírása

a kliens termináljára. response.setContentType("text/vndwapwml"); PrintWriter out = response.getWriter(); out.println(outMsg); out.close(); return; } } // :WapRoute/WapRouteServlet.java -----------------------------------------END- 160. oldal