SOFTVERSKA ARHITEKTURA ZA TRANSFORMACIJU GEOPROSTORNIH PODATAKA SOFTWARE ARCHITECTURE FOR TRANSFORMATION OF GEOSPATIAL DATA Đorđe Obradović, Milan Segedinac {obrad, mseg@uns.ns.ac.yu Fakultet tehničkih nauka, Novi Sad Sadržaj U radu je prikazana arhitektura sistema za transformaciju geoprostornih podataka definisanih u GML jeziku u POJO Java objektni model. Sistem je specificiran korišćenjem UMLa i implementiran u programskom jeziku Java. Šabloni za kreiranje napisani su u freemarker jeziku a model podataka se dobija preuzimanjem opisa objekata preko WFS servisa. Abstract The paper presents the architecture of the system aimed for transformation of the geospatial data defined in GML into POJO Java object model. The szsstem is specified using UML and implemented in Java programming language. The code templates have been implemented in freemarker language and the data model is based on definition accurired from WFS service. 1. UVOD U geografskim informacionim sistemima (GIS) integracija podataka je veoma čest problem. Različiti sistemi koriste po pravilu različite načine reprezentacije geoprostornih podataka. Razvojem infrastrukture geoprostornih podataka postoji veoma izražena potreba da se geoprostorni podaci učine dostupnijima. Razvoj standarda u ovoj oblast pomaže da se implementiraju alati za jedinstven pristup ovoj vrsti podataka kao i servisima koji podatke obezbeđuju. Najbolji primer za to su rezultati koje je postigla neprofitna organizacija Open Geospatial Consortium OGC, razvojem standarda za opis geoprostornih podataka kao i servisa. Tako je usvojen GML (Geography Markup Language) standard [1] za opis i prenos geoprostornih podataka koji predstavlja prošireni XML jezik dostupan različitim platformama i tehnologijama i WFS (Web Feature Service Interface Standard) standard [2] za opis servisa za pristup ovim podacima. Međutim i dalje postoji problem veoma kompleksnih procedura za transformaciju tako opisanih podataka u Java objekte, odnosno u objekte pomoću kojih je moguće izvršiti implementaciju softvera za složene geoprostorne procese. Postoje dva načina transformacije: (1) transformacija podataka u generički objekat (Feature) koji ima dinamički definisane atribute; (2) konkretna (POJOPlain Old Java Object) Java klasa sa statički definisanim atributima. U prvom slučaju različite klase geoprostornih podataka mapiraju se na jedinstveni Java objekat a vrednosti se upisuju u dinimički kreirane atribute. Ovaj pristup implementiran je u biblioteci Geotools [4]. Nedostatak ovakvog pristupa je nemogućnost provere validnosti podataka za vreme kompajliranja. Drugi pristup podrazumeva da se geoprostorni podaci transformišu u Java objekte generisan 'po meri', odnosno na osnovu metapodataka koji karakterišu grupu geoprostornih podataka. Rad sa ovakvim objektima obezbeđuje kotrolu validnosti i za vreme kompajliranja a ne samo u toku izvršavanja i značajno olakšava razvoj. Razvoj je olakšan jer se za vreme implementacije mogu koristiti alati razvojnih okruženja za dopunjavanje koda, kontrolu tipova i praćenje povezanosti sa ostalim delovima. Nedostatak ovog pristupa je potreba za dodatnim kodiranjem u kojem se na osnovu meta podataka kreiraju same POJO klase kao i implementacija posebnih procedura za transformaciju i popunjavanje tako kreiranih Java objekata. U radu je opisana arhitektura sistema baziranog na drugom pristupu i generator izvornog koda kojim se ceo proces automatizuje. Generator je implementiran kao Java aplikacija koja koristi šablone u kojima je opisan format, a model podataka kreira se na osnovu metapodataka koji se dobijaju preko WFS. Kao osnovna komponenta generatora iskorišćen je programski paket freemarker koji poseduje poseban jezik (freemarker language) i koji je, zbog svoje rasprostranjenosti i jednostavnosti, ugrađen u IDE (Integrisano razvojno okruženje) eclipse. 2. KORIŠĆENI STANDARDI I TEHNOLOGIJE Za implementaciju sistema korićeni su sledeći osnovni standardi i tehnologije: GML, WFS, Geoserver, Geotools, FreeMarker i Xstream. GML je XML gramatika za predstavljanje geoprostornih podataka. GML jezik služi za modeliranje i prenos podataka između korisnika i proizvođača prostornih podataka. Kao i većina drugih XML gramatika GML dokumenti sadrže opis strukture podataka zajedno sa samim podacima. Na ovaj način je omogućena razmena geoprostornih podataka između više aplikacija. GML jezikom geografski podaci predstavljaju se tačkama, linijama i poligonima (slika 1). Postoje inicijative za specijalizaciju odnosno kreiranje gramatika za specijalne primene kao što su saobraćajnice, mostovi zgrade itd. WFS je standard kojim je regulisan način pristupa geoprostornim podacima. Obuvaćeno je pretraživanje i preuzimanje geoprostornih podataka na osnovu prostornih i neprostornih ograničenja, kreiranje novih podataka,
preuzimanje opisa osobina klasa geoprostornih podataka, brisanje, ažuriranje i zaključavanje. Geoserver (1.7.1) je server napisan u programskom jeziku Java čiji izvorni kod je otvoren za korišćenje i proširenje bez posebnih uslova licenciranja. Dizajniran je za potrebe interoperabilnosti i razmene geoprostornih podataka između najznačajnijih izvora prostornih podataka korišćenjem otvorenih standarda. Geoserver je referentna implementacija WFS standarda, Web Coverage Service (WCS) standarda kao i Web Map Service (WMS) standarda i trenutno predstavlja centralnu komponentu skupa alata čije zajedničko ime je Geoprostorni web. Geoserver je implementiran kao web aplikacija i moguće ga je instalirati na postojeći aplikativni server ili ga pokrenuti kao samostalnu aplikaciju. Ima module za preuzimanje podataka iz različitih izvora kao što su: Shape file DataStore, Post GIS DataStore, Oracle DataStore, DB2 DataStore, ArcSDE DataStore. Slika 1. UML reprezentacija GML gramatike za opis geoprostornih atributa Geotools je biblioteka Java klasa implementirana u skladu sa (LGPL) licencom otvorenog koda. Bibliotekom su implementirane osnovne metode za manipulaciju prostornim podacima neophodnim za implementaciju GIS softverskog sistema. Razvijena biblioteka iskorišćena je kao jezgro u više projekata (Geoserver, WebFeatureServer, WebMapServer) i desktop Java aplikacijama za implementaciju složenih geoprostornih procesa. Korišćenjem ove biblioteke omogućeno je parsiranje GML datoteka i njihova konverzija u Java objektni model prikazan na slici 2. Na slici je prikazan samo deo klasa koje se koriste ili se kreiraju prilikom parsiranja GML datoteke. Kao što se vidi na slici, veoma velika kompleksnost java objektnog modela predstavlja potencijalno mesto za grešku koju je moguće otkriti tek za vreme izvršavanja. U procesu implementacije poslovne logike procedure se oslanjaju na ovaj kompleksni Java objektni model, što predstavlja otežavajući faktor u razvoju inače kompleksnih aplikacija. U odeljku 3. prikazana je arhitektura u kojoj se kompleksan Java objektni model enkapsulira jednom POJO klasom i odgovorajućom Service klasom. POJO klasa enkapsulira model podataka a Service klasa enkapsulra osnovne metode za pristup findall, create, update i delete. Freemarker je biblioteka java klasa implementirana u skladu sa (BSD) licencom otvorenog koda a namenjena je za generisanje tekstualnih datoteka na osnovu Java objekata i datoteke u kojoj je šablon opisan freemarker jezikom. FreeMarker koristi se za generisanje bilo koje vrste tekstualnih datoteka HTML, XML, RTF, properties, JAVA ili čak za servlet bazirane aplikacije implementirane u skladu sa MVC (Model View Controler) obrascem ponašanja. Ideja razdvajanja modela podataka od prikaza u ovom radu iskorišćena je da se razdvoji obrazac ponašanja (šablon) od konkretnog modela podatka.
DefaultFeature AttributeT ype DefaultFeature::Com plexwrapper <<Unresolved Class>> Sim plefeatureim pl (sim ple) Sim plefeature Cloneable (util) AttributeDescriptor (type) Geom etryattributet ype Factory (factory) Feature Sim plefeaturet ype (sim ple) Geom etrydescriptor (type) Prim ativeattributet ype <<Unresolved Class>> DefaultFeatureT ype Feature::NULL Sim plefeature (sim ple) FeatureT ype AttributeT ypefactory Com parable Sim plefeaturet ype Slika 2. UML Dijagram klasa paketa org.geotools.feature Pokretanjem freemarker procesora dolazi do spajanja šablona i modela podataka koje kao rezultat ima generisanje tekstualne datoteke, što u konkretnom slučaju znači da se, na osnovu šablona i modela podataka, generiše izvorni kod klase. Na primer, za model podatak prikazan na listingu 1 i šablon prikazan na listingu 2, i uz pretpostavku da je naziv paketa i naziv klase promenljiv, možemo da generišemo Java izvorni prikazan na listingu 3. Hashtable htobjekat = new Hashtable(); htobjekat.put("paket", "yu.inf.gis "); htobjekat.put("nazivklase", "Putevi"); package ${paket Listing 1. Model podataka public class ${nazivklase { public ${nazivklase(){... Listing 2. FreeMarker šablon za kreriranje klase Putevi package yu.inf.gis; public class Putevi { public Putevi(){... Listing 1. Java klasa Putevi FreeMarker biblioteku moguće je koristiti i kao integralni deo IDE eclipse okruženja, kao ant proces ili kao samostalna Java aplikacija pod nazivom File generator tool FMPP. Poput FreeMarkera postoje i drugi proizvodi za kreiranje Java izvornog koda [5]: XSLT, Velocity, Jostraca, XDoclet itd. FreeMarker je izabran zbog otvorenog koda i mogućnosti porširenja. Xstream[6] je biblioteka java klasa implementirana u skladu sa (BSD) licencom otvorenog koda. a namenjena je jednostavnoj serijalizaciji java objekata u XML i iz njega. Osnovne osobine ove biblioteke su: jednostavno korištenje (dovoljno je uključenje xstream.jar datoteke u projekat), nije neophodno posebno mapiranje (xstream na osnovu opisa klase vrši automatsko mapiranje), čist XML, ne zahteva izmenu samih Java klasa, podržava serijalizaciju kompletnog grafa objekata i na kraju mogućnost proširenja različitim tehnikama konverzija npr. datuma, lozinki i slično. Najčešče se koristi za transport Java objekata, konfiguraciju, testiranje i skladištenje objekata. 3. SOFTVERSKA ARHITEKTURA ZA TRANSFORMACIJU PODATAKA IZ GML MODELA U JAVA OBJEKTNI MODEL Savremene softverske aplikacije namenjene upravljanju geoprostornim sistemima i procesima zahtevaju resurse koje je moguće obezbediti samo kolaboracijom tehnološki različitih sistema logički pa i prostorno distribuiranih. Ovo podrazumeva da je neophodno zadovoljiti dva osnovna zahteva: podršku distribuiranim sistemima i interoperabilnost. Model arhitekture koji ovo obezbeđuje je višeslojna arhitektura u kojoj su razdvojeni slojevi prezentacije, poslovne logike i pristupa podacima. Jedan primer primene ovakve arhitekture je aplikacija koja na mobilnom uređaju prikazuje statističke podatke obrađene i preuzete sa nekoliko različitih GIS sistema. Isti ti podaci
mogu preko prezentacionog sloja biti prikazani u obliku web stranice ili kao deo nekog poslovnog informacionog sistema. Model arhitekture ovakvog sistema prikazan je na slici 3. U ovom radu predložen je način za implementaciju sloja za pristup geoprostornim podacima i njihovo korišćenje u sloju za poslovnu logiku. freem arker.tem plate org.geotools.feature org.geotools.data com.thoughtworks.xstream prezentacioni sloj poslovna logika com.gint.app.generator sloj za pristup podacima Slika 4. Dijagram paketa generatora Na slici 5. prikazan je dijagram osnovnih klasa paketa com.gint.app.generator. Geoserver WFS/GM L WFS/GM L Geoserver2 # serverurl # objectnam e <<Constructor>> ObjectDefinition ObjectDefinition (String aserverurl, String aobjectname) getfeaturedescription () getserverurl () setserverurl (String serverurl) getobjectname () setobjectname (String objectname) {abstract : Hashtable PostGIS Oracle Shape file PostGIS2 Oracle2 Shape file2 Slika 3. Arhitektura sistema Zadatak sloja za pristup podacima je da obezbedi podatke iz različitih izvora geoprostornih podataka, te podatke transformiše u oblik pogodan za korišćenje u sloju poslovne logike i omogući skladištenje objekata. Osnovna transformacija podrazumeva transformaciju geoprostornih podataka opisanih GML gramatikom u Java objekat. Ova transformacija odvija se posredstvom klasa biblioteke geotools u kojima se kreira instanca klase Feature. Ona sadrži dinamičke atribute pojedinačnih klasa geoprostornih podataka. Pored ovog objekta kreira se i FeatureType objekat koji u sebi sadrži definiciju i opise pojedinačnih atributa. U ovom radu prikazano je rešenje koje usvaja preporuku da se za svaku klasu geoprostornih podataka kreira POJO Java klasa koja enkapsulira informacije sadržane u Feature objektu tako da u sloju poslovne logike, umesto pristupa dinamičkim atributima i kontroli u trenutku izvršavanja, kontrola može da se izvrši i u trenutku kompajliranja a pristup atributima pojednostavi. Generisanje POJO Java klasa vrši se u posebnoj Java aplikaciji uz korišćenje FreeMarker i Xstream biblioteka. Pored generisanja POJO Java klase generiše se i JavaService klasa koja vrši transformaciju Feature objekata na POJO Java objekat. Dijagram paketa aplikacije za generisanje prikazan je na slici 4. Osnovni paket je com.gint.app.generator koji koristi pakete freemarker.template, org.geotools.feature, org.geotools.data i com.thoughtworks.xstream <<Constructor>> # <<Override>> serverurl objectnam e srcfolder destfolder Gm lobjectdefinition GmlObjectDefinition (String aserverurl, String aobjectname) converttojavaname (String name) getfeaturedescription () DataLayerGenerator = "http://localhost:8080/geoserver" = "topp:sk_parcele" = "C:\\java\\minzzsworkspace\\gmlTest\\generator\\src" = "C:\\java\\minzzsworkspace\\gmlTest\\src\\com \\gint\\app\\config\\" <<Constructor>> DataLayerGenerator () readconfiguration (String filename) execute () main (String args[]) : boolean Slika 5. Dijagram klasa paketa com.gint.app.generator : Hashtable ObjectDefinition klasa je apstraktna klasa koja služi kao osnova za implementaciju pojedinačnih konkretnih klasa za preuzimanje definicije objekata. GMLObjectDefinition klasa implementira metodu getfeaturedescription u kojem se vrši priprema modela podataka potrebnih klasi DataLayerGenerator koja poziva freemarker biblioteku i generiše za svaki objekat po jednu POJO Java klasu i Service Java klasu. U metodi readconfiguration preuzima se konfiguracija iz XML konfiguracione datoteke koja sadrži informacije o url adresi konkretnog geoservera (serverurl), naziv grupe geoprostornih podataka (objectname), direktorijum u kojem se nalaze šabloni (srcfolder) i direktorijum u koji će se generisati rezltujuće datoteke (destfolder). Na listingu 4. dat je deo koda metode execute u kojoj se vrši generisanje POJO i Service Java klasa.
// inicijalizacija modela podataka GmlObjectDefinition gml = new GmlObjectDefinition(serverUrl, objectname); Hashtable ht = gml.getfeaturedescription(); Configuration cfg = new Configuration(); cfg.setdirectoryfortemplateloading( new File(srcFolder)); // inicijalizacija POJO sablona Template temp = cfg.gettemplate("gmlentity.java"); String nazivklase = (String)ht.get("nazivKlase"); File destfolderfile = new File(destFoldernazivK lase".java"); FileOutputStream fo = new FileOutputStream(destFolderFile); Writer out = new OutputStreamWriter(fo); //generisanje POJO Java klase temp.process(ht, out); out.flush(); fo.close(); // inicijalizacija Service sablona temp = cfg.gettemplate("gmlentityservice.java"); File srcfolderfile = new File(destFoldernazivKlase"S ervice.java"); fo = new FileOutputStream(srcFolderFile); out = new OutputStreamWriter(fo); // generisanje Service Java klase temp.process(ht, out); out.flush(); fo.close(); Listing 4. deo metode execute u kojoj se vrši generisanje POJO i Service Java klasa GML opis geoprostornog podatka sk_parcele dat je u listingu 5. <xsd:schema elementformdefault="qualified" targetnamespace = "http://www.openplans.org/topp "> <xsd:import namespace="http://www.opengis.net/gm l" schemalocation="http://localhost:8080/geo server/schemas/gml/3.1.1/base/gml.xsd"/> <xsd:complextype name="sk_parceletype"> <xsd:complexcontent> <xsd:extension base="gml:abstractfeaturetype"> <xsd:sequence> name="wkb_geometry" nillable="true" type="gml:geometrypropertytype"/> name="area" nillable="true" type="xsd:double"/> name="perimeter" nillable="true" type="xsd:double"/> name="id" nillable="true" type="xsd:double"/> name="kultura" nillable="true" type="xsd:string"/> </xsd:sequence> </xsd:extension> </xsd:complexcontent> </xsd:complextype> name="sk_parcele" substitutiongroup="gml:_feature" type="topp:sk_parceletype"/> </xsd:schema> Listing 5. GML opis sk_parcele objekta Na slici 6. prikazan je dijagram klasa koje se kreiraju na osnovu GML opisa datog u listingu 5. fullnam e ID wkb_geom etry area perim eter id kultura <<Getter>> <<Setter>> serverurl objectnam e : Geom etry SkParcele = "topp:sk_parcele" getid () setid (String aid) getwkb_geometry () setwkb_geometry (Geometry wkb_geometry) getarea () setarea (Double area) getperim eter () setperim eter (Double perim eter) getid () setid (Double id) getkultura () setkultura (String kultura) SkParceleService findall () create (SkParcele obj) update (SkParcele obj) delete (SkParcele obj) getserverurl () setserverurl (String serverurl) getobjectname () setobjectname (String objectname) = "http://localhost:8080/geoserver" = "topp:sk_parcele" : Vector<SkParcele> Slika 6. Dijagram generisanih klasa : S tring : Geom etry : S tring U listingu 6. prikazan je deo u kojem se vrši transformacija Feature objekta u SkParcele objekat. Feature feature = ft.next(); SkParcele sk = new SkParcele(); sk.setid(feature.getid());
sk.setwkb_geometry((geometry) feature.getattribute("wkb_geometry")) ; sk.setarea((double)feature.getattribute(" area")); sk.setperimeter((double) feature.getattribute("perimeter")) ; sk.setid((double)feature.getattribute("id ")); sk.setkultura((string)feature.getattribut e("kultura")); Listing 6. deo izvornog koda u kojem se vrši mapiranje Deo šablona na osnovu kojeg je nastao ovaj kod prikazan je u listingu 7. Feature feature = ft.next(); ${nazivklase sk = new ${nazivklase(); <#list atributi as bp> sk.set${bp.naziv?cap_first((${bp.tip) feature.getattribute("$ {bp.naziv")); </#list> Listing 7. Deo šablona na osnovu kojeg je nastao listing 6 Primer korišćenja generisanih klasa u sloju poslovne logike dat je u listingu 8. SkParceleService service = new SkParceleService( ); // preuzimanje svih elemenata iz // sloja za pristup podacima Vector<SkParcele> all = service.findall(); for (SkParcele skparcele : all) { String id = skparcele.getid(); String kultura = skparcele.getkultura(); 4. ZAKLJUČAK Korišćenjem ovako definisane softverske arhitekture implementacija sloja poslovne logike postaje nezavisna od korišćene tehnologije za obezbeđenje geoprostornih podataka. Klase koje se nalaze u sloju poslovne logike, umesto da koriste kompleksan Feature objekat i preko metode getattribute preuzimaju vrednosti, rade sa POJO Java objektima i pozivanjem get metoda preuzimaju konkretne vrednosti. Na ovaj način se prilikom kompajliranja obezbeđuje kontrola tipova. Predložena arhitektura ima još dve značajne karakteristike: jednostavne mehanizme za proširenje funkcionalnosti i jednostavne mehanizme za uključivanjie novih modela podatak. Samo dodavanjem novih šablona mogu se dodavati nove funkcionalnosti kao što je kreiranje klasa za automatizovano testiranje i dokumentovanje. Odgovarajućom implementacijom apstraktne klase ObjectDefinition generatoru se mogu obezbediti rezličiti modeli podataka, odnosno jednostavno rukovanje podacima iz različitih izvora. 5. LITERATURA [1] WFS, http://www.opengeospatial.org/standards/wfs [2] GML, http://www.opengeospatial.org/standards/gml [3] GEOSERVER http://geoserver.org/display/geos/welcome [4] GeoTools, http://geotools.codehaus.org/ [5] J. Herrington, Code Generation in Action, Manning publications co. 2003. [6] Xstream, http://xstream.codehaus.org/index.html NAPOMENA: Rezultati rada su deo projekta tehnološkog razvoja Alternativa za eupravu bazirana na otvorenim standardima i otvorenom kodu koji finansira Ministarstvo za nauku i tehnološki razvoj Republike Srbije. System.out.println(id " "kultura); // promena vrednosti i snimanje skparcele.setkultura("nova vrednost"); service.update(skparcele); Listing 8. Primer korišćenja generisanih klasa