diff --git a/django/contrib/gis/db/backend/spatialite/__init__.py b/django/contrib/gis/db/backend/spatialite/__init__.py index 7010025e39..f26c96bd8e 100644 --- a/django/contrib/gis/db/backend/spatialite/__init__.py +++ b/django/contrib/gis/db/backend/spatialite/__init__.py @@ -47,6 +47,7 @@ SpatialBackend = BaseSpatialBackend(name='spatialite', spatialite=True, point_on_surface=POINT_ON_SURFACE, scale=SCALE, select=GEOM_SELECT, + svg=ASSVG, sym_difference=SYM_DIFFERENCE, transform=TRANSFORM, translate=TRANSLATE, diff --git a/django/contrib/gis/db/backend/spatialite/query.py b/django/contrib/gis/db/backend/spatialite/query.py index dea6420b70..462722fa5d 100644 --- a/django/contrib/gis/db/backend/spatialite/query.py +++ b/django/contrib/gis/db/backend/spatialite/query.py @@ -17,6 +17,7 @@ def get_func(str): # Functions used by the GeoManager & GeoQuerySet AREA = get_func('Area') +ASSVG = get_func('AsSVG') CENTROID = get_func('Centroid') CONTAINED = get_func('MbrWithin') DIFFERENCE = get_func('Difference') diff --git a/django/contrib/gis/db/models/query.py b/django/contrib/gis/db/models/query.py index 13e15721a8..25ea1aca71 100644 --- a/django/contrib/gis/db/models/query.py +++ b/django/contrib/gis/db/models/query.py @@ -275,15 +275,26 @@ class GeoQuerySet(QuerySet): return self._spatial_attribute('snap_to_grid', s, **kwargs) - def svg(self, **kwargs): + def svg(self, relative=False, precision=8, **kwargs): """ Returns SVG representation of the geographic field in a `svg` attribute on each element of this GeoQuerySet. + + Keyword Arguments: + `relative` => If set to True, this will evaluate the path in + terms of relative moves (rather than absolute). + + `precision` => May be used to set the maximum number of decimal + digits used in output (defaults to 8). """ + relative = int(bool(relative)) + if not isinstance(precision, (int, long)): + raise TypeError('SVG precision keyword argument must be an integer.') s = {'desc' : 'SVG', 'procedure_fmt' : '%(geo_col)s,%(rel)s,%(precision)s', - 'procedure_args' : {'rel' : int(kwargs.pop('relative', 0)), - 'precision' : kwargs.pop('precision', 8)}, + 'procedure_args' : {'rel' : relative, + 'precision' : precision, + } } return self._spatial_attribute('svg', s, **kwargs) diff --git a/django/contrib/gis/tests/geoapp/tests.py b/django/contrib/gis/tests/geoapp/tests.py index 53986ad7aa..f756f6222c 100644 --- a/django/contrib/gis/tests/geoapp/tests.py +++ b/django/contrib/gis/tests/geoapp/tests.py @@ -196,6 +196,19 @@ class GeoModelTest(unittest.TestCase): # Finally, we set every available keyword. self.assertEqual(City.objects.geojson(bbox=True, crs=True, precision=5).get(name='Chicago').geojson, json) + @no_oracle + def test03d_svg(self): + "Testing SVG output using GeoQuerySet.svg()." + if DISABLE: return + self.assertRaises(TypeError, City.objects.svg, precision='foo') + # SELECT AsSVG(geoapp_city.point, 0, 8) FROM geoapp_city WHERE name = 'Pueblo'; + svg1 = 'cx="-104.609252" cy="-38.255001"' + # Even though relative, only one point so it's practically the same except for + # the 'c' letter prefix on the x,y values. + svg2 = svg1.replace('c', '') + self.assertEqual(svg1, City.objects.svg().get(name='Pueblo').svg) + self.assertEqual(svg2, City.objects.svg(relative=5).get(name='Pueblo').svg) + def test04_transform(self): "Testing the transform() GeoManager method." if DISABLE: return @@ -499,10 +512,8 @@ class GeoModelTest(unittest.TestCase): union = union1 self.assertEqual(True, union.equals_exact(u1, tol)) self.assertEqual(True, union.equals_exact(u2, tol)) - # SpatiaLite will segfault trying to union a NULL geometry. - if not SpatialBackend.spatialite: - qs = City.objects.filter(name='NotACity') - self.assertEqual(None, qs.unionagg(field_name='point')) + qs = City.objects.filter(name='NotACity') + self.assertEqual(None, qs.unionagg(field_name='point')) @no_spatialite # SpatiaLite does not support abstract geometry columns def test18_geometryfield(self):