Django

Code

Changeset 6464

Show
Ignore:
Timestamp:
10/07/07 15:29:59 (1 year ago)
Author:
jbronn
Message:

gis: gdal: added support exporting/creating geometries to/from WKB and HEX.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/branches/gis/django/contrib/gis/gdal/feature.py

    r6436 r6464  
    11# types and ctypes 
    22from types import StringType 
    3 from ctypes import c_char_p, c_int, string_at 
     3from ctypes import c_char_p, c_int, c_void_p, string_at 
    44 
    55# The GDAL C library, OGR exception, and the Field object 
     
    9999 
    100100        # Geometry is cloned so the feature isn't invalidated. 
    101         return OGRGeometry(lgdal.OGR_G_Clone(geom_ptr), srs) 
     101        return OGRGeometry(c_void_p(lgdal.OGR_G_Clone(geom_ptr)), srs) 
    102102 
    103103    @property 
  • django/branches/gis/django/contrib/gis/gdal/geometries.py

    r6460 r6464  
    3939    True 
    4040""" 
    41 # types & ctypes 
    42 from types import IntType, StringType, UnicodeType 
    43 from ctypes import byref, string_at, c_char_p, c_double, c_int, c_void_p 
     41# Python library imports 
     42import re, sys 
     43from binascii import a2b_hex, b2a_hex 
     44from ctypes import byref, create_string_buffer, string_at, c_char_p, c_double, c_int, c_void_p 
     45from types import BufferType, IntType, StringType, UnicodeType 
    4446 
    4547# Getting GDAL prerequisites 
     
    7173get_area.argtypes = [c_void_p] 
    7274 
     75# Regular expression for determining whether the input is HEXEWKB. 
     76hex_regex = re.compile(r'^[0-9A-F]+$', re.I) 
     77 
    7378#### OGRGeometry Class #### 
    7479class OGRGeometry(object): 
     
    7883        "Initializes Geometry on either WKT or an OGR pointer as input." 
    7984 
    80         self._g = 0 # Initially NULL 
     85        self._g = c_void_p(None) # Initially NULL 
     86 
     87        # Checking if unicode 
     88        if isinstance(geom_input, UnicodeType): 
     89            # Encoding to ASCII, WKT or HEX doesn't need any more. 
     90            geo_input = geo_input.encode('ascii') 
     91 
     92        # If HEX, unpack input to to a binary buffer. 
     93        if isinstance(geom_input, StringType) and hex_regex.match(geom_input): 
     94            geom_input = buffer(a2b_hex(geom_input.upper())) 
    8195 
    8296        if isinstance(geom_input, StringType): 
     
    94108                except: 
    95109                    raise OGRException('Could not initialize OGR Geometry from: %s' % geom_input) 
     110        elif isinstance(geom_input, BufferType): 
     111            # WKB was passed in 
     112            g = c_void_p() 
     113            check_err(lgdal.OGR_G_CreateFromWkb(c_char_p(str(geom_input)), c_void_p(), byref(g), len(geom_input))) 
    96114        elif isinstance(geom_input, OGRGeomType): 
     115            # OGRGeomType was passed in, an empty geometry will be created. 
    97116            g = lgdal.OGR_G_CreateGeometry(geom_input.num) 
    98         elif isinstance(geom_input, IntType): 
    99             # OGR Pointer (integer) was the input 
     117        elif isinstance(geom_input, c_void_p): 
     118            # OGR pointer (c_void_p) was the input. 
    100119            g = geom_input 
    101120        else: 
     
    182201        return self.point_count 
    183202 
     203    @property 
     204    def geom_type(self): 
     205        "Returns the Type for this Geometry." 
     206        return OGRGeomType(lgdal.OGR_G_GetGeometryType(self._g)) 
     207 
     208    @property 
     209    def geom_name(self): 
     210        "Returns the Name of this Geometry." 
     211        return string_at(lgdal.OGR_G_GetGeometryName(self._g)) 
     212 
     213    @property 
     214    def area(self): 
     215        "Returns the area for a LinearRing, Polygon, or MultiPolygon; 0 otherwise." 
     216        return get_area(self._g) 
     217 
     218    @property 
     219    def envelope(self): 
     220        "Returns the envelope for this Geometry." 
     221        env = OGREnvelope() 
     222        lgdal.OGR_G_GetEnvelope(self._g, byref(env)) 
     223        return Envelope(env) 
     224 
     225    #### SpatialReference-related Properties #### 
     226     
    184227    # The SRS property 
    185228    def get_srs(self): 
     
    217260    srid = property(get_srid, set_srid) 
    218261 
    219     @property 
    220     def geom_type(self): 
    221         "Returns the Type for this Geometry." 
    222         return OGRGeomType(lgdal.OGR_G_GetGeometryType(self._g)) 
    223  
    224     @property 
    225     def geom_name(self): 
    226         "Returns the Name of this Geometry." 
    227         return string_at(lgdal.OGR_G_GetGeometryName(self._g)) 
    228  
    229     @property 
    230     def area(self): 
    231         "Returns the area for a LinearRing, Polygon, or MultiPolygon; 0 otherwise." 
    232         return get_area(self._g) 
    233  
    234     @property 
    235     def envelope(self): 
    236         "Returns the envelope for this Geometry." 
    237         env = OGREnvelope() 
    238         lgdal.OGR_G_GetEnvelope(self._g, byref(env)) 
    239         return Envelope(env) 
    240  
    241262    #### Output Methods #### 
    242263    @property 
     
    246267        if buf: return string_at(buf) 
    247268        else: return None 
     269 
     270    @property 
     271    def hex(self): 
     272        "Returns the hexadecimal representation of the WKB (a string)." 
     273        return b2a_hex(self.wkb).upper() 
     274 
     275    @property 
     276    def wkb_size(self): 
     277        "Returns the size of the WKB buffer." 
     278        return lgdal.OGR_G_WkbSize(self._g) 
     279 
     280    @property 
     281    def wkb(self): 
     282        "Returns the WKB representation of the Geometry." 
     283        if sys.byteorder == 'little': 
     284            byteorder = c_int(1) # wkbNDR (from ogr_core.h) 
     285        else: 
     286            byteorder = c_int(0) # wkbXDR (from ogr_core.h) 
     287        # Creating a mutable string buffer of the given size, exporting 
     288        # to WKB, and returning a Python buffer of the WKB. 
     289        sz = self.wkb_size 
     290        wkb = create_string_buffer(sz) 
     291        check_err(lgdal.OGR_G_ExportToWkb(self._g, byteorder, byref(wkb))) 
     292        return buffer(string_at(wkb, sz)) 
    248293 
    249294    @property 
     
    257302    def clone(self): 
    258303        "Clones this OGR Geometry." 
    259         return OGRGeometry(lgdal.OGR_G_Clone(self._g)) 
     304        return OGRGeometry(c_void_p(lgdal.OGR_G_Clone(self._g))) 
    260305 
    261306    def close_rings(self): 
     
    328373        "A helper routine for the OGR routines that generate geometries." 
    329374        if isinstance(other, OGRGeometry): 
    330             return OGRGeometry(gen_func(self._g, other._g)) 
    331         else: 
    332             return OGRGeometry(gen_func(self._g)) 
     375            return OGRGeometry(c_void_p(gen_func(self._g, other._g))) 
     376        else: 
     377            return OGRGeometry(c_void_p(gen_func(self._g))) 
    333378 
    334379    @property 
     
    383428    def tuple(self): 
    384429        "Returns the tuple of this point." 
    385         if self.coord_dim == 1: 
    386             return (self.x,) 
    387         elif self.coord_dim == 2: 
     430        if self.coord_dim == 2: 
    388431            return (self.x, self.y) 
    389432        elif self.coord_dim == 3: 
     
    442485            raise OGRIndexError('index out of range: %s' % str(index)) 
    443486        else: 
    444             return OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g, c_int(index))), self.srs) 
     487            return OGRGeometry(c_void_p(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g, c_int(index)))), self.srs) 
    445488 
    446489    # Polygon Properties 
     
    478521            raise OGRIndexError('index out of range: %s' % str(index)) 
    479522        else: 
    480             return OGRGeometry(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g, c_int(index))), self.srs) 
     523            return OGRGeometry(c_void_p(lgdal.OGR_G_Clone(lgdal.OGR_G_GetGeometryRef(self._g, c_int(index)))), self.srs) 
    481524         
    482525    def __iter__(self): 
     
    493536        if isinstance(geom, OGRGeometry): 
    494537            ptr = geom._g 
    495         elif isinstance(geom, StringType): 
     538        elif isinstance(geom, (StringType, UnicodeType)): 
    496539            tmp = OGRGeometry(geom) 
    497540            ptr = tmp._g 
  • django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py

    r6460 r6464  
    11import unittest 
    22from django.contrib.gis.gdal import OGRGeometry, OGRGeomType, OGRException, SpatialReference 
    3 from geometries import * 
     3from django.contrib.gis.tests.geometries import * 
    44 
    55class OGRGeomTest(unittest.TestCase): 
     
    4242            geom = OGRGeometry(g.wkt) 
    4343            self.assertEqual(g.gml, geom.gml) 
     44 
     45    def test01c_hex(self): 
     46        "Testing HEX input/output." 
     47        for g in hex_wkt: 
     48            geom1 = OGRGeometry(g.wkt) 
     49            self.assertEqual(g.hex, geom1.hex) 
     50            # Constructing w/HEX 
     51            geom2 = OGRGeometry(g.hex) 
     52            self.assertEqual(geom1, geom2) 
     53 
     54    def test01d_wkb(self): 
     55        "Testing WKB input/output." 
     56        from binascii import b2a_hex 
     57        for g in hex_wkt: 
     58            geom1 = OGRGeometry(g.wkt) 
     59            wkb = geom1.wkb 
     60            self.assertEqual(b2a_hex(wkb).upper(), g.hex) 
     61            # Constructing w/WKB. 
     62            geom2 = OGRGeometry(wkb) 
     63            self.assertEqual(geom1, geom2) 
    4464 
    4565    def test02_points(self):