comparison python/moving.py @ 781:7c38250ddfc7 dev

updated to deal with prepared polygons from shapely, and to extract the same positions from a second trajectory in a polygon (for velocities for example)
author Nicolas Saunier <nicolas.saunier@polymtl.ca>
date Thu, 11 Feb 2016 11:56:50 -0500
parents 1b22d81ef5ff
children 3aa6102ccc12
comparison
equal deleted inserted replaced
780:1b22d81ef5ff 781:7c38250ddfc7
10 from scipy.stats import scoreatpercentile 10 from scipy.stats import scoreatpercentile
11 from scipy.spatial.distance import cdist 11 from scipy.spatial.distance import cdist
12 12
13 try: 13 try:
14 from shapely.geometry import Polygon, Point as shapelyPoint 14 from shapely.geometry import Polygon, Point as shapelyPoint
15 from shapely.prepared import prep 15 from shapely.prepared import prep, PreparedGeometry
16 shapelyAvailable = True 16 shapelyAvailable = True
17 except ImportError: 17 except ImportError:
18 print('Shapely library could not be loaded') 18 print('Shapely library could not be loaded')
19 shapelyAvailable = False 19 shapelyAvailable = False
20 20
347 'Returns the middle of the segment [p1, p2]' 347 'Returns the middle of the segment [p1, p2]'
348 return Point(0.5*p1.x+0.5*p2.x, 0.5*p1.y+0.5*p2.y) 348 return Point(0.5*p1.x+0.5*p2.x, 0.5*p1.y+0.5*p2.y)
349 349
350 if shapelyAvailable: 350 if shapelyAvailable:
351 def pointsInPolygon(points, polygon): 351 def pointsInPolygon(points, polygon):
352 '''Optimized tests of a series of points within (Shapely) polygon ''' 352 '''Optimized tests of a series of points within (Shapely) polygon (not prepared)'''
353 prepared_polygon = prep(polygon) 353 if type(polygon) == PreparedGeometry:
354 prepared_polygon = polygon
355 else:
356 prepared_polygon = prep(polygon)
354 return filter(prepared_polygon.contains, points) 357 return filter(prepared_polygon.contains, points)
355 358
356 # Functions for coordinate transformation 359 # Functions for coordinate transformation
357 # From Paul St-Aubin's PVA tools 360 # From Paul St-Aubin's PVA tools
358 def subsec_spline_dist(splines): 361 def subsec_spline_dist(splines):
931 'Returns the positions very step' 934 'Returns the positions very step'
932 return Trajectory([self.positions[0][::step], 935 return Trajectory([self.positions[0][::step],
933 self.positions[1][::step]]) 936 self.positions[1][::step]])
934 937
935 if shapelyAvailable: 938 if shapelyAvailable:
936 def getTrajectoryInPolygon(self, polygon): 939 def getTrajectoryInPolygon(self, polygon, t2 = None):
937 '''Returns the trajectory built with the set of points inside the (shapely) polygon''' 940 '''Returns the trajectory built with the set of points inside the (shapely) polygon
941 The polygon could be a prepared polygon (faster) from prepared.prep
942
943 t2 is another trajectory (could be velocities)
944 which is filtered based on the first (self) trajectory'''
938 traj = Trajectory() 945 traj = Trajectory()
939 points = [p.asShapely() for p in self] 946 inPolygon = []
940 for p in pointsInPolygon(points, polygon): 947 for x, y in zip(self.positions[0], self.positions[1]):
941 traj.addPositionXY(p.x, p.y) 948 inPolygon.append(polygon.contains(shapelyPoint(x, y)))
942 return traj 949 if inPolygon[-1]:
950 traj.addPositionXY(x, y)
951 traj2 = Trajectory()
952 if t2 is not None:
953 for inp, x, y in zip(inPolygon, t2.positions[0], t2.positions[1]):
954 if inp:
955 traj2.addPositionXY(x, y)
956 return traj, traj2
943 957
944 def proportionInPolygon(self, polygon, minProportion = 0.5): 958 def proportionInPolygon(self, polygon, minProportion = 0.5):
945 pointsIn = pointsInPolygon([p.asShapely() for p in self], polygon) 959 inPolygon = [polygon.contains(shapelyPoint(x, y)) for x, y in zip(self.positions[0], self.positions[1])]
946 lengthThreshold = float(self.length())*minProportion 960 lengthThreshold = float(self.length())*minProportion
947 return len(pointsIn) >= lengthThreshold 961 return sum(inPolygon) >= lengthThreshold
948 else: 962 else:
949 def getTrajectoryInPolygon(self, polygon): 963 def getTrajectoryInPolygon(self, polygon, t2 = None):
950 '''Returns the trajectory built with the set of points inside the polygon 964 '''Returns the trajectory built with the set of points inside the polygon
951 (array of Nx2 coordinates of the polygon vertices)''' 965 (array of Nx2 coordinates of the polygon vertices)'''
952 traj = Trajectory() 966 traj = Trajectory()
967 inPolygon = []
953 for p in self: 968 for p in self:
954 if p.inPolygon(polygon): 969 inPolygon.append(p.inPolygon(polygon))
970 if inPolygon[-1]:
955 traj.addPosition(p) 971 traj.addPosition(p)
956 return traj 972 traj2 = Trajectory()
973 if t2 is not None:
974 for inp, x, y in zip(inPolygon, t2.positions[0], t2.positions[1]):
975 if inp:
976 traj2.addPositionXY(p.x, p.y)
977 return traj, traj2
957 978
958 def proportionInPolygon(self, polygon, minProportion = 0.5): 979 def proportionInPolygon(self, polygon, minProportion = 0.5):
959 pointsInPolygon = [p.inPolygon(polygon) for p in self] 980 inPolygon = [p.inPolygon(polygon) for p in self]
960 lengthThreshold = float(self.length())*minProportion 981 lengthThreshold = float(self.length())*minProportion
961 return len(pointsInPolygon) >= lengthThreshold 982 return sum(inPolygon) >= lengthThreshold
962 983
963 @staticmethod 984 @staticmethod
964 def lcss(t1, t2, lcss): 985 def lcss(t1, t2, lcss):
965 return lcss.compute(t1, t2) 986 return lcss.compute(t1, t2)
966 987