Mercurial Hosting > traffic-intelligence
comparison python/moving.py @ 372:349eb1e09f45
Cleaned the methods/functions indicating if a point is in a polygon
In general, shapely should be used, especially for lots of points:
from shapely.geometry import Polygon, Point
poly = Polygon(array([[0,0],[0,1],[1,1],[1,0]]))
p = Point(0.5,0.5)
poly.contains(p) -> returns True
poly.contains(Point(-1,-1)) -> returns False
You can convert a moving.Point to a shapely point: p = moving.Point(1,2) p.asShapely() returns the equivalent shapely point
If you have several points to test, use moving.pointsInPolygon(points, polygon) where points are moving.Point and polygon is a shapely polygon.
author | Nicolas Saunier <nicolas.saunier@polymtl.ca> |
---|---|
date | Tue, 16 Jul 2013 17:00:17 -0400 |
parents | 027e254f0b53 |
children | 2aed569f39e7 |
comparison
equal
deleted
inserted
replaced
371:924e38c9f70e | 372:349eb1e09f45 |
---|---|
5 import cvutils | 5 import cvutils |
6 | 6 |
7 from math import sqrt | 7 from math import sqrt |
8 from numpy import median | 8 from numpy import median |
9 | 9 |
10 #from shapely.geometry import Polygon | 10 try: |
11 from shapely.geometry import Polygon, Point as shapelyPoint | |
12 from shapely.prepared import prep | |
13 shapelyAvailable = True | |
14 except ImportError: | |
15 print('Shapely library could not be loaded') | |
16 shapelyAvailable = False | |
11 | 17 |
12 __metaclass__ = type | 18 __metaclass__ = type |
13 | 19 |
14 class Interval(object): | 20 class Interval(object): |
15 '''Generic interval: a subset of real numbers (not iterable)''' | 21 '''Generic interval: a subset of real numbers (not iterable)''' |
195 return (self.x, self.y) | 201 return (self.x, self.y) |
196 | 202 |
197 def asint(self): | 203 def asint(self): |
198 return Point(int(self.x), int(self.y)) | 204 return Point(int(self.x), int(self.y)) |
199 | 205 |
206 if shapelyAvailable: | |
207 def asShapely(self): | |
208 return shapelyPoint(self.x, self.y) | |
209 | |
200 def project(self, homography): | 210 def project(self, homography): |
201 from numpy.core.multiarray import array | 211 from numpy.core.multiarray import array |
202 projected = cvutils.projectArray(homography, array([[self.x], [self.y]])) | 212 projected = cvutils.projectArray(homography, array([[self.x], [self.y]])) |
203 return Point(projected[0], projected[1]) | 213 return Point(projected[0], projected[1]) |
204 | 214 |
205 def inPolygon(self, poly): | 215 def inPolygonNoShapely(self, polygon): |
206 '''Returns if the point x, y is inside the polygon. | 216 '''Indicates if the point x, y is inside the polygon |
207 The polygon is defined by the ordered list of points in poly | 217 (array of Nx2 coordinates of the polygon vertices) |
208 | 218 |
209 taken from http://www.ariel.com.au/a/python-point-int-poly.html | 219 taken from http://www.ariel.com.au/a/python-point-int-poly.html |
210 | 220 |
211 Use points_inside_poly from matplotlib.nxutils''' | 221 Use Polygon.contains if Shapely is installed''' |
212 | 222 |
213 n = len(poly); | 223 n = polygon.shape[0]; |
214 counter = 0; | 224 counter = 0; |
215 | 225 |
216 p1 = poly[0]; | 226 p1 = polygon[0,:]; |
217 for i in range(n+1): | 227 for i in range(n+1): |
218 p2 = poly[i % n]; | 228 p2 = polygon[i % n,:]; |
219 if self.y > min(p1.y,p2.y): | 229 if self.y > min(p1[1],p2[1]): |
220 if self.y <= max(p1.y,p2.y): | 230 if self.y <= max(p1[1],p2[1]): |
221 if self.x <= max(p1.x,p2.x): | 231 if self.x <= max(p1[0],p2[0]): |
222 if p1.y != p2.y: | 232 if p1[1] != p2[1]: |
223 xinters = (self.y-p1.y)*(p2.x-p1.x)/(p2.y-p1.y)+p1.x; | 233 xinters = (self.y-p1[1])*(p2[0]-p1[0])/(p2[1]-p1[1])+p1[0]; |
224 if p1.x == p2.x or self.x <= xinters: | 234 if p1[0] == p2[0] or self.x <= xinters: |
225 counter+=1; | 235 counter+=1; |
226 p1=p2 | 236 p1=p2 |
227 return (counter%2 == 1); | 237 return (counter%2 == 1); |
228 | 238 |
229 @staticmethod | 239 @staticmethod |
242 | 252 |
243 @staticmethod | 253 @staticmethod |
244 def plotAll(points, **kwargs): | 254 def plotAll(points, **kwargs): |
245 from matplotlib.pyplot import scatter | 255 from matplotlib.pyplot import scatter |
246 scatter([p.x for p in points],[p.y for p in points], **kwargs) | 256 scatter([p.x for p in points],[p.y for p in points], **kwargs) |
257 | |
258 if shapelyAvailable: | |
259 def pointsInPolygon(points, polygon): | |
260 '''Optimized tests of a series of points within (Shapely) polygon ''' | |
261 prepared_polygon = prep(polygon) | |
262 return filter(prepared_polygon.contains, points) | |
263 | |
247 | 264 |
248 class NormAngle(object): | 265 class NormAngle(object): |
249 '''Alternate encoding of a point, by its norm and orientation''' | 266 '''Alternate encoding of a point, by its norm and orientation''' |
250 | 267 |
251 def __init__(self, norm, angle): | 268 def __init__(self, norm, angle): |
523 return Trajectory([self.positions[0][inter.first:inter.last], | 540 return Trajectory([self.positions[0][inter.first:inter.last], |
524 self.positions[1][inter.first:inter.last]]) | 541 self.positions[1][inter.first:inter.last]]) |
525 else: | 542 else: |
526 return None | 543 return None |
527 | 544 |
528 def getTrajectoryInPolygon(self, polygon): | 545 def getTrajectoryInPolygonNoShapely(self, polygon): |
529 '''Returns the set of points inside the polygon | 546 '''Returns the trajectory built with the set of points inside the polygon |
530 (array of Nx2 coordinates of the polygon vertices)''' | 547 (array of Nx2 coordinates of the polygon vertices)''' |
531 import matplotlib.nxutils as nx | |
532 traj = Trajectory() | 548 traj = Trajectory() |
533 result = nx.points_inside_poly(self.asArray().T, polygon) | 549 for p in self: |
534 for i in xrange(self.length()): | 550 if p.inPolygonNoShapely(polygon): |
535 if result[i]: | 551 traj.addPosition(p) |
536 traj.addPositionXY(self.positions[0][i], self.positions[1][i]) | |
537 return traj | 552 return traj |
538 | 553 |
539 # version 2: use shapely polygon contains | 554 if shapelyAvailable: |
540 | 555 def getTrajectoryInPolygon(self, polygon): |
556 '''Returns the trajectory built with the set of points inside the (shapely) polygon''' | |
557 traj = Trajectory() | |
558 points = [p.asShapely() for p in self] | |
559 for p in pointsInPolygon(points, polygon): | |
560 traj.addPositionXY(p.x, p.y) | |
561 return traj | |
562 | |
541 @staticmethod | 563 @staticmethod |
542 def lcss(t1, t2, lcss): | 564 def lcss(t1, t2, lcss): |
543 return lcss.compute(t1, t2) | 565 return lcss.compute(t1, t2) |
544 | 566 |
545 class CurvilinearTrajectory(Trajectory): | 567 class CurvilinearTrajectory(Trajectory): |