Django

Code

Changeset 7404

Show
Ignore:
Timestamp:
04/07/08 15:15:04 (3 months ago)
Author:
jbronn
Message:

gis: geos: GEOSGeometry objects may now be pickled; added the clone keyword to transform which returns a cloned transformed geometry rather than transforming in-place.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/gis/django/contrib/gis/geos/base.py

    r7114 r7404  
    8888            raise GEOSException('Could not initialize GEOS Geometry with given input.') 
    8989 
     90        # Post-initialization setup. 
     91        self._post_init(srid) 
     92 
     93    def _post_init(self, srid): 
     94        "Helper routine for performing post-initialization setup." 
    9095        # Setting the SRID, if given. 
    9196        if srid and isinstance(srid, int): self.srid = srid 
    92  
     97         
    9398        # Setting the class type (e.g., Point, Polygon, etc.) 
    9499        self.__class__ = GEOS_CLASSES[self.geom_typeid] 
    95100 
    96101        # Setting the coordinate sequence for the geometry (will be None on  
    97         # geometries that do not have coordinate sequences) 
     102        # geometries that do not have coordinate sequences) 
    98103        self._set_cs() 
    99          
     104 
    100105    @property 
    101106    def ptr(self): 
     
    139144        "Short-hand representation because WKT may be very large." 
    140145        return '<%s object at %s>' % (self.geom_type, hex(addressof(self.ptr))) 
     146 
     147    # Pickling support 
     148    def __getstate__(self): 
     149        # The pickled state is simply a tuple of the WKB (in string form) 
     150        # and the SRID. 
     151        return str(self.wkb), self.srid 
     152 
     153    def __setstate__(self, state): 
     154        # Instantiating from the tuple state that was pickled. 
     155        wkb, srid = state 
     156        ptr = from_wkb(wkb, len(wkb)) 
     157        if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.') 
     158        self._ptr = ptr 
     159        self._post_init(srid) 
    141160 
    142161    # Comparison operators 
     
    414433        return self.srs 
    415434 
    416     def transform(self, ct): 
    417         "Transforms this Geometry; only works with GDAL." 
     435    def transform(self, ct, clone=False): 
     436        """ 
     437        Requires GDAL. Transforms the geometry according to the given  
     438        transformation object, which may be an integer SRID, and WKT or  
     439        PROJ.4 string. By default, the geometry is transformed in-place and  
     440        nothing is returned. However if the `clone` keyword is set, then this  
     441        geometry will not be modified and a transformed clone will be returned 
     442        instead. 
     443        """ 
    418444        srid = self.srid 
    419445        if HAS_GDAL and srid: 
     
    422448            wkb = str(g.wkb) 
    423449            ptr = from_wkb(wkb, len(wkb)) 
     450            if clone:  
     451                # User wants a cloned transformed geometry returned. 
     452                return GEOSGeometry(ptr, srid=g.srid) 
    424453            if ptr: 
    425                 # Reassigning pointer, and getting the new coordinate sequence pointer. 
     454                # Reassigning pointer, and performing post-initialization setup 
     455                # again due to the reassignment. 
    426456                destroy_geom(self.ptr) 
    427457                self._ptr = ptr 
    428                 self._set_cs() 
    429  
    430                 # Some coordinate transformations do not have an SRID associated 
    431                 # with them; only set if one exists. 
    432                 if g.srid: self.srid = g.srid 
     458                self._post_init(g.srid) 
     459            else: 
     460                raise GEOSException('Transformed WKB was invalid.') 
    433461 
    434462    #### Topology Routines #### 
  • django/branches/gis/django/contrib/gis/tests/test_geos.py

    r7114 r7404  
    704704        ct = CoordTransform(SpatialReference('WGS84'), SpatialReference(2774)) 
    705705        t3.transform(ct) 
     706 
     707        # Testing use of the `clone` keyword. 
     708        k1 = orig.clone() 
     709        k2 = k1.transform(trans.srid, clone=True) 
     710        self.assertEqual(k1, orig) 
     711        self.assertNotEqual(k1, k2) 
     712 
    706713        prec = 3 
    707         for p in (t1, t2, t3): 
     714        for p in (t1, t2, t3, k2): 
    708715            self.assertAlmostEqual(trans.x, p.x, prec) 
    709716            self.assertAlmostEqual(trans.y, p.y, prec) 
     
    725732        self.assertEqual((xmin, ymin, xmax, ymax), poly.extent) 
    726733 
     734    def test25_pickle(self): 
     735        "Testing pickling and unpickling support." 
     736        # Using both pickle and cPickle -- just 'cause. 
     737        import pickle, cPickle 
     738 
     739        # Creating a list of test geometries for pickling,  
     740        # and setting the SRID on some of them. 
     741        def get_geoms(lst, srid=None): 
     742            return [GEOSGeometry(tg.wkt, srid) for tg in lst] 
     743        tgeoms = get_geoms(points) 
     744        tgeoms.extend(get_geoms(multilinestrings, 4326)) 
     745        tgeoms.extend(get_geoms(polygons, 3084)) 
     746        tgeoms.extend(get_geoms(multipolygons, 900913)) 
     747         
     748        for geom in tgeoms: 
     749            s1, s2 = cPickle.dumps(geom), pickle.dumps(geom) 
     750            g1, g2 = cPickle.loads(s1), pickle.loads(s2) 
     751            for tmpg in (g1, g2): 
     752                self.assertEqual(geom, tmpg) 
     753                self.assertEqual(geom.srid, tmpg.srid) 
     754 
    727755def suite(): 
    728756    s = unittest.TestSuite()