Scriptie MES-Toolbox

advertisement
Scriptie MES-­‐Toolbox OpenStreetMap implementatie in de MES-­‐Toolbox Auteur Onderwijs instelling Opleiding Examinator Loopbaan Adviseur Stage bedrijf Bedrijf begeleider Versie Datum Jim Veldhuis (514601) Hogeschool van Amsterdam Technische Informatica Marten Teitsma Ferry Rietveld Cofely GDF-­‐Suez Siem Broersen 0.15 02-­‐01-­‐2012 Versiebeheer Versie Status Opzet 0.01 Datum 22-­‐aug-­‐2011 Opzet Opzet Opzet Opzet Opzet Opzet Opzet Opzet Opzet Opzet Opzet Opzet Opzet 06-­‐sep-­‐2011 15-­‐sep-­‐2011 06-­‐okt-­‐2011 13-­‐okt-­‐2011 18-­‐okt-­‐2011 21-­‐okt-­‐2011 29-­‐okt-­‐2011 07-­‐Nov-­‐2011 08-­‐Nov-­‐2011 15-­‐Nov-­‐2011 30-­‐Nov-­‐2011 15-­‐Dec-­‐2011 27-­‐Dec-­‐2011 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.10 0.11 0.12 0.13 0.14 Wijzigingen Opzet verslag met lay-­‐out, voorpagina en inhoudsopgave. Bedrijfs informatie verzamelen, en uittypen. Start maken met uitwerking van planning. Uitbreiding van hoofdstuk planning. Afronding hoofdstuk planning. Start maken met analysefase. Afronding analysefase. Start ontwerpfase. Uitbreiden ontwerpfase. Afronding ontwerpfase. Uitwerken Implementatiefase. Invoegen van eigen afbeeldingen. Uittypen van conclusie en reflectie. Referenties bijwerken, en verklarende woordenlijst opzetten. Spelfouten wegwerken, en zinsopbouw controle. Concept 30-­‐Dec-­‐2011 0.15 Goedkeuring Controle Versie Naam Datum Naam 0.15 Siem Broersen 04-­‐Jan-­‐2011 Scriptie MES-Toolbox
Jim Veldhuis
Goedkeuring Datum 2
Samenvatting An English version of this summary is available on the next page. Deze scriptie zal een onderzoek bevatten naar een implementatie van OpenStreetMap, met behulp van Geoserver. Deze afstudeeropdracht heeft plaatsgenomen bij Cofely te Zaandam, op de afdeling Manufacturing Execution System. OpenStreetMap is een gratis open source oplossing voor het gebruiken van kaarten data. Hiermee is het mogelijk om kaarten te maken en voor eigen of commerciële doeleinden te gebruiken. Hiermee kunnen hoge kosten worden voorkomen door kaarten te kopen van grote en vaak dure bedrijven. Geoserver is een Java gebaseerd programma dat gebruikt kan worden om vanuit verschillende bronnen geografische data te gebruiken. Het kan rekenen met geografische data waarmee coördinaten kunnen worden omgerekend naar verschillende projecties van de aarde. Door deze twee te combineren is het mogelijk om via een REST interface data verkrijgen, en deze te tonen op een kaart. Hiermee wordt het voor planners gemakkelijker om ritten te plannen doordat deze dichtbij elkaar gelegen klanten kunnen vaststellen. Ook is het mogelijk om vrachtwagens efficiënter te beladen doordat er meerdere klanten worden bediend met een enkele vrachtwagen. Scriptie MES-Toolbox
Jim Veldhuis
3
Summary This paper will enclose a research for an implementation of OpenStreetMap, with the use of Geoserver. This internship took place at Cofely, located in Zaandam, on the Manufacturing Execution System department. OpenStreetMap is a free to use open source solution for use of map data. With this it is possible to render maps for both personal and commercial purposes. With this high costs can be avoided by buying map data from big and often expensive companies. Geoserver is a Java bases program that can be used to collect and share geographical data from different resources. It has the ability to calculate with these geographical data to transform coordinates into another projection of the earth. By combining these two, it is possible to collect data by using the REST interface, and show these on the map. By this it is easier for planners to plan routes, because these planners can easily determine nearby located customers. Also this enables to load trucks more efficiently, due to delivery to multiple customers with a single truck. Scriptie MES-Toolbox
Jim Veldhuis
4
Verklarende woordenlijst C C++: Dit is een programmertaal dat een uitgebreide versie is van de programmeertaal C. Caching: Is het tijdelijk opslaan van data, met als doel sneller aanbieden van data. D Debian: Is een open source besturingssysteem dat gebaseerd is op de Linux kernel. E ERP: Staat voor Enterprise Resource Planning, en zorgt voor ondersteuning voor bedrijfsprocessen. G Geoserver: Is een open source programma gebouwd op Java, die kan rekenen met geografische data vanuit verschillende bronnen. GPS: Staat voor Global Positioning System en kan de geografische positie bepalen op de aarde met behulp van satellieten. H http: Staat voor Hypertext Transfer Protocol, dit is een protocol voor het communiceren tussen clients en servers. J Java: Java is een object georiënteerde programmeertaal. Jersey: Dit is een Java gebaseerde webserver. JPanel: Een container dat Java componenten kan vasthouden in een scherm. M Marshalling: Is het klaarmaken van een object voor het opslaan of verzenden hiervan. MES: Staat voor Manufactering Execution System en zorgt voor het monitoren en aansturen van productie processen. Mirror: Is een kopie van een server die gebruikt kan worden om sneller data aan te kunnen bieden, bijvoorbeeld doordat er een mirror fysiek dichterbij gevestigd is. MVC: Dit is een model voor het programmeren van programma’s, en wat structuur bied. Scriptie MES-Toolbox
Jim Veldhuis
5
O OPC: Staat voor OLE voor Process Control en is een standaard voor het versturen van data tussen verschillende industriële systemen. OpenStreetMap: Is een open source project dat kaarten data aanbied voor gratis gebruik. OSM: Is een afkorting voor OpenStreetMap, en tevens een bestands extensie dat gebruikt wordt door OpenStreetMap. OSM2PSQL: Is een programma dat gebruikt kan worden voor het importen van kaarten data in een PostgreSQL database. OSMOSIS: Is een programma dat gebruikt kan worden voor het samenvoegen, of extraheren van kaarten data uit een .osm bestand. P PLC: Staat voor Programmable Logic Controller en word ingezet om industriële systemen aan te sturen. PostgreSQL: Is een relationele database, wat inhoudt dat het relaties kan leggen tussen data in verschillende tabellen in de database. R REST: Staat voor Representational State Transfer, en is een manier van data oversturen tussen een client en een server, via het http protocol. S SCADA: Staat voor Supervisor Control and Data Acquisition, en is verantwoordelijk voor het ophalen, doorsturen en aanbieden van informatie uit een industriële omgeving. T Tiles: Tiles zijn afbeelding die onderdeel zijn van een grote afbeelding. Samen vormen deze een afbeelding. Tileset: Is een verzameling van tiles. U Ubuntu: Is een Linux distributie dat is gebaseerd op het besturingssysteem Debian. Unmarshalling: Is het tegenovergestelde van Marshalling, en is een proces dat ervoor zorgt dat verstuurder of opgeslagen data word omgezet in een object. Scriptie MES-Toolbox
Jim Veldhuis
6
URI: Staat voor Uniform Resource Identifier en word gebruikt om een resource te identificeren door middel van tekst. X XML: Staat voor Extensible Markup Language, en is een manier voor het opbouwen van taal zodat dit op een gestructureerde manier gebeurt. W WFS: Staat voor Web Feature Service en is een interface voor het aanbieden van data, en wordt gebruikt door Geoserver voor het aanbieden va geografische data. Scriptie MES-Toolbox
Jim Veldhuis
7
Inhoudsopgave SAMENVATTING .............................................................................................................................................. 3 SUMMARY .......................................................................................................................................................... 4 VERKLARENDE WOORDENLIJST ................................................................................................................ 5 INLEIDING ...................................................................................................................................................... 10 1. BEDRIJFSINFORMATIE .......................................................................................................................... 11 1.1 COFELY NEDERLAND ............................................................................................................................................... 11 1.2 COFELY NOORDWEST ............................................................................................................................................... 12 2. OPDRACHT FORMULERING ................................................................................................................. 14 2.1 PROBLEEMSTELLING ................................................................................................................................................ 14 2.2 DOELSTELLING .......................................................................................................................................................... 14 2.2.1 Randvoorwaarden ........................................................................................................................................... 15 2.3 PRODUCTEN ............................................................................................................................................................... 15 3. PLAN VAN AANPAK ................................................................................................................................. 16 3.1 SASHIMI-­‐MODEL ........................................................................................................................................................ 16 3.2 ANALYSEFASE ............................................................................................................................................................ 16 3.3 ONTWERPFASE .......................................................................................................................................................... 17 3.4 IMPLEMENTATIEFASE .............................................................................................................................................. 17 3.5 TESTFASE ................................................................................................................................................................... 17 3.6 ONDERHOUDSFASE ................................................................................................................................................... 17 3.7 FASEN OVERZICHT .................................................................................................................................................... 17 4. ANALYSE ..................................................................................................................................................... 19 4.1 TILE SERVER .............................................................................................................................................................. 19 4.1.1 Tiles genereren .................................................................................................................................................. 20 4.1.2 Schijruimte en genereertijd ......................................................................................................................... 22 4.2 MES-­‐TOOLBOX ......................................................................................................................................................... 24 4.3 GEOSERVER ................................................................................................................................................................ 27 4.3.1 REST plug-­‐in ....................................................................................................................................................... 29 5. ONTWERPEN ............................................................................................................................................. 30 5.1 TILE SERVER .............................................................................................................................................................. 30 5.2 MES-­‐TOOLBOX EN GEOSERVER ............................................................................................................................. 32 5.3 OVERZICHT ................................................................................................................................................................ 35 6. IMPLEMENTATIE ..................................................................................................................................... 37 6.1 TILE SERVER .............................................................................................................................................................. 37 6.2 REST RESOURCES .................................................................................................................................................... 37 6.2 MAPVIEWER .............................................................................................................................................................. 37 6.3 FEATURELAYER ........................................................................................................................................................ 38 6.4 MODEL ........................................................................................................................................................................ 38 6.5 VIEW ........................................................................................................................................................................... 39 6.6 VIEWADAPTER .......................................................................................................................................................... 39 7. CONCLUSIE ................................................................................................................................................ 40 ZELFREFLECTIE ............................................................................................................................................ 41 LITERATUURLIJST ....................................................................................................................................... 42 BIJLAGE A: AFSTUDEER OPDRACHT ...................................................................................................... 43 BIJLAGE B: SAMENVATTING SCRIPTIE DHR. N. SOELTAN .............................................................. 44 Scriptie MES-Toolbox
Jim Veldhuis
8
BIJLAGE C: CUSTOMERRESOURCE.JAVA ............................................................................................... 45 BIJLAGE D: ENTITY.JAVA ........................................................................................................................... 52 BIJLAGE E: MAPVIEWER.JAVA ................................................................................................................. 54 BIJLAGE F: FEATURELAYER CODE .......................................................................................................... 64 Scriptie MES-Toolbox
Jim Veldhuis
9
Inleiding In de industriële automatisering ligt er tussen de ERP en de SCADA lagen, de MES laag. Een MES is een informatiesysteem voor het monitoren en het aansturen van productieprocessen met een batch of continu karakter, bijvoorbeeld in olieproductie en –verwerking, metaalindustrie, chemie of voedingsmiddelenindustrie. Voor deze MES laag heeft Cofely West een applicatie gebouwd die de naam “MES-­‐Toolbox” draagt. Deze MES-­‐Toolbox zorgt ervoor dat de taken worden uitgevoerd die van een MES worden verwacht. Hieraan toegevoegd zijn extra functionaliteiten om het besturingsproces te vereenvoudigen, planning mogelijk te maken en orders te kunnen beheren. Een andere functie is een ritten planning, die zorgt dat planners gemakkelijk ritten kunnen plannen van de fabriek naar een klant. Hierbij wordt nagedacht over de bestelde hoeveelheden, dicht bij elkaar gelegen klanten en de te vervoeren producten. Om dit mogelijk te maken is het wenselijk dat er een gemakkelijk overzicht is waar een planner kan zien waar een klant gevestigd is en welke order hierbij hoort. In deze scriptie zal een onderzoek omschreven worden naar het ontwikkelen van een implementatie van een opensource kaarten service, genaamd “OpenStreetMap”. Tevens wordt er onderzoek gedaan naar een mogelijkheid om zelf gegenereerde tiles aan te leveren met de informatie die beschikbaar wordt gemaakt door OpenStreetMap. De scriptie begint met achtergrond informatie over het bedrijf waar de afstudeeropdracht heeft plaatsgenomen. Hierop volgend zal er in hoofdstuk 2 een gedetailleerde omschrijving gegeven worden van de afstudeeropdracht. In hoofdstuk 3 zal een planning besproken worden die voorafgaand aan de opdracht is vastgelegd. Hoofdstuk 4 bevat een analyse en beschrijvingen van producten en technieken die direct of indirect gerelateerd zijn aan deze opdracht. Vervolgens komen in hoofdstuk 5 ontwerpen aan bod en zal de implementatie van de opdracht in hoofdstuk 6 besproken worden. Hierop volgend zal een conclusie van de opdracht getrokken worden in hoofdstuk 7. Deze scriptie sluit af met een zelfreflectie, een literatuurlijst en tot slot de bijlagen. Scriptie MES-Toolbox
Jim Veldhuis
10
1. Bedrijfsinformatie Het bedrijf waar de afstudeeropdracht heeft plaats gevonden is Cofely – GDF Suez, hierna genoemd Cofely. Cofely is een beursgenoteerd bedrijf en houdt zich voornamelijk bezig met elektrotechniek, installatietechniek en procesautomatisering. Cofely is onderdeel van GDF Suez Energy Services, wat op zijn beurt onderdeel is van GDF Suez. GDF Suez Energy Services is de Europese marktleider in op het gebied van duurzame energie en milieuoplossingen. GDF Suez is een frans multinational energy maatschappij dat zich bezig houdt met elektriciteit winning en distributie, aardgas, en duurzame energie, en is hiermee de grootste energie leverancier van de wereld [1]. Het is s’ werelds grootste nutsbedrijf na overname van International Power van Groot Brittannië, dat origineel is opgezet door een fusie van Gaz de France en Suez op 22 Juli 2008 [2]. In afbeelding 1.1 is de bedrijfsstructuur van GDF Suez te zien die zich concentreert op Cofely Nederland. Cofely -­‐ GDF Suez
Energy France Energy Europe & International Global Gaz & LNG
France Energy Services Tractebel Engineering Infrastructures France Installation and related Services Fabricom Axima Cofely (Belgie) Benelux Energy Services Suez Environment International North Power Companies International South Cofely Fabricom (Nederland) Afbeelding 1.1 Organogram van de bedrijfsstructuur van GDF Suez. In dit hoofdstuk zullen we verder nog dieper ingaan op achtereenvolgens Cofely Nederland en Cofely Noordwest. In deze subhoofdstukken zullen we doornemen wat deze bedrijven doen en hoe de structuur is binnen deze bedrijven. 1.1 Cofely Nederland Cofely heeft vele vestigingen die verspreid zijn over Nederland. Het hoofdkantoor van Cofely Nederland is gevestigd in Bunnik. Cofely Nederland is verdeeld in regiobedrijven, marktsegment bedrijven, specialistische bedrijven competence centers. Regiobedrijven richten zich op optimale technische dienstverlening in de regio. Marktsegmenten bedrijven richten zich op bedrijfsprocessen van een bepaalde markt. Specialistische bedrijven zijn experts op een bepaald vakgebied. Competence centers zijn kennis-­‐ en ontwikkelcentra waar Cofely werkt aan innovaties en verbeteringen van hun producten en diensten. Afbeelding 1.2 laat een structuur zien van de opbouw van Cofely Nederland. Scriptie MES-Toolbox
Jim Veldhuis
11
Afbeelding 1.2 Structuur van Cofely Nederland.
1.2 Cofely Noordwest Deze afstudeeropdracht heeft plaatsgevonden bij het regiobedrijf Cofely Noordwest. Binnen Cofely Noordwest bevinden zich onder andere de afdelingen Industrial Automation (IA), en Manufacturing Execution System (MES). De MES afdeling ontwikkelt voornamelijk nieuwe software oplossingen en verbeterd deze. Een van deze producten is de eerder genoemde MES-­‐Toolbox. De IA afdeling voert projecten uit op het gebied van procesautomatisering. In deze projecten wordt gebruik gemaakt van software oplossingen van de MES afdeling. Deze twee afdelingen werken nauw samen met elkaar. In figuur 1.3 is een organogram van Cofely Noordwest te zien.
Scriptie MES-Toolbox
Jim Veldhuis
12
Afbeelding 1.3 organogram Cofely Noordwest. Marc Dierikx is begeleider gedurende deze opdracht, en werkt op de MES afdeling als programmeur van de MES-­‐Toolbox. Scriptie MES-Toolbox
Jim Veldhuis
13
2. Opdracht formulering De formele opdracht omschrijving luidt als volgt: Onderzoek of “OpenStreetMap” als geografische basis kan functioneren voor de MES Toolbox. Ontwerp een model waarbij de kaart informatie beschikbaar wordt gesteld op een server. De geografische data moet eenvoudig kunnen worden geüpdatet. Vanuit deze Geoserver moet een Java Swing panel beschikbaar komen in de MES Toolbox client applicatie. Hierbij is vooral de interfacing tussen de Geoserver en client belangrijk i.v.m. performance .De bestel informatie van klantorders moet grafisch op deze kaart worden weergegeven m.b.v. symbolen gecombineerd met tekst. De symbolen moeten klik baar zijn waardoor onder in beeld de informatie van de bestelling kan worden weergegeven. Onderzoek tevens of m.b.v. deze oplossing route planning kan worden uitgevoerd. Daarnaast moet er een systeem komen waarmee de coördinaten van de klantlocaties kunnen worden bepaald, bij voorkeur automatisch op basis van postcode en huisnummer. Een mogelijk alternatief is de huidige oplossing waarbij de geografische data in een scherm wordt gecombineerd met het klantbestand. Door selectie van een klant en een punt op de kaart wordt de locatie vastgelegd. In Bijlage A is de gehele opdracht omschrijving te vinden zoals deze is aangemeld bij Cofely. In dit hoofdstuk zal dieper ingegaan worden op de probleem-­‐ en doelstelling, hierna zal er kort uitgelicht worden wat er verwacht wordt qua oplevering. 2.1 Probleemstelling Binnen de MES-­‐Toolbox is er een overzicht van alle orders die klaar zijn om getransporteerd te worden. Wanneer een rittenplanner bezig is met het inplannen van ritten naar klanten is het mogelijk om op een scherm de posities van deze klanten te bekijken. Op basis hiervan kan de planner een inschatting maken van de dichtbij elkaar gelegen klanten, en zo deze indien mogelijk samen te voegen in een rit. Wanneer er ritten gepland worden is het niet mogelijk om op basis van de order te bepalen waar de klant gevestigd is. De planner die gebruik maakt van deze kaart dient zelf op de kaart te zoeken naar de locatie en zo te plannen. Een andere eis is dat de kaarten data zo min mogelijk hoeft te worden geüpdate. Dit omdat een vernieuwing van deze data veel geld kost. Doordat wegen voortdurend veranderen, nieuwe wegen worden aangelegd, straatnamen veranderen en dergelijken is het wel gewenst om deze kaarten data up-­‐to-­‐date te kunnen houden. 2.2 Doelstelling Voor het opzoeken van de klant is gekozen voor de volgende oplossing. Wanneer in het order overzicht op een order wordt gedrukt, wordt automatisch op de kaart de positie van de klant weergegeven. Dit zal resulteren in een snellere planning doordat de planner niet op eigen kracht de positie hoeft te bepalen. Scriptie MES-Toolbox
Jim Veldhuis
14
Om de kosten van het updaten van de kaarten data laag tot wel nihil te houden is gekozen om OpenStreetMap te implementeren. Op deze manier kun je frequent de kaarten updaten en zo beter service leveren voor de planners. Wenselijk is om op een server eigen kaarten tiles te genereren. Op deze manier kun je bij gebruikers van de MES-­‐Toolbox een tileset afleveren, die zij vervolgens direct kunnen gebruiken in de MES-­‐Toolbox. 2.2.1 Randvoorwaarden Om dit product juist geïmplementeerd te krijgen in de MES-­‐Toolbox en als product te kunnen leveren aan klanten dient de te implementeren software aan een aantal eisen voldoen: 1. Verzoeken tussen client en server dienen te verlopen via een REST interface; 2. Punten op de geografische kaart dienen via GeoServer te worden aangevraagd; 3. Tiles moeten kunnen geleverd worden als gerenderde Tileset; 4. Tiles moeten gemakkelijk kunnen worden gerenderd en uitgebreid worden. Deze voorwaarden samen zorgen ervoor dat je een hoogwaardig product krijgt wat aan de standaarden van de MES-­‐Toolbox zal voldoen. 2.3 Producten De volgende producten zullen aan het einde van de opdracht worden opgeleverd: • MES-­‐Toolbox met OpenStreetMap implementatie; • Broncode van bovengenoemde implementatie; • Stappenplan voor het opzetten van tile server; • Documentatie van de OpenStreetMap implementatie. Scriptie MES-Toolbox
Jim Veldhuis
15
3. Plan van Aanpak Om op een gestructureerde manier tot een eindproduct te komen is er voorafgaand aan de opdracht een planning opgesteld. De fasen die in voor deze opdracht doorlopen zijn, zijn: analysefase, ontwerpfase, implementatiefase en de testfase. Deze structuur is voortgekomen uit de watervalmethode. Binnen de waterval methode zal er gebruik gemaakt worden van het “Sashimi”-­‐model. In dit hoofdstuk zal er meer informatie gegeven worden over het Sashimi-­‐model, hierna zal er per fase besproken worden wat er verwacht word in deze fase. Vervolgens zal er een overzicht van de termijnen getoond worden waarin duidelijk wordt wanneer welke fase gestart / afgerond dient te worden. 3.1 Sashimi-­‐model Het Sashimi-­‐model is opgezet door Peter Degrace. De fasen zijn hetzelfde als in de traditionele watervalmethode, alleen nu overlappen de fasen elkaar ook. Door gebruik te maken van deze methode worden er veel minder bronnen verspild. Afbeelding 3.1 geeft weer hoe de fasen elkaar overlappen. Dit is echter een illustratie en dit geeft dus niet de werkelijke overlapping weer qua verhouding! Het verschil met het schematische overzicht van de standaard watervalmethode is dat de fasen deze keer tegen de doorlooptijd afgedrukt zijn. Dit betekent dat men al begint met het ontwerp terwijl de analyse nog bezig is. Dit betekent ook dat men terug kan vallen op de analyse in de ontwerpfase.
Afbeelding 3.1 Schematisch overzicht van de Sashimi-­‐watervalmethode met overlappende fasen... 3.2 Analysefase Gedurende de analysefase wordt er kennis opgedaan over de werking van de programma’s en de systemen die bij Cofely gebruikt worden. Hierbij zal het voornamelijk gaan om de MES-­‐Toolbox. Binnen deze fase zal ook onderzocht worden wat er nodig is om een tile-­‐server op te zetten. Zo zal er gekeken worden naar de opbouw die binnen OpenStreetMap gebruikt wordt om tiles te genereren, en wat er zelf gebruikt kan worden om dit proces na te bootsen. Scriptie MES-Toolbox
Jim Veldhuis
16
3.3 Ontwerpfase Tijdens de ontwerpfase zal er gestart gaan worden met het opzetten van een tile-­‐server, en zal er een Java code geschreven worden. Deze Java code zal een scherm omvatten waarin de tiles, die gegenereerd zijn via de tile-­‐server, getoond worden. Dit scherm zal later in de implementatiefase geïmplementeerd worden in de MES-­‐Toolbox. Wanneer het ontwerp van dit scherm klaar is, zal er gekeken gaan worden wat voor aanpassingen er in de MES-­‐Toolbox gedaan dienen te worden zodat dit scherm in de MES-­‐Toolbox beschikbaar wordt. 3.4 Implementatiefase Deze fase zal alles omvatten wat betreft de implementatie van het scherm dat gemaakt is in de ontwerpfase. Zo is er in subhoofdstuk 3.3 genoemd dat er gekeken zou worden naar de veranderingen die MES-­‐Toolbox moet ondergaan om de Java code werkend te krijgen. Deze wijzigingen zullen in deze fase doorgevoerd worden. Tevens zal er in de MES-­‐Toolbox een functie komen om ervoor te zorgen dat de kaart gekoppeld wordt aan de lijst met orders zodat deze acties op elkaar uit kunnen voeren. Zoals bijvoorbeeld, als je op een order drukt, je op de kaart de locatie van de Klant te zien krijgt. 3.5 Testfase In deze fase zal er uitgebreid getest worden door middel van verschillende scenario’s of er fouten zijn die opgelost dienen te worden. Doordat er gebruik gemaakt wordt van het Sashimi-­‐model zal deze fase de implementatie fase overlappen waardoor deze fase aanzienlijk korter zal zijn dan een normale testfase. Dit komt doordat je onmiddellijk de fouten die gevonden zijn kunt oplossen. 3.6 Onderhoudsfase Deze fase zal gedurende de afstudeeropdracht niet doorlopen worden. 3.7 Fasen overzicht Analysefase: • MES-­‐Toolbox analyseren; • Onderzoek doen naar OpenStreetMap; • Onderzoek doen naar benodigdheden voor tile-­‐server. Ontwerpfase: • Opzetten tile-­‐server; • Java code voor OpenStreetMap scherm; • Onderzoeken van benodigde wijzingen in MES-­‐Toolbox. Implementatiefase: • Implementeren van Java code in MES-­‐Toolbox; • Benodigde wijzigingen MES-­‐Toolbox; • Koppeling maken tussen scherm en orders. Testfase: • Testen van implementatie in MES-­‐Toolbox; • Testen tile-­‐server. Scriptie MES-Toolbox
Jim Veldhuis
17
Analysefase Ontwerpfase Implementatiefase Testfase Scriptie MES-Toolbox
Jim Veldhuis
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 18
4. Analyse Zoals in de opdracht omschrijving is beschreven dient er bij deze opdracht gebruik gemaakt te worden van OpenStreetMap en hiervoor een implementatie te construeren voor de MES-­‐Toolbox. Om tot een eindproduct te komen met goede kwaliteit dient er een uitgebreide analyse uitgevoerd te worden. Deze analysefase zal opgedeeld worden in drie delen: 1. Het opbouwen van een server voor het genereren van tiles, wordt later in dit hoofdstuk uitgelicht, op basis van OpenStreetMap data; 2. De raakvlakken binnen de MES-­‐Toolbox en mogelijke problemen die zich hierbij voor kunnen doen; 3. Geoserver in combinatie met REST plug-­‐in. In dit hoofdstuk zal er eerst ingegaan worden op de het analyse gedeelte van de tile server en vervolgens op de MES-­‐Toolbox, hierna zal nog verteld worden over Geoserver. Aan het einde van dit hoofdstuk zal duidelijk gemaakt zijn welke software er benodigd zijn om tot het eindproduct van deze opdracht te komen. 4.1 Tile server In dit subhoofdstuk zal de analyse naar de tile server besproken worden. Dit omvat zowel een onderzoek naar het genereren van tiles, zaken als bestandsgrootte en genereertijd, en software die hiervoor benodigd zijn. De functie van een tile server is het genereren van tiles die vervolgens als tileset gebruikt kunnen worden in een product, in het geval van deze opdracht de MES-­‐
Toolbox. Om te begrijpen wat de functie is van deze tiles, zal er eerst uitgelegd worden wat tiles precies inhouden en wat de functies hiervan zijn, en wat dit voor betrekking heeft op OpenStreetMap. Hierop volgend zal de software besproken worden waarin er uitgelegd wordt wat hun functies zijn, waarom deze van belang zijn voor de doelstelling. OpenStreetMap OpenStreetMap is een open source project van de “OpenStreetMap Foundation”, en zijn begonnen met project om gebruikers te voorzien van gratis kaarten [3]. Het doel van OpenStreetMap is om te voorkomen dat bedrijven dure kaarten moeten kopen van bedrijven die veel tijd en geld steken in het up-­‐to-­‐date houden van hun kaarten. Deze bedrijven vragen vaak veel geld voor deze kaarten en hierdoor wordt het product dat ermee gepaard gaat ook duurder. Doordat OpenStreetMap het bijhouden van kaarten data aan gebruikers overlaat kunnen zij deze data gratis aanleveren. Gebruikers die kaarten data bijwerken zorgen dat zij een GPS ontvanger bij zich dragen. Bij thuiskomst uploaden zij de data van deze ontvanger en passen zij de data aan zodat de onnauwkeurigheden, van bijvoorbeeld slecht GPS signaal, recht gezet worden. Vervolgens wordt deze data toegevoegd aan de OpenStreetMap database. Deze data kan vervolgens worden uitgelezen worden door beheerders, particulieren en/of bedrijven om hier tiles van te genereren. Scriptie MES-Toolbox
Jim Veldhuis
19
Tiles Tiles is gedurende dit verslag een veel voorkomende term, en zal in dit hoofdstuk duidelijk worden wat deze tiles zijn, en waar deze voor gebruikt kunnen worden. Tiles zijn kleine afbeeldingen die onderdeel zijn van een groter geheel. Dit houdt in dat een tile onderdeel is van een afbeelding, en dat dus meerdere tiles bij elkaar een afbeelding tonen. Dit principe zal afgebeeld worden in afbeelding 4.1 waarin te zien is dat tiles samengevoegd kunnen worden tot een grote afbeelding. Afbeelding 4.1: Presentatie van functie tiles. Door gebruik te maken van deze techniek kan de tijd van het laden van een afbeelding aanzienlijk worden verkleind. Doordat deze techniek veel tijd winst oplevert, wordt het om deze reden veel gebruikt bij het tonen van kaarten. Het idee achter tiles is dat je bijvoorbeeld niet in een keer de gehele afbeelding wilt laten zien van de gehele wereld, maar in plaats daarvan slechts een klein gedeelte. Zoomlevel OpenStreetMap gebruikt bij het tonen van kaarten de term “zoomlevel”. Deze geeft aan hoe dicht er op de kaart is ingezoomd, en is bij OpenStreetMap afgesteld op een bereik van 0 tot en met 18. Waarbij 0 volledig uitgezoomd, 156.412 meter per pixel, en 18 volledig ingezoomd, 0,596 meter per pixel [4]. Wanneer je kijkt naar zoomlevel 18, met zijn bijhorende schaal van 0,596 meter per pixel, is al snel te zien dat dit een gigantische afbeelding zou zijn wanneer je de gehele planeet in een afbeelding zou plaatsen. Om deze reden zijn tiles geïntroduceerd. 4.1.1 Tiles genereren In dit subhoofdstuk zal besproken worden welke software er benodigd zijn, met de in deze opdracht gebruikte basis opstelling, om tiles te genereren. De software zal besproken worden in volgorde van werking. Dit houdt in dat we volgens een stappenplan toewerken naar een gegenereerde tileset, dus basis opstelling, downloaden van kaarten data, data importeren naar de database, genereren van tileset. Scriptie MES-Toolbox
Jim Veldhuis
20
Basis opstelling Gedurende deze opdracht is er voor de tile server een virtuele machine beschikbaar gesteld. Hiervoor is gekozen vanwege het flexibel houden van de server omgeving, dit houdt in dat wanneer de server extra geheugen nodig heeft er geen gehele nieuwe machine geïnstalleerd dient te worden. Tevens is het gemakkelijker om de server te dupliceren en een back-­‐up te maken. De virtuele machine kreeg de in tabel 4.1 specificaties toegewezen. Type Waarde Processor AMD Opteron Processor 4180 Cores te beschikking 2 CPU MHZ 2609 MHz Geheugen 8 GB Schijfruimte 95 GB Tabel 4.1: Overzicht specificaties virtuele machine. Voor het besturingssysteem is gekozen voor de op Debian gebaseerde Ubuntu Linux distributie. Net als OpenStreetMap is Ubuntu een open source project. Tevens is er afgesproken dat er gebruik gemaakt wordt van de LTS versie van Ubuntu. Een LTS, Long Term Support, versie biedt langere ondersteuning in beveiliging updates, dan een standaard Ubuntu versie [5]. Downloaden van kaarten data OpenStreetMap levert elke week nieuwe kaarten data aan die gebruikers kunnen downloaden en zo naar eigen wil kunnen gebruiken. Deze bevat de nieuwste data en op deze manier is mogelijk om altijd de laatste kaarten data te bezitten. Het bestand dat OpenStreetMap aanlevert bevat de extensie .OSM, en is een eigen extensie van OpenStreetMap. Het bevat informatie over drie verschillende gebieden, namelijk: Nodes, Ways en Relations [6]. Samen vormen deze de data die gepresenteerd wordt op de kaart. Nodes, eindpunten in het Nederlands, bevatten informatie over een enkel punt. Elke node bevat 1 eindpunt. Het is opgebouwd uit een latitude en een longitude, welke afkomstig zijn uit het coördinaten systeem. Latitude representeert de locatie noordelijk of zuidelijk van de evenaar[7], waar de longitude de locatie representeert westelijk en oostelijk op de planeet [8]. Deze nodes kunnen zelfstandig zijn waardoor ze objecten kunnen positioneren zoals bijvoorbeeld een sportveld, bushalte of supermarkt. Ook kunnen ze gebruikt worden om gecombineerd met andere punten een weg te vormen. Ways, wegen in het Nederlands, is een combinatie van verschillende eindpunten om zo een weg te visualiseren. Dit object bevat informatie zoals het type weg, straatnaam en eenrichtingsverkeer. Relations, relaties in het Nederlands, kan relaties leggen tussen punten, wegen en zelfs tussen relaties. Doordat het bestand dat OpenStreetMap aanbiedt de gehele planeet omvat, is het niet verstandig deze direct te gebruiken vanwege de schijfruimte. Hiervoor zijn er een aantal mirrors die de data van OpenStreetMap extraheren en verdelen in kleinere pakketten. Scriptie MES-Toolbox
Jim Veldhuis
21
Hierbij kan gedacht worden aan data alleen voor Europa, Afrika of Nederland. Hierdoor kan een hoop onnodige schijfruimte bespaard blijven. Data importeren in de database OpenStreetMap biedt de keuze aan om naar eigenkeuze gebruik te maken van een database. De database die gebruikt dient te worden is echter afhankelijk van de software die gebruikt gaat worden voor het genereren van de tiles. Niet alle software hiervoor is compatible met alle verschillende databases, om deze reden dient er gekeken te worden naar de software voor het genereren van de tiles. In het geval van deze opdracht wordt er gebruik gemaakt van Mapnik als generatie tool en hiervoor dient er gebruik gemaakt te worden van een PostgreSQL database. PostgreSQL is een relationele database, wat inhoudt dat er tussen verschillende tabellen relaties gelegd kunnen worden door middel van de data in de kolommen [9]. Tevens dient er voor deze PostgreSQL database een PostGIS extensie te worden geïnstalleerd. Deze extensie bied de mogelijkheid om te kunnen omgaan met geografische data, wat vereist is voor Mapnik. De software die gebruikt word voor het extraheren van het OSM bestand en het importeren van de data is OSM2PGSQL. Deze tool zorgt dat alleen de nodige data uit het bestand geëxtraheerd en geïmporteerd wordt, zodat in een later stadium het genereren van de tiles sneller verloopt dan direct vanaf het OSM bestand. Genereren van tiles Zoals eerder in dit hoofdstuk genoemd wordt er voor het genereren van de tiles gebruik gemaakt van Mapnik. Mapnik is een open source tool dat geschreven is in C++[10], en biedt de mogelijkheid om te communiceren met een PostgreSQL database. In deze database staat de data die Mapnik nodig heeft om de tiles te kunnen genereren. Doordat deze software kan zien welke punten samen een weg vormen kan het een lijn tekenen wat een weg voorstelt op de kaart. Wanneer de tiles gegenereerd zijn worden deze geplaatst in een opgegeven locatie. De map structuur is als volgt: {zoomlevel}/{Y locatie}/{X locatie}.png. Hierdoor is er een logische opbouw van de opgeslagen tiles en zijn deze gemakkelijk terug te vinden. 4.1.2 Schijruimte en genereertijd In dit subhoofdstuk zal naar voren komen hoeveel schijfruimte er geschat kwijt is aan tiles, en hoe lang het duurt om tiles te genereren. Dit zal gedaan worden aan de hand van een eigen onderzoek. Dit onderzoek is verricht met kaarten data enkel van de landen die onder Benelux vallen. Hierdoor verklein je het onderzoeksgebied, dit bespaart ruimte en genereertijd. Elke tile die gegenereerd wordt kan variëren in bestandgrootte. Dit komt doordat een tile waarop alleen zee te zien is, dus alleen blauw, kleiner is dan een tile waarop verschillende straten en straatnamen staan. Dit is één van de cruciale punten die mee wegen in het schatten van de bestandsgrootte van een complete tileset. Een andere punt dat van belang is voor het inschatten van formaat van de tileset, is het begrijpen van de verhouding tussen zoomlevels en tiles. Voor elke tile komt er per Scriptie MES-Toolbox
Jim Veldhuis
22
zoomlevel 4 voor terug. Dit is geïllustreerd in afbeelding 4.4, waar te zien is hoe tiles reageren op het verhogen van het zoomlevel. Dit zal als resultaat hebben dat per zoomlevel je tileset 4 keer zo groot wordt. Afbeelding 4.4: Illustratie van de reactie van tiles bij het verhogen van het zoomlevel. In tabel 4.2 is te zien hoe de bestandgrootte toeneemt gelijk met de genereertijd van de tiles. Hier gaan we in zoomlevels stijgen van 2, dit wordt gedaan omdat het beeld dan ook getekend wordt maar minder ruimte in beslag neemt. Tevens zullen wij maar tot niveau 15 gaan in verband met schijfruimte en tijd. Zoomlevel Bestandsgrootte Genereertijd 0 20 KB ± 2 𝑚𝑖𝑛𝑢𝑡𝑒𝑛 2 24 KB ± 5 𝑚𝑖𝑛𝑢𝑡𝑒𝑛 4 20 KB ± 15 𝑚𝑖𝑛𝑢𝑡𝑒𝑛 6 56 KB ± 30 𝑚𝑖𝑛𝑢𝑡𝑒𝑛 8 564 KB ± 1𝑢𝑢𝑟 10 7.220 KB ± 2𝑢𝑢𝑟 12 80.636 KB ± 3.5𝑢𝑢𝑟 14 918.108 KB ± 8𝑢𝑢𝑟 Tabel 4.2: Tabel met resultaten van tile onerzoek. Zoals te zien is zit de bestandsgrootte op zoomlevel 14 al op bijna 1 gigabyte aan schijfruimte. Om deze reden is er verkozen om voor productie gebruik tot level 15 te gaan, aangezien dat ver genoeg is ingezoomd voor de werkzaamheden die ermee gedaan zullen worden. Zoals in tabel 4.1 te zien is loopt de tijd op naarmate er een dieper zoomlevel wordt bereikt. Wanneer in de MES-­‐Toolbox een aanvraag gedaan wordt voor een tile, is het gewenst om zo snel mogelijk de aanvraag af te handelen. Wanneer de tile pas op aanvraag gegenereerd wordt, duurt het langer voor de aanvraag afgehandeld kan worden. Om deze reden is het de bedoeling om vooraf een gegenereerde tileset aan te leveren voor gebruik binnen de MES-­‐Toolbox. Scriptie MES-Toolbox
Jim Veldhuis
23
4.2 MES-­‐Toolbox De MES-­‐Toolbox is een software pakket dat is ontwikkeld door Cofely, en wordt ingezet op verschillende projecten. Een van deze projecten is een veevoeder fabriek in Nijkerk. Dit project is gebruikt voor deze opdracht om als basis MES-­‐Toolbox te functioneren. Een project zoals de veevoeder fabriek in Nijkerk bestaat uit systemen die over verschillende lagen in de automatisering piramide bestaan, de piramide is te zien in afbeelding 4.5. De lagen die de MES-­‐Toolbox overlapt zijn de MES en SCADA lagen. Wat deze lagen inhouden zal later in dit hoofdstuk uitgelegd worden. ERP (Ondersteuning van productieproces) MES (Aansturing van het productieproces) SCADA (Visualitsatie van productieproces)
PLC (Productieproces besturing) I/O
(Bussystemen, Sensoren, Actuatoren) Afbeelding 4.5: Automatisering piramide. Normaliter wordt de MES-­‐Toolbox aangesloten op het ethernet, waarna deze via OPC PLC’s kan aansturen. In dit hoofdstuk zal besproken worden hoe de MES-­‐Toolbox is opgebouwd en van welke modules er gebruik worden gemaakt binnen dit systeem. SCADA SCADA staat voor “Supervisor Control And Data Acquisition”, en is een laag in de automatisering piramide die zorgt voor de proces visualisatie [11]. Dit is het systeem dat operators binnen een fabriek gebruiken om de statussen van apparatuur te kunnen volgen. In geval van nood is het mogelijk voor de operators om in te kunnen grijpen en zo het proces onder controle te krijgen. SCADA biedt de controle en visualisatie van een enkel proces of eventueel de gehele fabriek afhankelijk van het geïmplementeerde systeem. Om een voorbeeld van een SCADA systeem te geven is er in afbeelding 4.6 een deel van zo een systeem te zien. Het betreft hier een menger waarbij handmatig grondstoffen kunnen worden toegevoegd. Op de afbeelding is te zien hoe een operator kan zien Scriptie MES-Toolbox
Jim Veldhuis
24
hoeveel gewicht er inzit, bruto en netto, en wat het gewenste gewicht is. Dit is een simpel voorbeeld van wat een SCADA systeem voor informatie kan bieden. Afbeelding 4.6: Voorbeeld van een SCADA system. MES Een MES, Manufactering Execution System, staat boven de SCADA laag in de piramide. En zorgt voor de processen op een hoger niveau, hierbij kan gedacht worden aan het bijhouden van recepturen, opnemen van orders, bijhouden van klanten en locatiebeheer [12]. Tevens zorgt een MES voor het bijhouden van log bestanden voor zaken als wettelijke verplichte zaken als grondstoffen beheer en toevoeging, halffabricaten en afhandeling van eindproducten. Opbouw MES-­‐Toolbox De MES-­‐Toolbox is geprogrammeerd in de object-­‐georiënteerde taal Java. Dit houdt in dat er geprogrammeerd wordt door middel van objecten, die gerepresenteerd worden door klassen. Hierbij is de klasse een blauwdruk voor een object en is een object altijd een instantie van de klasse. Binnen de MES-­‐Toolbox wordt er veel gebruik gemaakt van XML. Deze XML bestanden worden veelal gebruikt om instellingen te verkrijgen voor de MES-­‐Toolbox. Bij deze instellingen kan gedacht worden aan projectnaam, klantnaam of database tabellen. Deze bestanden worden ook gebruikt voor het in-­‐ en uitschakelen van modules. Dit programma is modulair opgezet wat inhoudt dat de MES-­‐Toolbox is opgebouwd uit kleine los staande modules. Door modules in te schakelen is het mogelijk om de functionaliteit uit te breiden. Enkele van deze functies zijn: rittenplanning, fysiekmodel designer en voorraad beheer. In het geval van deze opdracht wordt er gebruik gemaakt van de klanten module, order module, en de webserver module. Klant module De klant module van de MES-­‐Toolbox is een module die ervoor zorgt dat er een klanten systeem bij gehouden kan worden. Voor elke klant wordt er contact informatie bewaard en informatie over de locatie waar zij gevestigd zijn. Deze informatie is van belang voor deze opdracht omdat dit de informatie is die getoond zal gaan worden in de kaart die Scriptie MES-Toolbox
Jim Veldhuis
25
wordt gegenereerd door middel van OpenStreetMap. In afbeelding 4.7 is te zien hoe het huidige scherm van het klanten overzicht er uitziet in de MES-­‐Toolbox. Afbeelding 4.7: Overzicht van klanten. Order module De order module die is geïmplementeerd in de MES-­‐Toolbox is een order beheer systeem. Het kan orders van klanten accepteren in de MES-­‐Toolbox die vervolgens verwerkt worden in de fabriek. Bijvoorbeeld wanneer door een klant 10 ton aan veevoer besteld wordt, wordt deze in het order systeem geplaatst welke vervolgens in de fabriek wordt geproduceerd. In afbeelding 4.8 is te zien hoe het huidige order systeem een overzicht genereerd waarin de planners kunnen zien hoe zij moeten plannen. Afbeelding 4.8: Overzicht van orders. Voor elke order die in de MES-­‐Toolbox wordt geplaatst, wordt er een klant aan gekoppeld. Elke klant die een order heeft zal op de kaart aangetoond worden waarna een planner kan zien waar de klanten met een order zich bevindt. Webserver module De webserver module is een module die aanvragen accepteert. Deze aanvragen dienen te verlopen volgens het REST model, dit model wordt verder uitgebreid besproken in hoofdstuk 5. Voor elke REST aanvraag dient er een resource aanwezig te zijn die de gewenste waardes teruggeeft. Scriptie MES-Toolbox
Jim Veldhuis
26
MVC Binnen de MES-­‐Toolbox wordt er vastgehouden aan het MVC principe. MVC staat voor Model View Controller, dit is een model dat de programmeur dient vast te houden en wat overzicht biedt binnen applicatie [13]. Door structureel alle modules op te bouwen via MVC is de opbouw van een module altijd logisch en is er gemakkelijk te herleiden wat er gebeurd binnen deze module. In afbeelding 4.9 is te zien hoe de communicatie verloopt binnen MVC. MES-Tooolbox
Controller
View
Afbeelding 4.9: MVC in kaart gebracht Model
Controller De controller binnen MVC is de klasse die de communicatie regelt tussen de model en de view. Tevens is dit de klasse waarbij de aanvraag binnen komt voor de data. Bijvoorbeeld wanneer er een aanvraag binnen komt voor een bepaalde pagina, om deze weer te geven. Hierna haalt de controller de data op uit de model waarbij de controller de data doorgeeft aan de view, die vervolgens deze data weergeeft. Model Dit is de klasse die ervoor zorgt dat er data vanuit de database wordt verkregen. Deze wordt in de klasse zo gevormd dat de controller hiermee kan werken en hierna kan doorgeven aan de View klasse. View De view klasse is verantwoordelijk voor het afhandelen van de view kant. Hier wordt de data verkregen van de controller omgevormd tot een grafische interface. Het zorgt dat de gebruiker gemakkelijk de data kan bekijken. 4.3 Geoserver Geoserver is een open source programma dat is ontwikkeld in Java, net zoals de MES-­‐
Toolbox [14]. Het is een programma dat kan rekenen met geografische data, en de resultaten publiceren op het netwerk. In dit subhoofdstuk zal besproken worden wat de functionaliteiten zijn waar we gebruik van maken binnen Geoserver, en de REST plug-­‐in die benodigd is voor de opdracht. Cofely heeft een eigen programma ontwikkeld dat inzicht kan bieden in de opstellingen binnen een fabriek. Dit programma heet CATIS, Cofely Asset Tracking and information System. Dit programma maakt gebruik van Geoserver om kaarten van de fabriek te Scriptie MES-Toolbox
Jim Veldhuis
27
kunnen genereren. Hierdoor is het mogelijk om punten op een kaart te laten zien. Om te zorgen dat de opdracht later geïmplementeerd kan worden in CATIS is het gewenst om binnen de MES-­‐Toolbox gebruik te maken van Geoserver. Hierdoor is het later gemakkelijker om te kunnen migreren naar CATIS. In afbeelding 4.10 is een screenshot te zien van CATIS waarin een fabriek vloer wordt getoond. Afbeelding 4.10: Afbeelding van CATIS met plattegrond van fabriek vloer. WFS WFS, Web Feature Service, is een service waar Geoserver gebruik van maakt. Het is een standaard voor het opvragen van web features, hierdoor weet je altijd op wat voor manier je deze terug aangeleverd krijgt. WFS werkt met een aantal standaard methodes die aangeroepen kunnen worden, deze zijn: GetCapabilities, DescribeFeatureType en GetFeature. GetCapabilities is een methode dat een XML document teruggeeft waarin staat aangegeven welke lagen er beschikbaar zijn in de service. DescribeFeatureType is een methode dat een schema weergeeft van de opgevraagde lagen. GetFeature is de methode die een GML bestand teruggeeft met hierin alle features in een laag. Hierin staan de punten waarop deze zich bevestigen, met deze data kun je ze plaatsen op de kaart die gegenereerd word. Scriptie MES-Toolbox
Jim Veldhuis
28
4.3.1 REST plug-­‐in Cofely heeft applicatie ontwikkeld die de apparatuur in een fabriek in kaart kan brengen met de daarbij behorende informatie. Dit programma wordt CATIS genoemd, Cofely Asset Tracking and Information System. Hiervoor heeft een stagiair een plug-­‐in geschreven die de MES-­‐Toolbox , genaamd de REST plug-­‐in. Deze is geschreven door Nazeem Soeltan, de samenvatting van zijn scriptie is bijgevoegd als bijlage B. Deze REST plug-­‐in zorgt ervoor dat wanneer er een web feature wordt aangevraagd bij Geoserver, deze via een REST aanvraag, wordt verder uitgelegd in hoofdstuk 5, bij de MES-­‐Toolbox data opgevraagd. In afbeelding 4.11 is te zien hoe deze verbinding loopt. Afbeelding 4.11: Tekening uit verslag Nazeem Soeltan, toont functie REST plug-­‐in. Scriptie MES-Toolbox
Jim Veldhuis
29
5. Ontwerpen In dit hoofdstuk zullen de ontwerpen besproken worden die zijn gemaakt in de ontwerpfase. Hierbij kan gedacht worden aan tekeningen waarbij de relaties worden gelegd tussen verschillende servers en/of services. Er zal begonnen worden met een uitleg over een model dat is opgezet voor de tile server om de onderlinge software te laten communiceren. Hierna zal er een model uitgelegd worden waarin de communicaties worden uitgewerkt tussen de MES-­‐Toolbox en Geoserver. 5.1 Tile server In dit subhoofdstuk zal besproken worden hoe de communicatie tussen OpenStreetMap en de onderzochte tile server zoals besproken in hoofdstuk 4. Het zal duidelijk worden hoe de communicatie verloopt tussen verschillende software en welke connecties er gelegd worden tussen de servers. In dit hoofdstuk zal het deel omvat worden van OpenStreetMap tot aan de tileset. OpenStreetMap backend Zoals in hoofdstuk 4 te lezen is dient er van OpenStreetMap kaarten data gedownload te worden. Binnen OpenStreetMap wordt er vanuit een PostgreSQL database gebruik gemaakt van een programma genaamd “Osmosis”. Dit programma zet data om in een .osm bestand waarna deze gedownload kan worden. In afbeelding 5.1 is de backend van OpenStreetMap te zien waarbij de data wordt omgezet in een .osm bestand die aangeboden wordt als download. PostgreSQL
Afbeelding 5 1: Backend van OpenStreetMap. Osmosis
Planet dump
Tile server In de tile server dient het .osm bestand in een database geplaatst te worden. Dit wordt gedaan middels het programma OSM2PSGL, deze importeert het bestand in de PostgreSQL database. Vervolgens is het de taak van Mapnik om de database uit te lezen waarna deze de tiles gaat genereren. In afbeelding 5.2 is te zien hoe het pad loopt binnen de tile server. Scriptie MES-Toolbox
Jim Veldhuis
30
Mapnik
Stylesheet
Mapnik
PostGIS
(PostgreSQL)
OSM2PGSQL
Document
Document
Tiles
Afbeelding 5.2 Tile server opbouw. Wanneer we deze twee zaken met elkaar combineren komt er een, zoals in afbeelding 5.3 te bekijken, schema uit. Dit schema omvat zowel het OpenStreetMap gedeelte als het gedeelte waar de tile server zich mee bezig houdt. PostgreSQL
Osmosis
Planet dump
PostGIS
(PostgreSQL)
OSM2PGSQL
Mapnik
Stylesheet
Mapnik
Document
Document
Tiles
Afbeelding 5.3 Gehele schema van tile server inclusief de OpenStreetMap backend. Scriptie MES-Toolbox
Jim Veldhuis
31
5.2 MES-­‐Toolbox en Geoserver In dit subhoofdstuk zal een koppeling getekend worden tussen de MES-­‐Toolbox en Geoserver. Zo zal ook vast een verbinding gelegd worden tussen Geoserver tussen CATIS en Geoserver. Binnen de MES-­‐Toolbox dient er een REST resource aangemaakt te worden die de klanten teruggeeft bij een REST aanvraag. Dit wordt afgehandeld in de zogenaamde Customer module, deze module beheert alle klanten en is verantwoordelijk voor de verbinding tussen de database en de MES-­‐Toolbox met betrekking tot klanten. Een aanvraag die de MES-­‐Toolbox doet zal via Geoserver verlopen zodat er later via CATIS dezelfde klant informatie verkregen kan worden. Een dergelijk model zoals bovenstaand omschreven zal als volgt eruit komen te zien. Het model is weergegeven in afbeelding 5.4. Customer
REST Resource
Geoserver
MES-Toolbox
CATIS
Afbeelding 5.4: Communicatie tussen MES-­‐Toolbox en de customer module. Zoals te zien in bovenstaande afbeelding is er geen verschil in de communicatie tussen CATIS & Geoserver en de MES-­‐Toolbox & Geoserver. Hierdoor zorg je ervoor dat zowel CATIS als de MES-­‐Toolbox beide dezelfde data tonen. MVC Binnen de MES-­‐Toolbox is de implementatie van MVC verwaterd. Gedurende de opbouw van het project zijn er beslissingen genomen die ervoor gezorgd hebben dat MVC anders geïmplementeerd is. Op moment van schrijven is de implementatie van het MVC model zodanig zoals in afbeelding 5.5. Scriptie MES-Toolbox
Jim Veldhuis
32
Controller
ViewAdapter
Instance
View
ViewAdapter
Model
ViewAdapter
Subklasse
Afbeelding 5.5: MVC implementatie van de MES-­‐Toolbox. Zoals te zien is communiceert de Controller met de view. Binnen deze communicatie wordt er aan de View een object gegeven dat een ViewAdapter bezit. De ViewAdapter is een klasse die twee onderdelen bevat, namelijk: de data van de model, en een component om te tonen in de view. Het component dat in de ViewAdapter plaats vindt handelt de data af en bepaalt wat er met de data van het model gebeurt. Bijvoorbeeld wanneer de ViewAdapter subklasse een label is zal dit label de inhoud tonen van de model, is de subklasse een colorpicker dan zal deze de kleur laten zien uit de waarde die verkregen is uit de model. Op deze manier is het mogelijk om eigen data te verwerken in een component. Zo is het ook de bedoeling om voor deze opdracht een eigen ViewAdapter te schrijven met een eigen subklasse. In dit geval zal het een subklasse omvatten die de kaart zal tonen met tiles gegenereerd door de tile server. Hierover meer in hoofdstuk 6. REST Bij deze opdracht is het de bedoeling dat er via REST een klantenlijst, met locaties overgedragen kan worden van de MES-­‐Toolbox via Geoserver, terug naar de MES-­‐
Toolbox. REST staat voor Representational State Transfer, en is een model dat voornamelijk gebruikt maakt van het http protocol. Het is een vorm van communicatie en afspraken waar aan gehouden dient te worden om ervoor te zorgen dat er een stabiele basis is voor communicatie. Deze afspraken zijn: 1. Client-­‐Server Communicatie verloopt altijd tussen client en server, waarbij de client geen zorgen heeft over de opslag van data, en de server geen zorgen heeft over de afhandeling van de data. Clients en servers kunnen onafhankelijk van elkaar doorontwikkeld worden zolang de interface maar onaangetast blijft. 2. Stateless Geen enkele staat van de client dient opgeslagen te worden in de server. Alle informatie die de server nodig heeft om een aanvraag af te handelen is voorzien in de aanvraag. Scriptie MES-Toolbox
Jim Veldhuis
33
3. Cacheable Er dient een keuze gemaakt te worden of caching gebruikt wordt of niet. Wanneer de keuze gemaakt wordt om gebruik te maken van caching, dient er geen communicatie meer te verlopen tussen de client en de server. De cache dient dus altijd client-­‐sided te gebeuren. 4. Layered system Een client heeft geen weet van wat er met de aanvraag gebeurt. Zo weet de client niet af van doorverwijzingen op de achtergrond. Hiermee wordt er bedoeld dat wanneer een server functioneert als tussenliggende server, de client hier niets van merkt. 5. Uniform interface De interface tussen client en server dient altijd ongewijzigd te blijven. Dit houdt in dat beide platformen onafhankelijk ontwikkeld kunnen worden maar de interface gelijk blijft. Om een visualisatie geven van de opbouw van de structuur die in deze opdracht wordt gebruikt, is er in afbeelding 5.6 een visualisatie van de REST structuur te zien. Deze structuur zal aangehouden worden om in het geval van deze opdracht de klanten lijst met locaties te verkrijgen. Interface
Interface
MES-Toolbox
Geoserver
MES-Toolbox
REST-Resource
Afbeelding 5.6: Visualisatie van de interfaces in verband met deze opdracht. Zoals REST dit voorschrijft zal de MES-­‐Toolbox geen weet hebben van het bestaan van Geoserver, en dus aannemen dat de lijst met klanten afkomstig is van de MES-­‐Toolbox. Een REST resource is altijd benaderbaar via een URI, deze URI bepaalt welke resource er aangesproken word. Bij binnenkomst van URI zal de juiste resource aangesproken worden waarna er een object gevormd word welke hierop volgend retourneert wordt. Binnen REST zijn er een 4 operaties die kunnen worden uitgevoerd, namelijk: view, add, update en delete. Respectievelijk aan deze operaties hangen de volgende HTTP operaties: GET, POST, PUT, DELETE. REST interface De MES-­‐Toolbox maakt gebruik van Jersey, dit is een Java gebaseerde webserver die gebruikt wordt om de resources aan te bieden. Voor de interface van de REST verbinding is gekozen om XML bestanden over te sturen, deze worden binnen Java omgezet met de JAXB library. Deze zorgt ervoor dat een object omgezet kan worden in XML. Dit proces word ook wel marshalling / unmarshalling genoemd. In afbeelding 5.7 is in kaart gebracht hoe dit proces verloopt. Scriptie MES-Toolbox
Jim Veldhuis
34
@XMLRootElement
public Entity {
int id;
Object value;
}
JAXB
<objects>
<object id="0">
<value>StringValue</value>
</object>
</objects>
Afbeelding 5.7: Verloop van marshalling binnen de Jersey java webserver. 5.3 Overzicht Door de voorgaande elementen samen te koppelen krijg je een systeem dat OpenStreetMap aan de MES-­‐Toolbox koppelt. In afbeelding 5.8 staat een tekening weergegeven waarin te zien is hoe alle modellen samenhangen. PostgreSQL
Osmosis
Planet dump
PostGIS
(PostgreSQL)
OSM2PGSQL
Mapnik
Stylesheet
Mapnik
Document
Document
Tiles
Handmatige
kopie
Geoserver
Customer
REST Resource
MES-Toolbox
CATIS
Afbeelding 5.8: Overzicht van connecties van deze afstudeeropdracht. Scriptie MES-Toolbox
Jim Veldhuis
35
Zoals te zien is in bovenstaande afbeelding, dienen de tiles handmatig gekopieerd te worden voor gebruik van Geoserver. Dit is omdat een fabriek geen rechtstreekse internet verbinding naar buiten heeft waardoor de Geoserver niet rechtstreeks met de tile server kan communiceren. Tilesets worden daarom handmatig gekopieerd en overhandigd aan de klanten. Wanneer de tileset eenmaal handmatig gekopieerd is, kan deze worden aangesproken door Geoserver en doorgegeven worden aan de MES-­‐Toolbox en / of CATIS. Scriptie MES-Toolbox
Jim Veldhuis
36
6. Implementatie Om de opdracht te kunnen voldoen dienen er een aantal zaken geïmplementeerd te worden, dit zijn onder andere: 1. REST-­‐Resource, voor het verkrijgen van klanten lijst; 2. MapViewer, voor het bekijken van kaarten; 3. FeatureLayer, voor het tekenen van punten; 4. Model, voor het ophalen van data; 5. View, voor het weergeven van data; 6. ViewAdapter, voor het communiceren tussen Model en View; 7. Tile server, voor het genereren van tiles; 8. Geoserver, voor het aanbieden van geografische data. Al deze zaken zullen aanbod komen in dit hoofdstuk en zullen uitgebreid beschreven worden. 6.1 Tile server Voor de implementatie van de tile server is gekozen om deze te installeren op een virtuele machine. Deze beslissing is genomen om geen fysieke machine te hoeven installeren en replicaties gemaakt worden. De implementatie zal verricht worden na het model dat is beschreven in het hoofdstuk ontwerpen. Volgens het ontwerp dienen er de volgende programma’s geïnstalleerd te worden: OSM2PGSQL, PostgreSQL en Mapnik. Deze drie programma’s samen vormen de tile server. Door middel van OSM2PSQL kunnen de gedownloaden OSM bestanden, die de kaartendata bevatten, geimporteerd worden in de PostgreSQL database. De database die hieruit voortkomt zal data bevatten die gemakkelijk en snel te lezen is door Mapnik. Het is gefilterde tekst waardoor het snel een afbeelding kan genereren met de daarop nodige lijnen en polygonen. 6.2 REST Resources Zoals in voorgaande hoofdstukken beschreven is, is het benodigd om een REST-­‐resource aan te maken. Om zo een lijst met klanten in combinatie met locatie vrij te geven. Deze REST resource zal volgens het in de ontwerp hoofdstuk beschreven protocol verlopen. Voor deze opdracht is er enkel een klanten resource nodig voor de zogenaamde Customer module. Binnen deze resource zullen alle klanten opgehaald worden en vervolgens getransformeerd worden in een XML bestand. Deze resource is toegevoegd als bijlage C. Om ervoor te zorgen dat alle data gelijkwaardig wordt overgedragen over de interface wordt er gekozen om een uniforme klasse aan te maken die de data bevat van in dit geval de klanten. Deze uniforme klasse is genaamd Entity, deze klasse vat alle informatie samen en wordt vervolgens door JAXB omgezet in een XML bestand. De Entity klasse is te vinden in bijlage D. 6.2 MapViewer In de opdracht omschrijving is te lezen dat het een eis is om in de MES-­‐Toolbox een kaart te kunnen tonen. Deze kaart met als basis de gegenereerde tiles die gegenereerd Scriptie MES-Toolbox
Jim Veldhuis
37
Afbeelding 6.1: Mapviewer implementatie in de MES-­‐Toolbox. zijn met data van OpenStreetMap. Deze kaarten zullen getoond worden in een JPanel. Dit zal worden gedaan in een klasse die MapViewer heet en die JPanel overerft. De klasse zorgt ervoor dat methodes zijn die features, term uit Geoserver die gebruikt wordt voor punten, kan toevoegen aan een laag binnen de klasse. In afbeelding 6.1 is een afbeelding te zien waarin de MapViewer implementatie te zien is in samenwerking met de MES-­‐
Toolbox. Tevens biedt de MapViewer klasse functionaliteit om op de kaart in-­‐ of uit te zoomen en te verplaatsen. Een van deze functionaliteiten is het berekenen van de x-­‐ en y positie van een feature. Om deze positie te berekenen heeft OpenStreetMap een formule vrijgegeven. De MapViewer klasse is te zien in Bijlage E. 6.3 FeatureLayer Bovenop de MapViewer klasse wordt nog een klasse geplaatst, deze draagt de naam FeatureLayer. Deze klasse zal informatie bevatten met betrekking tot het vasthouden van de punten om deze vervolgens op de kaart te laten zien. Tevens bevat deze klasse een overerving van de JPanel klasse waarmee dus componenten kan bevatten die getekend dienen te worden. Om deze punten te verkrijgen, krijgt deze klasse via de model een lijst met punten door. Dit wordt verder uitgewerkt in dit hoofdstuk, die vervolgens worden gekoppeld aan de Componenten laag die getekend wordt. De FeatureLayer code is terug te vinden in bijlage F. 6.4 Model Binnen de MES-­‐Toolbox is er een standaard voor het opzetten van een model. Alle modellen bevatten klassen, waar deze klassen een terug waarde representeren. Dit houdt in dat er voor elke waarde die kan worden opgevraagd in het Model er een aparte klasse binnen het model gemaakt dient te worden. De klasse beheerst twee functies: het aanvragen van data en het aanpassen van data. De opbouw van deze klasse is als volgt: private class voorbeeldKlasse { public Object getValue() { // Retourneer waarde, } public void setValue(Object value) { // Afhandelen van de opgegeven waarde. } } In het geval van deze opdracht dient er in het model / de modellen een klasse aangemaakt te worden die een lijst met features / punten kan retourneren, en aanpassen. Deze lijst zal vervolgens aan de FeatureLayer worden toegevoegd waarna deze getoond kunnen worden. Tevens dient alle data bij initialiseren van het model ingeladen te worden. Dit is zodat er gedurende het bekijken van een view, alle data direct geretourneerd kan worden. Dit Scriptie MES-Toolbox
Jim Veldhuis
38
wordt gedaan in de collectData() methode. Hierin worden alle variabelen gevuld in het model. Hierdoor kan er met snelheidwinst data teruggegeven worden. 6.5 View De View klasse is verantwoordelijk voor het tonen van componenten op basis van data vanuit het Model. Hierin wordt aangegeven welke informatie er uit de Model gehaald moet worden, hoe deze getoond wordt en uit welke delen het scherm bestaat. Hierbij kan gedacht worden aan een scherm dat uit twee delen bestaat. Een View bevat verschillende componenten die worden toegevoegd door middel van een ViewAdapter. Deze ViewAdapter word geïmplementeerd in een JPanel zodat deze vervolgens getoond kan worden in de MES-­‐Toolbox. 6.6 ViewAdapter Een ViewAdapter is een klasse die er voor zorgt dat er een verbinding gelegd kan worden tussen een Model en een View. In het geval van deze opdracht was het nodig om een ViewAdapter aan te maken, deze ViewAdapter maakt gebruik van de MapViewer klasse. Hierbij dient de MapViewer klasse als basis voor het te tekenen component, en worden hieraan de features / punten toegevoegd. De ViewAdapter zorgt er tevens voor dat er een selectie mechanisme gebruikt kan worden wat ervoor zorgt dat de punten op de kaart gecombineerd kunnen worden met de data in een tabel. Dit wordt bereikt door zogenaamde SelectedRows. Deze bevatten de data die aangeeft welke rij er geselecteerd is. Op deze manier is het mogelijk om een geselecteerde rij te selecteren op de kaart en vice versa. Afbeelding 6.2: Overzicht van selectie mechanisme. Zoals in afbeelding 6.2 is te zien dat er een klant geselecteerd is, welke vervolgens op de kaart wordt gecentreerd. Dit proces werkt ook andersom waardoor je op de kaart een klant kan selecteren waarna deze in de lijst geselecteerd wordt. Scriptie MES-Toolbox
Jim Veldhuis
39
7. Conclusie Het doel van deze opdracht is behaald. Zo is de doelstelling zoals deze in de opdracht omschreven staat voldaan, en is de opdracht opgeleverd aan de opdrachtgever. Door de in deze scriptie omschreven technieken te gebruiken is er een werkend product uitgekomen dat klaar is voor gebruik. De tile server is succesvol opgezet en is in staat om zijn functie te vervullen. Zo kan deze kaarten data downloaden van OpenStreetMap en deze data omzetten in een PostgreSQL database tabel. Vervolgens kan de tile server hieruit de data halen om vervolgens tiles te gaan genereren, en beschikbaar stellen voor extern gebruik. De implementatie binnen de MES-­‐Toolbox is in staat om punten, die via een REST interface zijn opgevraagd, te laten zien op een kaart. Hierop volgend is het mogelijk om door een selectie mechanisme de punten aan te klikken en de daarbij behorende rij te zien in de tabel en vice versa. De voorwaarden waar de implementatie in de MES-­‐Toolbox en de tile server aan moesten voldoen zijn behaald. Tevens is er gedurende de programmeer werkzaamheden rekening gehouden met de manier van opbouw zoals elders gebruikt in de MES-­‐Toolbox. Dit houdt in dat alle declaraties van variabelen, en instanties op een gelijkwaardige manier gebeuren. De planning die vooraf aan de opdracht is uitgedacht is niet geheel volgens plan verlopen. Door de uitsplitsing van de twee opdrachten, tile server en implementatie, zijn deze afzonderlijk van elkaar verlopen. Zo zijn eerst alle fasen doorlopen voor de tile server, en vervolgens dezelfde stappen voor de implementatie in de MES-­‐Toolbox doorlopen. Doordat de planning in de eerste fase van de stage al uit elkaar viel was er een nieuwe planning opgesteld die er als volgt uitzag: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 Analysefase Ontwerpfase Implementatiefase Testfase De bovenstaande planning is nagenoeg volgens planning verlopen. De fase van de tile server verliep sneller dan gepland, waar de implementatie fase van de MES-­‐Toolbox implementatie uitliep. Scriptie MES-Toolbox
Jim Veldhuis
40
20 Zelfreflectie Dit hoofdstuk zal een reflectie omvatten wat betrekking heeft op het verloop van de gelopen stage. Het zal alle leerdoelen uitlichten die vooraf vastgesteld, en behaald zijn. Elke leerdoel die in dit hoofdstuk beschreven zal worden, zal uitgelegd worden door middel van een compact stuk tekst. Analyseren van bestaande programma’s Deze afstudeeropdracht is voortgekomen uit een probleem in een bestaand programma. Hiermee heb ik gedurende de analyse fase in de MES-­‐Toolbox groot onderzoek moeten verrichten naar de werking en de opbouw hiervan. Zo heb ik onder andere geanalyseerd hoe MVC geïmplementeerd is in de MES-­‐Toolbox en hoe REST resources kunnen worden aangemaakt. Componenten toevoegen aan bestaande programma’s met het in acht nemen van de bedrijfsstandaarden Deze opdracht omvat een implementatie in de MES-­‐Toolbox waarmee ik dit leerdoel behaald heb. Zo is er een kaart ingevoegd in een panel, en is er een REST resource toegevoegd die de klanten data retourneert. Programmeerkennis uitbreiden met kennis en ervaring van ervaren programmeurs Binnen Cofely zijn er een aantal ervaren programmeurs waarmee meerdere malen mee is gecommuniceerd, en overlegd is om de geprogrammeerde componenten nader te bekijken met betrekking op opbouw en uitsplitsing van code in klassen. Praktijkkennis opdoen van werking binnen een industriële omgeving In de periode waar binnen deze afstudeeropdracht is voltooid is er deelgenomen aan een ISA88 cursus en een excursie naar de Verkade fabriek te Zaandam. De ISA88 cursus heeft een uitgebreide uitleg en kennis geboden met oog op standaarden in de industriële automatisering. De excursie heeft vooral kennis gegeven met betrekking tot de praktijk en functies van automatisering. Zo is er vernomen hoe de MES-­‐Toolbox wordt ingezet in de fabriek van Verkade, en wat hiervan de mogelijkheden zijn. Na afloop van de afstudeeropdracht denk ik alle leerdoelen te hebben behaald. Met elk van de genoemde onderdelen heb ik kennis opgedaan. De planning ging in het begin al fout en had me beter moeten verdiepen in de verschillende fasen die ik moest doorlopen. De tweede planning is echter verlopen zoals gepland. Over het algemeen heb ik gedurende mijn stage periode veel kennis opgedaan, over zowel kennis op programmeer gebied als daadwerkelijke industriële automatisering doordat ik met verschillende collega’s heb meegekeken. Scriptie MES-Toolbox
Jim Veldhuis
41
Literatuurlijst [1] Cofely en GDF Suez – Cofely – Ver vooruit in duurzame technologie [02-­‐Jan-­‐2012] http://www.cofely-­‐gdfsuez.nl/nl/over-­‐cofely/cofely-­‐en-­‐gdf-­‐suez.html [2] GDF Suez – Wikipedia [10-­‐Dec-­‐2011] http://en.wikipedia.org/wiki/GDF_Suez [3] OpenStreetMap – Wikipedia [24-­‐Okt-­‐2011] http://nl.wikipedia.org/wiki/OpenStreetMap [4] Zoom levels – OpenStreetMap Wiki [17-­‐Nov-­‐2011] http://wiki.openstreetmap.org/Zoom_levels [5] LTS – Ubuntu Wiki [01-­‐Dec-­‐2011] https://wiki.ubuntu.com/LTS [6] Elements – OpenStreetMap Wiki [21-­‐Dec-­‐2011] http://wiki.openstreetmap.org/wiki/Elements [7] Latitude – Wikipedia [31-­‐Dec-­‐2011] http://en.wikipedia.org/wiki/Latitude [8] Longitude – Wikipedia [31-­‐Dec-­‐2011] http://en.wikipedia.org/wiki/Longitude [9] PostgreSQL – Wikipedia [27-­‐Dec-­‐2011] http://nl.wikipedia.org/wiki/PostgreSQL [10] Mapnik – OpenStreetMap Wiki [29-­‐Dec-­‐2011] http://wiki.openstreetmap.org/wiki/Mapnik [11] SCADA – Wikipedia [21-­‐Dec-­‐2011] http://en.wikipedia.org/wiki/SCADA [12] Manufacturing execution system – Wikipedia [01-­‐Apr-­‐2011] http://nl.wikipedia.org/wiki/Manufacturing_execution_system [13] Model-­‐view-­‐control-­‐model – Wikipedia [31-­‐Okt-­‐2011] http://nl.wikipedia.org/wiki/Model-­‐view-­‐controller-­‐model [14] Overview – Geoserver 2.1.x User Manual [10-­‐Dec-­‐2011] http://docs.geoserver.org/stable/user/introduction/overview.html Scriptie MES-Toolbox
Jim Veldhuis
42
Bijlage A: Afstudeer opdracht Afstudeer opdracht Afdeling Industrial automation MES Expert center Onderwerp Integratie van Geo data in de MES Toolbox applicatie. Gegevens Contactpersoon info Begeleider Plaats Datum S. Broersen tel 0651361995 Marc Dierikx Cofely Zaandam 16 augustus 2011 Duur 100 dagen
Niveau HBO Probleem beschrijving In de huidige MES Toolbox versie is een applicatie aanwezig waarmee klantbestellingen op een geografische kaart kunnen worden weergegeven. Deze applicatie gebruikt een externe bibliotheek die niet meer wordt ondersteund. De onderhoudskosten voor de geografische data van deze oplossing zijn daarnaast ook zeer hoog. Aangezien de gebruikers van deze industriële systemen geen directe toegang tot het internet mogen hebben, zijn oplossingen m.b.v. google Maps geen oplossing. Om deze reden wordt de opensource applicatie “OpenStreetMap” overwogen als alternatief. Opdracht Onderzoek of “OpenStreetMap” als geografische basis kan functioneren voor de MES Toolbox. Ontwerp een model waarbij de kaart informatie beschikbaar wordt gesteld op een server. De geografische data moet eenvoudig kunnen worden geüpdatet. Vanuit deze Geo server moet een Java Swing panel beschikbaar komen in de MES Toolbox client applicatie. Hierbij is vooral de interfacing tussen geo server en client belangrijk i.v.m. performance. De bestelinformatie van klantorders moet grafisch op deze kaart worden weergegeven m.b.v. symbolen gecombineerd met tekst. De symbolen moeten klik baar zijn waardoor onder in beeld de informatie van de bestelling kan worden weergegeven. Onderzoek tevens of m.b.v. deze oplossing route planning kan worden uitgevoerd. Daarnaast moet er een systeem komen waarmee de coördinaten van de klantlocaties kunnen worden bepaald, bij voorkeur automatisch op basis van postcode en huisnummer. Een mogelijk alternatief is de huidige oplossing waarbij de geografische data in een scherm wordt gecombineerd met het klantbestand. Door selectie van een klant en een punt op de kaart wordt de locatie vastgelegd. Scriptie MES-Toolbox
Jim Veldhuis
43
Bijlage B: Samenvatting scriptie Dhr. N. Soeltan Samenvatting
An English version of the summary is available on the next page.
Deze scriptie beschrijft een onderzoek voor het realiseren van een REST
interface om CATIS en de MES Toolbox met elkaar te laten communiceren.
Dit onderzoek heeft plaatsgevonden bij Cofely Noordwest B.V. te Zaandam.
Cofely is een bedrijf dat zich voornamelijk bezighoudt met elektrotechniek,
installatietechniek en procesautomatisering.
CATIS is een applicatie bestaande uit een client en de GeoServer. CATIS
maakt het mogelijk om equipments van de Verkade fabriek te plaatsen op een
plattegrond. Van elke equipment kan informatie opgevraagd worden. Hier zit
de actuele status niet bij. De status van een equipment bevindt zich in de MES
Toolbox. Dit is een softwarepakket die de fabrieksprocessen van Verkade
bestuurt. De Toolbox is uitgerust met een REST server. Deze server heeft de
mogelijkheid om gegevens uit een database te halen en statussen op te
vragen van equipments.
Om de status te kunnen weergeven, is eerst onderzocht hoe CATIS met de
REST server kan communiceren. Het is gebleken dat GeoServer data kan
benaderen uit verschillende bronnen met een Datastore. Door een datastore
te ontwikkelen die fungeert als client, zou er gecommuniceerd kunnen worden
met de REST server.
De REST server moet wel de benodigde gegevens kunnen leveren. Hiervoor
moet een nieuwe webservice gemaakt worden. Deze webservice heeft de
mogelijkheid gekregen tot het opvragen, aanmaken, wijzigen en verwijderen
van equipmentgegevens. Voor elke equipment kan de status opgevraagd
worden door middel van een URI. De data wordt verstuurd in de vorm van een
XML document.
De Datastore communiceert met de webservice door een verzoek van de
CATIS client om te zetten naar een URI. De URI wordt geinterpeteerd door de
webservice en haalt de juiste equipmentgegevens op. Voor elke equipment
wordt de status opgehaald en verstuurt als XML. De Datastore zet dit XML
bestand om in het formaat waarmee GeoServer de data naar de client kan
sturen. De CATIS client weergeeft vervolgens de equipments met een actuele
status.
Scriptie MES-Toolbox
Jim Veldhuis
44
Bijlage C: CustomerResource.java 1 package gti.www.rest.resources;
2
3 import gti.www.rest.EntityCollection;
4 import gti.www.rest.Entity;
5 import gti.www.rest.SchemaEntity;
6 import gti.db.DbException;
7 import gti.domain.Customer;
8 import gti.domain.dao.CustomerDAO;
9 import gti.util.JPAUtil;
10
11 import java.util.List;
12 import javax.ws.rs.DELETE;
13 import javax.ws.rs.GET;
14 import javax.ws.rs.POST;
15 import javax.ws.rs.PUT;
16 import javax.ws.rs.Path;
17 import javax.ws.rs.PathParam;
18 import javax.ws.rs.WebApplicationException;
19 import javax.ws.rs.core.Context;
20 import javax.ws.rs.core.Response;
21 import javax.ws.rs.core.UriInfo;
22
23 /**
24 * Customer resource.
25 */
26 @Path("/customers")
27 public class CustomerResource
28
extends RestResource
29 {
30
31 /**
32
* Gets a SchemaEntity
33
*
34
* @return schemaEntity
35
*/
36 @GET
37 @Path("/schema")
38 public SchemaEntity getSchema()
39 {
40
// Declaration
41
SchemaEntity schemaEntity;
42
43
// Initialization
44
schemaEntity = new SchemaEntity();
45
46
schemaEntity.addAttributeDescription(Customer.A_NUMBER.columnName(),
47
"String");
48
schemaEntity.addAttributeDescription(Customer.A_NAME.columnName(),
49
"String");
50
schemaEntity.addAttributeDescription(Customer.A_STREET.columnName(),
51
"String");
52
schemaEntity.addAttributeDescription(Customer.A_HOUSE_NUMBER.columnName(),
53
"String");
Scriptie MES-Toolbox
Jim Veldhuis
45
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
schemaEntity.addAttributeDescription(Customer.A_POST_CODE.columnName(),
"String");
schemaEntity.addAttributeDescription(Customer.A_CITY.columnName(),
"String");
schemaEntity.addAttributeDescription("geometry",
"Geometry");
return schemaEntity;
}
/**
* Gets a EntityCollection with entities of {@link Customer}.
*
* @param info
*
URI information
* @return EntityCollection
*/
@GET
public EntityCollection readCustomers(@Context UriInfo info)
{
CustomerDAO customerDAO;
Entity entity;
EntityCollection entityCollection;
List<Customer> customers;
customerDAO = new CustomerDAO();
customers = customerDAO.selectAll();
entityCollection = new EntityCollection();
if (customers == null || customers.size() <= 0)
{
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
for (Customer customer : customers)
{
entity = buildEntity(customer);
entityCollection.add(entity);
}
return entityCollection;
}
/**
* Gets a Entity of a {@link Customer}.
*
* @param pbsCode
*
name of the feature.
* @param info
*
URI information
* @return featureEntity
*/
@GET
@Path("/{customerId}")
public Entity readCustomer(@PathParam("customerId") Long customerID,
Scriptie MES-Toolbox
Jim Veldhuis
46
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
@Context UriInfo info)
{
Entity entity;
Customer customer;
CustomerDAO dao;
dao = new CustomerDAO();
customer = dao.selectById(customerID);
if (customer == null)
{
throw new WebApplicationException(Response.Status.NOT_FOUND);
}
entity = buildEntity(customer);
return entity;
}
/**
* Creates a {@link Customer}.
*
* @param Entity of {@link Customer}.
*
data to be stored in the database.
*/
@POST
public void writeCustomer(Entity entity)
{
Customer customer;
CustomerDAO dao;
try
{
JPAUtil.beginTransaction();
dao = new CustomerDAO();
customer = dao.create();
customer = buildCustomer(entity, customer);
dao.insert(customer);
}
catch (DbException e)
{
throw new WebApplicationException(
Response.Status.INTERNAL_SERVER_ERROR);
}
finally
{
JPAUtil.commitTransaction();
}
}
/**
* Modifies a {@link Customer}.
Scriptie MES-Toolbox
Jim Veldhuis
47
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
*
* @param customerID
*
identifier of {@link Customer}.
* @param Entity
*
data to be stored in the database.
*/
@PUT
@Path("{customer_id}")
public void updateCustomer(@PathParam("customer_id") Long customerID,
Entity entity)
{
Customer customer, modifiedCustomer;
CustomerDAO dao;
JPAUtil.beginTransaction();
try
{
dao = new CustomerDAO();
customer = dao.selectById(customerID);
modifiedCustomer = buildCustomer(entity, customer);
dao.insert(modifiedCustomer);
}
catch (DbException e)
{
throw new WebApplicationException(
Response.Status.INTERNAL_SERVER_ERROR);
}
finally
{
JPAUtil.commitTransaction();
}
}
/**
* Deletes a {@link Customer}.
*
* @param customer_id
*
identifier of the {@link Customer}.
*
*/
@DELETE
@Path("/{customer_id}")
public void deleteCustomer(@PathParam("customer_id") Long customerID)
{
Customer customer;
CustomerDAO dao;
JPAUtil.beginTransaction();
try
{
dao = new CustomerDAO();
customer = dao.selectById(customerID);
Scriptie MES-Toolbox
Jim Veldhuis
48
216
if (customer != null)
217
{
218
dao.remove(customer);
219
}
220
}
221
catch (DbException e)
222
{
223
throw new WebApplicationException(
224
Response.Status.INTERNAL_SERVER_ERROR);
225
}
226
finally
227
{
228
JPAUtil.commitTransaction();
229
}
230 }
231
232 /**
233
* Builds a entity containing feature information.
234
*
235
* @param feature
236
*
the hibernate feature
237
* @return featureEntity containing the feature information.
238
*/
239 private Entity buildEntity(Customer customer)
240 {
241
Entity entity;
242
Long customerID;
243
244
entity = new Entity();
245
customerID = customer.getId();
246
247
entity.setId(customer.getId().toString());
248
entity.addAttribute(Customer.A_NUMBER.columnName(), customer.getNumber());
249
entity.addAttribute(Customer.A_NAME.columnName(), customer.getName());
250
entity.addAttribute(Customer.A_STREET.columnName(), customer.getStreet());
251
entity.addAttribute(Customer.A_HOUSE_NUMBER.columnName(),
customer.getHouseNumber());
252
entity.addAttribute(Customer.A_POST_CODE.columnName(), customer.getPostCode());
253
entity.addAttribute(Customer.A_CITY.columnName(), customer.getCity());
254
entity.addAttribute("geometry", getGeometry(customer));
255
256
return entity;
257 }
258
259 /**
260
* Builds a hibernate entity
261
*
262
* @param Entity
263
*
contains {@link Customer} information
264
* @param customer
265
*
the hibernate enitity
266
* @return the hibernate entity
267
*/
268 private Customer buildCustomer(Entity entity, Customer customer)
Scriptie MES-Toolbox
Jim Veldhuis
49
269 {
270
String name, street, houseNumber, postCode, city;
271
272
name = entity.getAttribute(Customer.A_NAME.columnName());
273
street = entity.getAttribute(Customer.A_STREET.columnName());
274
houseNumber = entity.getAttribute(Customer.A_HOUSE_NUMBER.columnName());
275
postCode = entity.getAttribute(Customer.A_POST_CODE.columnName());
276
city = entity.getAttribute(Customer.A_CITY.columnName());
277
278
if (name != null)
279
{
280
customer.setName(name);
281
}
282
if (street != null)
283
{
284
customer.setStreet(street);
285
}
286
if (houseNumber != null)
287
{
288
customer.setHouseNumber(houseNumber);
289
}
290
if (postCode != null)
291
{
292
customer.setPostCode(postCode);
293
}
294
if (city != null)
295
{
296
customer.setCity(city);
297
}
298
299
return customer;
300 }
301
302 /**
303
* Combine {@code coordinateEast} and {@code coordinateNorth} to a combined geometry.
304
*
305
* @param customer
306
*
Customer object for extracting coordinates.
307
* @return String containing geometry value like "POINT(52.0394 4.2039)".
308
*/
309 private String getGeometry(Customer customer)
310 {
311
String longitude, latitude;
312
313
if (customer == null || customer.getCoordinateEast() == null ||
customer.getCoordinateNorth() == null)
314
{
315
return "POINT(0 0)";
316
}
317
318
longitude = customer.getCoordinateEast();
319
latitude = customer.getCoordinateNorth();
320
321
return "POINT(" + latitude + " " + longitude + ")";
Scriptie MES-Toolbox
Jim Veldhuis
50
322 }
323 }
Scriptie MES-Toolbox
Jim Veldhuis
51
Bijlage D: Entity.java 1 package gti.www.rest;
2
3 import java.util.HashMap;
4 import java.util.Set;
5
6 import javax.xml.bind.annotation.XmlAccessType;
7 import javax.xml.bind.annotation.XmlAccessorType;
8 import javax.xml.bind.annotation.XmlAttribute;
9 import javax.xml.bind.annotation.XmlElement;
10 import javax.xml.bind.annotation.XmlRootElement;
11 import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
12
13 @XmlAccessorType(XmlAccessType.NONE)
14 @XmlRootElement(name = "entity")
15 public class Entity {
16
17 @XmlAttribute
18 private String id;
19
20 @XmlJavaTypeAdapter(HashMapAdapter.class)
21 @XmlElement(name = "attributes")
22 private HashMap<String, String> attributes;
23
24 public Entity() {
25 attributes = new HashMap<String, String>();
26 }
27
28 public void setId(String id) {
29 this.id = id;
30 }
31
32 public String getId() {
33 return id;
34 }
35
36 public String addAttribute(String key, String value) {
37 return attributes.put(key, value);
38 }
39
40 public String getAttribute(String key) {
41 return attributes.get(key);
42 }
43
44 public String removeAttribute(String key) {
45 return attributes.remove(key);
46 }
47
48 public Set<String> getAttributeNames() {
49 return attributes.keySet();
50 }
51
52 public int getAttributeCount() {
53 return attributes.size();
Scriptie MES-Toolbox
Jim Veldhuis
52
54 }
55
56 public void clearAttributes() {
57 attributes.clear();
58 }
59 }
Scriptie MES-Toolbox
Jim Veldhuis
53
Bijlage E: MapViewer.java 1 package gti.ui.main;
2
3 import gti.ui.base.RowId;
4 import gti.ui.base.UIView;
5 import java.awt.BorderLayout;
6 import java.awt.Color;
7 import java.awt.Dimension;
8 import java.awt.Graphics;
9 import java.awt.Graphics2D;
10 import java.awt.Point;
11 import java.awt.event.MouseAdapter;
12 import java.awt.event.MouseEvent;
13 import java.awt.event.MouseMotionListener;
14 import java.awt.event.MouseWheelEvent;
15 import java.awt.event.MouseWheelListener;
16 import java.util.HashMap;
17 import java.util.Iterator;
18 import java.util.List;
19 import java.util.Map;
20 import javax.swing.JPanel;
21 import org.opengis.feature.simple.SimpleFeature;
22
23 public class MapViewer
24 extends JPanel
25 {
26
27 // static variables
28 private int TILE_SIZE = new Integer(256);
29 public static final String SERVER_URL = "localhost";
30
31 // instance variables
32 private FeatureLayer m_featureLayer;
33 private int m_zoomLevel;
34 private Map<String, Tile> m_tileCache;
35 private MouseListener m_mousListener;
36 private Point m_position;
37 private RowId m_rowId;
38 private UIView m_view;
39
40 /**
41 * Accessor method for the {@link FeatureLayer} property {@code featureLayer}.
42 *
43 * @return JPanel representing the FeatureLayer
44 */
45 public FeatureLayer getFeatureLayer()
46 {
47 return m_featureLayer;
48 }
49
50 /**
51 * Accessor method for the {@link Point} property {@code position}.
52 *
53 * @return Point containing the current position of the map.
Scriptie MES-Toolbox
Jim Veldhuis
54
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
*/
public Point getPosition()
{
return m_position;
}
/**
* Parser method for the {@link Point} property {@code position}.
*
* @param Point that holds the x- and y-position of the map.
*/
public void setPosition(Point m_position)
{
this.m_position = m_position;
}
/**
* Accessor method for the {@link RowId} property {@code rowId}.
*
* @return RowId which represents the current RowId of the parent.
*/
public RowId getRowId()
{
return m_rowId;
}
/**
* Accessor method for the {@link Map} property {@code tileCache}.
*
* @return Map<String, Tile> which contains the cached tiles.
*/
public Map<String, Tile> getTileCache()
{
return m_tileCache;
}
/**
* Accessor method for the {@link UIView} property {@code view}.
*
* @return UIView link to the view.
*/
public UIView getView()
{
return m_view;
}
/**
* Accessor method for the {@link int} property {@code zoomLevel}.
*
* @return the zoomlevel value of the map.
*/
public int getZoomLevel()
{
return m_zoomLevel;
Scriptie MES-Toolbox
Jim Veldhuis
55
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
}
/**
* Parser method for the {@link int} property {@code zoomLevel}.
*
* @param zoomLevel that represents the view height on the map.
*/
public void setZoomLevel(int zoomLevel)
{
this.m_zoomLevel = zoomLevel;
}
/**
* Creates a new instance of {@link MapViewer}.
*/
public MapViewer(UIView view,
RowId rowId)
{
m_featureLayer = new FeatureLayer(this);
m_mousListener = new MouseListener();
m_position = new Point(33317,
21173);
m_rowId = rowId;
m_tileCache = new HashMap<String, Tile>();
m_view = view;
m_zoomLevel = 8;
setLayout(new BorderLayout());
setPreferredSize(new Dimension(0,
350));
setOpaque(true);
add(m_featureLayer);
addMouseListener(m_mousListener);
addMouseMotionListener(m_mousListener);
addMouseWheelListener(m_mousListener);
}
/**
* This method iterates through a list of features, and appends each one to the feature layer.
*
* @param SimpleFeature List which needs to be appended to the feature layer.
*/
public void addFeature(List<SimpleFeature> simpleFeatures)
{
Iterator<SimpleFeature> iterator;
if (m_featureLayer.featuresChanged(simpleFeatures))
{
m_featureLayer.resetFeatures();
iterator = simpleFeatures.iterator();
while (iterator.hasNext())
Scriptie MES-Toolbox
Jim Veldhuis
56
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
{
m_featureLayer.addFeature(iterator.next());
}
}
}
/**
* Zooms in on the map, with the given offset position.
*
* @param pivot
*
Represents a the Point where is zoomed in on.
*/
public void zoomIn(Point pivot)
{
if (getZoomLevel() < 15)
{
setZoomLevel(getZoomLevel() + 1);
setPosition(new Point((getPosition().x * 2 + pivot.x),
(getPosition().y * 2 + pivot.y)));
repaint();
}
}
/**
* Zooms out from the map, with the given offset position.
*
* @param pivot
*
Represents a the Point where is zoomed out from.
*/
public void zoomOut(Point pivot)
{
if (getZoomLevel() > 3)
{
setZoomLevel(getZoomLevel() - 1);
setPosition(new Point((getPosition().x - pivot.x) / 2,
(getPosition().y - pivot.y) / 2));
repaint();
}
}
/**
* This method zooms in or out to the requested zoomlevel.
*
* @param zoomLevel which represents the goal zoomlevel.
*/
public void zoomToLevel(int zoomLevel)
{
while (getZoomLevel() > zoomLevel)
{
zoomOut(new Point(0,
0));
}
Scriptie MES-Toolbox
Jim Veldhuis
57
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
while (getZoomLevel() < zoomLevel)
{
zoomIn(new Point(0,
0));
}
}
/**
* This method zooms to a feature on a given zoomlevel, and centers the feature.
*
* @param index representing the identifier on which has to be zoomed on.
*/
public void zoomToFeature(String index)
{
double longitude, latitude;
int coorX, coorY;
SimpleFeature feature;
feature = m_featureLayer.getFeature(index);
if (feature != null && getWidth() != 0 && getHeight() != 0)
{
zoomToLevel(13);
longitude = ((com.vividsolutions.jts.geom.Point) feature.getAttribute("geometry")).getY();
latitude = ((com.vividsolutions.jts.geom.Point) feature.getAttribute("geometry")).getX();
coorX = MapViewer.lon2position(longitude,
13) - (getWidth() / 2);
coorY = MapViewer.lat2position(latitude,
13) - (getHeight() / 2);
setPosition(new Point(coorX,
coorY));
repaint();
}
}
@Override
protected void paintComponent(Graphics gOrig)
{
Graphics2D g;
int coorX, coorY;
int tileEndX, tileEndY;
int tileStartX, tileStartY;
Tile tile;
String tid;
g = (Graphics2D) gOrig.create();
// Holds the x, and y position on which next tile should be positioned.
coorY = -(getPosition().y % TILE_SIZE);
coorX = -(getPosition().x % TILE_SIZE);
Scriptie MES-Toolbox
Jim Veldhuis
58
270
271 // Holds the number of the last tile to display.
272 tileEndX = (int) Math.floor(((double) getPosition().x + (getWidth() + TILE_SIZE)) /
TILE_SIZE);
273 tileEndY = (int) Math.floor(((double) getPosition().y + (getHeight() + TILE_SIZE)) /
TILE_SIZE);
274
275 // Holds the number of the first tile to display.
276 tileStartX = (int) Math.floor(((double) getPosition().x) / TILE_SIZE);
277 tileStartY = (int) Math.floor(((double) getPosition().y) / TILE_SIZE);
278
279 // Loops for painting tiles row by row.
280 for (int y = tileStartY; y < tileEndY; ++y)
281 {
282
coorX = -(getPosition().x % TILE_SIZE);
283
284
for (int x = tileStartX; x < tileEndX; ++x)
285
{
286
// Generate unique tile identifier.
287
tid = "CT" + x + y + getZoomLevel();
288
289
// Check for tile in cache.
290
// If not there download tile from tile server.
291
if (!getTileCache().containsKey(tid))
292
{
293
getTileCache().put(tid,
294
new Tile(MapViewer.getTileUrl(x,
295
y,
296
getZoomLevel())));
297
}
298
299
tile = getTileCache().get(tid);
300
if (tile.getStatus() == 200)
301
{
302
g.drawImage(tile.getTileIcon().getImage(),
303
coorX,
304
coorY,
305
this);
306
}
307
else
308
{
309
g.setColor(Color.LIGHT_GRAY);
310
g.fillRect(coorX,
311
coorY,
312
TILE_SIZE,
313
TILE_SIZE);
314
}
315
316
coorX += TILE_SIZE;
317
}
318
319
coorY += TILE_SIZE;
320 }
321
Scriptie MES-Toolbox
Jim Veldhuis
59
322 // Relocate the features on the map.
323 m_featureLayer.updateFeatures();
324
325 super.paintComponent(g);
326 }
327
328 /**
329 * This class extends the {@link MouseAdapter} class adds functionality to the mouse such like
zooming, dragging,
330 * and panning.
331 */
332 class MouseListener
333
extends MouseAdapter
334
implements MouseMotionListener, MouseWheelListener
335 {
336 // instance variables
337 private Point mi_mouseCoords;
338 private Point mi_downCoords;
339 private Point mi_downPosition;
340
341 @Override
342 public void mouseClicked(MouseEvent e)
343 {
344
mi_mouseCoords = e.getPoint();
345
if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() >= 2)
346
{
347
zoomIn(new Point(mi_mouseCoords.x,
348
mi_mouseCoords.y));
349
}
350
else if (e.getButton() == MouseEvent.BUTTON3 && e.getClickCount() >= 2)
351
{
352
zoomOut(new Point(mi_mouseCoords.x,
353
mi_mouseCoords.y));
354
}
355 }
356
357 @Override
358 public void mousePressed(MouseEvent e)
359 {
360
if (e.getButton() == MouseEvent.BUTTON1)
361
{
362
mi_downCoords = e.getPoint();
363
mi_downPosition = getPosition();
364
}
365 }
366
367 @Override
368 public void mouseDragged(MouseEvent e)
369 {
370
if (mi_downCoords != null)
371
{
372
int changeX = mi_downCoords.x - e.getX();
373
int changeY = mi_downCoords.y - e.getY();
374
Scriptie MES-Toolbox
Jim Veldhuis
60
375
setPosition(new Point(mi_downPosition.x + changeX,
376
mi_downPosition.y + changeY));
377
378
repaint();
379
}
380 }
381
382 @Override
383 public void mouseWheelMoved(MouseWheelEvent e)
384 {
385
mi_mouseCoords = e.getPoint();
386
if (e.getWheelRotation() < 0)
387
{
388
zoomIn(new Point(mi_mouseCoords.x,
389
mi_mouseCoords.y));
390
}
391
else
392
{
393
zoomOut(new Point(mi_mouseCoords.x,
394
mi_mouseCoords.y));
395
}
396 }
397 }
398
399 /**
400 * Returns a String containing an UR: to external tile image.
401 *
402 * @param xPosition
403 *
Represents the X position of the tile image.
404 * @param yPosition
405 *
Represents the Y position of the tile image.
406 * @param zoomLevel
407 *
Represents the zoom level of the tile image.
408 * @return a String containing an URL to external tile image.
409 */
410 public static String getTileUrl(int xPosition,
411
int yPosition,
412
int zoomLevel)
413 {
414 return "http://" + MapViewer.SERVER_URL + ":8080/geoserver/www/tiles/" + zoomLevel +
"/" + xPosition + "/"
415
+ yPosition + ".png";
416 }
417
418 /**
419 * Returns a position calculated from a X position and a zoom level.
420 *
421 * @param xPosition
422 *
Represents the pixels from point (0,0).
423 * @param zoomLevel
424 *
Represents the zoom level where the map is displayed.
425 * @return a position calculated from a position and a zoom level.
426 */
427 public static double position2lon(int xPosition,
Scriptie MES-Toolbox
Jim Veldhuis
61
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
int zoomLevel)
{
double xmax;
xmax = 256 * (1 << zoomLevel);
return xPosition / xmax * 360.0 - 180;
}
/**
* Returns a position calculated from a Y position and a zoom level.
*
* @param yPosition
*
Represents the pixels from point (0,0).
* @param zoomLevel
*
Represents the zoom level where the map is displayed.
* @return a position calculated from a Y position and a zoom level.
*/
public static double position2lat(int yPosition,
int zoomLevel)
{
double ymax;
ymax= 256 * (1 << zoomLevel);
return Math.toDegrees(Math.atan(Math.sinh(Math.PI - (2.0 * Math.PI * yPosition) / ymax)));
}
/**
* Returns the X position from a given longitude.
*
* @param longitude
*
Represents longitude, degrees from (0.0000, 0.0000);
* @param zoomLevel
*
Represents the zoom level where the map is displayed.
* @return the position from a given longitude.
*/
public static int lon2position(double longitude,
int zoomLevel)
{
double xmax;
xmax = 256 * (1 << zoomLevel);
return (int) Math.floor((longitude + 180) / 360 * xmax);
}
/**
* Returns the Y position from a given longitude.
*
* @param latitude
*
Represents latitude, degrees from (0.0000, 0.0000);
* @param zoomLevel
*
Represents the zoom level where the map is displayed.
Scriptie MES-Toolbox
Jim Veldhuis
62
482 * @return the position from a given longitude.
483 */
484 public static int lat2position(double latitude,
485
int zoomLevel)
486 {
487 double ymax;
488
489 ymax = 256 * (1 << zoomLevel);
490
491 return (int) Math.floor((1 - Math.log(Math.tan(Math.toRadians(latitude)) + 1 /
Math.cos(Math.toRadians(latitude)))
492
/ Math.PI)
493
/ 2 * ymax);
494 }
495 }
Scriptie MES-Toolbox
Jim Veldhuis
63
Bijlage F: FeatureLayer code 1 package gti.ui.main;
2
3 import com.vividsolutions.jts.geom.Point;
4 import gti.ui.base.UIModelEvent;
5 import gti.ui.base.UIModelRefreshMode;
6 import gti.ui.base.UIViewIF;
7 import gti.ui.main.MapViewer;
8 import java.awt.Color;
9 import java.awt.event.MouseAdapter;
10 import java.awt.event.MouseEvent;
11 import java.util.ArrayList;
12 import java.util.Iterator;
13 import java.util.List;
14 import javax.swing.JComponent;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import org.opengis.feature.simple.SimpleFeature;
18
19 public class FeatureLayer
20 extends JPanel
21 {
22 // instance variables
23 private List<JComponent> m_components;
24 private List<SimpleFeature> m_simpleFeatures;
25 private MapViewer m_parent;
26
27 /**
28 * Accessor method for the {@link List} property {@code components}.
29 *
30 * @return List of components which are drawn in the feature layer..
31 */
32 public List<JComponent> getFeatures()
33 {
34 return m_components;
35 }
36
37 @Override
38 public MapViewer getParent()
39 {
40 return m_parent;
41 }
42
43 /**
44 * Accessor method for the {@link List} property {@code simpleFeatures}.
45 *
46 * @return SimpleFeature List that contains all features in the feature layer.
47 */
48 public List<SimpleFeature> getSimpleFeatures()
49 {
50 return m_simpleFeatures;
51 }
52
53 /**
Scriptie MES-Toolbox
Jim Veldhuis
64
54 * Accessor method for the {@link SimpleFeature} property {@code simpleFeature} in the
features list.
55 *
56 * @return SimpleFeature that matches the given feature identifier.
57 */
58 public SimpleFeature getFeature(String index)
59 {
60 Iterator<SimpleFeature> iterator;
61 SimpleFeature feature;
62 String customerId;
63
64 iterator = m_simpleFeatures.iterator();
65 while (iterator.hasNext())
66 {
67
feature = iterator.next();
68
customerId = feature.getAttribute("number").toString();
69
if (customerId.equals(index))
70
{
71
return feature;
72
}
73 }
74
75 return null;
76 }
77
78 /**
79 * Creates a new instance of {@link FeatureLayer}.
80 */
81 public FeatureLayer(MapViewer parent)
82 {
83 m_components = new ArrayList<JComponent>();
84 m_parent = parent;
85 m_simpleFeatures = new ArrayList<SimpleFeature>();
86
87 setLayout(null);
88 setOpaque(false);
89 }
90
91 /**
92 * This method calculates a features location and appends this feature to the feature layer.
93 *
94 * @param SimpleFeature to add to the feature layer.
95 */
96 public void addFeature(SimpleFeature simpleFeature)
97 {
98 double longitude, latitude;
99 int coorX, coorY;
100 JComponent component;
101
102 // Calculation of x- and y-position, based on given coordinates.
103 latitude = ((Point) simpleFeature.getAttribute("geometry")).getX();
104 longitude = ((Point) simpleFeature.getAttribute("geometry")).getY();
105 coorX = MapViewer.lon2position(longitude,
106
m_parent.getZoomLevel()) - m_parent.getPosition().x;
Scriptie MES-Toolbox
Jim Veldhuis
65
107 coorY = MapViewer.lat2position(latitude,
108
m_parent.getZoomLevel()) - m_parent.getPosition().y;
109
110 // Create a JLabel that represents a feature.
111 component = new JLabel();
112 component.addMouseListener(new MouseListener(simpleFeature,
113
m_components.size()));
114 component.setBackground(Color.BLUE);
115 component.setLocation(coorX,
116
coorY);
117 component.setOpaque(true);
118 component.setSize(10,
119
10);
120 component.setToolTipText("<html><body>" + simpleFeature.getAttribute("name") +
"</body><html>");
121
122 // Save the feature for reuse at a later moment, for example repainting.
123 getFeatures().add(component);
124 getSimpleFeatures().add(simpleFeature);
125
126 add(component);
127 }
128
129 /**
130 * This method returns {@code true} or {@code false} depending on the outcome of the check.
131 * The check tests if the given {@link List} is equal to the feature list.
132 *
133 * @param List of SimpleFeature's which will be compared to the features list.
134 * @return {@code true} or {@code false} depening on the equal check.
135 */
136 public boolean featuresChanged(List<SimpleFeature> simpleFeatures)
137 {
138 return !getSimpleFeatures().equals(simpleFeatures);
139 }
140
141 /**
142 * This method clears the list of features.
143 */
144 public void resetFeatures()
145 {
146 getFeatures().clear();
147 getSimpleFeatures().clear();
148 }
149
150 /**
151 * This method recalculates the position of the features this layer holds.
152 * This recalculation is necessary for locating the features on dragging, zooming or panning the
map.
153 */
154 public void updateFeatures()
155 {
156 double latitude, longitude;
157 int coorX, coorY;
158 JComponent component;
Scriptie MES-Toolbox
Jim Veldhuis
66
159 SimpleFeature feature;
160
161 for (int i = 0; i < getSimpleFeatures().size(); i++)
162 {
163
// Find the matching component related to the feature.
164
component = getFeatures().get(i);
165
feature = getSimpleFeatures().get(i);
166
167
if (component != null && feature != null)
168
{
169
// Recalculate the x- and y-position on the updated location of the maps.
170
latitude = ((Point) feature.getAttribute("geometry")).getX();
171
longitude = ((Point) feature.getAttribute("geometry")).getY();
172
coorX = MapViewer.lon2position(longitude,
173
m_parent.getZoomLevel()) - m_parent.getPosition().x;
174
coorY = MapViewer.lat2position(latitude,
175
m_parent.getZoomLevel()) - m_parent.getPosition().y;
176
177
// Relocate the component on the calculated position.
178
component.setLocation(coorX,
179
coorY);
180
}
181
182 }
183 }
184
185 /**
186 * This class extends the {@link MouseAdapter} class adds functionality to the mouse to handle
selection functionality.
187 */
188 class MouseListener
189
extends MouseAdapter
190 {
191 // instance variables
192 int mi_row;
193 SimpleFeature mi_simpleFeature;
194
195 /**
196
* Creates a new instance of {@link MouseListener}.
197
*/
198 public MouseListener(SimpleFeature simpleFeature,
199
int row)
200 {
201
mi_row = row;
202
mi_simpleFeature = simpleFeature;
203 }
204
205 @Override
206 public void mouseClicked(MouseEvent e)
207 {
209
UIModelEvent event;
210
UIViewIF view;
211
212
view = m_parent.getView();
Scriptie MES-Toolbox
Jim Veldhuis
67
218
219
view.getCurrentRow().setCurrentRow(m_parent.getRowId(),
220
mi_row);
221
222
event = new UIModelEvent(m_parent.getRowId());
223
event.setRefreshMode(UIModelRefreshMode.REFRESHFROMSELECTROW);
224
view.updateView(event);
225 }
226 }
227 }
Scriptie MES-Toolbox
Jim Veldhuis
68
Download