Mercurial > hg > nsaunier > traffic-intelligence
comparison python/storage.py @ 758:0a05883216cf
merge with dev
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Tue, 03 Nov 2015 13:48:56 -0500 |
| parents | a73f43aac00e |
| children | a05b70f307dd |
comparison
equal
deleted
inserted
replaced
| 748:d99866b0528a | 758:0a05883216cf |
|---|---|
| 1 #! /usr/bin/env python | 1 #! /usr/bin/env python |
| 2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
| 3 '''Various utilities to save and load data''' | 3 '''Various utilities to save and load data''' |
| 4 | 4 |
| 5 import utils, moving, events, indicators | 5 import utils, moving, events, indicators, shutil |
| 6 from base import VideoFilenameAddable | 6 from base import VideoFilenameAddable |
| 7 | 7 |
| 8 import sqlite3, logging | 8 import sqlite3, logging |
| 9 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt | 9 from numpy import log, min as npmin, max as npmax, round as npround, array, sum as npsum, loadtxt |
| 10 from pandas import read_csv, merge | |
| 10 | 11 |
| 11 | 12 |
| 12 commentChar = '#' | 13 commentChar = '#' |
| 13 | 14 |
| 14 delimiterChar = '%'; | 15 delimiterChar = '%'; |
| 161 returns a moving object''' | 162 returns a moving object''' |
| 162 cursor = connection.cursor() | 163 cursor = connection.cursor() |
| 163 | 164 |
| 164 try: | 165 try: |
| 165 objectCriteria = getObjectCriteria(objectNumbers) | 166 objectCriteria = getObjectCriteria(objectNumbers) |
| 167 queryStatement = None | |
| 166 if trajectoryType == 'feature': | 168 if trajectoryType == 'feature': |
| 167 queryStatement = 'SELECT * from '+tableName | 169 queryStatement = 'SELECT * from '+tableName |
| 168 if objectNumbers is not None: | 170 if objectNumbers is not None: |
| 169 queryStatement += ' where trajectory_id '+objectCriteria | 171 queryStatement += ' WHERE trajectory_id '+objectCriteria |
| 170 queryStatement += ' ORDER BY trajectory_id, frame_number' | 172 queryStatement += ' ORDER BY trajectory_id, frame_number' |
| 171 cursor.execute(queryStatement) | |
| 172 logging.debug(queryStatement) | |
| 173 elif trajectoryType == 'object': | 173 elif trajectoryType == 'object': |
| 174 queryStatement = 'SELECT OF.object_id, P.frame_number, avg(P.x_coordinate), avg(P.y_coordinate) from '+tableName+' P, objects_features OF where P.trajectory_id = OF.trajectory_id' | 174 queryStatement = 'SELECT OF.object_id, P.frame_number, avg(P.x_coordinate), avg(P.y_coordinate) from '+tableName+' P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id' |
| 175 if objectNumbers is not None: | 175 if objectNumbers is not None: |
| 176 queryStatement += ' and OF.object_id '+objectCriteria | 176 queryStatement += ' and OF.object_id '+objectCriteria |
| 177 queryStatement += ' GROUP BY OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' | 177 queryStatement += ' GROUP BY OF.object_id, P.frame_number ORDER BY OF.object_id, P.frame_number' |
| 178 cursor.execute(queryStatement) | |
| 179 logging.debug(queryStatement) | |
| 180 elif trajectoryType in ['bbtop', 'bbbottom']: | 178 elif trajectoryType in ['bbtop', 'bbbottom']: |
| 181 if trajectoryType == 'bbtop': | 179 if trajectoryType == 'bbtop': |
| 182 corner = 'top_left' | 180 corner = 'top_left' |
| 183 elif trajectoryType == 'bbbottom': | 181 elif trajectoryType == 'bbbottom': |
| 184 corner = 'bottom_right' | 182 corner = 'bottom_right' |
| 185 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName | 183 queryStatement = 'SELECT object_id, frame_number, x_'+corner+', y_'+corner+' FROM '+tableName |
| 186 if objectNumbers is not None: | 184 if objectNumbers is not None: |
| 187 queryStatement += ' WHERE object_id '+objectCriteria | 185 queryStatement += ' WHERE object_id '+objectCriteria |
| 188 queryStatement += ' ORDER BY object_id, frame_number' | 186 queryStatement += ' ORDER BY object_id, frame_number' |
| 187 else: | |
| 188 print('no trajectory type was chosen') | |
| 189 if queryStatement is not None: | |
| 189 cursor.execute(queryStatement) | 190 cursor.execute(queryStatement) |
| 190 logging.debug(queryStatement) | 191 logging.debug(queryStatement) |
| 191 else: | |
| 192 print('no trajectory type was chosen') | |
| 193 except sqlite3.OperationalError as error: | 192 except sqlite3.OperationalError as error: |
| 194 printDBError(error) | 193 printDBError(error) |
| 195 return [] | 194 return [] |
| 196 | 195 |
| 197 objId = -1 | 196 objId = -1 |
| 218 | 217 |
| 219 def loadUserTypesFromTable(cursor, trajectoryType, objectNumbers): | 218 def loadUserTypesFromTable(cursor, trajectoryType, objectNumbers): |
| 220 objectCriteria = getObjectCriteria(objectNumbers) | 219 objectCriteria = getObjectCriteria(objectNumbers) |
| 221 queryStatement = 'SELECT object_id, road_user_type from objects' | 220 queryStatement = 'SELECT object_id, road_user_type from objects' |
| 222 if objectNumbers is not None: | 221 if objectNumbers is not None: |
| 223 queryStatement += ' where object_id '+objectCriteria | 222 queryStatement += ' WHERE object_id '+objectCriteria |
| 224 cursor.execute(queryStatement) | 223 cursor.execute(queryStatement) |
| 225 userTypes = {} | 224 userTypes = {} |
| 226 for row in cursor: | 225 for row in cursor: |
| 227 userTypes[row[0]] = row[1] | 226 userTypes[row[0]] = row[1] |
| 228 return userTypes | 227 return userTypes |
| 245 if trajectoryType == 'object': | 244 if trajectoryType == 'object': |
| 246 cursor = connection.cursor() | 245 cursor = connection.cursor() |
| 247 try: | 246 try: |
| 248 # attribute feature numbers to objects | 247 # attribute feature numbers to objects |
| 249 objectCriteria = getObjectCriteria(objectNumbers) | 248 objectCriteria = getObjectCriteria(objectNumbers) |
| 250 queryStatement = 'SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id' | 249 queryStatement = 'SELECT P.trajectory_id, OF.object_id from positions P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id' |
| 251 if objectNumbers is not None: | 250 if objectNumbers is not None: |
| 252 queryStatement += ' and OF.object_id '+objectCriteria | 251 queryStatement += ' and OF.object_id '+objectCriteria |
| 253 queryStatement += ' group by P.trajectory_id order by OF.object_id' # order is important to group all features per object | 252 queryStatement += ' group by P.trajectory_id order by OF.object_id' # order is important to group all features per object |
| 254 cursor.execute(queryStatement) | 253 cursor.execute(queryStatement) |
| 255 logging.debug(queryStatement) | 254 logging.debug(queryStatement) |
| 393 TODO choose the interactions to load''' | 392 TODO choose the interactions to load''' |
| 394 interactions = [] | 393 interactions = [] |
| 395 connection = sqlite3.connect(filename) | 394 connection = sqlite3.connect(filename) |
| 396 cursor = connection.cursor() | 395 cursor = connection.cursor() |
| 397 try: | 396 try: |
| 398 cursor.execute('select INT.id, INT.object_id1, INT.object_id2, INT.first_frame_number, INT.last_frame_number, IND.indicator_type, IND.frame_number, IND.value from interactions INT, indicators IND where INT.id = IND.interaction_id ORDER BY INT.id, IND.indicator_type, IND.frame_number') | 397 cursor.execute('select INT.id, INT.object_id1, INT.object_id2, INT.first_frame_number, INT.last_frame_number, IND.indicator_type, IND.frame_number, IND.value from interactions INT, indicators IND WHERE INT.id = IND.interaction_id ORDER BY INT.id, IND.indicator_type, IND.frame_number') |
| 399 interactionNum = -1 | 398 interactionNum = -1 |
| 400 indicatorTypeNum = -1 | 399 indicatorTypeNum = -1 |
| 401 tmpIndicators = {} | 400 tmpIndicators = {} |
| 402 for row in cursor: | 401 for row in cursor: |
| 403 if row[0] != interactionNum: | 402 if row[0] != interactionNum: |
| 416 printDBError(error) | 415 printDBError(error) |
| 417 return [] | 416 return [] |
| 418 connection.close() | 417 connection.close() |
| 419 return interactions | 418 return interactions |
| 420 # load first and last object instants | 419 # load first and last object instants |
| 421 # CREATE TEMP TABLE IF NOT EXISTS object_instants AS SELECT OF.object_id, min(frame_number) as first_instant, max(frame_number) as last_instant from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id group by OF.object_id order by OF.object_id | 420 # CREATE TEMP TABLE IF NOT EXISTS object_instants AS SELECT OF.object_id, min(frame_number) as first_instant, max(frame_number) as last_instant from positions P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id group by OF.object_id order by OF.object_id |
| 422 | 421 |
| 423 def createBoundingBoxTable(filename, invHomography = None): | 422 def createBoundingBoxTable(filename, invHomography = None): |
| 424 '''Create the table to store the object bounding boxes in image space | 423 '''Create the table to store the object bounding boxes in image space |
| 425 ''' | 424 ''' |
| 426 connection = sqlite3.connect(filename) | 425 connection = sqlite3.connect(filename) |
| 427 cursor = connection.cursor() | 426 cursor = connection.cursor() |
| 428 try: | 427 try: |
| 429 cursor.execute('CREATE TABLE IF NOT EXISTS bounding_boxes (object_id INTEGER, frame_number INTEGER, x_top_left REAL, y_top_left REAL, x_bottom_right REAL, y_bottom_right REAL, PRIMARY KEY(object_id, frame_number))') | 428 cursor.execute('CREATE TABLE IF NOT EXISTS bounding_boxes (object_id INTEGER, frame_number INTEGER, x_top_left REAL, y_top_left REAL, x_bottom_right REAL, y_bottom_right REAL, PRIMARY KEY(object_id, frame_number))') |
| 430 cursor.execute('INSERT INTO bounding_boxes SELECT object_id, frame_number, min(x), min(y), max(x), max(y) from ' | 429 cursor.execute('INSERT INTO bounding_boxes SELECT object_id, frame_number, min(x), min(y), max(x), max(y) from ' |
| 431 '(SELECT object_id, frame_number, (x*{}+y*{}+{})/w as x, (x*{}+y*{}+{})/w as y from ' | 430 '(SELECT object_id, frame_number, (x*{}+y*{}+{})/w as x, (x*{}+y*{}+{})/w as y from ' |
| 432 '(SELECT OF.object_id, P.frame_number, P.x_coordinate as x, P.y_coordinate as y, P.x_coordinate*{}+P.y_coordinate*{}+{} as w from positions P, objects_features OF where P.trajectory_id = OF.trajectory_id)) '.format(invHomography[0,0], invHomography[0,1], invHomography[0,2], invHomography[1,0], invHomography[1,1], invHomography[1,2], invHomography[2,0], invHomography[2,1], invHomography[2,2])+ | 431 '(SELECT OF.object_id, P.frame_number, P.x_coordinate as x, P.y_coordinate as y, P.x_coordinate*{}+P.y_coordinate*{}+{} as w from positions P, objects_features OF WHERE P.trajectory_id = OF.trajectory_id)) '.format(invHomography[0,0], invHomography[0,1], invHomography[0,2], invHomography[1,0], invHomography[1,1], invHomography[1,2], invHomography[2,0], invHomography[2,1], invHomography[2,2])+ |
| 433 'GROUP BY object_id, frame_number') | 432 'GROUP BY object_id, frame_number') |
| 434 except sqlite3.OperationalError as error: | 433 except sqlite3.OperationalError as error: |
| 435 printDBError(error) | 434 printDBError(error) |
| 436 connection.commit() | 435 connection.commit() |
| 437 connection.close() | 436 connection.close() |
| 645 | 644 |
| 646 def setRoutes(filename, objects): | 645 def setRoutes(filename, objects): |
| 647 connection = sqlite3.connect(filename) | 646 connection = sqlite3.connect(filename) |
| 648 cursor = connection.cursor() | 647 cursor = connection.cursor() |
| 649 for obj in objects: | 648 for obj in objects: |
| 650 cursor.execute('update objects set startRouteID = {} where object_id = {}'.format(obj.startRouteID, obj.getNum())) | 649 cursor.execute('update objects set startRouteID = {} WHERE object_id = {}'.format(obj.startRouteID, obj.getNum())) |
| 651 cursor.execute('update objects set endRouteID = {} where object_id = {}'.format(obj.endRouteID, obj.getNum())) | 650 cursor.execute('update objects set endRouteID = {} WHERE object_id = {}'.format(obj.endRouteID, obj.getNum())) |
| 652 connection.commit() | 651 connection.commit() |
| 653 connection.close() | 652 connection.close() |
| 654 | 653 |
| 655 def setRoadUserTypes(filename, objects): | 654 def setRoadUserTypes(filename, objects): |
| 656 '''Saves the user types of the objects in the sqlite database stored in filename | 655 '''Saves the user types of the objects in the sqlite database stored in filename |
| 657 The objects should exist in the objects table''' | 656 The objects should exist in the objects table''' |
| 658 connection = sqlite3.connect(filename) | 657 connection = sqlite3.connect(filename) |
| 659 cursor = connection.cursor() | 658 cursor = connection.cursor() |
| 660 for obj in objects: | 659 for obj in objects: |
| 661 cursor.execute('update objects set road_user_type = {} where object_id = {}'.format(obj.getUserType(), obj.getNum())) | 660 cursor.execute('update objects set road_user_type = {} WHERE object_id = {}'.format(obj.getUserType(), obj.getNum())) |
| 662 connection.commit() | 661 connection.commit() |
| 663 connection.close() | 662 connection.close() |
| 664 | 663 |
| 665 ######################### | 664 ######################### |
| 666 # txt files | 665 # txt files |
| 731 else: return self.fp.readline() | 730 else: return self.fp.readline() |
| 732 | 731 |
| 733 def generatePDLaneColumn(data): | 732 def generatePDLaneColumn(data): |
| 734 data['LANE'] = data['LANE\LINK\NO'].astype(str)+'_'+data['LANE\INDEX'].astype(str) | 733 data['LANE'] = data['LANE\LINK\NO'].astype(str)+'_'+data['LANE\INDEX'].astype(str) |
| 735 | 734 |
| 736 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, nObjects = -1, warmUpLastInstant = None, usePandas = False, nDecimals = 2, lowMemory = True): | 735 def convertTrajectoriesVissimToSqlite(filename): |
| 736 '''Relies on a system call to sqlite3 | |
| 737 sqlite3 [file.sqlite] < import_fzp.sql''' | |
| 738 sqlScriptFilename = "import_fzp.sql" | |
| 739 # create sql file | |
| 740 out = openCheck(sqlScriptFilename, "w") | |
| 741 out.write(".separator \";\"\n"+ | |
| 742 "CREATE TABLE IF NOT EXISTS curvilinear_positions (t REAL, trajectory_id INTEGER, link_id INTEGER, lane_id INTEGER, s_coordinate REAL, y_coordinate REAL, speed REAL, PRIMARY KEY (t, trajectory_id));\n"+ | |
| 743 ".import "+filename+" curvilinear_positions\n"+ | |
| 744 "DELETE FROM curvilinear_positions WHERE trajectory_id IS NULL OR trajectory_id = \"NO\";\n") | |
| 745 out.close() | |
| 746 # system call | |
| 747 from subprocess import check_call | |
| 748 out = openCheck("err.log", "w") | |
| 749 check_call("sqlite3 "+utils.removeExtension(filename)+".sqlite < "+sqlScriptFilename, stderr = out, shell = True) | |
| 750 out.close() | |
| 751 shutil.os.remove(sqlScriptFilename) | |
| 752 | |
| 753 def loadObjectNumbersInLinkFromVissimFile(filename, linkIds): | |
| 754 '''Finds the ids of the objects that go through any of the link in the list linkIds''' | |
| 755 connection = sqlite3.connect(filename) | |
| 756 cursor = connection.cursor() | |
| 757 queryStatement = 'SELECT DISTINCT trajectory_id FROM curvilinear_positions where link_id IN ('+','.join([str(id) for id in linkIds])+')' | |
| 758 try: | |
| 759 cursor.execute(queryStatement) | |
| 760 return [row[0] for row in cursor] | |
| 761 except sqlite3.OperationalError as error: | |
| 762 printDBError(error) | |
| 763 | |
| 764 | |
| 765 def loadTrajectoriesFromVissimFile(filename, simulationStepsPerTimeUnit, objectNumbers = None, warmUpLastInstant = None, usePandas = False, nDecimals = 2, lowMemory = True): | |
| 737 '''Reads data from VISSIM .fzp trajectory file | 766 '''Reads data from VISSIM .fzp trajectory file |
| 738 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM | 767 simulationStepsPerTimeUnit is the number of simulation steps per unit of time used by VISSIM (second) |
| 739 for example, there seems to be 5 simulation steps per simulated second in VISSIM, | 768 for example, there seems to be 10 simulation steps per simulated second in VISSIM, |
| 740 so simulationStepsPerTimeUnit should be 5, | 769 so simulationStepsPerTimeUnit should be 10, |
| 741 so that all times correspond to the number of the simulation step (and can be stored as integers) | 770 so that all times correspond to the number of the simulation step (and can be stored as integers) |
| 742 | 771 |
| 743 Objects positions will be considered only after warmUpLastInstant | 772 Objects positions will be considered only after warmUpLastInstant |
| 744 (if the object has no such position, it won't be loaded) | 773 (if the object has no such position, it won't be loaded) |
| 745 | 774 |
| 746 Assumed to be sorted over time''' | 775 Assumed to be sorted over time |
| 776 Warning: if reading from SQLite a limited number of objects, objectNumbers will be the maximum object id''' | |
| 747 objects = {} # dictionary of objects index by their id | 777 objects = {} # dictionary of objects index by their id |
| 748 | 778 |
| 749 if usePandas: | 779 if usePandas: |
| 750 from pandas import read_csv | |
| 751 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, low_memory = lowMemory) | 780 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, low_memory = lowMemory) |
| 752 generatePDLaneColumn(data) | 781 generatePDLaneColumn(data) |
| 753 data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit | 782 data['TIME'] = data['$VEHICLE:SIMSEC']*simulationStepsPerTimeUnit |
| 754 if warmUpLastInstant is not None: | 783 if warmUpLastInstant is not None: |
| 755 data = data[data['TIME']>=warmUpLastInstant] | 784 data = data[data['TIME']>=warmUpLastInstant] |
| 759 objNum = int(row['NO']) | 788 objNum = int(row['NO']) |
| 760 tmp = data[data['NO'] == objNum] | 789 tmp = data[data['NO'] == objNum] |
| 761 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(row['first'], row['last'])) | 790 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(row['first'], row['last'])) |
| 762 # positions should be rounded to nDecimals decimals only | 791 # positions should be rounded to nDecimals decimals only |
| 763 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory(S = npround(tmp['POS'].tolist(), nDecimals), Y = npround(tmp['POSLAT'].tolist(), nDecimals), lanes = tmp['LANE'].tolist()) | 792 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory(S = npround(tmp['POS'].tolist(), nDecimals), Y = npround(tmp['POSLAT'].tolist(), nDecimals), lanes = tmp['LANE'].tolist()) |
| 764 if nObjects > 0 and len(objects) >= nObjects: | 793 if objectNumbers is not None and objectNumbers > 0 and len(objects) >= objectNumbers: |
| 765 break | 794 objects.values() |
| 766 return objects.values() | |
| 767 else: | 795 else: |
| 768 inputfile = openCheck(filename, quitting = True) | 796 if filename.endswith(".fzp"): |
| 769 # data = pd.read_csv(filename, skiprows=15, delimiter=';') | 797 inputfile = openCheck(filename, quitting = True) |
| 770 # skip header: 15 lines + 1 | |
| 771 line = readline(inputfile, '*$') | |
| 772 while len(line) > 0:#for line in inputfile: | |
| 773 data = line.strip().split(';') | |
| 774 objNum = int(data[1]) | |
| 775 instant = int(float(data[0])*simulationStepsPerTimeUnit) | |
| 776 s = float(data[4]) | |
| 777 y = float(data[5]) | |
| 778 lane = data[2]+'_'+data[3] | |
| 779 if objNum not in objects: | |
| 780 if warmUpLastInstant is None or instant >= warmUpLastInstant: | |
| 781 if nObjects < 0 or len(objects) < nObjects: | |
| 782 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant)) | |
| 783 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory() | |
| 784 if (warmUpLastInstant is None or instant >= warmUpLastInstant) and objNum in objects: | |
| 785 objects[objNum].timeInterval.last = instant | |
| 786 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane) | |
| 787 line = readline(inputfile, '*$') | 798 line = readline(inputfile, '*$') |
| 788 | 799 while len(line) > 0:#for line in inputfile: |
| 800 data = line.strip().split(';') | |
| 801 objNum = int(data[1]) | |
| 802 instant = float(data[0])*simulationStepsPerTimeUnit | |
| 803 s = float(data[4]) | |
| 804 y = float(data[5]) | |
| 805 lane = data[2]+'_'+data[3] | |
| 806 if objNum not in objects: | |
| 807 if warmUpLastInstant is None or instant >= warmUpLastInstant: | |
| 808 if objectNumbers is None or len(objects) < objectNumbers: | |
| 809 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant)) | |
| 810 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory() | |
| 811 if (warmUpLastInstant is None or instant >= warmUpLastInstant) and objNum in objects: | |
| 812 objects[objNum].timeInterval.last = instant | |
| 813 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane) | |
| 814 line = readline(inputfile, '*$') | |
| 815 elif filename.endswith(".sqlite"): | |
| 816 connection = sqlite3.connect(filename) | |
| 817 cursor = connection.cursor() | |
| 818 queryStatement = 'SELECT t, trajectory_id, link_id, lane_id, s_coordinate, y_coordinate FROM curvilinear_positions' | |
| 819 if objectNumbers is not None: | |
| 820 queryStatement += ' WHERE trajectory_id '+getObjectCriteria(objectNumbers) | |
| 821 queryStatement += ' ORDER BY trajectory_id, t' | |
| 822 try: | |
| 823 cursor.execute(queryStatement) | |
| 824 for row in cursor: | |
| 825 objNum = row[1] | |
| 826 instant = row[0]*simulationStepsPerTimeUnit | |
| 827 s = row[4] | |
| 828 y = row[5] | |
| 829 lane = '{}_{}'.format(row[2], row[3]) | |
| 830 if objNum not in objects: | |
| 831 if warmUpLastInstant is None or instant >= warmUpLastInstant: | |
| 832 if objectNumbers is None or len(objects) < objectNumbers: | |
| 833 objects[objNum] = moving.MovingObject(num = objNum, timeInterval = moving.TimeInterval(instant, instant)) | |
| 834 objects[objNum].curvilinearPositions = moving.CurvilinearTrajectory() | |
| 835 if (warmUpLastInstant is None or instant >= warmUpLastInstant) and objNum in objects: | |
| 836 objects[objNum].timeInterval.last = instant | |
| 837 objects[objNum].curvilinearPositions.addPositionSYL(s, y, lane) | |
| 838 except sqlite3.OperationalError as error: | |
| 839 printDBError(error) | |
| 840 else: | |
| 841 print("File type of "+filename+" not supported (only .sqlite and .fzp files)") | |
| 789 return objects.values() | 842 return objects.values() |
| 790 | 843 |
| 791 def selectPDLanes(data, lanes = None): | 844 def selectPDLanes(data, lanes = None): |
| 792 '''Selects the subset of data for the right lanes | 845 '''Selects the subset of data for the right lanes |
| 793 | 846 |
| 808 | 861 |
| 809 Vehicles are considered finally stationary | 862 Vehicles are considered finally stationary |
| 810 if more than proportionStationaryTime of their total time | 863 if more than proportionStationaryTime of their total time |
| 811 If lanes is not None, only the data for the selected lanes will be provided | 864 If lanes is not None, only the data for the selected lanes will be provided |
| 812 (format as string x_y where x is link index and y is lane index)''' | 865 (format as string x_y where x is link index and y is lane index)''' |
| 813 from pandas import read_csv | 866 if filename.endswith(".fzp"): |
| 814 columns = ['NO', '$VEHICLE:SIMSEC', 'POS'] | 867 columns = ['NO', '$VEHICLE:SIMSEC', 'POS'] |
| 815 if lanes is not None: | 868 if lanes is not None: |
| 816 columns += ['LANE\LINK\NO', 'LANE\INDEX'] | 869 columns += ['LANE\LINK\NO', 'LANE\INDEX'] |
| 817 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = columns, low_memory = lowMemory) | 870 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = columns, low_memory = lowMemory) |
| 818 data = selectPDLanes(data, lanes) | 871 data = selectPDLanes(data, lanes) |
| 819 data.sort(['$VEHICLE:SIMSEC'], inplace = True) | 872 data.sort(['$VEHICLE:SIMSEC'], inplace = True) |
| 820 | 873 |
| 821 nStationary = 0 | 874 nStationary = 0 |
| 822 nVehicles = 0 | 875 nVehicles = 0 |
| 823 for name, group in data.groupby(['NO'], sort = False): | 876 for name, group in data.groupby(['NO'], sort = False): |
| 824 nVehicles += 1 | 877 nVehicles += 1 |
| 825 positions = array(group['POS']) | 878 positions = array(group['POS']) |
| 826 diff = positions[1:]-positions[:-1] | 879 diff = positions[1:]-positions[:-1] |
| 827 if npsum(diff == 0.) >= proportionStationaryTime*len(positions): | 880 if npsum(diff == 0.) >= proportionStationaryTime*(len(positions)-1): |
| 828 nStationary += 1 | 881 nStationary += 1 |
| 882 elif filename.endswith(".sqlite"): | |
| 883 # select trajectory_id, t, s_coordinate, speed from curvilinear_positions where trajectory_id between 1860 and 1870 and speed < 0.1 | |
| 884 # pb of the meaning of proportionStationaryTime in arterial network? Why proportion of existence time? | |
| 885 pass | |
| 886 else: | |
| 887 print("File type of "+filename+" not supported (only .sqlite and .fzp files)") | |
| 829 | 888 |
| 830 return nStationary, nVehicles | 889 return nStationary, nVehicles |
| 831 | 890 |
| 832 def countCollisionsVissim(filename, lanes = None, collisionTimeDifference = 0.2, lowMemory = True): | 891 def countCollisionsVissim(filename, lanes = None, collisionTimeDifference = 0.2, lowMemory = True): |
| 833 '''Counts the number of collisions per lane in a VISSIM trajectory file | 892 '''Counts the number of collisions per lane in a VISSIM trajectory file |
| 835 To distinguish between cars passing and collision, | 894 To distinguish between cars passing and collision, |
| 836 one checks when the sign of the position difference inverts | 895 one checks when the sign of the position difference inverts |
| 837 (if the time are closer than collisionTimeDifference) | 896 (if the time are closer than collisionTimeDifference) |
| 838 If lanes is not None, only the data for the selected lanes will be provided | 897 If lanes is not None, only the data for the selected lanes will be provided |
| 839 (format as string x_y where x is link index and y is lane index)''' | 898 (format as string x_y where x is link index and y is lane index)''' |
| 840 from pandas import read_csv, merge | |
| 841 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC', 'NO', 'POS'], low_memory = lowMemory) | 899 data = read_csv(filename, delimiter=';', comment='*', header=0, skiprows = 1, usecols = ['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC', 'NO', 'POS'], low_memory = lowMemory) |
| 842 data = selectPDLanes(data, lanes) | 900 data = selectPDLanes(data, lanes) |
| 843 data = data.convert_objects(convert_numeric=True) | 901 data = data.convert_objects(convert_numeric=True) |
| 844 | 902 |
| 845 merged = merge(data, data, how='inner', left_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], right_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], sort = False) | 903 merged = merge(data, data, how='inner', left_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], right_on=['LANE\LINK\NO', 'LANE\INDEX', '$VEHICLE:SIMSEC'], sort = False) |
| 852 if len(diff) >= 2 and npmin(diff) < 0 and npmax(diff) > 0: | 910 if len(diff) >= 2 and npmin(diff) < 0 and npmax(diff) > 0: |
| 853 xidx = diff[diff < 0].argmax() | 911 xidx = diff[diff < 0].argmax() |
| 854 yidx = diff[diff > 0].argmin() | 912 yidx = diff[diff > 0].argmin() |
| 855 if abs(group.loc[xidx, '$VEHICLE:SIMSEC'] - group.loc[yidx, '$VEHICLE:SIMSEC']) <= collisionTimeDifference: | 913 if abs(group.loc[xidx, '$VEHICLE:SIMSEC'] - group.loc[yidx, '$VEHICLE:SIMSEC']) <= collisionTimeDifference: |
| 856 nCollisions += 1 | 914 nCollisions += 1 |
| 915 | |
| 916 # select TD1.link_id, TD1.lane_id from temp.diff_positions as TD1, temp.diff_positions as TD2 where TD1.link_id = TD2.link_id and TD1.lane_id = TD2.lane_id and TD1.id1 = TD2.id1 and TD1.id2 = TD2.id2 and TD1.t = TD2.t+0.1 and TD1.diff*TD2.diff < 0; # besoin de faire un group by?? | |
| 917 # create temp table diff_positions as select CP1.t as t, CP1.link_id as link_id, CP1.lane_id as lane_id, CP1.trajectory_id as id1, CP2.trajectory_id as id2, CP1.s_coordinate - CP2.s_coordinate as diff from curvilinear_positions CP1, curvilinear_positions CP2 where CP1.link_id = CP2.link_id and CP1.lane_id = CP2.lane_id and CP1.t = CP2.t and CP1.trajectory_id > CP2.trajectory_id; | |
| 918 # SQL select link_id, lane_id, id1, id2, min(diff), max(diff) from (select CP1.t as t, CP1.link_id as link_id, CP1.lane_id as lane_id, CP1.trajectory_id as id1, CP2.trajectory_id as id2, CP1.s_coordinate - CP2.s_coordinate as diff from curvilinear_positions CP1, curvilinear_positions CP2 where CP1.link_id = CP2.link_id and CP1.lane_id = CP2.lane_id and CP1.t = CP2.t and CP1.trajectory_id > CP2.trajectory_id) group by link_id, lane_id, id1, id2 having min(diff)*max(diff) < 0 | |
| 857 return nCollisions | 919 return nCollisions |
| 858 | 920 |
| 859 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): | 921 def loadTrajectoriesFromNgsimFile(filename, nObjects = -1, sequenceNum = -1): |
| 860 '''Reads data from the trajectory data provided by NGSIM project | 922 '''Reads data from the trajectory data provided by NGSIM project |
| 861 and returns the list of Feature objects''' | 923 and returns the list of Feature objects''' |
