| 1 | # intersect.py |
|---|
| 2 | # |
|---|
| 3 | # Demonstrate how Shapely can be used to analyze and plot the intersection of |
|---|
| 4 | # a trajectory and regions in space. |
|---|
| 5 | |
|---|
| 6 | from functools import partial |
|---|
| 7 | import random |
|---|
| 8 | |
|---|
| 9 | import pylab |
|---|
| 10 | |
|---|
| 11 | from shapely.geometry import LineString, Point |
|---|
| 12 | from shapely.ops import cascaded_union |
|---|
| 13 | |
|---|
| 14 | # Build patches as in dissolved.py |
|---|
| 15 | r = partial(random.uniform, -20.0, 20.0) |
|---|
| 16 | points = [Point(r(), r()) for i in range(100)] |
|---|
| 17 | spots = [p.buffer(2.5) for p in points] |
|---|
| 18 | patches = cascaded_union(spots) |
|---|
| 19 | |
|---|
| 20 | # Represent the following geolocation parameters |
|---|
| 21 | # |
|---|
| 22 | # initial position: -25, -25 |
|---|
| 23 | # heading: 45.0 |
|---|
| 24 | # speed: 50*sqrt(2) |
|---|
| 25 | # |
|---|
| 26 | # as a line |
|---|
| 27 | vector = LineString(((-25.0, -25.0), (25.0, 25.0))) |
|---|
| 28 | |
|---|
| 29 | # Find intercepted and missed patches. List the former so we can count them |
|---|
| 30 | # later |
|---|
| 31 | intercepts = [patch for patch in patches.geoms if vector.intersects(patch)] |
|---|
| 32 | misses = (patch for patch in patches.geoms if not vector.intersects(patch)) |
|---|
| 33 | |
|---|
| 34 | # Illustrate the results using matplotlib's pylab interface |
|---|
| 35 | pylab.figure(num=None, figsize=(4, 4), dpi=180) |
|---|
| 36 | |
|---|
| 37 | # Plot the misses |
|---|
| 38 | for spot in misses: |
|---|
| 39 | x, y = spot.exterior.xy |
|---|
| 40 | pylab.fill(x, y, color='#cccccc', aa=True) |
|---|
| 41 | pylab.plot(x, y, color='#999999', aa=True, lw=1.0) |
|---|
| 42 | |
|---|
| 43 | # Do the same for the holes of the patch |
|---|
| 44 | for hole in spot.interiors: |
|---|
| 45 | x, y = hole.xy |
|---|
| 46 | pylab.fill(x, y, color='#ffffff', aa=True) |
|---|
| 47 | pylab.plot(x, y, color='#999999', aa=True, lw=1.0) |
|---|
| 48 | |
|---|
| 49 | # Plot the intercepts |
|---|
| 50 | for spot in intercepts: |
|---|
| 51 | x, y = spot.exterior.xy |
|---|
| 52 | pylab.fill(x, y, color='red', alpha=0.25, aa=True) |
|---|
| 53 | pylab.plot(x, y, color='red', alpha=0.5, aa=True, lw=1.0) |
|---|
| 54 | |
|---|
| 55 | # Do the same for the holes of the patch |
|---|
| 56 | for hole in spot.interiors: |
|---|
| 57 | x, y = hole.xy |
|---|
| 58 | pylab.fill(x, y, color='#ffffff', aa=True) |
|---|
| 59 | pylab.plot(x, y, color='red', alpha=0.5, aa=True, lw=1.0) |
|---|
| 60 | |
|---|
| 61 | # Draw the projected trajectory |
|---|
| 62 | pylab.arrow(-25, -25, 50, 50, color='#999999', aa=True, |
|---|
| 63 | head_width=1.0, head_length=1.0) |
|---|
| 64 | |
|---|
| 65 | # Plot the intersection |
|---|
| 66 | intersection = vector.intersection(patches) |
|---|
| 67 | assert intersection.geom_type in ['MultiLineString'] |
|---|
| 68 | |
|---|
| 69 | for segment in intersection.geoms: |
|---|
| 70 | x, y = segment.xy |
|---|
| 71 | pylab.plot(x, y, color='red', aa=True, lw=1.5) |
|---|
| 72 | |
|---|
| 73 | # Write the number of patches and the total patch area to the figure |
|---|
| 74 | pylab.text(-28, 25, |
|---|
| 75 | "Patches: %d/%d (%d), total length: %.1f" \ |
|---|
| 76 | % (len(intercepts), len(patches.geoms), |
|---|
| 77 | len(intersection.geoms), intersection.length)) |
|---|
| 78 | |
|---|
| 79 | pylab.savefig('intersect.png') |
|---|
| 80 | |
|---|