source: anuga_core/source/anuga/utilities/test_polygon.py @ 5897

Last change on this file since 5897 was 5897, checked in by ole, 15 years ago

Reverted numpy changes to the trunk that should have been made to the branch.
The command was svn merge -r 5895:5890 .

File size: 30.8 KB
Line 
1#!/usr/bin/env python
2
3
4import unittest
5from Numeric import zeros, array, allclose
6from math import sqrt, pi
7from anuga.utilities.numerical_tools import ensure_numeric
8from anuga.utilities.system_tools import get_pathname_from_package
9
10from polygon import *
11from anuga.coordinate_transforms.geo_reference import Geo_reference
12from anuga.geospatial_data.geospatial_data import Geospatial_data
13
14def test_function(x, y):
15    return x+y
16
17class Test_Polygon(unittest.TestCase):
18    def setUp(self):
19        pass
20
21    def tearDown(self):
22        pass
23
24
25    def test_that_C_extension_compiles(self):
26        FN = 'polygon_ext.c'
27        try:
28            import polygon_ext
29        except:
30            from compile import compile
31
32            try:
33                compile(FN)
34            except:
35                raise 'Could not compile %s' %FN
36            else:
37                import polygon_ext
38
39
40    # Polygon stuff
41    def test_polygon_function_constants(self):
42        p1 = [[0,0], [10,0], [10,10], [0,10]]
43        p2 = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
44
45        f = Polygon_function( [(p1, 1.0)] )
46        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1
47        assert allclose(z, [1,1,0,0])
48
49
50        f = Polygon_function( [(p2, 2.0)] )
51        z = f([5, 5, 27, 35], [5, 9, 8, -5]) # First and last inside p2
52        assert allclose(z, [2,0,0,2])
53
54
55        #Combined
56        f = Polygon_function( [(p1, 1.0), (p2, 2.0)] )
57        z = f([5, 5, 27, 35], [5, 9, 8, -5])
58        assert allclose(z, [2,1,0,2])
59
60    def test_polygon_function_csvfile(self):
61        from os import sep, getenv
62
63
64        # Get path where this test is run
65        path = get_pathname_from_package('anuga.utilities')
66
67        # Form absolute filename and read
68        filename = path + sep +  'mainland_only.csv'
69        p1 = read_polygon(filename)       
70
71        f = Polygon_function( [(p1, 10.0)] )
72        z = f([430000,480000], [490000,7720000]) # first outside, second inside
73       
74        assert allclose(z, [0,10])
75
76    def test_polygon_function_georef(self):
77        """Check that georeferencing works
78        """
79
80        from anuga.coordinate_transforms.geo_reference import Geo_reference
81
82        geo = Geo_reference(56, 200, 1000)
83
84        # Make points 'absolute'
85        p1 = [[200,1000], [210,1000], [210,1010], [200,1010]]
86        p2 = [[200,1000], [210,1010], [215,1005], [220, 1010], [225,1000],
87              [230,1010], [240,990]]
88
89        f = Polygon_function( [(p1, 1.0)], geo_reference=geo)
90        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1
91
92        assert allclose(z, [1,1,0,0])
93
94
95        f = Polygon_function( [(p2, 2.0)], geo_reference=geo)
96        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #First and last inside p2
97        assert allclose(z, [2,0,0,2])
98
99
100        # Combined
101        f = Polygon_function( [(p1, 1.0), (p2, 2.0)], geo_reference=geo)
102        z = f([5, 5, 27, 35], [5, 9, 8, -5])
103        assert allclose(z, [2,1,0,2])
104
105
106        # Check that it would fail without geo
107        f = Polygon_function( [(p1, 1.0), (p2, 2.0)])
108        z = f([5, 5, 27, 35], [5, 9, 8, -5])
109        assert not allclose(z, [2,1,0,2])       
110
111
112
113    def test_polygon_function_callable(self):
114        """Check that values passed into Polygon_function can be callable
115        themselves.
116        """
117        p1 = [[0,0], [10,0], [10,10], [0,10]]
118        p2 = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
119
120        f = Polygon_function( [(p1, test_function)] )
121        z = f([5, 5, 27, 35], [5, 9, 8, -5]) #Two first inside p1
122        assert allclose(z, [10,14,0,0])
123
124        # Combined
125        f = Polygon_function( [(p1, test_function), (p2, 2.0)] )
126        z = f([5, 5, 27, 35], [5, 9, 8, -5])
127        assert allclose(z, [2,14,0,2])
128
129
130        # Combined w default
131        f = Polygon_function( [(p1, test_function), (p2, 2.0)], default = 3.14)
132        z = f([5, 5, 27, 35], [5, 9, 8, -5])
133        assert allclose(z, [2,14,3.14,2])
134
135
136        # Combined w default func
137        f = Polygon_function( [(p1, test_function), (p2, 2.0)],
138                              default = test_function)
139        z = f([5, 5, 27, 35], [5, 9, 8, -5])
140        assert allclose(z, [2,14,35,2])
141
142
143
144    def test_point_on_line(self):
145
146        # Endpoints first
147        assert point_on_line( [0, 0], [[0,0], [1,0]] )
148        assert point_on_line( [1, 0], [[0,0], [1,0]] )
149
150        # Then points on line
151        assert point_on_line( [0.5, 0], [[0,0], [1,0]] )
152        assert point_on_line( [0, 0.5], [[0,1], [0,0]] )
153        assert point_on_line( [1, 0.5], [[1,1], [1,0]] )
154        assert point_on_line( [0.5, 0.5], [[0,0], [1,1]] )
155
156        # Then points not on line
157        assert not point_on_line( [0.5, 0], [[0,1], [1,1]] )
158        assert not point_on_line( [0, 0.5], [[0,0], [1,1]] )
159
160        # From real example that failed
161        assert not point_on_line( [40,50], [[40,20], [40,40]] )
162
163
164        # From real example that failed
165        assert not point_on_line( [40,19], [[40,20], [40,40]] )
166
167        # Degenerate line
168        assert point_on_line( [40,19], [[40,19], [40,19]] )
169        assert not point_on_line( [40,19], [[40,40], [40,40]] )       
170
171
172
173    def test_is_inside_polygon_main(self):
174
175
176        # Simplest case: Polygon is the unit square
177        polygon = [[0,0], [1,0], [1,1], [0,1]]
178
179        assert is_inside_polygon( (0.5, 0.5), polygon )
180        assert not is_inside_polygon( (0.5, 1.5), polygon )
181        assert not is_inside_polygon( (0.5, -0.5), polygon )
182        assert not is_inside_polygon( (-0.5, 0.5), polygon )
183        assert not is_inside_polygon( (1.5, 0.5), polygon )
184
185        # Try point on borders
186        assert is_inside_polygon( (1., 0.5), polygon, closed=True)
187        assert is_inside_polygon( (0.5, 1), polygon, closed=True)
188        assert is_inside_polygon( (0., 0.5), polygon, closed=True)
189        assert is_inside_polygon( (0.5, 0.), polygon, closed=True)
190
191        assert not is_inside_polygon( (0.5, 1), polygon, closed=False)
192        assert not is_inside_polygon( (0., 0.5), polygon, closed=False)
193        assert not is_inside_polygon( (0.5, 0.), polygon, closed=False)
194        assert not is_inside_polygon( (1., 0.5), polygon, closed=False)
195
196
197    def test_inside_polygon_main(self):
198
199        # Simplest case: Polygon is the unit square
200        polygon = [[0,0], [1,0], [1,1], [0,1]]       
201
202        # From real example (that failed)
203        polygon = [[20,20], [40,20], [40,40], [20,40]]
204        points = [ [40, 50] ]
205        res = inside_polygon(points, polygon)
206        assert len(res) == 0
207
208        polygon = [[20,20], [40,20], [40,40], [20,40]]
209        points = [ [25, 25], [30, 20], [40, 50], [90, 20], [40, 90] ]
210        res = inside_polygon(points, polygon)
211        assert len(res) == 2
212        assert allclose(res, [0,1])
213
214
215
216        # More convoluted and non convex polygon
217        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
218        assert is_inside_polygon( (0.5, 0.5), polygon )
219        assert is_inside_polygon( (1, -0.5), polygon )
220        assert is_inside_polygon( (1.5, 0), polygon )
221
222        assert not is_inside_polygon( (0.5, 1.5), polygon )
223        assert not is_inside_polygon( (0.5, -0.5), polygon )
224
225
226        # Very convoluted polygon
227        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
228        assert is_inside_polygon( (5, 5), polygon )
229        assert is_inside_polygon( (17, 7), polygon )
230        assert is_inside_polygon( (27, 2), polygon )
231        assert is_inside_polygon( (35, -5), polygon )
232        assert not is_inside_polygon( (15, 7), polygon )
233        assert not is_inside_polygon( (24, 3), polygon )
234        assert not is_inside_polygon( (25, -10), polygon )
235
236
237
238        # Another combination (that failed)
239        polygon = [[0,0], [10,0], [10,10], [0,10]]
240        assert is_inside_polygon( (5, 5), polygon )
241        assert is_inside_polygon( (7, 7), polygon )
242        assert not is_inside_polygon( (-17, 7), polygon )
243        assert not is_inside_polygon( (7, 17), polygon )
244        assert not is_inside_polygon( (17, 7), polygon )
245        assert not is_inside_polygon( (27, 8), polygon )
246        assert not is_inside_polygon( (35, -5), polygon )
247
248
249
250
251        # Multiple polygons
252
253        polygon = [[0,0], [1,0], [1,1], [0,1], [0,0],
254                   [10,10], [11,10], [11,11], [10,11], [10,10]]
255        assert is_inside_polygon( (0.5, 0.5), polygon )
256        assert is_inside_polygon( (10.5, 10.5), polygon )
257
258        #FIXME: Fails if point is 5.5, 5.5
259        assert not is_inside_polygon( (0, 5.5), polygon )
260
261        # Polygon with a hole
262        polygon = [[-1,-1], [2,-1], [2,2], [-1,2], [-1,-1],
263                   [0,0], [1,0], [1,1], [0,1], [0,0]]
264
265        assert is_inside_polygon( (0, -0.5), polygon )
266        assert not is_inside_polygon( (0.5, 0.5), polygon )
267
268
269
270    def test_duplicate_points_being_ok(self):
271
272
273        # Simplest case: Polygon is the unit square
274        polygon = [[0,0], [1,0], [1,0], [1,0], [1,1], [0,1], [0,0]]
275
276        assert is_inside_polygon( (0.5, 0.5), polygon )
277        assert not is_inside_polygon( (0.5, 1.5), polygon )
278        assert not is_inside_polygon( (0.5, -0.5), polygon )
279        assert not is_inside_polygon( (-0.5, 0.5), polygon )
280        assert not is_inside_polygon( (1.5, 0.5), polygon )
281
282        # Try point on borders
283        assert is_inside_polygon( (1., 0.5), polygon, closed=True)
284        assert is_inside_polygon( (0.5, 1), polygon, closed=True)
285        assert is_inside_polygon( (0., 0.5), polygon, closed=True)
286        assert is_inside_polygon( (0.5, 0.), polygon, closed=True)
287
288        assert not is_inside_polygon( (0.5, 1), polygon, closed=False)
289        assert not is_inside_polygon( (0., 0.5), polygon, closed=False)
290        assert not is_inside_polygon( (0.5, 0.), polygon, closed=False)
291        assert not is_inside_polygon( (1., 0.5), polygon, closed=False)
292
293        # From real example
294        polygon = [[20,20], [40,20], [40,40], [20,40]]
295        points = [ [40, 50] ]
296        res = inside_polygon(points, polygon)
297        assert len(res) == 0
298
299       
300
301    def test_inside_polygon_vector_version(self):
302        # Now try the vector formulation returning indices
303        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
304        points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
305        res = inside_polygon( points, polygon, verbose=False )
306
307        assert allclose( res, [0,1,2] )
308
309    def test_outside_polygon(self):
310        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
311
312        assert not is_outside_polygon( [0.5, 0.5], U )
313        # evaluate to False as the point 0.5, 0.5 is inside the unit square
314       
315        assert is_outside_polygon( [1.5, 0.5], U )
316        # evaluate to True as the point 1.5, 0.5 is outside the unit square
317       
318        indices = outside_polygon( [[0.5, 0.5], [1, -0.5], [0.3, 0.2]], U )
319        assert allclose( indices, [1] )
320       
321        # One more test of vector formulation returning indices
322        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
323        points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
324        res = outside_polygon( points, polygon )
325
326        assert allclose( res, [3, 4] )
327
328
329
330        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
331        points = [ [0.5, 1.4], [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
332        res = outside_polygon( points, polygon )
333
334        assert allclose( res, [0, 4, 5] )       
335     
336    def test_outside_polygon2(self):
337        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
338   
339        assert not outside_polygon( [0.5, 1.0], U, closed = True )
340        # evaluate to False as the point 0.5, 1.0 is inside the unit square
341       
342        assert is_outside_polygon( [0.5, 1.0], U, closed = False )
343        # evaluate to True as the point 0.5, 1.0 is outside the unit square
344
345    def test_all_outside_polygon(self):
346        """Test case where all points are outside poly
347        """
348       
349        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
350
351        points = [[2,2], [1,3], [-1,1], [0,2]] #All outside
352
353
354        indices, count = separate_points_by_polygon(points, U)
355        #print indices, count
356        assert count == 0 #None inside
357        assert allclose(indices, [3,2,1,0])
358
359        indices = outside_polygon(points, U, closed = True)
360        assert allclose(indices, [0,1,2,3])
361
362        indices = inside_polygon(points, U, closed = True)
363        assert allclose(indices, [])               
364
365
366    def test_all_inside_polygon(self):
367        """Test case where all points are inside poly
368        """
369       
370        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
371
372        points = [[0.5,0.5], [0.2,0.3], [0,0.5]] #All inside (or on edge)
373
374
375        indices, count = separate_points_by_polygon(points, U)
376        assert count == 3 #All inside
377        assert allclose(indices, [0,1,2])
378
379        indices = outside_polygon(points, U, closed = True)
380        assert allclose(indices, [])
381
382        indices = inside_polygon(points, U, closed = True)
383        assert allclose(indices, [0,1,2])
384       
385
386    def test_separate_points_by_polygon(self):
387        U = [[0,0], [1,0], [1,1], [0,1]] #Unit square   
388
389        indices, count = separate_points_by_polygon( [[0.5, 0.5], [1, -0.5], [0.3, 0.2]], U )
390        assert allclose( indices, [0,2,1] )
391        assert count == 2
392       
393        #One more test of vector formulation returning indices
394        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
395        points = [ [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
396        res, count = separate_points_by_polygon( points, polygon )
397
398        assert allclose( res, [0,1,2,4,3] )
399        assert count == 3
400
401
402        polygon = [[0,0], [1,0], [0.5,-1], [2, -1], [2,1], [0,1]]
403        points = [ [0.5, 1.4], [0.5, 0.5], [1, -0.5], [1.5, 0], [0.5, 1.5], [0.5, -0.5]]
404        res, count = separate_points_by_polygon( points, polygon )
405
406        assert allclose( res, [1,2,3,5,4,0] )       
407        assert count == 3
408       
409
410    def test_populate_polygon(self):
411
412        polygon = [[0,0], [1,0], [1,1], [0,1]]
413        points = populate_polygon(polygon, 5)
414
415        assert len(points) == 5
416        for point in points:
417            assert is_inside_polygon(point, polygon)
418
419
420        #Very convoluted polygon
421        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
422
423        points = populate_polygon(polygon, 5)
424
425        assert len(points) == 5
426        for point in points:
427            assert is_inside_polygon(point, polygon)
428
429
430    def test_populate_polygon_with_exclude(self):
431       
432
433        polygon = [[0,0], [1,0], [1,1], [0,1]]
434        ex_poly = [[0,0], [0.5,0], [0.5, 0.5], [0,0.5]] #SW quarter
435        points = populate_polygon(polygon, 5, exclude = [ex_poly])
436
437        assert len(points) == 5
438        for point in points:
439            assert is_inside_polygon(point, polygon)
440            assert not is_inside_polygon(point, ex_poly)           
441
442
443        #overlap
444        polygon = [[0,0], [1,0], [1,1], [0,1]]
445        ex_poly = [[-1,-1], [0.5,0], [0.5, 0.5], [-1,0.5]]
446        points = populate_polygon(polygon, 5, exclude = [ex_poly])
447
448        assert len(points) == 5
449        for point in points:
450            assert is_inside_polygon(point, polygon)
451            assert not is_inside_polygon(point, ex_poly)                       
452       
453        #Multiple
454        polygon = [[0,0], [1,0], [1,1], [0,1]]
455        ex_poly1 = [[0,0], [0.5,0], [0.5, 0.5], [0,0.5]] #SW quarter
456        ex_poly2 = [[0.5,0.5], [0.5,1], [1, 1], [1,0.5]] #NE quarter       
457       
458        points = populate_polygon(polygon, 20, exclude = [ex_poly1, ex_poly2])
459
460        assert len(points) == 20
461        for point in points:
462            assert is_inside_polygon(point, polygon)
463            assert not is_inside_polygon(point, ex_poly1)
464            assert not is_inside_polygon(point, ex_poly2)                               
465       
466
467        #Very convoluted polygon
468        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
469        ex_poly = [[-1,-1], [5,0], [5, 5], [-1,5]]
470        points = populate_polygon(polygon, 20, exclude = [ex_poly])
471       
472        assert len(points) == 20
473        for point in points:
474            assert is_inside_polygon(point, polygon)
475            assert not is_inside_polygon(point, ex_poly), '%s' %str(point)                       
476
477
478    def test_populate_polygon_with_exclude2(self):
479       
480
481        min_outer = 0 
482        max_outer = 1000
483        polygon_outer = [[min_outer,min_outer],[max_outer,min_outer],
484                   [max_outer,max_outer],[min_outer,max_outer]]
485
486        delta = 10
487        min_inner1 = min_outer + delta
488        max_inner1 = max_outer - delta
489        inner1_polygon = [[min_inner1,min_inner1],[max_inner1,min_inner1],
490                   [max_inner1,max_inner1],[min_inner1,max_inner1]]
491     
492       
493        density_inner2 = 1000 
494        min_inner2 = min_outer +  2*delta
495        max_inner2 = max_outer -  2*delta
496        inner2_polygon = [[min_inner2,min_inner2],[max_inner2,min_inner2],
497                   [max_inner2,max_inner2],[min_inner2,max_inner2]]     
498       
499        points = populate_polygon(polygon_outer, 20, exclude = [inner1_polygon, inner2_polygon])
500
501        assert len(points) == 20
502        for point in points:
503            assert is_inside_polygon(point, polygon_outer)
504            assert not is_inside_polygon(point, inner1_polygon)
505            assert not is_inside_polygon(point, inner2_polygon)                               
506       
507
508        #Very convoluted polygon
509        polygon = [[0,0], [10,10], [15,5], [20, 10], [25,0], [30,10], [40,-10]]
510        ex_poly = [[-1,-1], [5,0], [5, 5], [-1,5]]
511        points = populate_polygon(polygon, 20, exclude = [ex_poly])
512       
513        assert len(points) == 20
514        for point in points:
515            assert is_inside_polygon(point, polygon)
516            assert not is_inside_polygon(point, ex_poly), '%s' %str(point)                       
517
518    def test_point_in_polygon(self):
519        polygon = [[0,0], [1,0], [1,1], [0,1]]
520        point = point_in_polygon(polygon)
521        assert is_inside_polygon(point, polygon)
522
523        #this may get into a vicious loop
524        #polygon = [[1e32,1e54], [1,0], [1,1], [0,1]]
525       
526        polygon = [[1e15,1e7], [1,0], [1,1], [0,1]]
527        point = point_in_polygon(polygon)
528        assert is_inside_polygon(point, polygon)
529
530
531        polygon = [[0,0], [1,0], [1,1], [1e8,1e8]]
532        point = point_in_polygon(polygon)
533        assert is_inside_polygon(point, polygon)
534
535       
536        polygon = [[1e32,1e54], [-1e32,1e54], [1e32,-1e54]]
537        point = point_in_polygon(polygon)
538        assert is_inside_polygon(point, polygon)
539
540       
541        polygon = [[1e18,1e15], [1,0], [0,1]]
542        point = point_in_polygon(polygon)
543        assert is_inside_polygon(point, polygon)
544
545    def test_in_and_outside_polygon_main(self):
546
547
548        #Simplest case: Polygon is the unit square
549        polygon = [[0,0], [1,0], [1,1], [0,1]]
550
551        inside, outside =  in_and_outside_polygon( (0.5, 0.5), polygon )
552        assert inside[0] == 0
553        assert len(outside) == 0
554       
555        inside, outside =  in_and_outside_polygon(  (1., 0.5), polygon, closed=True)
556        assert inside[0] == 0
557        assert len(outside) == 0
558       
559        inside, outside =  in_and_outside_polygon(  (1., 0.5), polygon, closed=False)
560        assert len(inside) == 0
561        assert outside[0] == 0
562
563        points =  [(1., 0.25),(1., 0.75) ]
564        inside, outside =  in_and_outside_polygon( points, polygon, closed=True)
565        assert (inside, [0,1])
566        assert len(outside) == 0
567       
568        inside, outside =  in_and_outside_polygon( points, polygon, closed=False)
569        assert len(inside) == 0
570        assert (outside, [0,1])
571
572       
573        points =  [(100., 0.25),(0.5, 0.5) ] 
574        inside, outside =  in_and_outside_polygon( points, polygon)
575        assert (inside, [1])
576        assert outside[0] == 0
577       
578        points =  [(100., 0.25),(0.5, 0.5), (39,20), (0.6,0.7),(56,43),(67,90) ] 
579        inside, outside =  in_and_outside_polygon( points, polygon)
580        assert (inside, [1,3])
581        assert (outside, [0,2,4,5])
582
583
584    def test_intersection1(self):
585        line0 = [[-1,0], [1,0]]
586        line1 = [[0,-1], [0,1]]
587
588        status, value = intersection(line0, line1)
589        assert status == 1
590        assert allclose(value, [0.0, 0.0])
591
592    def test_intersection2(self):
593        line0 = [[0,0], [24,12]]
594        line1 = [[0,12], [24,0]]
595
596        status, value = intersection(line0, line1)
597        assert status == 1
598        assert allclose(value, [12.0, 6.0])
599
600        # Swap direction of one line
601        line1 = [[24,0], [0,12]]
602
603        status, value = intersection(line0, line1)
604        assert status == 1
605        assert allclose(value, [12.0, 6.0])
606
607        # Swap order of lines
608        status, value = intersection(line1, line0)
609        assert status == 1
610        assert allclose(value, [12.0, 6.0])       
611       
612    def test_intersection3(self):
613        line0 = [[0,0], [24,12]]
614        line1 = [[0,17], [24,0]]
615
616        status, value = intersection(line0, line1)
617        assert status == 1
618        assert allclose(value, [14.068965517, 7.0344827586])
619
620        # Swap direction of one line
621        line1 = [[24,0], [0,17]]
622
623        status, value = intersection(line0, line1)
624        assert status == 1
625        assert allclose(value, [14.068965517, 7.0344827586])       
626
627        # Swap order of lines
628        status, value = intersection(line1, line0)
629        assert status == 1       
630        assert allclose(value, [14.068965517, 7.0344827586])       
631
632
633    def test_intersection_endpoints(self):
634        """test_intersection_endpoints(self):
635
636        Test that coinciding endpoints are picked up
637        """
638        line0 = [[0,0], [1,1]]
639        line1 = [[1,1], [2,1]]
640
641        status, value = intersection(line0, line1)
642        assert status == 1
643        assert allclose(value, [1.0, 1.0])
644
645
646        line0 = [[1,1], [2,0]]
647        line1 = [[1,1], [2,1]]
648
649        status, value = intersection(line0, line1)
650        assert status == 1
651        assert allclose(value, [1.0, 1.0])       
652       
653
654    def test_intersection_direction_invariance(self):
655        """This runs through a number of examples and checks that direction of lines don't matter.
656        """
657             
658        line0 = [[0,0], [100,100]]
659
660        common_end_point = [20, 150]
661       
662        for i in range(100):
663            x = 20 + i * 1.0/100
664
665            line1 = [[x,0], common_end_point]
666            status, p1 = intersection(line0, line1)
667            assert status == 1
668
669
670            # Swap direction of line1
671            line1 = [common_end_point, [x,0]]           
672            status, p2 = intersection(line0, line1)
673            assert status == 1           
674
675            msg = 'Orientation of line shouldn not matter.\n'
676            msg += 'However, segment [%f,%f], [%f, %f]' %(x,
677                                                          0,
678                                                          common_end_point[0],
679                                                          common_end_point[1])
680            msg += ' gave %s, \nbut when reversed we got %s' %(p1, p2)
681            assert allclose(p1, p2), msg
682
683            # Swap order of lines
684            status, p3 = intersection(line1, line0)
685            assert status == 1                       
686            msg = 'Order of lines gave different results'
687            assert allclose(p1, p3), msg
688           
689
690    def test_no_intersection(self):
691        line0 = [[-1,1], [1,1]]
692        line1 = [[0,-1], [0,0]]
693
694        status, value = intersection(line0, line1)
695        assert status == 0
696        assert value is None
697       
698
699    def test_intersection_parallel(self):
700        line0 = [[-1,1], [1,1]]
701        line1 = [[-1,0], [5,0]]
702
703        status, value = intersection(line0, line1)
704        assert status == 4       
705        assert value is None
706
707
708        line0 = [[0,0], [10,100]]
709        line1 = [[-10,5], [0,105]]
710
711        status, value = intersection(line0, line1)
712        assert status == 4               
713        assert value is None       
714
715
716    def test_intersection_coincide(self):
717        """def test_intersection_coincide(self):
718        Test what happens whe two lines partly coincide
719        """
720
721        # Overlap 1
722        line0 = [[0,0], [5,0]]
723        line1 = [[-3,0], [3,0]]
724
725        status, value = intersection(line0, line1)
726        assert status == 2
727        assert allclose(value, [[0,0], [3,0]])
728
729        # Overlap 2
730        line0 = [[-10,0], [5,0]]
731        line1 = [[-3,0], [10,0]]
732
733        status, value = intersection(line0, line1)
734        assert status == 2
735        assert allclose(value, [[-3, 0], [5,0]])       
736
737        # Inclusion 1
738        line0 = [[0,0], [5,0]]
739        line1 = [[2,0], [3,0]]
740
741        status, value = intersection(line0, line1)
742        assert status == 2       
743        assert allclose(value, line1)
744
745        # Inclusion 2
746        line0 = [[1,0], [5,0]]
747        line1 = [[-10,0], [15,0]]
748
749        status, value = intersection(line0, line1)
750        assert status == 2       
751        assert allclose(value, line0)                                       
752
753
754        # Exclusion (no intersection)
755        line0 = [[-10,0], [1,0]]
756        line1 = [[3,0], [15,0]]
757
758        status, value = intersection(line0, line1)
759        assert status == 3       
760        assert value is None
761       
762
763        # Try examples with some slope (y=2*x+5)
764
765        # Overlap
766        line0 = [[0,5], [7,19]]
767        line1 = [[1,7], [10,25]]
768        status, value = intersection(line0, line1)
769        assert status == 2               
770        assert allclose(value, [[1, 7], [7, 19]])
771
772        status, value = intersection(line1, line0)
773        assert status == 2
774        assert allclose(value, [[1, 7], [7, 19]])
775
776        # Swap direction
777        line0 = [[7,19], [0,5]]
778        line1 = [[1,7], [10,25]]
779        status, value = intersection(line0, line1)
780        assert status == 2
781        assert allclose(value, [[7, 19], [1, 7]])
782
783        line0 = [[0,5], [7,19]]
784        line1 = [[10,25], [1,7]]
785        status, value = intersection(line0, line1)
786        assert status == 2
787        assert allclose(value, [[1, 7], [7, 19]])       
788       
789
790        # Inclusion
791        line0 = [[1,7], [7,19]]
792        line1 = [[0,5], [10,25]]
793        status, value = intersection(line0, line1)
794        assert status == 2                       
795        assert allclose(value, [[1,7], [7, 19]])               
796
797        line0 = [[0,5], [10,25]]
798        line1 = [[1,7], [7,19]]
799        status, value = intersection(line0, line1)
800        assert status == 2                       
801        assert allclose(value, [[1,7], [7, 19]])
802
803
804        line0 = [[0,5], [10,25]]
805        line1 = [[7,19], [1,7]]
806        status, value = intersection(line0, line1)
807        assert status == 2                       
808        assert allclose(value, [[7, 19], [1, 7]])                       
809       
810       
811    def zzztest_inside_polygon_main(self):  \
812
813        #FIXME (Ole): Why is this disabled?
814        print "inside",inside
815        print "outside",outside
816       
817        assert not inside_polygon( (0.5, 1.5), polygon )
818        assert not inside_polygon( (0.5, -0.5), polygon )
819        assert not inside_polygon( (-0.5, 0.5), polygon )
820        assert not inside_polygon( (1.5, 0.5), polygon )
821
822        #Try point on borders
823        assert inside_polygon( (1., 0.5), polygon, closed=True)
824        assert inside_polygon( (0.5, 1), polygon, closed=True)
825        assert inside_polygon( (0., 0.5), polygon, closed=True)
826        assert inside_polygon( (0.5, 0.), polygon, closed=True)
827
828        assert not inside_polygon( (0.5, 1), polygon, closed=False)
829        assert not inside_polygon( (0., 0.5), polygon, closed=False)
830        assert not inside_polygon( (0.5, 0.), polygon, closed=False)
831        assert not inside_polygon( (1., 0.5), polygon, closed=False)
832
833
834
835        #From real example (that failed)
836        polygon = [[20,20], [40,20], [40,40], [20,40]]
837        points = [ [40, 50] ]
838        res = inside_polygon(points, polygon)
839        assert len(res) == 0
840
841        polygon = [[20,20], [40,20], [40,40], [20,40]]
842        points = [ [25, 25], [30, 20], [40, 50], [90, 20], [40, 90] ]
843        res = inside_polygon(points, polygon)
844        assert len(res) == 2
845        assert allclose(res, [0,1])
846
847    def test_polygon_area(self):
848
849        #Simplest case: Polygon is the unit square
850        polygon = [[0,0], [1,0], [1,1], [0,1]]
851        assert polygon_area(polygon) == 1
852
853        #Simple case: Polygon is a rectangle
854        polygon = [[0,0], [1,0], [1,4], [0,4]]
855        assert polygon_area(polygon) == 4
856
857        #Simple case: Polygon is a unit triangle
858        polygon = [[0,0], [1,0], [0,1]]
859        assert polygon_area(polygon) == 0.5
860
861        #Simple case: Polygon is a diamond
862        polygon = [[0,0], [1,1], [2,0], [1, -1]]
863        assert polygon_area(polygon) == 2.0
864
865    def test_poly_xy(self):
866 
867        #Simplest case: Polygon is the unit square
868        polygon = [[0,0], [1,0], [1,1], [0,1]]
869        x, y = poly_xy(polygon)
870        assert len(x) == len(polygon)+1
871        assert len(y) == len(polygon)+1
872        assert x[0] == 0
873        assert x[1] == 1
874        assert x[2] == 1
875        assert x[3] == 0
876        assert y[0] == 0
877        assert y[1] == 0
878        assert y[2] == 1
879        assert y[3] == 1
880
881        #Arbitrary polygon
882        polygon = [[1,5], [1,1], [100,10], [1,10], [3,6]]
883        x, y = poly_xy(polygon)
884        assert len(x) == len(polygon)+1
885        assert len(y) == len(polygon)+1
886        assert x[0] == 1
887        assert x[1] == 1
888        assert x[2] == 100
889        assert x[3] == 1
890        assert x[4] == 3
891        assert y[0] == 5
892        assert y[1] == 1
893        assert y[2] == 10
894        assert y[3] == 10
895        assert y[4] == 6
896
897    # Disabled   
898    def xtest_plot_polygons(self):
899       
900        import os
901       
902        #Simplest case: Polygon is the unit square
903        polygon1 = [[0,0], [1,0], [1,1], [0,1]]
904        polygon2 = [[1,1], [2,1], [3,2], [2,2]]
905        v = plot_polygons([polygon1, polygon2],'test1')
906        assert len(v) == 4
907        assert v[0] == 0
908        assert v[1] == 3
909        assert v[2] == 0
910        assert v[3] == 2
911
912        #Another case
913        polygon3 = [[1,5], [10,1], [100,10], [50,10], [3,6]]
914        v = plot_polygons([polygon2,polygon3],'test2')
915        assert len(v) == 4
916        assert v[0] == 1
917        assert v[1] == 100
918        assert v[2] == 1
919        assert v[3] == 10
920
921        os.remove('test1.png')
922        os.remove('test2.png')
923
924       
925    def test_inside_polygon_geospatial(self):
926
927
928        polygon_absolute = [[0,0], [1,0], [1,1], [0,1]]
929        poly_geo_ref = Geo_reference(57,100,100)
930       
931
932
933
934        #Simplest case: Polygon is the unit square
935        polygon_absolute = [[0,0], [1,0], [1,1], [0,1]]
936        poly_geo_ref = Geo_reference(57,100,100)
937        polygon = poly_geo_ref.change_points_geo_ref(polygon_absolute)
938        poly_spatial = Geospatial_data(polygon,
939                                       geo_reference=poly_geo_ref)
940       
941        points_absolute = (0.5, 0.5)
942        points_geo_ref = Geo_reference(57,78,-56)
943        points = points_geo_ref.change_points_geo_ref(points_absolute)
944        points_spatial = Geospatial_data(points,
945                                         geo_reference=points_geo_ref) 
946       
947        assert is_inside_polygon(points_absolute, polygon_absolute)
948        assert is_inside_polygon(ensure_numeric(points_absolute),
949                                 ensure_numeric(polygon_absolute))
950        assert is_inside_polygon(points_absolute, poly_spatial)
951        assert is_inside_polygon(points_spatial, poly_spatial)
952        assert is_inside_polygon(points_spatial, polygon_absolute)
953
954        assert is_inside_polygon(points_absolute, polygon_absolute)
955
956
957    def NOtest_decimate_polygon(self):
958
959        polygon = [[0,0], [10,10], [15,5], [20, 10],
960                   [25,0], [30,10], [40,-10], [35, -5]]
961
962        #plot_polygons([polygon], figname='test')
963       
964        dpoly = decimate_polygon(polygon, factor=2)
965
966        print dpoly
967       
968        assert len(dpoly)*2==len(polygon)
969
970        minx = maxx = polygon[0][0]
971        miny = maxy = polygon[0][1]
972        for point in polygon[1:]:
973            x, y = point
974           
975            if x < minx: minx = x
976            if x > maxx: maxx = x
977            if y < miny: miny = y
978            if y > maxy: maxy = y
979           
980
981        assert [minx, miny] in polygon
982        print minx, maxy
983        assert [minx, maxy] in polygon
984        assert [maxx, miny] in polygon
985        assert [maxx, maxy] in polygon               
986       
987
988       
989#-------------------------------------------------------------
990if __name__ == "__main__":
991    suite = unittest.makeSuite(Test_Polygon,'test')
992    #suite = unittest.makeSuite(Test_Polygon,'test_inside_polygon_geo_ref')
993    runner = unittest.TextTestRunner()
994    runner.run(suite)
995
996
997
998
Note: See TracBrowser for help on using the repository browser.