Ticket #13788: 13788_geos_transform.diff

File 13788_geos_transform.diff, 10.1 KB (added by Robert Coup, 9 years ago)

initial patch

  • docs/internals/deprecation.txt

     
    100100        * The ``no`` language code has been deprecated in favor of the ``nb``
    101101          language code.
    102102
     103    * 1.5
     104        * :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` will raise
     105          an exception when called and the geometry has no SRID set.
     106
    103107    * 2.0
    104108        * ``django.views.defaults.shortcut()``. This function has been moved
    105109          to ``django.contrib.contenttypes.views.shortcut()`` as part of the
  • docs/releases/1.3-alpha-1.txt

     
     1.. _releases-1.3-alpha-1:
     2
     3================================
     4Django 1.3 alpha 1 release notes
     5================================
     6
     7Backwards-incompatible changes in 1.3
     8=====================================
     9
     10Wherever possible the new features above have been introduced in a
     11backwards-compatible manner per :ref:`our API stability policy
     12<misc-api-stability>` policy. This means that practically all existing
     13code which worked with Django 1.2 will continue to work with Django
     141.3; such code will, however, begin issuing warnings (see below for
     15details).
     16
     17However, a handful of features *have* changed in ways that, for some
     18users, will be immediately backwards-incompatible. Those changes are
     19detailed below.
     20
     21GeoDjango
     22---------------
     23
     24* Calling :meth:`~django.contrib.gis.geos.GEOSGeometry.transform` when
     25the GDAL library is not available used to silently do nothing. Except
     26when the source & destination SRIDs match or are ``None``, this is a
     27potentially serious bug in application code. A
     28:class:`~django.contrib.gis.geos.GEOSException` is now raised.
  • docs/ref/contrib/gis/install.txt

    Property changes on: docs/releases/1.3-alpha-1.txt
    ___________________________________________________________________
    Added: svn:eol-style
       + native
    
     
    9898.. admonition::  Install GDAL
    9999
    100100    While :ref:`gdalbuild` is technically not required, it is *recommended*.
    101     Some features of GeoDjango (including the :ref:`ref-layermapping` and the geographic
    102     admin) depend on its functionality.
     101    Some features of GeoDjango (including the :ref:`ref-layermapping`,
     102    geometry reprojection, and the geographic admin) depend on its
     103    functionality.
    103104
    104105.. note::
    105106
  • docs/ref/contrib/gis/geos.txt

     
    529529
    530530.. note::
    531531
    532     Requires GDAL.
     532    Requires GDAL. Before 1.3, this method would silently no-op if GDAL wasn't
     533    available, but a GEOSException is now raised, since this is in all cases a bug.
     534
     535.. note::
     536   
     537    From 1.3, calling ``transform()`` when the SRID of the geometry is ``None`` or
     538    < 0 generates a warning, but continues. From 1.5 this behavior will change and
     539    a GEOSException will be raised.
    533540
    534541``Point``
    535542---------
  • django/contrib/gis/geos/geometry.py

     
    44"""
    55# Python, ctypes and types dependencies.
    66import re
     7import warnings
    78from ctypes import addressof, byref, c_double, c_size_t
    89
    910# super-class for mutable list behavior
     
    489490        instead.
    490491        """
    491492        srid = self.srid
    492         if gdal.HAS_GDAL and srid:
    493             # Creating an OGR Geometry, which is then transformed.
    494             g = gdal.OGRGeometry(self.wkb, srid)
    495             g.transform(ct)
    496             # Getting a new GEOS pointer
    497             ptr = wkb_r().read(g.wkb)
     493       
     494        if ct == srid:
     495            # short-circuit where source & dest SRIDs match
    498496            if clone:
    499                 # User wants a cloned transformed geometry returned.
    500                 return GEOSGeometry(ptr, srid=g.srid)
    501             if ptr:
    502                 # Reassigning pointer, and performing post-initialization setup
    503                 # again due to the reassignment.
    504                 capi.destroy_geom(self.ptr)
    505                 self.ptr = ptr
    506                 self._post_init(g.srid)
     497                return self.clone()
    507498            else:
    508                 raise GEOSException('Transformed WKB was invalid.')
     499                return
     500       
     501        if (srid is None) or (srid < 0):
     502            warnings.warn("Calling transform() with no SRID set does no transform!", stacklevel=2)
     503            warnings.warn("Calling transform() with no SRID will raise a GEOSException from v1.5", FutureWarning, stacklevel=2)
     504            return
     505       
     506        if not gdal.HAS_GDAL:
     507            raise GEOSException("GDAL library is not available to transform() geometry.")
     508       
     509        # Creating an OGR Geometry, which is then transformed.
     510        g = gdal.OGRGeometry(self.wkb, srid)
     511        g.transform(ct)
     512        # Getting a new GEOS pointer
     513        ptr = wkb_r().read(g.wkb)
     514        if clone:
     515            # User wants a cloned transformed geometry returned.
     516            return GEOSGeometry(ptr, srid=g.srid)
     517        if ptr:
     518            # Reassigning pointer, and performing post-initialization setup
     519            # again due to the reassignment.
     520            capi.destroy_geom(self.ptr)
     521            self.ptr = ptr
     522            self._post_init(g.srid)
     523        else:
     524            raise GEOSException('Transformed WKB was invalid.')
    509525
    510526    #### Topology Routines ####
    511527    def _topology(self, gptr):
  • django/contrib/gis/geos/tests/test_geos.py

     
    853853            self.assertAlmostEqual(trans.x, p.x, prec)
    854854            self.assertAlmostEqual(trans.y, p.y, prec)
    855855
     856    def test23_transform_noop(self):
     857        """ Testing `transform` method (SRID match) """
     858        # transform() should no-op if source & dest SRIDs match,
     859        # regardless of whether GDAL is available.
     860        if gdal.HAS_GDAL:
     861            g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
     862            gt = g.tuple
     863            g.transform(4326)
     864            self.assertEqual(g.tuple, gt)
     865            self.assertEqual(g.srid, 4326)
     866           
     867            g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
     868            g1 = g.transform(4326, clone=True)
     869            self.assertEqual(g1.tuple, g.tuple)
     870            self.assertEqual(g1.srid, 4326)
     871            self.assert_(g1 is not g, "Clone didn't happen")
     872       
     873        old_has_gdal = gdal.HAS_GDAL
     874        try:
     875            gdal.HAS_GDAL = False
     876           
     877            g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
     878            gt = g.tuple
     879            g.transform(4326)
     880            self.assertEqual(g.tuple, gt)
     881            self.assertEqual(g.srid, 4326)
     882           
     883            g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
     884            g1 = g.transform(4326, clone=True)
     885            self.assertEqual(g1.tuple, g.tuple)
     886            self.assertEqual(g1.srid, 4326)
     887            self.assert_(g1 is not g, "Clone didn't happen")
     888        finally:
     889            gdal.HAS_GDAL = old_has_gdal
     890
     891    def test23_transform_nosrid(self):
     892        """ Testing `transform` method (no SRID) """
     893        # raise a warning if SRID <0/None
     894        import warnings
     895       
     896        print "\nBEGIN - expecting Warnings; safe to ignore.\n"
     897
     898        # test for do-nothing behaviour
     899        g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
     900        g.transform(2774)
     901        self.assertEqual(g.tuple, (-104.609, 38.255))
     902        self.assertEqual(g.srid, None)
     903       
     904        g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
     905        g1 = g.transform(2774, clone=True)
     906        self.assert_(g1 is None)
     907       
     908        g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
     909        g.transform(2774)
     910        self.assertEqual(g.tuple, (-104.609, 38.255))
     911        self.assertEqual(g.srid, -1)
     912       
     913        g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
     914        g1 = g.transform(2774, clone=True)
     915        self.assert_(g1 is None)
     916       
     917        # test warning is raised
     918        try:
     919            warnings.simplefilter('error', FutureWarning)
     920           
     921            g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
     922            self.assertRaises(FutureWarning, g.transform, 2774)
     923           
     924            g = GEOSGeometry('POINT (-104.609 38.255)', srid=None)
     925            self.assertRaises(FutureWarning, g.transform, 2774, clone=True)
     926           
     927            g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
     928            self.assertRaises(FutureWarning, g.transform, 2774)
     929           
     930            g = GEOSGeometry('POINT (-104.609 38.255)', srid=-1)
     931            self.assertRaises(FutureWarning, g.transform, 2774, clone=True)
     932        finally:
     933            warnings.simplefilter('default', category=FutureWarning)
     934
     935        print "\END - expecting Warnings; safe to ignore.\n"
     936
     937    def test23_transform_nogdal(self):
     938        """ Testing `transform` method (GDAL not available) """
     939        old_has_gdal = gdal.HAS_GDAL
     940        try:
     941            gdal.HAS_GDAL = False
     942           
     943            g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
     944            self.assertRaises(GEOSException, g.transform, 2774)
     945           
     946            g = GEOSGeometry('POINT (-104.609 38.255)', 4326)
     947            self.assertRaises(GEOSException, g.transform, 2774, clone=True)
     948        finally:
     949            gdal.HAS_GDAL = old_has_gdal
     950
    856951    def test24_extent(self):
    857952        "Testing `extent` method."
    858953        # The xmin, ymin, xmax, ymax of the MultiPoint should be returned.
Back to Top