def test_make_line(self): """ Testing the (deprecated) `make_line` GeoQuerySet method and the MakeLine aggregate. """ if not connection.features.supports_make_line_aggr: # Only PostGIS has support for the MakeLine aggregate. For other # backends, test that NotImplementedError is raised self.assertRaises( NotImplementedError, City.objects.all().aggregate, MakeLine('point') ) return # Ensuring that a `TypeError` is raised on models without PointFields. self.assertRaises(TypeError, State.objects.make_line) self.assertRaises(TypeError, Country.objects.make_line) # MakeLine on an inappropriate field returns simply None self.assertIsNone(State.objects.aggregate(MakeLine('poly'))['poly__makeline']) # Reference query: # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; ref_line = GEOSGeometry( 'LINESTRING(-95.363151 29.763374,-96.801611 32.782057,' '-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,' '-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326 ) # We check for equality with a tolerance of 10e-5 which is a lower bound # of the precisions of ref_line coordinates line1 = City.objects.make_line() line2 = City.objects.aggregate(MakeLine('point'))['point__makeline'] for line in (line1, line2): self.assertTrue(ref_line.equals_exact(line, tolerance=10e-5), "%s != %s" % (ref_line, line))
def test_make_line(self): """ Testing the `MakeLine` aggregate. """ if not connection.features.supports_make_line_aggr: with self.assertRaises(NotImplementedError): City.objects.all().aggregate(MakeLine('point')) return # MakeLine on an inappropriate field returns simply None self.assertIsNone(State.objects.aggregate(MakeLine('poly'))['poly__makeline']) # Reference query: # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; ref_line = GEOSGeometry( 'LINESTRING(-95.363151 29.763374,-96.801611 32.782057,' '-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,' '-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326 ) # We check for equality with a tolerance of 10e-5 which is a lower bound # of the precisions of ref_line coordinates line = City.objects.aggregate(MakeLine('point'))['point__makeline'] self.assertTrue( ref_line.equals_exact(line, tolerance=10e-5), "%s != %s" % (ref_line, line) )
def test_srid(self): "Testing GeometryField with a SRID set." # Input that doesn't specify the SRID is assumed to be in the SRID # of the input field. fld = forms.GeometryField(srid=4326) geom = fld.clean("POINT(5 23)") self.assertEqual(4326, geom.srid) # Making the field in a different SRID from that of the geometry, and # asserting it transforms. fld = forms.GeometryField(srid=32140) tol = 0.0000001 xform_geom = GEOSGeometry("POINT (951640.547328465 4219369.26171664)", srid=32140) # The cleaned geometry should be transformed to 32140. cleaned_geom = fld.clean("SRID=4326;POINT (-95.363151 29.763374)") self.assertTrue(xform_geom.equals_exact(cleaned_geom, tol))
def test_make_line(self): "Testing the `make_line` GeoQuerySet method." # Ensuring that a `TypeError` is raised on models without PointFields. self.assertRaises(TypeError, State.objects.make_line) self.assertRaises(TypeError, Country.objects.make_line) # Reference query: # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; ref_line = GEOSGeometry( 'LINESTRING(-95.363151 29.763374,-96.801611 32.782057,' '-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,' '-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326 ) # We check for equality with a tolerance of 10e-5 which is a lower bound # of the precisions of ref_line coordinates self.assertTrue(ref_line.equals_exact(City.objects.make_line(), tolerance=10e-5))
def test_srid(self): "Testing GeometryField with a SRID set." # Input that doesn't specify the SRID is assumed to be in the SRID # of the input field. fld = forms.GeometryField(srid=4326) geom = fld.clean('POINT(5 23)') self.assertEqual(4326, geom.srid) # Making the field in a different SRID from that of the geometry, and # asserting it transforms. fld = forms.GeometryField(srid=32140) tol = 0.0000001 xform_geom = GEOSGeometry('POINT (951640.547328465 4219369.26171664)', srid=32140) # The cleaned geometry is transformed to 32140 (the widget map_srid is 3857). cleaned_geom = fld.clean('SRID=3857;POINT (-10615777.40976205 3473169.895707852)') self.assertEqual(cleaned_geom.srid, 32140) self.assertTrue(xform_geom.equals_exact(cleaned_geom, tol))
def _has_changed(self, initial, data): """ Compare geographic value of data with its initial value. """ # Ensure we are dealing with a geographic object if isinstance(initial, six.string_types): try: initial = GEOSGeometry(initial) except (GEOSException, ValueError): initial = None # Only do a geographic comparison if both values are available if initial and data: data = fromstr(data) data.transform(initial.srid) # If the initial value was not added by the browser, the geometry # provided may be slightly different, the first time it is saved. # The comparison is done with a very low tolerance. return not initial.equals_exact(data, tolerance=0.000001) else: # Check for change of state of existence return bool(initial) != bool(data)
def test_unionagg_tolerance(self): City.objects.create( point=fromstr('POINT(-96.467222 32.751389)', srid=4326), name='Forney', ) tx = Country.objects.get(name='Texas').mpoly # Tolerance is greater than distance between Forney and Dallas, that's # why Dallas is ignored. forney_houston = GEOSGeometry( 'MULTIPOINT(-95.363151 29.763374, -96.467222 32.751389)', srid=4326, ) self.assertIs( forney_houston.equals_exact( City.objects.filter(point__within=tx).aggregate( Union('point', tolerance=32000), )['point__union'], tolerance=10e-6, ), True, )
def test_GeometryField_filtering(self): """Checks that the GeometryField allows sane filtering.""" self.assertEqual(Location.objects.count(), 0) treasure_island = Location() treasure_island.name = "Treasure Island" treasure_island.geometry = self.treasure_island_geom treasure_island.full_clean() treasure_island.save() ggpark = Location() ggpark.name = "Golden Gate Park" ggpark.geometry = self.ggpark_geom ggpark.save() point_inside_ggpark_geojson = """ { "type": "Point", "coordinates": [ -122.49034881591797, 37.76949349270407 ] } """ try: quoted_param = urllib.quote(point_inside_ggpark_geojson) except AttributeError: quoted_param = urllib.parse.quote(point_inside_ggpark_geojson) url_params = "?contains_properly=%s" % (quoted_param, ) response = self.client.get('{0}{1}'.format( self.geojson_contained_in_geometry, url_params)) self.assertEqual(len(response.data), 1) geometry_response = GEOSGeometry( json.dumps(response.data[0]['geometry'])) self.assertTrue(geometry_response.equals_exact(self.ggpark_geom)) self.assertEqual(response.data[0]['name'], ggpark.name) # try without any param, should return both response = self.client.get(self.geojson_contained_in_geometry) self.assertEqual(len(response.data), 2)
def test_make_line(self): """ Testing the `MakeLine` aggregate. """ if not connection.features.supports_make_line_aggr: with self.assertRaises(NotSupportedError): City.objects.all().aggregate(MakeLine('point')) return # MakeLine on an inappropriate field returns simply None self.assertIsNone( State.objects.aggregate(MakeLine('poly'))['poly__makeline']) # Reference query: # SELECT AsText(ST_MakeLine(geoapp_city.point)) FROM geoapp_city; ref_line = GEOSGeometry( 'LINESTRING(-95.363151 29.763374,-96.801611 32.782057,' '-97.521157 34.464642,174.783117 -41.315268,-104.609252 38.255001,' '-95.23506 38.971823,-87.650175 41.850385,-123.305196 48.462611)', srid=4326) # We check for equality with a tolerance of 10e-5 which is a lower bound # of the precisions of ref_line coordinates line = City.objects.aggregate(MakeLine('point'))['point__makeline'] self.assertTrue(ref_line.equals_exact(line, tolerance=10e-5), "%s != %s" % (ref_line, line))
def test_GeometryField_filtering(self): """ Checks that the GeometryField allows sane filtering. """ self.assertEqual(Location.objects.count(), 0) treasure_island_geojson = """{ "type": "Polygon", "coordinates": [ [ [ -122.44640350341795, 37.86103094116189 ], [ -122.44262695312501, 37.85506751416839 ], [ -122.43481636047363, 37.853305500228025 ], [ -122.42975234985352, 37.854660899304704 ], [ -122.41953849792479, 37.852627791344894 ], [ -122.41807937622069, 37.853305500228025 ], [ -122.41868019104004, 37.86211514878027 ], [ -122.42391586303711, 37.870584971740065 ], [ -122.43035316467285, 37.8723465726078 ], [ -122.43515968322752, 37.86963639998042 ], [ -122.43953704833984, 37.86882332875222 ], [ -122.44640350341795, 37.86103094116189 ] ] ] }""" treasure_island_geom = GEOSGeometry(treasure_island_geojson) treasure_island = Location() treasure_island.name = "Treasure Island" treasure_island.geometry = treasure_island_geom treasure_island.full_clean() treasure_island.save() ggpark_geojson = """{ "type": "Polygon", "coordinates": [ [ [ -122.5111198425293, 37.77125750792944 ], [ -122.51026153564452, 37.76447260365713 ], [ -122.45309829711913, 37.76677954095475 ], [ -122.45481491088867, 37.77424266859531 ], [ -122.5111198425293, 37.77125750792944 ] ] ] }""" ggpark_geom = GEOSGeometry(ggpark_geojson) ggpark = Location() ggpark.name = "Golden Gate Park" ggpark.geometry = ggpark_geom ggpark.save() point_inside_ggpark_geojson = """{ "type": "Point", "coordinates": [ -122.49034881591797, 37.76949349270407 ] }""" try: quoted_param = urllib.quote(point_inside_ggpark_geojson) except AttributeError: quoted_param = urllib.parse.quote(point_inside_ggpark_geojson) url_params = "?contains_properly=%s" % quoted_param response = self.client.get(self.geojson_contained_in_geometry + url_params) self.assertEqual(len(response.data), 1) geometry_response = GEOSGeometry(json.dumps(response.data[0]['geometry'])) self.assertTrue(geometry_response.equals_exact(ggpark_geom)) self.assertEqual(response.data[0]['name'], ggpark.name) # try without any param, should return both response = self.client.get(self.geojson_contained_in_geometry) self.assertEqual(len(response.data), 2)
def test_GeometryField_filtering(self): """ Checks that the GeometryField allows sane filtering. """ self.assertEqual(Location.objects.count(), 0) treasure_island_geojson = """{ "type": "Polygon", "coordinates": [ [ [ -122.44640350341795, 37.86103094116189 ], [ -122.44262695312501, 37.85506751416839 ], [ -122.43481636047363, 37.853305500228025 ], [ -122.42975234985352, 37.854660899304704 ], [ -122.41953849792479, 37.852627791344894 ], [ -122.41807937622069, 37.853305500228025 ], [ -122.41868019104004, 37.86211514878027 ], [ -122.42391586303711, 37.870584971740065 ], [ -122.43035316467285, 37.8723465726078 ], [ -122.43515968322752, 37.86963639998042 ], [ -122.43953704833984, 37.86882332875222 ], [ -122.44640350341795, 37.86103094116189 ] ] ] }""" treasure_island_geom = GEOSGeometry(treasure_island_geojson) treasure_island = Location() treasure_island.name = "Treasure Island" treasure_island.geometry = treasure_island_geom treasure_island.full_clean() treasure_island.save() ggpark_geojson = """{ "type": "Polygon", "coordinates": [ [ [ -122.5111198425293, 37.77125750792944 ], [ -122.51026153564452, 37.76447260365713 ], [ -122.45309829711913, 37.76677954095475 ], [ -122.45481491088867, 37.77424266859531 ], [ -122.5111198425293, 37.77125750792944 ] ] ] }""" ggpark_geom = GEOSGeometry(ggpark_geojson) ggpark = Location() ggpark.name = "Golden Gate Park" ggpark.geometry = ggpark_geom ggpark.save() point_inside_ggpark_geojson = """{ "type": "Point", "coordinates": [ -122.49034881591797, 37.76949349270407 ] }""" try: quoted_param = urllib.quote(point_inside_ggpark_geojson) except AttributeError: quoted_param = urllib.parse.quote(point_inside_ggpark_geojson) url_params = "?contains_properly=%s" % quoted_param response = self.client.get('{0}{1}'.format( self.geojson_contained_in_geometry, url_params)) self.assertEqual(len(response.data), 1) geometry_response = GEOSGeometry( json.dumps(response.data[0]['geometry'])) self.assertTrue(geometry_response.equals_exact(ggpark_geom)) self.assertEqual(response.data[0]['name'], ggpark.name) # try without any param, should return both response = self.client.get(self.geojson_contained_in_geometry) self.assertEqual(len(response.data), 2)