1
0
mirror of https://github.com/django/django.git synced 2025-07-04 09:49:12 +00:00

gis: added get_srid() spatial backend utility that takes into account -1 SRID values; removed from_hex flag from GEOS initialization; added tests for SRID values, and changed test_gdal module docstring.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6596 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Justin Bronn 2007-10-22 23:37:26 +00:00
parent aed1db8266
commit f66ee9d006
7 changed files with 38 additions and 13 deletions

View File

@ -4,7 +4,7 @@ from django.db import connection
from django.db.backends.util import truncate_name from django.db.backends.util import truncate_name
from django.db.models.fields import Field # Django base Field class from django.db.models.fields import Field # Django base Field class
from django.contrib.gis.geos import GEOSGeometry from django.contrib.gis.geos import GEOSGeometry
from django.contrib.gis.db.backend.util import GeoFieldSQL from django.contrib.gis.db.backend.util import get_srid, GeoFieldSQL
from django.contrib.gis.db.backend.oracle.adaptor import OracleSpatialAdaptor from django.contrib.gis.db.backend.oracle.adaptor import OracleSpatialAdaptor
from django.contrib.gis.db.backend.oracle.query import ORACLE_SPATIAL_TERMS, TRANSFORM from django.contrib.gis.db.backend.oracle.query import ORACLE_SPATIAL_TERMS, TRANSFORM
@ -118,8 +118,7 @@ class OracleSpatialField(Field):
# Getting the SRID of the geometry, or defaulting to that of the field if # Getting the SRID of the geometry, or defaulting to that of the field if
# it is None. # it is None.
if value.srid is None: srid = self._srid srid = get_srid(self, value)
else: srid = value.srid
# The adaptor will be used by psycopg2 for quoting the WKT. # The adaptor will be used by psycopg2 for quoting the WKT.
adapt = OracleSpatialAdaptor(value) adapt = OracleSpatialAdaptor(value)

View File

@ -2,7 +2,7 @@ from types import StringType, UnicodeType
from django.db import connection from django.db import connection
from django.db.models.fields import Field # Django base Field class from django.db.models.fields import Field # Django base Field class
from django.contrib.gis.geos import GEOSGeometry, GEOSException from django.contrib.gis.geos import GEOSGeometry, GEOSException
from django.contrib.gis.db.backend.util import GeoFieldSQL from django.contrib.gis.db.backend.util import get_srid, GeoFieldSQL
from django.contrib.gis.db.backend.postgis.adaptor import PostGISAdaptor from django.contrib.gis.db.backend.postgis.adaptor import PostGISAdaptor
from django.contrib.gis.db.backend.postgis.query import POSTGIS_TERMS, TRANSFORM from django.contrib.gis.db.backend.postgis.query import POSTGIS_TERMS, TRANSFORM
from psycopg2 import Binary from psycopg2 import Binary
@ -109,8 +109,7 @@ class PostGISField(Field):
# Getting the SRID of the geometry, or defaulting to that of the field if # Getting the SRID of the geometry, or defaulting to that of the field if
# it is None. # it is None.
if value.srid is None: srid = self._srid srid = get_srid(self, value)
else: srid = value.srid
# The adaptor will be used by psycopg2 for quoting the WKB. # The adaptor will be used by psycopg2 for quoting the WKB.
adapt = PostGISAdaptor(value, srid) adapt = PostGISAdaptor(value, srid)

View File

@ -6,3 +6,13 @@ class GeoFieldSQL(object):
def __init__(self, where=[], params=[]): def __init__(self, where=[], params=[]):
self.where = where self.where = where
self.params = params self.params = params
def get_srid(field, geom):
"""
Gets the SRID depending on the value of the SRID setting of the field
and that of the given geometry.
"""
if geom.srid is None or (geom.srid == -1 and field._srid != -1):
return field._srid
else:
return geom.srid

View File

