Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

gis: Fixed #5440 with patches from rcoup; cleaned up notice handler i…

…n libgeos.

git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6314 bcc190cf-cafb-0310-a4f2-bffc1f526a37
commit 101446dbda1c047cdac245ee753be83240f47ed4 1 parent 483a807
Justin Bronn authored September 15, 2007
24  django/contrib/gis/geos/base.py
@@ -6,7 +6,7 @@
6 6
 from ctypes import \
7 7
      byref, string_at, create_string_buffer, pointer, \
8 8
      c_char_p, c_double, c_int, c_size_t
9  
-from types import StringType, UnicodeType, IntType, FloatType
  9
+from types import StringType, UnicodeType, IntType, FloatType, BufferType
10 10
 
11 11
 # Python and GEOS-related dependencies.
12 12
 import re
@@ -30,9 +30,13 @@ class GEOSGeometry(object):
30 30
     #### Python 'magic' routines ####
31 31
     def __init__(self, geo_input, srid=None):
32 32
         """
33  
-        The base constructor for GEOS geometry objects, and may take the following
34  
-         string inputs: WKT and HEXEWKB (a PostGIS-specific canonical form).
35  
-
  33
+        The base constructor for GEOS geometry objects, and may take the 
  34
+         following inputs:
  35
+         
  36
+         * string: WKT
  37
+         * string: HEXEWKB (a PostGIS-specific canonical form)
  38
+         * buffer: WKB
  39
+        
36 40
         The `srid` keyword is used to specify the Source Reference Identifier
37 41
          (SRID) number for this Geometry.  If not set, the SRID will be None.
38 42
         """
@@ -55,6 +59,11 @@ def __init__(self, geo_input, srid=None):
55 59
             # When the input is either a memory address (an integer), or a 
56 60
             #  GEOSPointer object.
57 61
             g = geo_input
  62
+        elif isinstance(geo_input, BufferType):
  63
+            # When the input is a buffer (WKB).
  64
+            wkb_input = str(geo_input)
  65
+            sz = c_size_t(len(wkb_input))
  66
+            g = lgeos.GEOSGeomFromWKB_buf(c_char_p(wkb_input), sz)
58 67
         else:
59 68
             # Invalid geometry type.
60 69
             raise TypeError, 'Improper geometry input type: %s' % str(type(geo_input))
@@ -414,6 +423,13 @@ def hex(self):
414 423
         return string_at(h, sz.value)
415 424
 
416 425
     @property
  426
+    def wkb(self):
  427
+        "Returns the WKB of the Geometry as a buffer."
  428
+        sz = c_size_t()
  429
+        h = lgeos.GEOSGeomToWKB_buf(self._ptr(), byref(sz))
  430
+        return buffer(string_at(h, sz.value))
  431
+
  432
+    @property
417 433
     def kml(self):
418 434
         "Returns the KML representation of this Geometry."
419 435
         gtype = self.geom_type
8  django/contrib/gis/geos/libgeos.py
@@ -52,8 +52,12 @@
52 52
 #  Supposed to mimic the GEOS message handler (C below):
53 53
 #  "typedef void (*GEOSMessageHandler)(const char *fmt, ...);"
54 54
 NOTICEFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
55  
-def notice_h(fmt, list, output_h=sys.stdout):
56  
-    output_h.write('GEOS_NOTICE: %s\n' % (fmt % list))
  55
+def notice_h(fmt, lst, output_h=sys.stdout):
  56
+    try:
  57
+        warn_msg = fmt % lst
  58
+    except:
  59
+        warn_msg = fmt 
  60
+    output_h.write('GEOS_NOTICE: %s\n' % warn_msg)
57 61
 notice_h = NOTICEFUNC(notice_h)
58 62
 
59 63
 ERRORFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
1  django/contrib/gis/tests/geometries.py
@@ -49,6 +49,7 @@ def __init__(self, wkt, **kwargs):
49 49
           TestGeom('POINT (5, 23)', bad=True, hex=False),
50 50
           TestGeom('AAABBBDDDAAD##@#1113511111-098111111111111111533333333333333', bad=True, hex=True),
51 51
           TestGeom('FFFFFFFFFFFFFFFFF1355555555555555555565111', bad=True, hex=True),
  52
+          TestGeom('', bad=True, hex=False),
52 53
           )
53 54
 
54 55
 # Polygons
42  django/contrib/gis/tests/test_geos.py
@@ -31,14 +31,48 @@ def test01c_kml(self):
31 31
 
32 32
     def test01d_errors(self):
33 33
         "Testing the Error handlers."
  34
+        # string-based
34 35
         print "\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n"
35 36
         for err in errors:
36  
-            if err.hex:
37  
-                self.assertRaises(GEOSException, fromstr, err.wkt)
38  
-            else:
39  
-                self.assertRaises(GEOSException, fromstr, err.wkt)
  37
+            self.assertRaises(GEOSException, fromstr, err.wkt)
40 38
         print "\nEND - expecting GEOS_ERROR; safe to ignore.\n"
  39
+        
  40
+        class NotAGeometry(object):
  41
+            pass
  42
+        
  43
+        # Some other object
  44
+        self.assertRaises(TypeError, GEOSGeometry, NotAGeometry())
  45
+        # None
  46
+        self.assertRaises(TypeError, GEOSGeometry, None)
  47
+        # Bad WKB
  48
+        self.assertRaises(GEOSException, GEOSGeometry, buffer('0'))
41 49
                 
  50
+    def test01e_wkb(self):
  51
+        "Testing WKB output."
  52
+        from binascii import b2a_hex
  53
+        for g in hex_wkt:
  54
+            geom = fromstr(g.wkt)
  55
+            wkb = geom.wkb
  56
+            self.assertEqual(b2a_hex(wkb).upper(), g.hex)
  57
+
  58
+    def test01f_create_hex(self):
  59
+        "Testing creation from HEX."
  60
+        for g in hex_wkt:
  61
+            geom_h = GEOSGeometry(g.hex)
  62
+            # we need to do this so decimal places get normalised
  63
+            geom_t = fromstr(g.wkt)
  64
+            self.assertEqual(geom_t.wkt, geom_h.wkt)
  65
+
  66
+    def test01g_create_wkb(self):
  67
+        "Testing creation from WKB."
  68
+        from binascii import a2b_hex
  69
+        for g in hex_wkt:
  70
+            wkb = buffer(a2b_hex(g.hex))
  71
+            geom_h = GEOSGeometry(wkb)
  72
+            # we need to do this so decimal places get normalised
  73
+            geom_t = fromstr(g.wkt)
  74
+            self.assertEqual(geom_t.wkt, geom_h.wkt)
  75
+    
42 76
     def test02a_points(self):
43 77
         "Testing Point objects."
44 78
         prev = fromstr('POINT(0 0)')

0 notes on commit 101446d

Please sign in to comment.
Something went wrong with that request. Please try again.