Refs #17635 -- Tested the Cast function in a geography to geometry context

Thanks Tim Graham for the review.
This commit is contained in:
Claude Paroz 2016-04-10 19:55:29 +02:00
parent 1c30a6473d
commit 1ee9c5b4a9
2 changed files with 30 additions and 0 deletions

View File

@ -235,6 +235,18 @@ available for geography columns:
* :lookup:`covers` * :lookup:`covers`
* :lookup:`intersects` * :lookup:`intersects`
If you need to use a spatial lookup or aggregate that doesn't support the
geography type as input, you can use the
:class:`~django.db.models.functions.Cast` database function to convert the
geography column to a geometry type in the query::
from django.contrib.gis.db.models import PointField
from django.db.models.functions import Cast
Zipcode.objects.annotate(
geom=Cast('geography_field', PointField())
).filter(geom__within=poly)
For more information, the PostGIS documentation contains a helpful section on For more information, the PostGIS documentation contains a helpful section on
determining `when to use geography data type over geometry data type determining `when to use geography data type over geometry data type
<http://postgis.net/docs/manual-2.1/using_postgis_dbmanagement.html#PostGIS_GeographyVSGeometry>`_. <http://postgis.net/docs/manual-2.1/using_postgis_dbmanagement.html#PostGIS_GeographyVSGeometry>`_.

View File

@ -6,9 +6,12 @@ from __future__ import unicode_literals
import os import os
from unittest import skipUnless from unittest import skipUnless
from django.contrib.gis.db import models
from django.contrib.gis.db.models.functions import Area, Distance from django.contrib.gis.db.models.functions import Area, Distance
from django.contrib.gis.gdal import HAS_GDAL from django.contrib.gis.gdal import HAS_GDAL
from django.contrib.gis.measure import D from django.contrib.gis.measure import D
from django.db import connection
from django.db.models.functions import Cast
from django.test import TestCase, ignore_warnings, skipUnlessDBFeature from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
from django.utils._os import upath from django.utils._os import upath
from django.utils.deprecation import RemovedInDjango20Warning from django.utils.deprecation import RemovedInDjango20Warning
@ -113,6 +116,21 @@ class GeographyTest(TestCase):
class GeographyFunctionTests(TestCase): class GeographyFunctionTests(TestCase):
fixtures = ['initial'] fixtures = ['initial']
@skipUnlessDBFeature("supports_extent_aggr")
def test_cast_aggregate(self):
"""
Cast a geography to a geometry field for an aggregate function that
expects a geometry input.
"""
if not connection.ops.geography:
self.skipTest("This test needs geography support")
expected = (-96.8016128540039, 29.7633724212646, -95.3631439208984, 32.782058715820)
res = City.objects.filter(
name__in=('Houston', 'Dallas')
).aggregate(extent=models.Extent(Cast('point', models.PointField())))
for val, exp in zip(res['extent'], expected):
self.assertAlmostEqual(exp, val, 4)
@skipUnlessDBFeature("has_Distance_function", "supports_distance_geodetic") @skipUnlessDBFeature("has_Distance_function", "supports_distance_geodetic")
def test_distance_function(self): def test_distance_function(self):
""" """