├── images ├── mongodb.png ├── speedGraph.png ├── appInterface.png └── systemArchitecture.PNG ├── Analysis-Result-Visualization-PyQT5 ├── converterCode ├── MsSQLConnectorClass.py ├── README.md ├── program.py ├── userInterface.py └── userInterface.ui ├── Data-Analysis-with-Spark ├── MsSQLConnectorClass.py ├── MongoDbConnectorClass.py ├── README.md ├── Functions.py └── Program.py └── README.md /images/mongodb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zekeriyyaa/Traffic-Data-Analysis-with-Apache-Spark-Based-on-Mobile-Robot-Data/HEAD/images/mongodb.png -------------------------------------------------------------------------------- /images/speedGraph.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zekeriyyaa/Traffic-Data-Analysis-with-Apache-Spark-Based-on-Mobile-Robot-Data/HEAD/images/speedGraph.png -------------------------------------------------------------------------------- /images/appInterface.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zekeriyyaa/Traffic-Data-Analysis-with-Apache-Spark-Based-on-Mobile-Robot-Data/HEAD/images/appInterface.png -------------------------------------------------------------------------------- /images/systemArchitecture.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/zekeriyyaa/Traffic-Data-Analysis-with-Apache-Spark-Based-on-Mobile-Robot-Data/HEAD/images/systemArchitecture.PNG -------------------------------------------------------------------------------- /Analysis-Result-Visualization-PyQT5/converterCode: -------------------------------------------------------------------------------- 1 | # convert userInterface.ui to userInterface.py file 2 | 3 | C:\Users\zekeriyya\AppData\Local\Programs\Python\Python35\Lib\site-packages\PyQt5\pyuic5.bat userInterface.ui -o userInterface.py 4 | 5 | -------------------------------------------------------------------------------- /Data-Analysis-with-Spark/MsSQLConnectorClass.py: -------------------------------------------------------------------------------- 1 | import pyodbc 2 | class MsSQLConnection: 3 | __server="SERVERNAME" 4 | __database = 'DATABASENAME' 5 | __conn="null" 6 | 7 | def __init__(self,server="SERVERNAME",database= 'DATABASENAME'): 8 | self.__server=server 9 | self.__database=database 10 | self.__conn=self.__GetConnect() 11 | 12 | def __SetConnection(self): 13 | self.__conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};' 14 | 'Server='+self.__server+';' 15 | 'Database='+self.__database+';' 16 | 'Trusted_Connection=yes;') 17 | 18 | def __GetConnect(self): 19 | if(self.__conn=="null"): 20 | self.__SetConnection() 21 | return self.__conn 22 | 23 | def GetConnection(self): 24 | return self.__conn 25 | -------------------------------------------------------------------------------- /Analysis-Result-Visualization-PyQT5/MsSQLConnectorClass.py: -------------------------------------------------------------------------------- 1 | import pyodbc 2 | class MsSQLConnection: 3 | __server="SERVERNAME" 4 | __database = 'DATABASENAME' 5 | __conn="null" 6 | 7 | def __init__(self,server="SERVERNAME",database= 'DATABASENAME'): 8 | self.__server=server 9 | self.__database=database 10 | self.__conn=self.__GetConnect() 11 | 12 | def __SetConnection(self): 13 | self.__conn = pyodbc.connect('Driver={ODBC Driver 17 for SQL Server};' 14 | 'Server='+self.__server+';' 15 | 'Database='+self.__database+';' 16 | 'Trusted_Connection=yes;') 17 | 18 | def __GetConnect(self): 19 | if(self.__conn=="null"): 20 | self.__SetConnection() 21 | return self.__conn 22 | 23 | def GetConnection(self): 24 | return self.__conn 25 | -------------------------------------------------------------------------------- /Data-Analysis-with-Spark/MongoDbConnectorClass.py: -------------------------------------------------------------------------------- 1 | from pyspark.sql import SparkSession 2 | 3 | class MongoDBConnection: 4 | 5 | ##for localhost connection 6 | __host = "127.0.0.1" 7 | __database = "DATABASENAME" 8 | __collection = "COLLECTIONNAME" 9 | 10 | ##for server connection 11 | __host = "192.168.10.155" 12 | __host = "127.0.0.1" 13 | __database = "DATABASENAME" 14 | __collection = "COLLECTIONNAME" 15 | 16 | # Structure the connection 17 | #__connectionString = "mongodb://{0}:{1}@{2}:{3}/{4}.{5}?ssl=true&replicaSet=globaldb".format(userName, primaryKey, __host, port, __database, __collection) 18 | __connectionString="mongodb://"+__host+"/"+__database+"."+__collection 19 | 20 | __spark="null" 21 | 22 | def __init__(self,host="127.0.0.1",database="DATABASENAME",collection="COLLECTIONNAME"): 23 | self.__host=host 24 | self.__database=database 25 | self.__collection=collection 26 | self.__spark=self.__GetSparkSessionPrivate() 27 | 28 | def __SetSparkSession(self): 29 | self.__spark = SparkSession \ 30 | .builder \ 31 | .config('spark.mongodb.input.uri', self.__connectionString) \ 32 | .config('spark.mongodb.output.uri', self.__connectionString) \ 33 | .config('spark.jars.packages', 'org.mongodb.spark:mongo-spark-connector_2.11:2.4.1') \ 34 | .getOrCreate() 35 | 36 | def __GetSparkSessionPrivate(self): 37 | if(self.__spark=="null"): 38 | self.__SetSparkSession() 39 | return self.__spark 40 | 41 | def GetSparkSession(self): 42 | return self.__spark 43 | 44 | def GetConnectionString(self): 45 | return self.__connectionString 46 | 47 | def GetDatabase(self): 48 | return self.__database 49 | 50 | def GetCollection(self): 51 | return self.__collection 52 | -------------------------------------------------------------------------------- /Analysis-Result-Visualization-PyQT5/README.md: -------------------------------------------------------------------------------- 1 | #### [Analysis-Result-Visualization-PyQT5](https://github.com/zekeriyyaa/Traffic-Data-Analysis-with-Spark/tree/master/Analysis-Result-Visualization-PyQT5) 2 | The desktop app is improved. So, result of the analysis has visualized to easly understanding. At the app, you can select way and time interval which to show all analysis result. 3 | The desktop app look like as shown below: 4 | > 5 | 6 | And also you can select which type of analysis that you want to visualized for a way that you already specified. 7 | The speed analysis of all way is shown as below ( **red**: low speed **green**: medium speed **yellow**: high speed ) : 8 | > 9 | 10 | #### Installation Steps 11 | Given tools, setups and IDEs used for this project. Given steps is available for Windows installation. 12 | - [python3.5](https://www.python.org/downloads/) : specify version 3.5 13 | - [PyCharm](https://www.jetbrains.com/pycharm/download/#section=windows) : is a IDE for python (recommended) 14 | - [QtDesigner](https://build-system.fman.io/qt-designer-download) : a interface designer 15 | - [pyodbc](https://pypi.org/project/pyodbc/) : is an open source Python module that makes accessing ODBC databases simple. 16 | ```sh 17 | pip install pyodbc 18 | ``` 19 | - [pyqtgraph](https://pypi.org/project/pyqtgraph/) : is a pure-python graphics and GUI library built on PyQt4/PyQt5/PySide/PySide2 and numpy. 20 | ```sh 21 | pip install pyqtgraph 22 | ``` 23 | 24 | #### Usage 25 | After the design is completed, QtDesigner produce file has .ui extension. So, you need to convert this file to python file and you can import design file by another python file. **pyuic.bat** is convert .ui ext file to .py file with help given code : 26 | ```sh 27 | C:\Users\zekeriyya\AppData\Local\Programs\Python\Python35\Lib\site-packages\PyQt5\pyuic5.bat inputFileName.ui -o outputFileName.py 28 | ``` 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Traffic-Data-Analysis-with-Spark-Based-on-Autonomous-Transport-Vehicle-Data 2 | There could be a traffic in smart factories caused by autonomous transport vehicles (ATVs). So, it is needed to analyzed the data generated by ATV and produce useful feedback to system to enhance the system productivity. For this purpose, five analysis are done such as travel time, waiting time, average speed, occupancy and density and the results were visualized. 3 | 4 | The data that generated from AGV analyzied with using [Apache Spark](https://spark.apache.org). And desktop app improved and results is visualised for understanding easily using [PyQT5](https://pypi.org/project/PyQt5/).This project has been developed within [ifarlab](https://ifarlab.ogu.edu.tr). 5 | 6 | System architecture is shown below: 7 | > 8 | 9 | #### [Data-Analysis-with-Spark](https://github.com/zekeriyyaa/Traffic-Data-Analysis-with-Spark/tree/master/Data-Analysis-with-Spark) 10 | 11 | ATV generates current position and speed data 150 times per minute. And these data store MongoDB database as a **document**. Each document has position, speed, datetime and ID datas as shown below. In addition, some information about the way is obtained from the MSSQL database.
12 | 13 | MongoDB document instance: 14 | > 15 | 16 | **Using these datas, five analysis that is shown below is made:** 17 | - **Travel time**: The elapsed time between the ATV starting to task and finishing. 18 | - **Waiting time**: The elapsed time while ATV is waiting during performing its task. 19 | - **Average speed**: The average speed of the ATV while performing its task. 20 | - **Occupancy**: (way lenght) / (number of vehicle * vehicle length) 21 | - **Density**: ( number of vehicle / way length ) 22 | 23 | 24 | #### [Analysis-Result-Visualization-PyQT5](https://github.com/zekeriyyaa/Traffic-Data-Analysis-with-Spark/tree/master/Analysis-Result-Visualization-PyQT5) 25 | The desktop app is improved. So, result of the analysis has visualized to easly understanding. At the app, you can select way and time interval which to show all analysis result. 26 | The desktop app look like as shown below: 27 | > 28 | 29 | And also you can select which type of analysis that you want to visualized for a way that you already specified. 30 | The speed analysis of all way is shown as below ( **red**: low speed **green**: medium speed **yellow**: high speed ) : 31 | > 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Data-Analysis-with-Spark/README.md: -------------------------------------------------------------------------------- 1 | # Traffic-Data-Analysis-with-Spark 2 | A smart factory has many smart systems like autonomous transport vehicle. These all are generate many data like position and speed continuously. So, it is needed to analysis these data and get some useful result. For this purpose, the datas that generated from ATV analyzied with using [Apache Spark](https://spark.apache.org). And desktop app improved and results is visualised for understanding easily using [PyQT5](https://pypi.org/project/PyQt5/).This project has been developed within [CISAR](https://cisar.ogu.edu.tr). 3 | 4 | System architecture is shown below: 5 | > 6 | 7 | #### [Data-Analysis-with-Spark](https://github.com/zekeriyyaa/Traffic-Data-Analysis-with-Spark/tree/master/Data-Analysis-with-Spark) 8 | 9 | AGV is generated its current position and speed data 150 times per minute. And these data store MongoDB database as a **document**. Each document has position, speed, datetime and ID datas as shown below. In addition, some information about the way which is ATV is travel on is received from MsSQL database.
10 | 11 | MongoDB document instance: 12 | > 13 | 14 | **Using these datas, five analysis that is shown below is made:** 15 | - **Travel time**: The elapsed time between the ATV starting to task and finishing. 16 | - **Waiting time**: The elapsed time while ATV is waiting during performing its task. 17 | - **Average speed**: The average speed of the ATV while performing its task. 18 | - **Occupancy**: (way lenght) / (number of vehicle * vehicle length) 19 | - **Density**: ( number of vehicle / way length ) 20 | 21 | #### Installation Steps 22 | Given tools, setups and IDEs used for this project. Given steps is available for Windows installation. 23 | - [python3.7](https://www.python.org/downloads/) 24 | - [PyCharm](https://www.jetbrains.com/pycharm/download/#section=windows) : is a IDE for python (recommended) 25 | - [Apache Spark](https://spark.apache.org/downloads.html) : is a unified analytics engine for large-scale data processing ( **specify version:2.4.5**) 26 | - [Java](https://www.java.com/tr/download/windows-64bit.jsp) 27 | - [pip installer](https://bootstrap.pypa.io/get-pip.py) : download and setup it 28 | - [pyspark](https://pypi.org/project/pyspark/) : is a Python library. specify given version: 29 | ```sh 30 | $ pip install pyspark==2.4.5 31 | ``` 32 | - [winutils](https://github.com/steveloughran/winutils/blob/master/hadoop-2.7.1/bin/winutils.exe) : download and store it in C:\winutils\bin\ 33 | - Make winutils executable with given code : 34 | ```sh 35 | winutils.exe chmod -R 777 C:\tmp\hive 36 | ``` 37 | - Change env. variable shown as url 38 | > https://www.youtube.com/watch?v=l6L5oyKzHrI&feature=youtu.be
https://medium.com/@sinemhasircioglu/apache-spark-kurulumu-windows-4d411a5c9b43 39 | - Install findspark 40 | ```sh 41 | pip install findspark 42 | ``` 43 | - [pyodbc](https://pypi.org/project/pyodbc/) : is an open source Python module that makes accessing ODBC databases simple. 44 | ```sh 45 | pip install pyodbc 46 | ``` 47 | - [Download ODBC Driver for SQL Server for Windows](https://docs.microsoft.com/en-us/sql/connect/odbc/download-odbc-driver-for-sql-server?view=sql-server-ver15) : is a single dynamic-link library (DLL) containing run-time support for applications using native-code APIs to connect to SQL Server
Use this selection: **+ msiexec /quiet /passive /qn /i msodbcsql.msi IACCEPTMSODBCSQLLICENSETERMS=YES ADDLOCAL=ALL**
48 | [Download ODBC Driver for SQL Server for Linux](https://docs.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver15)
49 | -------------------------------------------------------------------------------- /Analysis-Result-Visualization-PyQT5/program.py: -------------------------------------------------------------------------------- 1 | from PyQt5.QtWidgets import* 2 | from userInterface import Ui_MainWindow 3 | import MsSQLConnectorClass as MsSQL 4 | import datetime 5 | import matplotlib.pyplot as plt 6 | 7 | from PyQt5 import QtWidgets, uic 8 | from pyqtgraph import PlotWidget, plot 9 | import pyqtgraph as pg 10 | 11 | 12 | 13 | class visualisation(QMainWindow): 14 | # create MsSQL class object and set connection with default value that placed in class 15 | MsSQLConnector = MsSQL.MsSQLConnection() 16 | conn = MsSQLConnector.GetConnection() 17 | cursor = conn.cursor() 18 | 19 | def __init__(self): 20 | super().__init__() 21 | 22 | self.ui = Ui_MainWindow() 23 | self.ui.setupUi(self) 24 | 25 | self.ui.cboxYolID.addItems(self.getWayIDFromDB()) 26 | self.ui.cboxTimeLabel.addItems(self.getTimeLabelFromDB()) 27 | 28 | #self.conn.close() 29 | 30 | def getWayIDFromDB(self): 31 | ### get wayIDs from MsSQL 32 | self.cursor.execute("SELECT Anl_wayID FROM DefAnalysisResult group by Anl_wayID") 33 | wayIDs=[] 34 | for i in self.cursor: 35 | wayIDs.append(str(i[0])) 36 | return wayIDs 37 | 38 | def getTimeLabelFromDB(self): 39 | ### get analysis result from MsSQL 40 | self.cursor.execute("SELECT Anl_timeLabel FROM DefAnalysisResult group by Anl_timeLabel order by Anl_timeLabel") 41 | times=[] 42 | for i in self.cursor: 43 | times.append(str(i[0])) 44 | return times 45 | 46 | def setAnalysisResult(self): 47 | # set analysis result info into interface 48 | wayID = self.ui.cboxYolID.currentText() 49 | timeLabel = self.ui.cboxTimeLabel.currentText() 50 | # get selected way' info from MsSQL 51 | self.cursor.execute("SELECT * FROM DefAnalysisResult where Anl_wayID=" + wayID + " and Anl_timeLabel='" + timeLabel + "'") 52 | results = self.cursor.fetchone() 53 | self.ui.lblMinSpeed.setText(str(round(results[3],7))) 54 | self.ui.lblMaxSpeed.setText(str(round(results[4],7))) 55 | self.ui.lblAvgSpeed.setText(str(round(results[5],7))) 56 | self.ui.lblMinTt.setText(str(round(results[6],7))) 57 | self.ui.lblMaxTt.setText(str(round(results[7],7))) 58 | self.ui.lblAvgTt.setText(str(round(results[8],7))) 59 | self.ui.lblMinWt.setText(str(round(results[9],7))) 60 | self.ui.lblMaxWt.setText(str(round(results[10],7))) 61 | self.ui.lblAvgWt.setText(str(round(results[11],7))) 62 | self.ui.lblOccupancy.setText(str(round(results[12],7))) 63 | self.ui.lblDensity.setText(str(round(results[13],7))) 64 | 65 | def setGraphic(self): 66 | ### get way' coordinate from MsSQL to set on graphic 67 | self.cursor.execute("SELECT w.Way_ID,nd.Nd_Latitute,nd.Nd_Longtitute,wp.Wyp_EnterExitCode FROM ((DefWays as w INNER JOIN DefWaypoints as wp on w.Way_ID=wp.Wyp_WayID ) INNER JOIN DefNodes as nd ON nd.Nd_ID=wp.Wyp_NodeID) where wp.Wyp_EnterExitCode in (0,1) order by w.Way_ID,wp.Wyp_EnterExitCode") 68 | waysCoordinate = [] 69 | for i in self.cursor: 70 | waysCoordinate.append(i) 71 | 72 | timeLabel = self.ui.cboxTimeLabel.currentText() 73 | tag="" 74 | content="" 75 | if(self.ui.cboxAnalysisType.currentText()=="Hız"): 76 | tag="Hız" 77 | content="Anl_speed_avg" 78 | elif(self.ui.cboxAnalysisType.currentText()=="Seyahat Süresi"): 79 | tag="Seyahat Süresi" 80 | content="Anl_travelTime_avg" 81 | elif(self.ui.cboxAnalysisType.currentText()=="Bekleme Süresi"): 82 | tag="Bekleme Süresi" 83 | content="Anl_waitingTime_avg" 84 | elif(self.ui.cboxAnalysisType.currentText()=="Doluluk"): 85 | tag="Doluluk" 86 | content="Anl_occupancy" 87 | elif(self.ui.cboxAnalysisType.currentText()=="Yoğunluk"): 88 | tag="Yoğunluk" 89 | content="Anl_density" 90 | 91 | 92 | ### get selected way' analysis result from MsSQL 93 | self.cursor.execute("SELECT Anl_wayID,"+content+" FROM DefAnalysisResult where Anl_timeLabel='" + timeLabel + "'") 94 | 95 | values=[] 96 | valuesSum=[] 97 | 98 | for i in self.cursor: 99 | values.append(i) 100 | valuesSum.append(i[1]) 101 | 102 | # calculate min-max-avg value for selected way 103 | temp=(max(valuesSum)-min(valuesSum))/3.33 104 | minTop=min(valuesSum)+temp 105 | maxBottom=max(valuesSum)-temp 106 | 107 | fig_size = [12,8] 108 | plt.figure(figsize=fig_size) 109 | 110 | # draw graph 111 | x1,x2,x3=0,0,0 112 | for i in waysCoordinate: 113 | x, y = [], [] 114 | for k in waysCoordinate: 115 | if(k[0]==i[0]): 116 | x.append(k[1]) 117 | y.append(k[2]) 118 | for j in values: 119 | if(j[0]==i[0]): 120 | if(j[1]maxBottom): 128 | if(x2==0): 129 | plt.plot(x, y, 'o-', color="yellow",lineWidth=3,label="Orta "+tag) 130 | x2=1 131 | else: 132 | plt.plot(x, y, 'o-', color="yellow", lineWidth=3) 133 | break 134 | else: 135 | if(x3==0): 136 | plt.plot(x, y, 'o-', color="green",lineWidth=3,label="Yüksek "+tag) 137 | x3=1 138 | else: 139 | plt.plot(x, y, 'o-', color="green", lineWidth=3) 140 | break 141 | 142 | plt.title("Analiz Sonuçları") 143 | plt.xlabel("X Ekseni") 144 | plt.ylabel("Y Ekseni") 145 | #plt.legend(["Düşük Hız","Orta Hız","Yüksek Hız"]) 146 | plt.legend() 147 | plt.show() 148 | 149 | ### get selected timeLabel 150 | self.cursor.execute("SELECT * FROM DefAnalysisResult where Anl_timeLabel='"+self.ui.cboxTimeLabel.currentText()+"'") 151 | analysis = [] 152 | for i in self.cursor: 153 | analysis.append(i) 154 | 155 | print("") 156 | 157 | 158 | uygulama = QApplication([]) 159 | pencere = visualisation() 160 | pencere.show() 161 | uygulama.exec_() -------------------------------------------------------------------------------- /Data-Analysis-with-Spark/Functions.py: -------------------------------------------------------------------------------- 1 | import MsSQLConnectorClass as MsSQL 2 | import numpy as np 3 | import datetime 4 | 5 | 6 | ### Match packages and ways if they are at the same coordinates. 7 | def GetSelected(packets): 8 | ### get MsSQL connection 9 | MsSQLConnector = MsSQL.MsSQLConnection() 10 | 11 | conn1 = MsSQLConnector.GetConnection() 12 | conn2 = MsSQLConnector.GetConnection() 13 | conn3 = MsSQLConnector.GetConnection() 14 | 15 | cursor1 = conn1.cursor() 16 | cursor2 = conn2.cursor() 17 | cursor3 = conn3.cursor() 18 | 19 | ### get way's information from MsSQL 20 | cursor1.execute("SELECT Way_ID,Way_SpeedLimit,Way_LineWidth,Way_Length FROM DefWays") 21 | 22 | ### get robot's information from MsSQL 23 | cursor3.execute("SELECT Rbt_ID,Rbt_Length FROM DefRobots") 24 | robot_length_list={} 25 | for rbt in cursor3: 26 | robot_length_list[str(rbt[0])]=rbt[1] 27 | selected=[] 28 | 29 | # initialize stop speed value 30 | stopSpeed=0.001 31 | 32 | # look all way to which packet meet it 33 | for way in cursor1: 34 | # assign specific way ID 35 | wayID = str(way[0]) 36 | # get half way width 37 | half_WayWidth = way[2] / 2 38 | # get way length 39 | WayLength = float(way[3]) 40 | 41 | ## get way coordinate information from MsSQL 42 | cursor2.execute("SELECT n.Nd_Latitute, n.Nd_Longtitute from DefWays w INNER JOIN DefWaypoints wp ON wp.Wyp_WayID = w.Way_ID INNER JOIN DefNodes n ON n.Nd_ID = wp.Wyp_NodeID Where w.Way_ID = " + wayID + " AND wp.Wyp_EnterExitCode IN ('0','1')") 43 | 44 | coordinates = [] 45 | ## get ways to list 46 | for row in cursor2: 47 | ## tek bır yol ıcın kullanılacak dıct. hazırlanıyor 48 | coordinate = {"latitute": "", "longtitute": ""} 49 | coordinate["latitute"] = row[0] 50 | coordinate["longtitute"] = row[1] 51 | ## ways added list 52 | coordinates.append(coordinate) 53 | 54 | ## call a function that find a corner of ways with given ways information 55 | linesCoordinates = CalculateRectLineCoordinate(coordinates, half_WayWidth, WayLength) 56 | 57 | ## check the way coordinate and compare them with packet's coordinate, and deside whether packer created at the same way 58 | select = CheckCoordinate(linesCoordinates, packets, wayID,WayLength,stopSpeed,robot_length_list); 59 | 60 | # if packet created on the current way, add it "select" list 61 | selected.extend(select) 62 | return selected 63 | 64 | # A utility function to calculate 65 | # area of triangle formed by (x1, y1), 66 | # (x2, y2) and (x3, y3) 67 | def area(x1, y1, x2, y2, x3, y3): 68 | return abs((x1 * (y2 - y3) +x2 * (y3 - y1) +x3 * (y1 - y2)) / 2.0) 69 | 70 | # A function to check whether point 71 | # P(x, y) lies inside the rectangle 72 | # formed by A(x1, y1), B(x2, y2), 73 | # C(x3, y3) and D(x4, y4) 74 | def checkC(x1, y1, x2, y2, x3,y3, x4, y4, x, y): 75 | # Calculate area of rectangle ABCD 76 | A = (area(x1, y1, x2, y2, x3, y3) + 77 | area(x1, y1, x4, y4, x3, y3)) 78 | 79 | # Calculate area of triangle PAB 80 | A1 = area(x, y, x1, y1, x2, y2) 81 | 82 | # Calculate area of triangle PBC 83 | A2 = area(x, y, x2, y2, x3, y3) 84 | 85 | # Calculate area of triangle PCD 86 | A3 = area(x, y, x3, y3, x4, y4) 87 | 88 | # Calculate area of triangle PAD 89 | A4 = area(x, y, x1, y1, x4, y4); 90 | 91 | # Check if sum of A1, A2, A3 92 | # and A4 is same as A 93 | 94 | return (round(A,7) == round(A1 + A2 + A3 + A4,7)) 95 | 96 | ### check the given packets coordinate and find which is in the current way 97 | def CheckCoordinate(list, packets, wayID,WayLength,stopSpeed,robot_length_list): 98 | 99 | selected = [] 100 | 101 | wayCount = 0; 102 | wayCountCheck = -1; 103 | 104 | for packet in packets: 105 | # use for add tourCount 106 | temp = [] 107 | for t in packet: 108 | temp.append(t) 109 | 110 | # check: default true. if packet is on the current way value is true else false. 111 | check = True 112 | 113 | # check coordinate whether packet is on the current way with given way coordinates and packet 114 | if (not checkC(list[0],list[1],list[2],list[3],list[4],list[5],list[6],list[7],packet[1],packet[2])): 115 | #plt.scatter(x=packet[1], y=packet[2], color="red") 116 | check = False 117 | wayCountCheck = -1 118 | if (check): 119 | #plt.scatter(x=packet[1], y=packet[2], color="green") 120 | if (wayCountCheck != 1): 121 | wayCount += 1 122 | temp.append(wayCount) 123 | temp.append(wayID) 124 | temp.append(WayLength) 125 | temp.append(robot_length_list[str(temp[5])]) 126 | 127 | # check the robot is stopped or moving with given stopSpeed. default 0.001 128 | # 1 : stop 0 : moving 129 | 130 | if(abs(temp[3]) coordinats[1]["latitute"] and coordinats[0]["longtitute"] > coordinats[1][ 176 | "longtitute"]) or coordinats[0]["latitute"] < coordinats[1]["latitute"] and coordinats[0]["longtitute"] < 177 | coordinats[1]["longtitute"]): 178 | # yolun noktalarını ayarlamak için kullanılıyor 179 | # şekil : https://drive.google.com/open?id=1ISh5PhXmOlso1T22xzeXJUfWYIH_xVE4 180 | # şekildeki gibi hesaplamalarımızı yolun genişliğini kullanarak buluyoruz bu nedenle nodeların konumunu şekildeki gibi olması gerekir. 181 | if (coordinats[0]["latitute"] > coordinats[1]["latitute"] and coordinats[0]["longtitute"] > coordinats[1][ 182 | "longtitute"]): 183 | tmp = coordinats[0]; 184 | coordinats[0] = coordinats[1]; 185 | coordinats[1] = tmp; 186 | 187 | # sekil : https://drive.google.com/open?id=1ISh5PhXmOlso1T22xzeXJUfWYIH_xVE4 188 | # şekilde belirtilen nokların hesaplanması ~ begin 189 | coordinat1lt = {"latitute": "", "longtitute": ""} 190 | coordinat1lt["longtitute"] = coordinats[1]["longtitute"] - yofsquare; 191 | coordinat1lt["latitute"] = coordinats[1]["latitute"] + xofsquare; 192 | 193 | coordinat1gt = {"latitute": "", "longtitute": ""} 194 | coordinat1gt["longtitute"] = coordinats[1]["longtitute"] + yofsquare; 195 | coordinat1gt["latitute"] = coordinats[1]["latitute"] - xofsquare; 196 | 197 | coordinat0lt = {"latitute": "", "longtitute": ""} 198 | coordinat0lt["longtitute"] = coordinats[0]["longtitute"] - yofsquare; 199 | coordinat0lt["latitute"] = coordinats[0]["latitute"] + xofsquare; 200 | 201 | coordinat0gt = {"latitute": "", "longtitute": ""} 202 | coordinat0gt["longtitute"] = coordinats[0]["longtitute"] + yofsquare; 203 | coordinat0gt["latitute"] = coordinats[0]["latitute"] - xofsquare; 204 | # şekilde belirtilen nokların hesaplanması ~ end 205 | 206 | # yolun 4 köşesinin koordinatları listeye eklendi. 207 | Coordinatelist.append(coordinat0lt["latitute"]); 208 | Coordinatelist.append(coordinat0lt["longtitute"]); 209 | Coordinatelist.append(coordinat1lt["latitute"]); 210 | Coordinatelist.append(coordinat1lt["longtitute"]); 211 | Coordinatelist.append(coordinat1gt["latitute"]); 212 | Coordinatelist.append(coordinat1gt["longtitute"]); 213 | Coordinatelist.append(coordinat0gt["latitute"]); 214 | Coordinatelist.append(coordinat0gt["longtitute"]); 215 | 216 | # pozitif eğimli mi yoksa neğatif eğimli mi kontrolu 217 | # eğer negatif eğimli ise else in içine girer 218 | 219 | else: 220 | # yolun noktalarını ayarlamak için kullanılıyor 221 | # şekil : https://drive.google.com/open?id=1qoiPwURDgAL8j8Uh8Rsz89B-iLqigf6s 222 | # şekildeki gibi hesaplamalarımızı yolun genişliğini kullanarak buluyoruz bu nedenle nodeların konumunu şekildeki gibi olması gerekir. 223 | if (coordinats[0]["latitute"] < coordinats[1]["latitute"] and coordinats[0]["longtitute"] > coordinats[1][ 224 | "longtitute"]): 225 | tmp = coordinats[0]; 226 | coordinats[0] = coordinats[1]; 227 | coordinats[1] = tmp; 228 | 229 | # sekil : https://drive.google.com/open?id=1qoiPwURDgAL8j8Uh8Rsz89B-iLqigf6s 230 | # şekilde belirtilen nokların hesaplanması ~ begin 231 | coordinat1lt = {"latitute": "", "longtitute": ""} 232 | coordinat1lt["longtitute"] = coordinats[1]["longtitute"] - yofsquare; 233 | coordinat1lt["latitute"] = coordinats[1]["latitute"] - xofsquare; 234 | 235 | coordinat1gt = {"latitute": "", "longtitute": ""} 236 | coordinat1gt["longtitute"] = coordinats[1]["longtitute"] + yofsquare; 237 | coordinat1gt["latitute"] = coordinats[1]["latitute"] + xofsquare; 238 | 239 | coordinat0lt = {"latitute": "", "longtitute": ""} 240 | coordinat0lt["longtitute"] = coordinats[0]["longtitute"] - yofsquare; 241 | coordinat0lt["latitute"] = coordinats[0]["latitute"] - xofsquare; 242 | 243 | coordinat0gt = {"latitute": "", "longtitute": ""} 244 | coordinat0gt["longtitute"] = coordinats[0]["longtitute"] + yofsquare; 245 | coordinat0gt["latitute"] = coordinats[0]["latitute"] + xofsquare; 246 | # şekilde belirtilen nokların hesaplanması ~ end 247 | 248 | # yolun 4 köşesinin koordinatları listeye eklendi. 249 | Coordinatelist.append(coordinat0lt["latitute"]); 250 | Coordinatelist.append(coordinat0lt["longtitute"]); 251 | Coordinatelist.append(coordinat1lt["latitute"]); 252 | Coordinatelist.append(coordinat1lt["longtitute"]); 253 | Coordinatelist.append(coordinat1gt["latitute"]); 254 | Coordinatelist.append(coordinat1gt["longtitute"]); 255 | Coordinatelist.append(coordinat0gt["latitute"]); 256 | Coordinatelist.append(coordinat0gt["longtitute"]); 257 | 258 | return Coordinatelist 259 | -------------------------------------------------------------------------------- /Data-Analysis-with-Spark/Program.py: -------------------------------------------------------------------------------- 1 | import MongoDbConnectorClass as Mongo 2 | import MsSQLConnectorClass as MsSQL 3 | import Functions 4 | import pandas as pd 5 | from pyspark.sql import SparkSession 6 | from pyspark.sql.types import StructField, StructType, StringType, IntegerType, FloatType 7 | from pyspark.sql import functions as f 8 | import datetime 9 | import json 10 | 11 | ## get the program start time to calculate process time 12 | temptime = datetime.datetime.now() 13 | 14 | ## create a object of MongoDBConnection and Spark Session to get exist location packets from MongoDB database 15 | mongoDB = Mongo.MongoDBConnection() 16 | sparkSession = mongoDB.GetSparkSession() 17 | 18 | ## read all data from MongoDB and assisgn them into dataframe as df 19 | df = sparkSession.read.format("mongo").load() 20 | 21 | ## specify the time which interval is when do you want to analysis datas 22 | timeMax = datetime.datetime.now() 23 | timeMin = datetime.datetime.now() - datetime.timedelta(days=30, hours=3, minutes=24) 24 | timeMin = "2020-03-12 12:45:00.000" 25 | timeMax = "2020-03-12 13:00:00.000" 26 | 27 | ## get time interval as min-max variable 28 | timeMin = datetime.datetime.strptime("2020-03-12 12:15:00.000", '%Y-%m-%d %H:%M:%S.%f') 29 | timeMax = datetime.datetime.strptime("2020-03-12 14:15:00.000", '%Y-%m-%d %H:%M:%S.%f') 30 | 31 | ## convert dataframe df to tempView to enable ask SQL queries. 32 | df.createOrReplaceTempView("sqlMongo") 33 | 34 | ## specify the datetime interval and get all datas that are existed and order 35 | packets = sparkSession.sql("select datetime,cast(positionX as float),cast(positionY as float),cast(linearX as float),cast(linearY as float),cast(rbt_id as int) from sqlMongo where datetime between '" + str(timeMin) + "' and '" + str(timeMax) + "' order by datetime").collect() 36 | 37 | ## show exist schema 38 | # df.printSchema() 39 | 40 | # Create a schema for the convert selected data list to dataframe 41 | schema_Selected = StructType([ 42 | StructField('datetime', StringType(), True), 43 | StructField('positionX', FloatType(), True), 44 | StructField('positionY', FloatType(), True), 45 | StructField('lineerX', FloatType(), True), 46 | StructField('lineerY', FloatType(), True), 47 | StructField('rbt_id', IntegerType(), True), 48 | StructField('tourCount', IntegerType(), True), 49 | StructField('wayID', StringType(), True), 50 | StructField('wayLength', FloatType(), True), 51 | StructField('rbtLength', FloatType(), True), 52 | StructField('action', IntegerType(), True) 53 | 54 | ]) 55 | 56 | # Create a schema for the convert selected data list to dataframe 57 | schema_Difference = StructType([ 58 | StructField('wayID', StringType(), True), 59 | StructField('rbt_id', IntegerType(), True), 60 | StructField('tourCount', IntegerType(), True), 61 | StructField('timeDifference', FloatType(), True), 62 | ]) 63 | 64 | 65 | ## using function.py send the packets that include all datas you want to analysis as input 66 | ## and return back all ways with packets datas 67 | selected_list = Functions.GetSelected(packets) 68 | 69 | if (len(selected_list) != 0): 70 | # Convert list to RDD 71 | selected_rdd = sparkSession.sparkContext.parallelize(selected_list) 72 | 73 | # Create data frame 74 | df_Selected = sparkSession.createDataFrame(selected_rdd, schema_Selected) 75 | 76 | # find a tourCount each way 77 | turSayısı=df_Selected.filter(df_Selected['wayID']=="-106381").groupBy("wayID","tourCount","datetime").count().orderBy("wayID","tourCount","datetime").collect() 78 | 79 | # convert dataframe df to tempView to enable ask SQL queries. 80 | df_Selected.createOrReplaceTempView("sqlDF") 81 | 82 | ### travelling time process 83 | 84 | # find a start and finish time interval for each tour and each way 85 | # and calculate travelling time for each way 86 | ttDF = sparkSession.sql("select wayID,rbt_id,tourCount,min(datetime),max(datetime) from sqlDF group by wayID,rbt_id,tourCount ").collect() 87 | ttDF2 = sparkSession.sparkContext.parallelize(ttDF) 88 | ttDF3 = ttDF2.map(lambda x: (x[0], x[1], x[2], (datetime.datetime.strptime(x[4], '%Y-%m-%d %H:%M:%S.%f') - datetime.datetime.strptime(x[3],'%Y-%m-%d %H:%M:%S.%f')).total_seconds())).collect() 89 | 90 | # Create data frame 91 | df_TravelTime = sparkSession.createDataFrame(ttDF3, schema_Difference) 92 | df_TravelTime.createOrReplaceTempView("dfTravelTime") 93 | travelTimeResult = sparkSession.sql("select wayID,min(timeDifference),max(timeDifference),avg(timeDifference) from dfTravelTime group by wayID").collect() 94 | 95 | ### waiting time process 96 | 97 | # count of different queries 98 | # print(df_Selected.filter(df_Selected['lineerX'] < 0.0001).count()) # 3561 99 | # print(df_Selected.filter(df_Selected['lineerX'] < 0.00001).count()) # 1721 100 | # print(df_Selected.filter(df_Selected['lineerX'] < 0.000001).count()) # 1598 101 | # print(df_Selected.filter(df_Selected['lineerX'] ==0).count()) # 0 102 | # print(df_Selected.filter(df_Selected['lineerX'] < 0.001).count()) # 3988 103 | # print(df_Selected.filter(df_Selected['lineerX'] < 0.01).count()) # 4051 104 | # print(df_Selected.filter(df_Selected['lineerX'] < 0.05).count()) # 4095 105 | 106 | 107 | # find a start and finish time interval for each tour and each way where action=1 that mean is robot was stopped. 108 | # and calculate waiting time for each way 109 | wtDF = sparkSession.sql("select wayID,rbt_id,tourCount,min(datetime),max(datetime) from sqlDF where action=1 group by wayID,rbt_id,tourCount ").collect() 110 | wtDF2 = sparkSession.sparkContext.parallelize(wtDF) 111 | wtDF3 = wtDF2.map(lambda x: (x[0], x[1], x[2], (datetime.datetime.strptime(x[4], '%Y-%m-%d %H:%M:%S.%f') - datetime.datetime.strptime(x[3],'%Y-%m-%d %H:%M:%S.%f')).total_seconds())).collect() 112 | # Create data frame 113 | df_WaitingTime = sparkSession.createDataFrame(wtDF3, schema_Difference) 114 | df_WaitingTime.createOrReplaceTempView("dfWaitingTime") 115 | waitingTimeResult = sparkSession.sql("select wayID,min(timeDifference),max(timeDifference),avg(timeDifference) from dfWaitingTime group by wayID").collect() 116 | 117 | ### average speed process 118 | 119 | # avg_speed = all speed / number of packet 120 | # for rbt_id 121 | # df_Selected.groupBy("rbt_id").agg({"lineerX":"mean"}) 122 | # for wayID,rbt_id 123 | # df_Selected.groupBy("rbt_id").agg({"lineerX":"mean"}) 124 | # for wayID,rbt_id,tourCount 125 | # ms_WRT=df_Selected.groupBy("wayID","rbt_id","tourCount").agg({"lineerX":"mean"}).collect() 126 | 127 | # find average speed for each way 128 | averageSpeedResult = sparkSession.sql("select wayID,min(lineerX),max(lineerX),avg(lineerX) from sqlDF group by wayID ").collect() 129 | 130 | 131 | ### density process 132 | # density = number of robot / way lenght; 133 | density_rdd = df_Selected.select("wayID", "rbt_id", "wayLength").distinct().groupBy("wayID","wayLength").count().collect() 134 | density_rdd2 = sparkSession.sparkContext.parallelize(density_rdd) 135 | densityResult = density_rdd2.map(lambda x: (x[0], x[2] / x[1])).collect() 136 | 137 | ### occupancy process 138 | # occupancy = (way length / (all robot lenght)) 139 | occupancy_rdd = df_Selected.select("wayID", "rbt_id", "wayLength", "rbtLength").distinct().groupBy("wayID","wayLength","rbtLength").count().collect() 140 | occupancy_rdd2 = sparkSession.sparkContext.parallelize(occupancy_rdd) 141 | occupancy_rdd3 = occupancy_rdd2.map(lambda x: (x[0], x[1] / (x[2] * x[3]))) 142 | occupanyResult = occupancy_rdd3.reduceByKey(lambda x, y: x + y).collect() 143 | 144 | ### prepare data to write MsSQL 145 | analysisResults = {} 146 | 147 | # add travel time result to analysis dict 148 | for tt in travelTimeResult: 149 | analysisSub = [] 150 | analysisSub.append(tt[1]) 151 | analysisSub.append(tt[2]) 152 | analysisSub.append(tt[3]) 153 | analysisResults[tt[0]] = analysisSub 154 | 155 | # add average speed result to analysis dict 156 | for avgs in averageSpeedResult: 157 | analysisResults[avgs[0]].append(avgs[1]) 158 | analysisResults[avgs[0]].append(avgs[2]) 159 | analysisResults[avgs[0]].append(avgs[3]) 160 | 161 | # add occupancy result to analysis dict 162 | for occ in occupanyResult: 163 | analysisResults[occ[0]].append(occ[1]) 164 | # add density result to analysis dict 165 | for dens in densityResult: 166 | analysisResults[dens[0]].append(dens[1]) 167 | 168 | # create MsSQL connection 169 | MsSQLConnector1 = MsSQL.MsSQLConnection() 170 | conn1 = MsSQLConnector1.GetConnection() 171 | cursor1 = conn1.cursor() 172 | 173 | # get way info from MsSQL 174 | cursor1.execute("SELECT Way_ID FROM DefWays") 175 | 176 | # find ways that does not have a packet that generated on. 177 | notExistWay = [] 178 | for way in cursor1: 179 | check = 0 180 | for val in travelTimeResult: 181 | if (str(way[0]) == val[0]): 182 | check = 1 183 | break 184 | if (check == 0): 185 | notExistWay.append(str(way[0])) 186 | 187 | # get way info from MsSQL 188 | cursor1.execute("SELECT Way_ID FROM DefWays") 189 | print("") 190 | 191 | # add waiting time result to analysis dict 192 | for way in cursor1: 193 | if (str(way[0]) in notExistWay): 194 | analysisResults[str(way[0])] = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 195 | continue 196 | else: 197 | ch = 0 198 | for val in waitingTimeResult: 199 | if (str(way[0]) == val[0]): 200 | analysisResults[val[0]].append(val[1]) 201 | analysisResults[val[0]].append(val[2]) 202 | analysisResults[val[0]].append(val[3]) 203 | ch = 1 204 | break 205 | if (ch == 0): 206 | analysisResults[str(way[0])].append(0) 207 | analysisResults[str(way[0])].append(0) 208 | analysisResults[str(way[0])].append(0) 209 | 210 | # for the label analysis result, we seperate a hour four part that each has 15 minute and assign them a significant number 211 | tag = -1 212 | if (timeMin.minute < 15): 213 | tag = 1 214 | elif (timeMin.minute >= 15 and timeMin.minute < 30): 215 | tag = 2 216 | elif (timeMin.minute >= 30 and timeMin.minute < 45): 217 | tag = 3 218 | else: 219 | tag = 4 220 | 221 | # generate label like YY/MM/DD/HH/Tag ex: 12/02/2020/14/3 >> date:12/02/2020 hour:14 interval:30-45 minutes 222 | timeLabel = str(timeMin.year) + "/" + str(timeMin.month) + "/" + str(timeMin.day) + "/" + str(timeMin.hour) + "/" + str(tag) 223 | #timeLabel="100_tur" 224 | 225 | ### get way information from MsSQL and store analysis result for each way 226 | cursor1.execute("SELECT Way_ID FROM DefWays") 227 | ways=[] 228 | for i in cursor1: 229 | ways.append(i[0]) 230 | 231 | query="" 232 | try: 233 | count=0 234 | for way in ways: 235 | count+=1 236 | if(count==len(ways)): 237 | query+="('"+timeLabel + "'," + str(way) + "," +str(analysisResults[str(way)][3]) + "," + str(analysisResults[str(way)][4]) + "," + str(analysisResults[str(way)][5]) + "," +str(analysisResults[str(way)][0]) + "," + str(analysisResults[str(way)][1]) + "," + str(analysisResults[str(way)][2]) + "," +str(analysisResults[str(way)][8]) + "," + str(analysisResults[str(way)][9]) + "," + str(analysisResults[str(way)][10]) + "," +str(analysisResults[str(way)][6]) + "," + str(analysisResults[str(way)][7]) +")" 238 | else: 239 | query+="('"+timeLabel + "'," + str(way) + "," +str(analysisResults[str(way)][3]) + "," + str(analysisResults[str(way)][4]) + "," + str(analysisResults[str(way)][5]) + "," +str(analysisResults[str(way)][0]) + "," + str(analysisResults[str(way)][1]) + "," + str(analysisResults[str(way)][2]) + "," +str(analysisResults[str(way)][8]) + "," + str(analysisResults[str(way)][9]) + "," + str(analysisResults[str(way)][10]) + "," +str(analysisResults[str(way)][6]) + "," + str(analysisResults[str(way)][7]) +")," 240 | 241 | cursor1.execute("insert into DefAnalysisResult (Anl_timeLabel,Anl_wayID,Anl_speed_min,Anl_speed_max,Anl_speed_avg,Anl_travelTime_min,Anl_travelTime_max,Anl_travelTime_avg,Anl_waitingTime_min,Anl_waitingTime_max,Anl_waitingTime_avg,Anl_occupancy,Anl_density) values "+query) 242 | conn1.commit() 243 | except Exception as e : 244 | print(e) 245 | 246 | ## show all processs time 247 | print(temptime, " : ", datetime.datetime.now(), " : ", (datetime.datetime.now() - temptime).total_seconds()) 248 | print("finish") 249 | -------------------------------------------------------------------------------- /Analysis-Result-Visualization-PyQT5/userInterface.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'userInterface.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.6 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_MainWindow(object): 12 | def setupUi(self, MainWindow): 13 | MainWindow.setObjectName("MainWindow") 14 | MainWindow.resize(1107, 825) 15 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed) 16 | sizePolicy.setHorizontalStretch(0) 17 | sizePolicy.setVerticalStretch(0) 18 | sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth()) 19 | MainWindow.setSizePolicy(sizePolicy) 20 | self.centralwidget = QtWidgets.QWidget(MainWindow) 21 | self.centralwidget.setObjectName("centralwidget") 22 | self.groupBox = QtWidgets.QGroupBox(self.centralwidget) 23 | self.groupBox.setGeometry(QtCore.QRect(40, 30, 371, 171)) 24 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 25 | sizePolicy.setHorizontalStretch(0) 26 | sizePolicy.setVerticalStretch(0) 27 | sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth()) 28 | self.groupBox.setSizePolicy(sizePolicy) 29 | font = QtGui.QFont() 30 | font.setPointSize(9) 31 | self.groupBox.setFont(font) 32 | self.groupBox.setObjectName("groupBox") 33 | self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox) 34 | self.verticalLayout.setObjectName("verticalLayout") 35 | self.gridLayout = QtWidgets.QGridLayout() 36 | self.gridLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint) 37 | self.gridLayout.setContentsMargins(0, -1, 0, -1) 38 | self.gridLayout.setObjectName("gridLayout") 39 | self.cboxTimeLabel = QtWidgets.QComboBox(self.groupBox) 40 | font = QtGui.QFont() 41 | font.setPointSize(10) 42 | font.setBold(False) 43 | font.setWeight(50) 44 | self.cboxTimeLabel.setFont(font) 45 | self.cboxTimeLabel.setCurrentText("") 46 | self.cboxTimeLabel.setObjectName("cboxTimeLabel") 47 | self.gridLayout.addWidget(self.cboxTimeLabel, 1, 1, 1, 1) 48 | self.label_1 = QtWidgets.QLabel(self.groupBox) 49 | font = QtGui.QFont() 50 | font.setPointSize(11) 51 | font.setBold(False) 52 | font.setWeight(50) 53 | self.label_1.setFont(font) 54 | self.label_1.setObjectName("label_1") 55 | self.gridLayout.addWidget(self.label_1, 0, 0, 1, 1) 56 | self.cboxYolID = QtWidgets.QComboBox(self.groupBox) 57 | font = QtGui.QFont() 58 | font.setPointSize(10) 59 | font.setBold(False) 60 | font.setWeight(50) 61 | self.cboxYolID.setFont(font) 62 | self.cboxYolID.setObjectName("cboxYolID") 63 | self.gridLayout.addWidget(self.cboxYolID, 0, 1, 1, 1) 64 | self.label_2 = QtWidgets.QLabel(self.groupBox) 65 | font = QtGui.QFont() 66 | font.setPointSize(11) 67 | font.setBold(False) 68 | font.setWeight(50) 69 | self.label_2.setFont(font) 70 | self.label_2.setObjectName("label_2") 71 | self.gridLayout.addWidget(self.label_2, 1, 0, 1, 1) 72 | self.verticalLayout.addLayout(self.gridLayout) 73 | self.pushButton = QtWidgets.QPushButton(self.groupBox) 74 | font = QtGui.QFont() 75 | font.setPointSize(10) 76 | self.pushButton.setFont(font) 77 | self.pushButton.setObjectName("pushButton") 78 | self.verticalLayout.addWidget(self.pushButton) 79 | self.groupBox_2 = QtWidgets.QGroupBox(self.centralwidget) 80 | self.groupBox_2.setGeometry(QtCore.QRect(440, 30, 651, 311)) 81 | sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) 82 | sizePolicy.setHorizontalStretch(0) 83 | sizePolicy.setVerticalStretch(0) 84 | sizePolicy.setHeightForWidth(self.groupBox_2.sizePolicy().hasHeightForWidth()) 85 | self.groupBox_2.setSizePolicy(sizePolicy) 86 | font = QtGui.QFont() 87 | font.setPointSize(9) 88 | self.groupBox_2.setFont(font) 89 | self.groupBox_2.setObjectName("groupBox_2") 90 | self.gridLayoutWidget_4 = QtWidgets.QWidget(self.groupBox_2) 91 | self.gridLayoutWidget_4.setGeometry(QtCore.QRect(10, 30, 631, 271)) 92 | self.gridLayoutWidget_4.setObjectName("gridLayoutWidget_4") 93 | self.gridLayout_4 = QtWidgets.QGridLayout(self.gridLayoutWidget_4) 94 | self.gridLayout_4.setContentsMargins(0, 0, 0, 0) 95 | self.gridLayout_4.setObjectName("gridLayout_4") 96 | self.groupBox_5 = QtWidgets.QGroupBox(self.gridLayoutWidget_4) 97 | self.groupBox_5.setObjectName("groupBox_5") 98 | self.gridLayoutWidget_6 = QtWidgets.QWidget(self.groupBox_5) 99 | self.gridLayoutWidget_6.setGeometry(QtCore.QRect(10, 30, 301, 91)) 100 | self.gridLayoutWidget_6.setObjectName("gridLayoutWidget_6") 101 | self.gridLayout_6 = QtWidgets.QGridLayout(self.gridLayoutWidget_6) 102 | self.gridLayout_6.setContentsMargins(0, 0, 0, 0) 103 | self.gridLayout_6.setObjectName("gridLayout_6") 104 | self.lblAvgWt = QtWidgets.QLabel(self.gridLayoutWidget_6) 105 | font = QtGui.QFont() 106 | font.setPointSize(11) 107 | font.setBold(False) 108 | font.setWeight(50) 109 | self.lblAvgWt.setFont(font) 110 | self.lblAvgWt.setText("") 111 | self.lblAvgWt.setObjectName("lblAvgWt") 112 | self.gridLayout_6.addWidget(self.lblAvgWt, 1, 1, 1, 1) 113 | self.label_17 = QtWidgets.QLabel(self.gridLayoutWidget_6) 114 | font = QtGui.QFont() 115 | font.setPointSize(11) 116 | font.setBold(False) 117 | font.setWeight(50) 118 | self.label_17.setFont(font) 119 | self.label_17.setObjectName("label_17") 120 | self.gridLayout_6.addWidget(self.label_17, 0, 0, 1, 1) 121 | self.lblMinWt = QtWidgets.QLabel(self.gridLayoutWidget_6) 122 | font = QtGui.QFont() 123 | font.setPointSize(11) 124 | font.setBold(False) 125 | font.setWeight(50) 126 | self.lblMinWt.setFont(font) 127 | self.lblMinWt.setText("") 128 | self.lblMinWt.setObjectName("lblMinWt") 129 | self.gridLayout_6.addWidget(self.lblMinWt, 0, 1, 1, 1) 130 | self.label_18 = QtWidgets.QLabel(self.gridLayoutWidget_6) 131 | font = QtGui.QFont() 132 | font.setPointSize(11) 133 | font.setBold(False) 134 | font.setWeight(50) 135 | self.label_18.setFont(font) 136 | self.label_18.setObjectName("label_18") 137 | self.gridLayout_6.addWidget(self.label_18, 1, 0, 1, 1) 138 | self.label_19 = QtWidgets.QLabel(self.gridLayoutWidget_6) 139 | font = QtGui.QFont() 140 | font.setPointSize(11) 141 | font.setBold(False) 142 | font.setWeight(50) 143 | self.label_19.setFont(font) 144 | self.label_19.setObjectName("label_19") 145 | self.gridLayout_6.addWidget(self.label_19, 2, 0, 1, 1) 146 | self.lblMaxWt = QtWidgets.QLabel(self.gridLayoutWidget_6) 147 | font = QtGui.QFont() 148 | font.setPointSize(11) 149 | font.setBold(False) 150 | font.setWeight(50) 151 | self.lblMaxWt.setFont(font) 152 | self.lblMaxWt.setText("") 153 | self.lblMaxWt.setObjectName("lblMaxWt") 154 | self.gridLayout_6.addWidget(self.lblMaxWt, 2, 1, 1, 1) 155 | self.gridLayout_4.addWidget(self.groupBox_5, 1, 0, 1, 1) 156 | self.groupBox_4 = QtWidgets.QGroupBox(self.gridLayoutWidget_4) 157 | self.groupBox_4.setObjectName("groupBox_4") 158 | self.gridLayoutWidget_5 = QtWidgets.QWidget(self.groupBox_4) 159 | self.gridLayoutWidget_5.setGeometry(QtCore.QRect(10, 30, 291, 91)) 160 | self.gridLayoutWidget_5.setObjectName("gridLayoutWidget_5") 161 | self.gridLayout_5 = QtWidgets.QGridLayout(self.gridLayoutWidget_5) 162 | self.gridLayout_5.setContentsMargins(0, 0, 0, 0) 163 | self.gridLayout_5.setObjectName("gridLayout_5") 164 | self.lblAvgTt = QtWidgets.QLabel(self.gridLayoutWidget_5) 165 | font = QtGui.QFont() 166 | font.setPointSize(11) 167 | font.setBold(False) 168 | font.setWeight(50) 169 | self.lblAvgTt.setFont(font) 170 | self.lblAvgTt.setText("") 171 | self.lblAvgTt.setObjectName("lblAvgTt") 172 | self.gridLayout_5.addWidget(self.lblAvgTt, 1, 1, 1, 1) 173 | self.label_14 = QtWidgets.QLabel(self.gridLayoutWidget_5) 174 | font = QtGui.QFont() 175 | font.setPointSize(11) 176 | font.setBold(False) 177 | font.setWeight(50) 178 | self.label_14.setFont(font) 179 | self.label_14.setObjectName("label_14") 180 | self.gridLayout_5.addWidget(self.label_14, 0, 0, 1, 1) 181 | self.lblMinTt = QtWidgets.QLabel(self.gridLayoutWidget_5) 182 | font = QtGui.QFont() 183 | font.setPointSize(11) 184 | font.setBold(False) 185 | font.setWeight(50) 186 | self.lblMinTt.setFont(font) 187 | self.lblMinTt.setText("") 188 | self.lblMinTt.setObjectName("lblMinTt") 189 | self.gridLayout_5.addWidget(self.lblMinTt, 0, 1, 1, 1) 190 | self.label_15 = QtWidgets.QLabel(self.gridLayoutWidget_5) 191 | font = QtGui.QFont() 192 | font.setPointSize(11) 193 | font.setBold(False) 194 | font.setWeight(50) 195 | self.label_15.setFont(font) 196 | self.label_15.setObjectName("label_15") 197 | self.gridLayout_5.addWidget(self.label_15, 1, 0, 1, 1) 198 | self.label_16 = QtWidgets.QLabel(self.gridLayoutWidget_5) 199 | font = QtGui.QFont() 200 | font.setPointSize(11) 201 | font.setBold(False) 202 | font.setWeight(50) 203 | self.label_16.setFont(font) 204 | self.label_16.setObjectName("label_16") 205 | self.gridLayout_5.addWidget(self.label_16, 2, 0, 1, 1) 206 | self.lblMaxTt = QtWidgets.QLabel(self.gridLayoutWidget_5) 207 | font = QtGui.QFont() 208 | font.setPointSize(11) 209 | font.setBold(False) 210 | font.setWeight(50) 211 | self.lblMaxTt.setFont(font) 212 | self.lblMaxTt.setText("") 213 | self.lblMaxTt.setObjectName("lblMaxTt") 214 | self.gridLayout_5.addWidget(self.lblMaxTt, 2, 1, 1, 1) 215 | self.gridLayout_4.addWidget(self.groupBox_4, 0, 1, 1, 1) 216 | self.groupBox_3 = QtWidgets.QGroupBox(self.gridLayoutWidget_4) 217 | self.groupBox_3.setObjectName("groupBox_3") 218 | self.gridLayoutWidget_2 = QtWidgets.QWidget(self.groupBox_3) 219 | self.gridLayoutWidget_2.setGeometry(QtCore.QRect(10, 30, 301, 91)) 220 | self.gridLayoutWidget_2.setObjectName("gridLayoutWidget_2") 221 | self.gridLayout_2 = QtWidgets.QGridLayout(self.gridLayoutWidget_2) 222 | self.gridLayout_2.setContentsMargins(0, 0, 0, 0) 223 | self.gridLayout_2.setObjectName("gridLayout_2") 224 | self.lblAvgSpeed = QtWidgets.QLabel(self.gridLayoutWidget_2) 225 | font = QtGui.QFont() 226 | font.setPointSize(11) 227 | font.setBold(False) 228 | font.setWeight(50) 229 | self.lblAvgSpeed.setFont(font) 230 | self.lblAvgSpeed.setText("") 231 | self.lblAvgSpeed.setObjectName("lblAvgSpeed") 232 | self.gridLayout_2.addWidget(self.lblAvgSpeed, 1, 1, 1, 1) 233 | self.label_4 = QtWidgets.QLabel(self.gridLayoutWidget_2) 234 | font = QtGui.QFont() 235 | font.setPointSize(11) 236 | font.setBold(False) 237 | font.setWeight(50) 238 | self.label_4.setFont(font) 239 | self.label_4.setObjectName("label_4") 240 | self.gridLayout_2.addWidget(self.label_4, 0, 0, 1, 1) 241 | self.lblMinSpeed = QtWidgets.QLabel(self.gridLayoutWidget_2) 242 | font = QtGui.QFont() 243 | font.setPointSize(11) 244 | font.setBold(False) 245 | font.setWeight(50) 246 | self.lblMinSpeed.setFont(font) 247 | self.lblMinSpeed.setText("") 248 | self.lblMinSpeed.setObjectName("lblMinSpeed") 249 | self.gridLayout_2.addWidget(self.lblMinSpeed, 0, 1, 1, 1) 250 | self.label_9 = QtWidgets.QLabel(self.gridLayoutWidget_2) 251 | font = QtGui.QFont() 252 | font.setPointSize(11) 253 | font.setBold(False) 254 | font.setWeight(50) 255 | self.label_9.setFont(font) 256 | self.label_9.setObjectName("label_9") 257 | self.gridLayout_2.addWidget(self.label_9, 1, 0, 1, 1) 258 | self.label_10 = QtWidgets.QLabel(self.gridLayoutWidget_2) 259 | font = QtGui.QFont() 260 | font.setPointSize(11) 261 | font.setBold(False) 262 | font.setWeight(50) 263 | self.label_10.setFont(font) 264 | self.label_10.setObjectName("label_10") 265 | self.gridLayout_2.addWidget(self.label_10, 2, 0, 1, 1) 266 | self.lblMaxSpeed = QtWidgets.QLabel(self.gridLayoutWidget_2) 267 | font = QtGui.QFont() 268 | font.setPointSize(11) 269 | font.setBold(False) 270 | font.setWeight(50) 271 | self.lblMaxSpeed.setFont(font) 272 | self.lblMaxSpeed.setText("") 273 | self.lblMaxSpeed.setObjectName("lblMaxSpeed") 274 | self.gridLayout_2.addWidget(self.lblMaxSpeed, 2, 1, 1, 1) 275 | self.gridLayout_4.addWidget(self.groupBox_3, 0, 0, 1, 1) 276 | self.groupBox_6 = QtWidgets.QGroupBox(self.gridLayoutWidget_4) 277 | self.groupBox_6.setObjectName("groupBox_6") 278 | self.lblDensity = QtWidgets.QLabel(self.groupBox_6) 279 | self.lblDensity.setGeometry(QtCore.QRect(120, 72, 128, 25)) 280 | font = QtGui.QFont() 281 | font.setPointSize(11) 282 | font.setBold(False) 283 | font.setWeight(50) 284 | self.lblDensity.setFont(font) 285 | self.lblDensity.setText("") 286 | self.lblDensity.setObjectName("lblDensity") 287 | self.lblOccupancy = QtWidgets.QLabel(self.groupBox_6) 288 | self.lblOccupancy.setGeometry(QtCore.QRect(120, 44, 128, 25)) 289 | font = QtGui.QFont() 290 | font.setPointSize(11) 291 | font.setBold(False) 292 | font.setWeight(50) 293 | self.lblOccupancy.setFont(font) 294 | self.lblOccupancy.setText("") 295 | self.lblOccupancy.setObjectName("lblOccupancy") 296 | self.label_5 = QtWidgets.QLabel(self.groupBox_6) 297 | self.label_5.setGeometry(QtCore.QRect(10, 72, 91, 25)) 298 | font = QtGui.QFont() 299 | font.setPointSize(11) 300 | font.setBold(False) 301 | font.setWeight(50) 302 | self.label_5.setFont(font) 303 | self.label_5.setObjectName("label_5") 304 | self.label_20 = QtWidgets.QLabel(self.groupBox_6) 305 | self.label_20.setGeometry(QtCore.QRect(10, 44, 91, 25)) 306 | font = QtGui.QFont() 307 | font.setPointSize(11) 308 | font.setBold(False) 309 | font.setWeight(50) 310 | self.label_20.setFont(font) 311 | self.label_20.setObjectName("label_20") 312 | self.gridLayout_4.addWidget(self.groupBox_6, 1, 1, 1, 1) 313 | self.groupBox_7 = QtWidgets.QGroupBox(self.centralwidget) 314 | self.groupBox_7.setGeometry(QtCore.QRect(40, 210, 371, 131)) 315 | font = QtGui.QFont() 316 | font.setPointSize(9) 317 | self.groupBox_7.setFont(font) 318 | self.groupBox_7.setObjectName("groupBox_7") 319 | self.label_3 = QtWidgets.QLabel(self.groupBox_7) 320 | self.label_3.setGeometry(QtCore.QRect(10, 40, 121, 27)) 321 | font = QtGui.QFont() 322 | font.setPointSize(11) 323 | font.setBold(False) 324 | font.setWeight(50) 325 | self.label_3.setFont(font) 326 | self.label_3.setObjectName("label_3") 327 | self.cboxAnalysisType = QtWidgets.QComboBox(self.groupBox_7) 328 | self.cboxAnalysisType.setGeometry(QtCore.QRect(120, 40, 241, 27)) 329 | font = QtGui.QFont() 330 | font.setPointSize(10) 331 | font.setBold(False) 332 | font.setWeight(50) 333 | self.cboxAnalysisType.setFont(font) 334 | self.cboxAnalysisType.setEditable(False) 335 | self.cboxAnalysisType.setObjectName("cboxAnalysisType") 336 | self.cboxAnalysisType.addItem("") 337 | self.cboxAnalysisType.addItem("") 338 | self.cboxAnalysisType.addItem("") 339 | self.cboxAnalysisType.addItem("") 340 | self.cboxAnalysisType.addItem("") 341 | self.pushButton_2 = QtWidgets.QPushButton(self.groupBox_7) 342 | self.pushButton_2.setGeometry(QtCore.QRect(12, 90, 347, 30)) 343 | font = QtGui.QFont() 344 | font.setPointSize(10) 345 | self.pushButton_2.setFont(font) 346 | self.pushButton_2.setObjectName("pushButton_2") 347 | MainWindow.setCentralWidget(self.centralwidget) 348 | self.menubar = QtWidgets.QMenuBar(MainWindow) 349 | self.menubar.setGeometry(QtCore.QRect(0, 0, 1107, 26)) 350 | self.menubar.setObjectName("menubar") 351 | MainWindow.setMenuBar(self.menubar) 352 | self.statusbar = QtWidgets.QStatusBar(MainWindow) 353 | self.statusbar.setObjectName("statusbar") 354 | MainWindow.setStatusBar(self.statusbar) 355 | 356 | self.retranslateUi(MainWindow) 357 | self.pushButton.clicked.connect(MainWindow.setAnalysisResult) 358 | self.pushButton_2.clicked.connect(MainWindow.setGraphic) 359 | QtCore.QMetaObject.connectSlotsByName(MainWindow) 360 | 361 | def retranslateUi(self, MainWindow): 362 | _translate = QtCore.QCoreApplication.translate 363 | MainWindow.setWindowTitle(_translate("MainWindow", "Analiz Görselleştirme Programı")) 364 | self.groupBox.setTitle(_translate("MainWindow", "Analiz Özellik Seçimi")) 365 | self.label_1.setText(_translate("MainWindow", "Yol ID:")) 366 | self.label_2.setText(_translate("MainWindow", "Zaman Aralığı:")) 367 | self.pushButton.setText(_translate("MainWindow", "Değerleri Göster")) 368 | self.groupBox_2.setTitle(_translate("MainWindow", "Analiz Sonuçları")) 369 | self.groupBox_5.setTitle(_translate("MainWindow", "Bekleme Süresi")) 370 | self.label_17.setText(_translate("MainWindow", "Minimum:")) 371 | self.label_18.setText(_translate("MainWindow", "Ortalama:")) 372 | self.label_19.setText(_translate("MainWindow", "Maksimum:")) 373 | self.groupBox_4.setTitle(_translate("MainWindow", "Seyahat Süresi")) 374 | self.label_14.setText(_translate("MainWindow", "Minimum:")) 375 | self.label_15.setText(_translate("MainWindow", "Ortalama:")) 376 | self.label_16.setText(_translate("MainWindow", "Maksimum:")) 377 | self.groupBox_3.setTitle(_translate("MainWindow", "Hız")) 378 | self.label_4.setText(_translate("MainWindow", "Minimum:")) 379 | self.label_9.setText(_translate("MainWindow", "Ortalama:")) 380 | self.label_10.setText(_translate("MainWindow", "Maksimum:")) 381 | self.groupBox_6.setTitle(_translate("MainWindow", "Diğer")) 382 | self.label_5.setText(_translate("MainWindow", "Yoğunluk:")) 383 | self.label_20.setText(_translate("MainWindow", "Doluluk:")) 384 | self.groupBox_7.setTitle(_translate("MainWindow", "Analiz Grafikte Gösterim")) 385 | self.label_3.setText(_translate("MainWindow", "Analiz Türü:")) 386 | self.cboxAnalysisType.setCurrentText(_translate("MainWindow", "Hız")) 387 | self.cboxAnalysisType.setItemText(0, _translate("MainWindow", "Hız")) 388 | self.cboxAnalysisType.setItemText(1, _translate("MainWindow", "Seyahat Süresi")) 389 | self.cboxAnalysisType.setItemText(2, _translate("MainWindow", "Bekleme Süresi")) 390 | self.cboxAnalysisType.setItemText(3, _translate("MainWindow", "Yoğunluk")) 391 | self.cboxAnalysisType.setItemText(4, _translate("MainWindow", "Doluluk")) 392 | self.pushButton_2.setText(_translate("MainWindow", "Grafikte Göster")) 393 | 394 | -------------------------------------------------------------------------------- /Analysis-Result-Visualization-PyQT5/userInterface.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | MainWindow 4 | 5 | 6 | 7 | 0 8 | 0 9 | 1107 10 | 825 11 | 12 | 13 | 14 | 15 | 0 16 | 0 17 | 18 | 19 | 20 | Analiz Görselleştirme Programı 21 | 22 | 23 | 24 | 25 | 26 | 40 27 | 30 28 | 371 29 | 171 30 | 31 | 32 | 33 | 34 | 0 35 | 0 36 | 37 | 38 | 39 | 40 | 9 41 | 42 | 43 | 44 | Analiz Özellik Seçimi 45 | 46 | 47 | 48 | 49 | 50 | QLayout::SetDefaultConstraint 51 | 52 | 53 | 0 54 | 55 | 56 | 0 57 | 58 | 59 | 60 | 61 | 62 | 10 63 | 50 64 | false 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 11 77 | 50 78 | false 79 | 80 | 81 | 82 | Yol ID: 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 10 91 | 50 92 | false 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 11 102 | 50 103 | false 104 | 105 | 106 | 107 | Zaman Aralığı: 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 10 118 | 119 | 120 | 121 | Değerleri Göster 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 440 131 | 30 132 | 651 133 | 311 134 | 135 | 136 | 137 | 138 | 0 139 | 0 140 | 141 | 142 | 143 | 144 | 9 145 | 146 | 147 | 148 | Analiz Sonuçları 149 | 150 | 151 | 152 | 153 | 10 154 | 30 155 | 631 156 | 271 157 | 158 | 159 | 160 | 161 | 162 | 163 | Bekleme Süresi 164 | 165 | 166 | 167 | 168 | 10 169 | 30 170 | 301 171 | 91 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 11 180 | 50 181 | false 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 11 194 | 50 195 | false 196 | 197 | 198 | 199 | Minimum: 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 11 208 | 50 209 | false 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 11 222 | 50 223 | false 224 | 225 | 226 | 227 | Ortalama: 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 11 236 | 50 237 | false 238 | 239 | 240 | 241 | Maksimum: 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 11 250 | 50 251 | false 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | Seyahat Süresi 267 | 268 | 269 | 270 | 271 | 10 272 | 30 273 | 291 274 | 91 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 11 283 | 50 284 | false 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 11 297 | 50 298 | false 299 | 300 | 301 | 302 | Minimum: 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | 11 311 | 50 312 | false 313 | 314 | 315 | 316 | 317 | 318 | 319 | 320 | 321 | 322 | 323 | 324 | 11 325 | 50 326 | false 327 | 328 | 329 | 330 | Ortalama: 331 | 332 | 333 | 334 | 335 | 336 | 337 | 338 | 11 339 | 50 340 | false 341 | 342 | 343 | 344 | Maksimum: 345 | 346 | 347 | 348 | 349 | 350 | 351 | 352 | 11 353 | 50 354 | false 355 | 356 | 357 | 358 | 359 | 360 | 361 | 362 | 363 | 364 | 365 | 366 | 367 | 368 | 369 | Hız 370 | 371 | 372 | 373 | 374 | 10 375 | 30 376 | 301 377 | 91 378 | 379 | 380 | 381 | 382 | 383 | 384 | 385 | 11 386 | 50 387 | false 388 | 389 | 390 | 391 | 392 | 393 | 394 | 395 | 396 | 397 | 398 | 399 | 11 400 | 50 401 | false 402 | 403 | 404 | 405 | Minimum: 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 11 414 | 50 415 | false 416 | 417 | 418 | 419 | 420 | 421 | 422 | 423 | 424 | 425 | 426 | 427 | 11 428 | 50 429 | false 430 | 431 | 432 | 433 | Ortalama: 434 | 435 | 436 | 437 | 438 | 439 | 440 | 441 | 11 442 | 50 443 | false 444 | 445 | 446 | 447 | Maksimum: 448 | 449 | 450 | 451 | 452 | 453 | 454 | 455 | 11 456 | 50 457 | false 458 | 459 | 460 | 461 | 462 | 463 | 464 | 465 | 466 | 467 | 468 | 469 | 470 | 471 | 472 | Diğer 473 | 474 | 475 | 476 | 477 | 120 478 | 72 479 | 128 480 | 25 481 | 482 | 483 | 484 | 485 | 11 486 | 50 487 | false 488 | 489 | 490 | 491 | 492 | 493 | 494 | 495 | 496 | 497 | 120 498 | 44 499 | 128 500 | 25 501 | 502 | 503 | 504 | 505 | 11 506 | 50 507 | false 508 | 509 | 510 | 511 | 512 | 513 | 514 | 515 | 516 | 517 | 10 518 | 72 519 | 91 520 | 25 521 | 522 | 523 | 524 | 525 | 11 526 | 50 527 | false 528 | 529 | 530 | 531 | Yoğunluk: 532 | 533 | 534 | 535 | 536 | 537 | 10 538 | 44 539 | 91 540 | 25 541 | 542 | 543 | 544 | 545 | 11 546 | 50 547 | false 548 | 549 | 550 | 551 | Doluluk: 552 | 553 | 554 | 555 | 556 | 557 | 558 | 559 | 560 | 561 | 562 | 40 563 | 210 564 | 371 565 | 131 566 | 567 | 568 | 569 | 570 | 9 571 | 572 | 573 | 574 | Analiz Grafikte Gösterim 575 | 576 | 577 | 578 | 579 | 10 580 | 40 581 | 121 582 | 27 583 | 584 | 585 | 586 | 587 | 11 588 | 50 589 | false 590 | 591 | 592 | 593 | Analiz Türü: 594 | 595 | 596 | 597 | 598 | 599 | 120 600 | 40 601 | 241 602 | 27 603 | 604 | 605 | 606 | 607 | 10 608 | 50 609 | false 610 | 611 | 612 | 613 | false 614 | 615 | 616 | Hız 617 | 618 | 619 | 620 | Hız 621 | 622 | 623 | 624 | 625 | Seyahat Süresi 626 | 627 | 628 | 629 | 630 | Bekleme Süresi 631 | 632 | 633 | 634 | 635 | Yoğunluk 636 | 637 | 638 | 639 | 640 | Doluluk 641 | 642 | 643 | 644 | 645 | 646 | 647 | 12 648 | 90 649 | 347 650 | 30 651 | 652 | 653 | 654 | 655 | 10 656 | 657 | 658 | 659 | Grafikte Göster 660 | 661 | 662 | 663 | 664 | 665 | 666 | 667 | 0 668 | 0 669 | 1107 670 | 26 671 | 672 | 673 | 674 | 675 | 676 | 677 | 678 | 679 | pushButton 680 | clicked() 681 | MainWindow 682 | setAnalysisResult() 683 | 684 | 685 | 242 686 | 195 687 | 688 | 689 | 192 690 | 276 691 | 692 | 693 | 694 | 695 | pushButton_2 696 | clicked() 697 | MainWindow 698 | setGraphic() 699 | 700 | 701 | 254 702 | 444 703 | 704 | 705 | 264 706 | 520 707 | 708 | 709 | 710 | 711 | 712 | setAnalysisResult() 713 | setGraphic() 714 | 715 | 716 | --------------------------------------------------------------------------------