Wednesday, February 22, 2017

Crowdsourced traffic data analysis and visualizing using WSO2 CEP.

Introduction

Aim was to develop a mobile application and a website to get reliable traffic data in certain areas. GPS data received from smart phones of users was analyzed via CEP. When the users log into the android application their GPS data was sent to the CEP. From the data received, it was possible identify the location and moving speeds of users. Analyzing the traffic condition was done inside CEP. After analyzing, crowd sourced data about traffic is displayed on a map. 

Usage of geo-fencing and level of service to calculate traffic

Geo fencing is a feature that can be used in a software program to define the geometrical boundaries. In our project this technology was used to segment the road. Geo-fencing custom extension in WSO2 CEP is used to define the boundaries and filter vehicular data. When CEP receives an event, its coordinates are checked against the defined boundaries to check whether it is inside or outside, using OSGeo Geo Tools library [1].

We used the method Average Travel Speed (ATS) to calculate traffic level of service.

ATS = Distance / average time of vehicles

One execution plan includes all the required processes to calculate the traffic status of a particular road segment. 

User’s imei number, longitude, latitude values were passed in to the execution plan from an event stream.
In the execution plan two polygons in one junction were defined using longitude and latitude coordinates of the road segments. When CEP receives an event check whether it was within the range of defined polygons. If they were within those polygons events were sent to two different streams based on the polygon which they belong to.

Siddhi Query

from nospeedstream[geo:iswithin(longitude,latitude,"{'type':'Polygon','coordinates':[[[79.84941602,6.91021645],[79.85038161,6.91049338],[79.85070348,6.90979042],[79.84948039,6.90930048],[79.84941602,6.91021645]]]}")==true]
select imei , longitude,latitude,timemili
insert into filteredPoly1;

Then the entering time stamps of each individual vehicle for first polygon and the second polygon were recorded separately. And those timestamps and imei number of vehicles were passed to another stream.

from filteredPoly1#window.unique(imei) as p1 join filteredPoly2#window.unique(imei) as p2
on p1.imei == p2.imei
select p1.imei as imei, p1.timemili as timemili1,p2.timemili as timemili2
insert into joinedpolydata;

from joinedpolydata#window.firstUnique(imei) as p1
select * insert into uniquejoinedpolydata;


After that, time difference of each vehicle was calculated. If it becomes negative that indicates the vehicle is travelling to the opposite direction. From that we can separate the vehicles according to their travelling directions. Vehicles having positive time differences were sent to the ‘positivetimeDiffStream’ and negative ones were sent to the ‘negativetimeDiffStream’.

from uniquejoinedpolydata
select imei, (timemili2-timemili1) as timediffmili
insert into timeDiffStream;

from timeDiffStream[timediffmili>0]
select imei,timediffmili as postimediffmili
insert into positivetimeDiffStream;

from timeDiffStream[timediffmili<0]
select imei,(-1*timediffmili) as negtimediffmili
insert into negativetimeDiffStream;

Then the average time difference of all the vehicles belonging to that road segment within a particular time period was calculated for both directions.

from positivetimeDiffStream#window.time(30 sec)
select "Kolpity" as junc_id,avg(postimediffmili) as free_flow_speed_d1
insert into avgtimediffmilistream;

from negativetimeDiffStream#window.time(30 sec)
select "Kolpity" as junc_id,avg(negtimediffmili) as free_flow_speed_D2
insert into avgtimediffmilistreamneg;

Then the average vehicle speeds of each direction were calculated and the distance of road segment was divided by it to calculate the average speed of each direction.

from avgtimediffmilistream
select junc_id, ((1000/free_flow_speed_d1)*5/18) as free_flow_speed_d1
insert into avgspeedpositive;

from avgtimediffmilistreamneg
select junc_id, ((1000/free_flow_speed_D2)*5/18) as free_flow_speed_D2
insert into avgspeednegative;

This average speed data was then sent to a mysql database through a mysql output adapter in CEP [2].
From this average speed, we can define the traffic level of each direction in application level.

API

A REST API was introduced for outside apps to can call and get data from the system. The API was written using WSO2 Jaggery. It is possible to receive the following metrics through the REST API.


Get all traffic data

Sample request:

GET /apis/traffic

Sample response


Get traffic for specific junction

Sample request:
GET /apis/traffic?junc_id=kolpity
                   
junc_id : We can get traffic status in a particular junction. 

Sample Response


All traffic(only traffic info)

Sample request:


Sample response:



Traffic for specific junction (only traffic info)

Sample request:


Sample response


Finally, traffic condition will be visualized on a google map as in the picture shown below. Red marks are for visualizing high traffic areas and green marks are used to visualize low traffic areas. 


No comments:

Post a Comment