diff trafficintelligence/iframework.py @ 1293:4dd446835e7d

update closer to Studio iframework
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Wed, 02 Oct 2024 12:19:12 -0400
parents c4c50678c856
children
line wrap: on
line diff
--- a/trafficintelligence/iframework.py	Wed Sep 25 08:42:45 2024 -0400
+++ b/trafficintelligence/iframework.py	Wed Oct 02 12:19:12 2024 -0400
@@ -11,8 +11,11 @@
 Base = declarative_base()
 
 GenderEnum = Enum('GenderEnum', 'male female unknown')
-ModeEnum = Enum('ModeEnum', 'cardriver carpassenger transit taxi motorcycle cycling walking other') # the idea is that the mode could be sufficient to record all events (line and zone crossings), whether the actual, more precise vehicle, is 
-VehicleEnum = Enum('VehicleEnum', 'car suv van truck motorcycle bus bike scooter skate rollers')
+ModeEnum = Enum('ModeEnum', 'car_driver car_passenger transit taxi motorcycle cycling walking other') # the idea is that the mode could be sufficient to record all events (line and zone crossings), whether the actual, more precise vehicle, is 
+VehicleEnum = Enum('VehicleEnum', 'car bike van truck bus taxi motorcycle scooter skate rollers mobility_scooter')
+ActivityEnum = Enum('ActivityEnum', 'unknown strolling jogging shopping sitting talking resting eating playing doing_exercise smoking using_cellphone observing reading_writing performing selling playing_with_pet taking_pet_for_walk')
+DisabilityEnum = Enum('DisabilityEnum', 'none wheelchair walker cane white_cane')
+AgeEnum = Enum('AgeEnum', 'unknown infant toddler child teen young_adult adult senior') # 0-1, 1-4, 4-12, 12-18...
 
 # should there be a survey object for site info, observer, etc?
 
@@ -74,12 +77,14 @@
     __tablename__ = 'persons'
     idx = Column(Integer, primary_key=True)
     #groupIdx = Column(Integer, ForeignKey('groups.idx'))
-    age = Column(String)
+    age = Column(SQLEnum(AgeEnum), nullable=True) #Column(String)
     gender = Column(SQLEnum(GenderEnum), nullable=False)
-    disability = Column(String) # could be enum
+    disability = Column(String) #Column(SQLEnum(DisabilityEnum) #Boolean in Studio
     stroller = Column(Boolean) # the booleans could be strings or enum to have more information
     bag = Column(Boolean) 
     animal = Column(Boolean)
+    # databaseFilename = Column(String) # refers to trajectory database, relative path
+    # objectIdx = Column(Integer) # refers to object id in trajectory database
 
     #group = relationship('Group', backref = backref('persons'))
 
@@ -100,8 +105,8 @@
             except ValueError:
                 pass
         else:
-             return self.age   
-        
+            return self.age
+
     def getGroups(self):
         if len(self.groupBelongings) > 0:
             return [gb.group for gb in self.groupBelongings]
@@ -112,7 +117,9 @@
     __tablename__ = 'vehicles'
     idx = Column(Integer, primary_key=True)
     category = Column(SQLEnum(VehicleEnum), nullable=False)
-    trailer = Column(Boolean) 
+    trailer = Column(Boolean)
+    # databaseFilename = Column(String) # refers to trajectory database, relative path
+    # objectIdx = Column(Integer) # refers to object id in trajectory database
 
     def __init__(self, category, trailer = False):
         self.category = category
@@ -131,7 +138,7 @@
 pointLineAssociation = Table('pointlines', Base.metadata,
                              Column('pointIdx', Integer, ForeignKey('points.idx')),
                              Column('lineIdx', Integer, ForeignKey('lines.idx')))
-    
+
 class Line(Base):
     __tablename__ = 'lines'
     idx = Column(Integer, primary_key=True)
@@ -159,9 +166,9 @@
         'xs and ys are the list of x and y coordinates'
         self.name = name
         if xs is not None and ys is not None:
-            for x,y in zip(xs, ys):
-                self.addPoint(x,y)
-    
+            for x, y in zip(xs, ys):
+                self.addPoint(x, y)
+
     def addPoint(self, x, y):
         self.points.append(Point(x, y))
 
@@ -190,7 +197,8 @@
     pointIdx = Column(Integer, ForeignKey('points.idx'))
     instant = Column(DateTime)
     speed = Column(Float)
-    wrongDirection = Column(Boolean)
+    # wrongDirection = Column(Boolean)
+    rightToLeft = Column(Boolean)
 
     line = relationship('Line')
     group = relationship('Group')
@@ -214,29 +222,31 @@
     pointIdx = Column(Integer, ForeignKey('points.idx'))
     instant = Column(DateTime)
     entering = Column(Boolean)
+    speed = Column(Float)
 
     zone = relationship('Zone')
     group = relationship('Group')
     point = relationship('Point')
 
-    def __init__(self, zone, instant, entering, p = None, group = None, person = None, modeName = None, vehicle = None):
+    def __init__(self, zone, instant, entering, speed = None, p = None, group = None, person = None, modeName = None, vehicle = None):
         self.zone = zone
         self.instant = instant
         self.entering = entering
