Package madrona :: Package manipulators :: Module tests
[hide private]

Source Code for Module madrona.manipulators.tests

  1  from django.test import TestCase 
  2  from django.test.client import Client 
  3  from django.conf import settings 
  4  from django.conf.urls.defaults import * 
  5  from django.contrib.gis.geos import * 
  6  from madrona.studyregion.models import StudyRegion 
  7  from django.core import serializers  
  8  from manipulators import *       
  9  from madrona.features.models import Feature, PointFeature, LineFeature, PolygonFeature, FeatureCollection 
 10  from madrona.features.forms import FeatureForm 
 11  from madrona.features import register 
 12  from django.contrib.auth.models import User 
 13  from django.test.utils import override_settings 
 14  import json 
 15  import re 
16 17 # set up some test manipulators 18 -class TestManipulator(BaseManipulator):
19 """ 20 This manipulator does nothing but ensure the geometry is clean. 21 """
22 - def __init__(self, target_shape, **kwargs):
24
25 - def manipulate(self):
26 target_shape = self.target_to_valid_geom(self.target_shape) 27 status_html = self.do_template("0") 28 return self.result(target_shape, status_html)
29
30 - class Options(BaseManipulator.Options):
31 name = 'TestManipulator' 32 supported_geom_fields = ['PolygonField'] 33 html_templates = {'0':'manipulators/valid.html', }
34 35 manipulatorsDict[TestManipulator.Options.name] = TestManipulator
36 37 -class ManipulatorsTest(TestCase):
38 fixtures = ['manipulators_test_data'] 39
40 - def setUp(self):
41 ''' 42 Build geometries for the following test cases: 43 code0_poly clips successfully 44 code1_poly overlaps with estuary, oceanic part chosen 45 code2_poly target geometry lies outside of geometry being clipped against 46 or in the case of Estuary clipping, no estuaries were found to clip against 47 code3_poly target geometry is not valid 48 code4_poly this code has the most meanings, each depending on context 49 in the case of Estuary clipping, it means the target was estuary only 50 code5_poly overlaps with estuary, estuary part chosen 51 other case one or more required kwargs not provided 52 ''' 53 54 self.code0_poly = fromstr('SRID=4326;POLYGON ((-1 -1, 1 -1, 1 -3, -1 -3, -1 -1))') # area = 4 55 self.code1_poly = fromstr('SRID=4326;POLYGON ((-1 1, 1 1, 1 -1, -1 -1, -1 1))') # area = 4 56 self.code2_poly = fromstr('SRID=4326;POLYGON ((3 3, 4 3, 4 4, 3 4, 3 3))') # area = 1 57 self.code3_poly = fromstr('SRID=4326;POLYGON ((3 3, 4 3, 3 4, 4 4, 3 3))') # area = 0 58 self.code4_poly = fromstr('SRID=4326;POLYGON ((0 2, 1 0, 2 2, 0 2))') # area = 2 59 self.code5_poly = fromstr('SRID=4326;POLYGON ((0 2, 2 2, 2 1, 0 1, 0 2))') # area = 2 60 61 self.study_region = fromstr('SRID=4326;POLYGON ((-2 2, 2 2, 2 -2, -2 -2, -2 2))') 62 63 self.est1 = fromstr('SRID=4326;POLYGON ((0 2, 1 0, 2 2, 0 2))') # same as code4_poly 64 self.est2 = fromstr('SRID=4326;POLYGON ((0 2, -1 0, -2 2, 0 2))') # est1.area == est2.area == 2 65 self.ests = MultiPolygon(self.est1, self.est2) 66 67 self.client = Client()
68
69 - def tearDown(self):
70 71 self.code0_poly = None 72 self.code1_poly = None 73 self.code2_poly = None 74 self.code3_poly = None 75 self.code4_poly = None 76 self.code5_poly = None 77 78 self.study_region = None 79 80 self.est1 = None 81 self.est2 = None 82 self.ests = None 83 84 self.client = None
85 86 @override_settings(GEOMETRY_CLIENT_SRID=4326)
87 - def test_clipToGraticule(self):
88 ''' 89 Tests the following: 90 clip to graticule 91 ''' 92 #clip to graticule test 93 response1 = self.client.post('/manipulators/ClipToGraticule/', {'target_shape': display_kml(self.code1_poly), 'west': .5, 'east': -.5}) 94 self.assertEquals(response1.status_code, 200) 95 graticule_clipper = ClipToGraticuleManipulator(target_shape=display_kml(self.code1_poly), west=.5, east=-.5) 96 result = graticule_clipper.manipulate() 97 gclip = result['clipped_shape'] 98 self.assertAlmostEquals(result["clipped_shape"].area, 2, places=1)
99 100 @override_settings(GEOMETRY_CLIENT_SRID=4326)
101 - def test_clipToStudyRegion(self):
102 ''' 103 Tests the following: 104 clipped to study region 105 outside study region 106 geometry not valid 107 ''' 108 #clip to study region 109 response0 = self.client.post('/manipulators/ClipToStudyRegion/', {'target_shape': display_kml(self.code0_poly), 'study_region': self.study_region.wkt}) 110 self.assertEquals(response0.status_code, 200) 111 studyregion_clipper = ClipToStudyRegionManipulator(target_shape=display_kml(self.code0_poly), study_region=self.study_region) 112 result = studyregion_clipper.manipulate() 113 self.assertAlmostEquals(result["clipped_shape"].area, 2, places=1) 114 115 #outside study region 116 response2 = self.client.post('/manipulators/ClipToStudyRegion/', {'target_shape': display_kml(self.code2_poly), 'study_region': self.study_region.wkt}) 117 self.assertEquals(response2.status_code, 200) 118 try: 119 graticule_clipper = ClipToStudyRegionManipulator(target_shape=display_kml(self.code2_poly)) 120 except HaltManipulations: 121 pass 122 123 #geometry not valid 124 response3 = self.client.post('/manipulators/ClipToStudyRegion/', {'target_shape': display_kml(self.code3_poly), 'study_region': self.study_region.wkt}) 125 self.assertEquals(response3.status_code, 200) 126 try: 127 graticule_clipper = ClipToStudyRegionManipulator(target_shape=display_kml(self.code3_poly)) 128 except InvalidGeometryException: 129 pass
130
132 ''' 133 Tests the following: 134 clip to study region and clip to estuaries manipulations 135 clip to study region and clip to graticules manipulations 136 137 ''' 138 #clip to study region and estuaries test 139 response1 = self.client.post('/manipulators/ClipToStudyRegion,ClipToEstuaries/', {'target_shape': display_kml(self.code1_poly)}) 140 self.assertEquals(response1.status_code, 200) 141 #clip to study region and clip to graticules test 142 response1 = self.client.post('/manipulators/ClipToStudyRegion,ClipToGraticule/', {'target_shape': display_kml(self.code1_poly), 'east': .5}) 143 self.assertEquals(response1.status_code, 200)
144
145 - def test_studyregion(self):
146 ''' 147 Tests the following: 148 clipped to study region 149 ''' 150 study_region = StudyRegion.objects.current().geometry 151 152 w = study_region.extent[0] 153 s = study_region.extent[1] 154 e = study_region.extent[2] 155 n = study_region.extent[3] 156 157 center_lat = study_region.centroid.y 158 center_lon = study_region.centroid.x 159 160 target_shape = Polygon(LinearRing([Point(center_lon, center_lat), 161 Point(e, center_lat), 162 Point(e, s), 163 Point(center_lon, s), 164 Point(center_lon, center_lat)])) 165 target_shape.set_srid(settings.GEOMETRY_DB_SRID) 166 target_shape.transform(settings.GEOMETRY_CLIENT_SRID) 167 168 #clip to study region 169 response0 = self.client.post('/manipulators/ClipToStudyRegion/', {'target_shape': display_kml(target_shape)}) 170 self.assertEquals(response0.status_code, 200)
171
172 @register 173 -class TestPoly(PolygonFeature):
174 type = models.CharField(max_length=1) 175
176 - class Options:
177 verbose_name = 'Test Poly' 178 form = 'madrona.manipulators.tests.TestPolyForm' 179 manipulators = ['madrona.manipulators.manipulators.ClipToStudyRegionManipulator']
180 -class TestPolyForm(FeatureForm):
181 - class Meta:
183
184 @register 185 -class TestOptmanip(PolygonFeature):
186 type = models.CharField(max_length=1) 187
188 - class Options:
189 verbose_name = 'Feature to Test Optional Manipulators' 190 form = 'madrona.manipulators.tests.TestOptmanipForm' 191 optional_manipulators = ['madrona.manipulators.manipulators.ClipToStudyRegionManipulator'] 192 manipulators = []
193
194 -class TestOptmanipForm(FeatureForm):
195 - class Meta(FeatureForm.Meta):
197
198 @register 199 -class TestLine(LineFeature):
200 type = models.CharField(max_length=1) 201 diameter = models.FloatField(null=True) 202
203 - class Options:
204 verbose_name = 'TestLine' 205 form = 'madrona.manipulators.tests.TestLineForm' 206 manipulators = ['madrona.manipulators.manipulators.ClipToStudyRegionManipulator']
207 -class TestLineForm(FeatureForm):
208 - class Meta:
210
211 @register 212 -class TestPoint(PointFeature):
213 incident = models.CharField(max_length=1) 214
215 - class Options:
216 verbose_name = 'TestPoint' 217 form = 'madrona.manipulators.tests.TestPointForm' 218 manipulators = ['madrona.manipulators.manipulators.ClipToStudyRegionManipulator']
219 -class TestPointForm(FeatureForm):
220 - class Meta:
222
223 -class FeaturesManipulatorTest(TestCase):
224 fixtures = ['example_data'] 225
226 - def setUp(self):
227 self.client = Client() 228 self.user = User.objects.create_user( 229 'featuretest', 'featuretest@madrona.org', password='pword') 230 self.client.login(username='featuretest', password='pword')
231
232 - def test_point_outside(self):
233 from madrona.manipulators.manipulators import ClipToStudyRegionManipulator as csrm 234 with self.assertRaisesRegexp(csrm.HaltManipulations, 'empty'): 235 g = GEOSGeometry('SRID=4326;POINT(-100.45 14.32)') 236 g.transform(settings.GEOMETRY_DB_SRID) 237 feature = TestPoint(user=self.user, name="Outside Region", geometry_orig=g) 238 feature.save()
239
240 - def test_studyregion_point(self):
241 g = GEOSGeometry('SRID=4326;POINT(-119.82 34.404)') 242 g.transform(settings.GEOMETRY_DB_SRID) 243 feature = TestPoint(user=self.user, name="Nearby Wreck", geometry_orig=g) 244 feature.save() 245 self.assertAlmostEquals(g[0], feature.geometry_final[0]) 246 self.assertAlmostEquals(g[1], feature.geometry_final[1])
247
249 # all in 250 g = GEOSGeometry('SRID=4326;LINESTRING(-120.234 34.46, -120.152 34.454)') 251 g.transform(settings.GEOMETRY_DB_SRID) 252 feature = TestLine(user=self.user, name="My Pipeline", geometry_orig=g) 253 feature.save() 254 # floating point imprecission .. can't do this 255 # self.assertTrue(g.equals(feature.geometry_final)) 256 self.assertAlmostEquals(g[1][0], feature.geometry_final[1][0]) 257 self.assertAlmostEquals(g[1][1], feature.geometry_final[1][1])
258
260 # partial 261 g = GEOSGeometry('SRID=4326;LINESTRING(-120.234 34.46, -120.162 34.547)') 262 g.transform(settings.GEOMETRY_DB_SRID) 263 feature = TestLine(user=self.user, name="My Pipeline", geometry_orig=g) 264 feature.save() 265 clip = GEOSGeometry('SRID=3310;LINESTRING (-21492.0524731723162404 -395103.6204170039854944, -20676.0969509799033403 -393916.9388333586975932)') 266 clip.transform(settings.GEOMETRY_DB_SRID) 267 # use a 2.0 delta to accoutn for projection oddities 268 self.assertAlmostEquals(clip[1][0], feature.geometry_final[1][0], delta=2.0) 269 self.assertAlmostEquals(clip[1][1], feature.geometry_final[1][1], delta=2.0)
270
272 # all in 273 g = GEOSGeometry('SRID=4326;POLYGON((-120.161 34.441, -120.144 34.458, -120.186 34.455, -120.161 34.441))') 274 g.transform(settings.GEOMETRY_DB_SRID) 275 feature = TestPoly(user=self.user, name="My Mpa", geometry_orig=g) 276 feature.save() 277 self.assertAlmostEquals(g.area, feature.geometry_final.area, 2)
278
280 #partial 281 g = GEOSGeometry('SRID=4326;POLYGON((-120.234 34.46, -120.152 34.454, -120.162 34.547, -120.234 34.46))') 282 g.transform(settings.GEOMETRY_DB_SRID) 283 feature = TestPoly(user=self.user, name="My Mpa", geometry_orig=g) 284 feature.save() 285 self.assertNotAlmostEquals(g.area, feature.geometry_final.area)
286
287 - def test_optional_manip_form(self):
288 # TestPoly should NOT have any optional manipulators defined 289 options = TestPoly.get_options() 290 response = self.client.get(options.get_create_form()) 291 self.assertEqual(response.status_code, 200) 292 self.assertNotRegexpMatches(response.content, r'optional_manipulators') 293 294 # get the form and confirm that it allows cliptostudyregion as optional manip 295 options = TestOptmanip.get_options() 296 response = self.client.get(options.get_create_form()) 297 self.assertEqual(response.status_code, 200) 298 self.assertRegexpMatches(response.content, r'optional_manipulators') 299 self.assertRegexpMatches(response.content, r'ClipToStudyRegion')
300
301 - def test_optional_manip(self):
302 # partial polygon 303 g = GEOSGeometry('SRID=4326;POLYGON((-120.234 34.46, -120.152 34.454, -120.162 34.547, -120.234 34.46))') 304 g.transform(settings.GEOMETRY_DB_SRID) 305 306 # Next, POST to manipulators url with no manipulators specified; should get original geom back 307 response = self.client.post('/manipulators//', {'target_shape': display_kml(g)}) 308 self.assertEqual(response.status_code, 200, response.content) 309 kml = json.loads(response.content)['final_shape_kml'] 310 search = re.search('<coordinates>(.*)</coordinates>', kml) 311 coords = search.groups()[0] 312 coords_count = coords.count(',') / 2 # number of coordinates in final geom 313 self.assertEqual(coords_count, g.num_coords, coords) 314 315 # Next, POST to manipulators url with ClipToStudyRegionManipulator specified; should get clipped geom back 316 response = self.client.post('/manipulators/ClipToStudyRegion/', {'target_shape': display_kml(g)}) 317 self.assertEqual(response.status_code, 200, response.content) 318 kml = json.loads(response.content)['final_shape_kml'] 319 search = re.search('<coordinates>(.*)</coordinates>', kml) 320 coords = search.groups()[0] 321 coords_count = coords.count(',') / 2 322 self.assertGreater(coords_count, g.num_coords)
323