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:`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
determining `when to use geography data type over geometry data type
<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
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.gdal import HAS_GDAL
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.utils._os import upath
from django.utils.deprecation import RemovedInDjango20Warning
@ -113,6 +116,21 @@ class GeographyTest(TestCase):
class GeographyFunctionTests(TestCase):
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")
def test_distance_function(self):
"""