+        self.speed = speed
         self.point = p
         self.initPersonGroupCrossing(group, person, modeName, vehicle)
 
 class Activity(AbstractCrossing,Base):
     __tablename__ = 'activities'
     idx = Column(Integer, primary_key=True)
-    activity = Column(String) # could be enum
+    activity = Column(SQLEnum(ActivityEnum), nullable=False) #Column(String)
     groupIdx = Column(Integer, ForeignKey('groups.idx'))
     # can an activity be done in a vehicle? Is it relevant? Can it be unambiguously identified?
     startTime = Column(DateTime)
     endTime = Column(DateTime)
     zoneIdx = Column(Integer, ForeignKey('zones.idx'))
     pointIdx = Column(Integer, ForeignKey('points.idx'))
-   
+
     group = relationship('Group')
     zone = relationship('Zone')
     point = relationship('Point')
@@ -256,7 +266,7 @@
         return None
     else:
         engine = create_engine('sqlite:///'+filename)
-        if createOnlyGroupTables: 
+        if createOnlyGroupTables:
             Base.metadata.create_all(engine, tables = [Base.metadata.tables['modes'], Base.metadata.tables['groups'], Base.metadata.tables['groupbelongings'], Base.metadata.tables['persons'], Base.metadata.tables['vehicles'], Base.metadata.tables['points']])
         else:
             Base.metadata.create_all(engine)
@@ -278,28 +288,27 @@
     if session is None:
         session = connectDatabase('test.sqlite')
     # count example
-    p = Person(6, 'female', bag = True)
+    p = Person('infant', 'female', bag = True)
     veh1 = Vehicle('car')
     modes = [Mode('cardriver', p, veh1), Mode('walking', p, startTime = datetime(2020,7,7,11,20))]
     
     line = Line('line1', 0.,0.,0.,10.)
     zone = Zone('zone1', [0., 0., 1., 1.], [0., 1., 1., 0.])
     destination = Zone('destination1', [10., 10., 11., 11.], [10., 11., 11., 10.])
-    counts = [LineCrossing(line, datetime(2020,7,2,23,20+i), person = Person(20+i, 'female', disability = True), modeName = 'walking') for i in range(5)]
-    group1 = Group([Person(13+i,'female', False, False, True, False) for i in range(3)])
+    counts = [LineCrossing(line, datetime(2020,7,2,23,20+i), person = Person(AgeEnum(1+i), 'female', disability = True), modeName = 'walking') for i in range(5)]
+    group1 = Group([Person(AgeEnum(3+i),'female', False, False, True, False) for i in range(3)])
     groupMode1 = Mode.initGroup('walking', group1)
-    activities = [Activity('walking', datetime(2020,7,2,23,0), datetime(2020,7,2,23,10), zone, person = Person(40, 'male', True, False, True, False)),
-                  Activity('eating', datetime(2020,7,2,23,10), datetime(2020,7,2,23,12), zone, person = Person(40, 'male', True, False, True, False)),
+    activities = [Activity('strolling', datetime(2020,7,2,23,0), datetime(2020,7,2,23,10), zone, person = Person('adult', 'male', True, False, True, False)),
+                  Activity('eating', datetime(2020,7,2,23,10), datetime(2020,7,2,23,12), zone, person = Person('senior', 'male', True, False, True, False)),
                   Activity('playing', datetime(2020,7,2,22,0), datetime(2020,7,2,23,0), zone, group = group1)]
     counts.append(LineCrossing(line, datetime(2020,7,2,23,5), group = group1))
-    counts.append(LineCrossing(line, datetime(2020,7,2,23,7), person = Person(23, 'unknown'), modeName = 'cardriver', vehicle = Vehicle('car')))
+    counts.append(LineCrossing(line, datetime(2020,7,2,23,7), person = Person('young_adult', 'unknown'), modeName = 'cardriver', vehicle = Vehicle('car')))
     counts.append(LineCrossing(line, datetime(2020,7,2,23,9), person = Person('teen', 'unknown'), modeName = 'other', vehicle = Vehicle('scooter')))
-    counts.append(LineCrossing(line, datetime(2020,7,2,23,11), person = Person(12, 'female'), modeName = 'cycling'))
+    counts.append(LineCrossing(line, datetime(2020,7,2,23,11), person = Person('teen', 'female'), modeName = 'cycling'))
     counts.append(LineCrossing(line, datetime(2020,7,2,23,13), person = Person(), modeName = 'cardriver')) # example of counting cars without knowing the driver and passenger's attributes
-    counts.append(LineCrossing(line, datetime(2020,7,2,23,15), group = Group([Person(34+i) for i in range(3)]), modeName = 'carpassenger'))
+    counts.append(LineCrossing(line, datetime(2020,7,2,23,15), group = Group([Person(AgeEnum(6+i)) for i in range(3)]), modeName = 'car_passenger'))
 
-    
-    counts.append(ZoneCrossing(zone, datetime(2020,7,7,9,5), True, person = Person(33, 'male', False, False, True, False)))
+    counts.append(ZoneCrossing(zone, datetime(2020,7,7,9,5), True, person = Person('adult', 'male', False, False, True, False)))
     
     session.add_all([line, p, zone, group1, destination]+modes+groupMode1+counts+activities)