\begin{tikzpicture}
\tikzumlset{font = \sffamily\footnotesize, fill class=white}
\umlclass[x=6, y=-4]{Profile}{
	title : character\\
	number : int\\
	measurementType : character}{
	plot(p : Profile, dataType : character,\\ ~~~~withTopo : logical) : void\\
	levelplot(p : Profile, dataType : character,\\ ~~~~withTopo : logical) : void\\
	
	plot3d(p : Profile) : void\\
	plotIntersect(p1 : Profile, p2 : Profile) : void}
\umlclass[x=13, y=-4]{ProfileSet}{
	title : character\\
	/minLat : double\\
	/minLon : double\\
	/minData : double\\
	/maxData : double}{
	plot3d(p : ProfileSet) : void\\
	plotLegend(p : ProfileSet) : void\\
	plotIntersect(p : ProfileSet) : void}
\umlclass[y=-0.5, x=-2]{RawData}{
	address : character\\
	points : data.frame}{
	RawData()\\
	RawData(address : character)\\
	parseRawDataFile(address : character) : data.frame}
\umlclass[y=-4, x=-3]{GpsCoordinates}{
	address : character\\
	exact : data.frame\\
	/relative : data.frame\\
	/lm : lm\\
	/lmRelative : lm}{
	GpsCoordinates()\\
	GpsCoordinates(address : character)\\
	calcRelativeCoords(minLat : double, minLon : double)}
\umlclass[y=-8.5, x=-2]{ProcessedData}{
	address : character\\
	points : data.frame\\
	pointsWithTopo : data.frame\\
	/minData : double\\
	/maxData : double\\
	/height : data.frame}{
	ProcessedData()\\
	ProcessedData(address : character)\\
	parseProcessedDataFile(address : character) : list\\
	getHeightInformation(processedData : ProcessedData) : data.frame}
	
\umluniaggreg[mult1=$^*$, mult2=$^*$, arg=profiles, pos2=0.65]{ProfileSet}{Profile}
\umlunicompo[geometry=|-, mult2=$0..1$, arg=rawData, pos2=1.8, anchor1=90, anchor2=0]{Profile}{RawData}
\umlunicompo[geometry=|-, mult2=$0..1$, arg=processedData, pos2=1.7, anchor1=-90, anchor2=0]{Profile}{ProcessedData}
\umlunicompo[mult2=$0..1$, arg2=gpsCoordinates, pos2=0.5]{Profile}{GpsCoordinates}
\end{tikzpicture}