@ -48,14 +48,12 @@ class GEOSGeometry(object):
The `srid` keyword is used to specify the Source Reference Identifier The `srid` keyword is used to specify the Source Reference Identifier
(SRID) number for this Geometry. If not set, the SRID will be None. (SRID) number for this Geometry. If not set, the SRID will be None.
""" """
from_hex = False
if isinstance(geo_input, UnicodeType): if isinstance(geo_input, UnicodeType):
# Encoding to ASCII, WKT or HEXEWKB doesn't need any more. # Encoding to ASCII, WKT or HEXEWKB doesn't need any more.
geo_input = geo_input.encode('ascii') geo_input = geo_input.encode('ascii')
if isinstance(geo_input, StringType): if isinstance(geo_input, StringType):
if hex_regex.match(geo_input): if hex_regex.match(geo_input):
# If the regex matches, the geometry is in HEX form. # If the regex matches, the geometry is in HEX form.
from_hex = True
sz = c_size_t(len(geo_input)) sz = c_size_t(len(geo_input))
buf = create_string_buffer(geo_input) buf = create_string_buffer(geo_input)
g = lgeos.GEOSGeomFromHEX_buf(buf, sz) g = lgeos.GEOSGeomFromHEX_buf(buf, sz)
@ -86,10 +84,6 @@ class GEOSGeometry(object):
# Setting the SRID, if given. # Setting the SRID, if given.
if srid and isinstance(srid, int): self.srid = srid if srid and isinstance(srid, int): self.srid = srid
# Exported HEX from other GEOS geometries will have -1 SRID --
# set here to 0, when the SRID is not explicitly given.
if not srid and from_hex: self.srid = 0
# Setting the class type (e.g., 'Point', 'Polygon', etc.) # Setting the class type (e.g., 'Point', 'Polygon', etc.)
self.__class__ = GEOS_CLASSES[self.geom_type] self.__class__ = GEOS_CLASSES[self.geom_type]
@ -422,6 +416,8 @@ class GEOSGeometry(object):
included in this representation, because the GEOS C library uses included in this representation, because the GEOS C library uses
-1 by default, even if the SRID is set. -1 by default, even if the SRID is set.
""" """
# A possible faster, all-python, implementation:
# str(self.wkb).encode('hex')
sz = c_size_t() sz = c_size_t()
h = lgeos.GEOSGeomToHEX_buf(self._ptr(), byref(sz)) h = lgeos.GEOSGeomToHEX_buf(self._ptr(), byref(sz))
return string_at(h, sz.value) return string_at(h, sz.value)

View File

@ -138,10 +138,12 @@ class GeoModelTest(unittest.TestCase):
# the pre-transformed points. Oracle does not have the 3084 SRID. # the pre-transformed points. Oracle does not have the 3084 SRID.
if not oracle: if not oracle:
h = City.objects.transform('point', srid=htown.srid).get(name='Houston') h = City.objects.transform('point', srid=htown.srid).get(name='Houston')
self.assertEqual(3084, h.point.srid)
self.assertAlmostEqual(htown.x, h.point.x, 8) self.assertAlmostEqual(htown.x, h.point.x, 8)
self.assertAlmostEqual(htown.y, h.point.y, 8) self.assertAlmostEqual(htown.y, h.point.y, 8)
p = City.objects.transform('point', srid=ptown.srid).get(name='Pueblo') p = City.objects.transform('point', srid=ptown.srid).get(name='Pueblo')
self.assertEqual(2774, p.point.srid)
self.assertAlmostEqual(ptown.x, p.point.x, 7) self.assertAlmostEqual(ptown.x, p.point.x, 7)
self.assertAlmostEqual(ptown.y, p.point.y, 7) self.assertAlmostEqual(ptown.y, p.point.y, 7)

View File

@ -1,3 +1,7 @@
"""
Module for executing all of the GDAL tests. None
of these tests require the use of the database.
"""
from unittest import TestSuite, TextTestRunner from unittest import TestSuite, TextTestRunner
# Importing the GDAL test modules. # Importing the GDAL test modules.
@ -20,5 +24,5 @@ def suite():
return s return s
def run(verbosity=1): def run(verbosity=1):
"Runs the tests that do not require geographic (GEOS, GDAL, etc.) models." "Runs the GDAL tests."
TextTestRunner(verbosity=verbosity).run(suite()) TextTestRunner(verbosity=verbosity).run(suite())

View File

@ -607,6 +607,21 @@ class GEOSTest(unittest.TestCase):
self.assertEqual(32021, gc.srid) self.assertEqual(32021, gc.srid)
for i in range(len(gc)): self.assertEqual(32021, gc[i].srid) for i in range(len(gc)): self.assertEqual(32021, gc[i].srid)
# GEOS may get the SRID from HEXEWKB
# 'POINT(5 23)' at SRID=4326 in hex form -- obtained from PostGIS
# using `SELECT GeomFromText('POINT (5 23)', 4326);`.
hex = '0101000020E610000000000000000014400000000000003740'
p1 = fromstr(hex)
self.assertEqual(4326, p1.srid)
# However, when HEX is exported, the SRID information is lost
# and set to -1. Essentially, the 'E' of the EWKB is not
# encoded in HEX by the GEOS C library for some reason.
p2 = fromstr(p1.hex)
self.assertEqual(-1, p2.srid)
p3 = fromstr(p1.hex, srid=-1) # -1 is intended.
self.assertEqual(-1, p3.srid)
def test16_mutable_geometries(self): def test16_mutable_geometries(self):
"Testing the mutability of Polygons and Geometry Collections." "Testing the mutability of Polygons and Geometry Collections."
### Testing the mutability of Polygons ### ### Testing the mutability of Polygons ###