Fixed #27607 -- Added Oracle support for AsGML GIS function.

This commit is contained in:
Sergey Fedoseev 2016-12-16 01:00:08 +06:00 committed by Tim Graham
parent d2a26c1a90
commit 5a23cc00f5
6 changed files with 26 additions and 17 deletions

View File

@ -132,8 +132,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
truncate_params = {'relate': None}
unsupported_functions = {
'AsGeoJSON', 'AsGML', 'AsKML', 'AsSVG',
'BoundingCircle', 'Envelope',
'AsGeoJSON', 'AsKML', 'AsSVG', 'BoundingCircle', 'Envelope',
'ForceRHR', 'GeoHash', 'MakeValid', 'MemSize', 'Scale',
'SnapToGrid', 'Translate',
}

View File

@ -38,12 +38,12 @@ class GeoFunc(Func):
except (AttributeError, FieldError):
return None
def as_sql(self, compiler, connection):
def as_sql(self, compiler, connection, **extra_context):
if self.function is None:
self.function = connection.ops.spatial_function_name(self.name)
if any(isinstance(field, RasterField) for field in self.get_source_fields()):
raise TypeError("Geometry functions not supported for raster fields.")
return super(GeoFunc, self).as_sql(compiler, connection)
return super(GeoFunc, self).as_sql(compiler, connection, **extra_context)
def resolve_expression(self, *args, **kwargs):
res = super(GeoFunc, self).resolve_expression(*args, **kwargs)
@ -172,6 +172,14 @@ class AsGML(GeoFunc):
expressions.append(self._handle_param(precision, 'precision', six.integer_types))
super(AsGML, self).__init__(*expressions, **extra)
def as_oracle(self, compiler, connection, **extra_context):
source_expressions = self.get_source_expressions()
version = source_expressions[0]
clone = self.copy()
clone.set_source_expressions([source_expressions[1]])
extra_context['function'] = 'SDO_UTIL.TO_GML311GEOMETRY' if version.value == 3 else 'SDO_UTIL.TO_GMLGEOMETRY'
return super(AsGML, clone).as_sql(compiler, connection, **extra_context)
class AsKML(AsGML):
def as_sqlite(self, compiler, connection):

View File

@ -379,7 +379,7 @@ Function PostGIS Oracle MySQL SpatiaLite
==================================== ======= ====== =========== ==========
:class:`Area` X X X X
:class:`AsGeoJSON` X X
:class:`AsGML` X X
:class:`AsGML` X X X
:class:`AsKML` X X
:class:`AsSVG` X X
:class:`BoundingCircle` X

View File

@ -81,7 +81,7 @@ Keyword Argument Description
.. class:: AsGML(expression, version=2, precision=8, **extra)
*Availability*: PostGIS, SpatiaLite
*Availability*: Oracle, PostGIS, SpatiaLite
Accepts a single geographic field or expression and returns a `Geographic Markup
Language (GML)`__ representation of the geometry.
@ -98,13 +98,17 @@ Keyword Argument Description
===================== =====================================================
``precision`` Specifies the number of significant digits for the
coordinates in the GML representation -- the default
value is 8.
value is 8. Ignored on Oracle.
``version`` Specifies the GML version to use: 2 (default) or 3.
===================== =====================================================
__ https://en.wikipedia.org/wiki/Geography_Markup_Language
.. versionchanged:: 1.11
Oracle support was added.
``AsKML``
=========

View File

@ -164,7 +164,8 @@ Minor features
:lookup:`isvalid` lookup.
* Added Oracle support for the
:class:`~django.contrib.gis.db.models.functions.IsValid` function and
:class:`~django.contrib.gis.db.models.functions.AsGML` function,
:class:`~django.contrib.gis.db.models.functions.IsValid` function, and
:lookup:`isvalid` lookup.
:mod:`django.contrib.messages`

View File

@ -11,7 +11,7 @@ from django.db.models import Sum
from django.test import TestCase, skipUnlessDBFeature
from django.utils import six
from ..utils import mysql, oracle, postgis, spatialite
from ..utils import mysql, oracle, spatialite
from .models import City, Country, CountryWebMercator, State, Track
@ -104,7 +104,7 @@ class GISFunctionsTests(TestCase):
if oracle:
# No precision parameter for Oracle :-/
gml_regex = re.compile(
r'^<gml:Point srsName="SDO:4326" xmlns:gml="http://www.opengis.net/gml">'
r'^<gml:Point srsName="EPSG:4326" xmlns:gml="http://www.opengis.net/gml">'
r'<gml:coordinates decimal="\." cs="," ts=" ">-104.60925\d+,38.25500\d+ '
r'</gml:coordinates></gml:Point>'
)
@ -113,10 +113,7 @@ class GISFunctionsTests(TestCase):
r'^<gml:Point srsName="EPSG:4326"><gml:coordinates>'
r'-104\.60925\d+,38\.255001</gml:coordinates></gml:Point>'
)
self.assertTrue(gml_regex.match(ptown.gml))
if postgis:
self.assertIn(
'<gml:pos srsDimension="2">',
City.objects.annotate(gml=functions.AsGML('point', version=3)).get(name='Pueblo').gml