Mercurial > hg > nsaunier > traffic-intelligence
comparison trafficintelligence/moving.py @ 1078:8cc3feb1c1c5
merged
| author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
|---|---|
| date | Fri, 20 Jul 2018 16:26:57 -0400 |
| parents | 3939ae415be0 |
| children | 845d694af7b8 |
comparison
equal
deleted
inserted
replaced
| 1074:b123fa0e5440 | 1078:8cc3feb1c1c5 |
|---|---|
| 78 return None | 78 return None |
| 79 | 79 |
| 80 @classmethod | 80 @classmethod |
| 81 def union(cls, interval1, interval2): | 81 def union(cls, interval1, interval2): |
| 82 '''Smallest interval comprising self and interval2''' | 82 '''Smallest interval comprising self and interval2''' |
| 83 return cls(min(interval1.first, interval2.first), max(interval2.last, interval2.last)) | 83 return cls(min(interval1.first, interval2.first), max(interval1.last, interval2.last)) |
| 84 | 84 |
| 85 @classmethod | 85 @classmethod |
| 86 def intersection(cls, interval1, interval2): | 86 def intersection(cls, interval1, interval2): |
| 87 '''Largest interval comprised in both self and interval2''' | 87 '''Largest interval comprised in both self and interval2''' |
| 88 return cls(max(interval1.first, interval2.first), min(interval1.last, interval2.last)) | 88 return cls(max(interval1.first, interval2.first), min(interval1.last, interval2.last)) |
| 1157 self.geometry = geometry | 1157 self.geometry = geometry |
| 1158 self.userType = userType | 1158 self.userType = userType |
| 1159 self.setNObjects(nObjects) # a feature has None for nObjects | 1159 self.setNObjects(nObjects) # a feature has None for nObjects |
| 1160 self.features = None | 1160 self.features = None |
| 1161 # compute bounding polygon from trajectory | 1161 # compute bounding polygon from trajectory |
| 1162 | |
| 1163 @staticmethod | |
| 1164 def cropedTimeInterval(obj, value, after = True): | |
| 1165 newTimeInterval = TimeInterval(obj.getFirstInstant(), min(value, obj.getLastInstant())) if after else TimeInterval(max(obj.getFirstInstant(), value), obj.getLastInstant()) | |
| 1166 if obj.positions is not None : | |
| 1167 newPositions = obj.positions[slice(newTimeInterval.first, newTimeInterval.last+1)] | |
| 1168 else: | |
| 1169 newPositions = None | |
| 1170 if obj.velocities is not None : | |
| 1171 newVelocities = obj.velocities[slice(newTimeInterval.first, newTimeInterval.last+1)] | |
| 1172 else: | |
| 1173 newVelocities = None | |
| 1174 if obj.features is not None : | |
| 1175 newFeatures = [f.cropedTimeInterval(value, after) for f in obj.features] | |
| 1176 else: | |
| 1177 newFeatures = None | |
| 1178 res = MovingObject(obj.getNum(), newTimeInterval, newPositions, newVelocities, obj.geometry, obj.userType, obj.nObjects) | |
| 1179 res.features = newFeatures | |
| 1180 res.featureNumbers = obj.featureNumbers | |
| 1181 if hasattr(obj, 'projectedPositions'): | |
| 1182 res.projectedPositions = obj.projectedPositions[slice(newTimeInterval.first, newTimeInterval.last+1)] | |
| 1183 return res | |
| 1184 | |
| 1162 | 1185 |
| 1163 @staticmethod | 1186 @staticmethod |
| 1164 def aggregateTrajectories(features, interval = None, aggFunc = mean): | 1187 def aggregateTrajectories(features, interval = None, aggFunc = mean): |
| 1165 'Computes the aggregate trajectory from list of MovingObject features' | 1188 'Computes the aggregate trajectory from list of MovingObject features' |
| 1166 positions = Trajectory() | 1189 positions = Trajectory() |
| 1199 else: | 1222 else: |
| 1200 newNum = num | 1223 newNum = num |
| 1201 commonTimeInterval = obj1.commonTimeInterval(obj2) | 1224 commonTimeInterval = obj1.commonTimeInterval(obj2) |
| 1202 if commonTimeInterval.empty(): | 1225 if commonTimeInterval.empty(): |
| 1203 #print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) | 1226 #print('The two objects\' time intervals do not overlap: obj1 {} and obj2 {}'.format(obj1.getTimeInterval(), obj2.getTimeInterval())) |
| 1204 emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()), max(obj1.getFirstInstant(),obj2.getFirstInstant())) | 1227 emptyInterval = TimeInterval(min(obj1.getLastInstant(),obj2.getLastInstant()), max(obj1.getFirstInstant(),obj2.getFirstInstant())+1) |
| 1205 if obj1.existsAtInstant(emptyInterval.last): | 1228 if obj1.existsAtInstant(emptyInterval.last): |
| 1206 firstObject = obj2 | 1229 firstObject = obj2 |
| 1207 secondObject = obj1 | 1230 secondObject = obj1 |
| 1208 else: | 1231 else: |
| 1209 firstObject = obj1 | 1232 firstObject = obj1 |
| 1212 positions = copy.deepcopy(firstObject.getPositions()) | 1235 positions = copy.deepcopy(firstObject.getPositions()) |
| 1213 velocities = copy.deepcopy(firstObject.getPositions()) | 1236 velocities = copy.deepcopy(firstObject.getPositions()) |
| 1214 featurePositions = Trajectory() | 1237 featurePositions = Trajectory() |
| 1215 featureVelocities = Trajectory() | 1238 featureVelocities = Trajectory() |
| 1216 p = firstObject.getPositionAtInstant(emptyInterval.first)+v | 1239 p = firstObject.getPositionAtInstant(emptyInterval.first)+v |
| 1217 for t in range(emptyInterval.first+1, emptyInterval.last): | 1240 for t in range(emptyInterval.first+1, emptyInterval.last+1): |
| 1218 positions.addPosition(p) | 1241 positions.addPosition(p) |
| 1219 velocities.addPosition(v) | 1242 velocities.addPosition(v) |
| 1220 featurePositions.addPosition(p) | 1243 featurePositions.addPosition(p) |
| 1221 featureVelocities.addPosition(v) | 1244 featureVelocities.addPosition(v) |
| 1222 p=p+v | 1245 p=p+v |
| 1229 newObject.featureNumbers = obj1.featureNumbers+obj2.featureNumbers+[newFeatureNum] | 1252 newObject.featureNumbers = obj1.featureNumbers+obj2.featureNumbers+[newFeatureNum] |
| 1230 else: | 1253 else: |
| 1231 print('Issue, new created feature has no num id') | 1254 print('Issue, new created feature has no num id') |
| 1232 if obj1.hasFeatures() and obj2.hasFeatures(): | 1255 if obj1.hasFeatures() and obj2.hasFeatures(): |
| 1233 newObject.features = obj1.getFeatures()+obj2.getFeatures()+[MovingObject(newFeatureNum, TimeInterval(emptyInterval.first+1, emptyInterval.last-1), featurePositions, featureVelocities)] | 1256 newObject.features = obj1.getFeatures()+obj2.getFeatures()+[MovingObject(newFeatureNum, TimeInterval(emptyInterval.first+1, emptyInterval.last-1), featurePositions, featureVelocities)] |
| 1257 newObject.updatePositions() | |
| 1234 else: # time intervals overlap | 1258 else: # time intervals overlap |
| 1235 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) | 1259 newTimeInterval = TimeInterval.union(obj1.getTimeInterval(), obj2.getTimeInterval()) |
| 1236 newObject = MovingObject(newNum, newTimeInterval, nObjects = 1) # hypothesis is that it's the same object being reunited | 1260 newObject = MovingObject(newNum, newTimeInterval, nObjects = 1) # hypothesis is that it's the same object being reunited |
| 1237 if hasattr(obj1, 'featureNumbers') and hasattr(obj2, 'featureNumbers'): | 1261 if hasattr(obj1, 'featureNumbers') and hasattr(obj2, 'featureNumbers'): |
| 1238 newObject.featureNumbers = obj1.featureNumbers+obj2.featureNumbers | 1262 newObject.featureNumbers = obj1.featureNumbers+obj2.featureNumbers |
| 1346 def setNObjects(self, nObjects): | 1370 def setNObjects(self, nObjects): |
| 1347 if nObjects is None or nObjects >= 1: | 1371 if nObjects is None or nObjects >= 1: |
| 1348 self.nObjects = nObjects | 1372 self.nObjects = nObjects |
| 1349 else: | 1373 else: |
| 1350 print('Number of objects represented by object {} must be greater or equal to 1 ({})'.format(self.getNum(), nObjects)) | 1374 print('Number of objects represented by object {} must be greater or equal to 1 ({})'.format(self.getNum(), nObjects)) |
| 1375 self.nObjects = None | |
| 1351 | 1376 |
| 1352 def setFeatures(self, features, featuresOrdered = False): | 1377 def setFeatures(self, features, featuresOrdered = False): |
| 1353 '''Sets the features in the features field based on featureNumbers | 1378 '''Sets the features in the features field based on featureNumbers |
| 1354 if not all features are loaded from 0, one needs to renumber in a dict''' | 1379 if not all features are loaded from 0, one needs to renumber in a dict''' |
| 1355 if featuresOrdered: | 1380 if featuresOrdered: |
