Django

Code

Changeset 7107

Show
Ignore:
Timestamp:
02/12/08 18:38:36 (5 months ago)
Author:
jbronn
Message:

gis: gdal: Added support for GeoJSON input/output in OGRGeometry.

Files:

Legend:

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

    r7012 r7107  
    4343from binascii import a2b_hex 
    4444from ctypes import byref, string_at, c_char_p, c_double, c_ubyte, c_void_p 
    45 from types import BufferType, IntType, StringType, UnicodeType 
     45from types import UnicodeType 
    4646 
    4747# Getting GDAL prerequisites 
     
    6363hex_regex = re.compile(r'^[0-9A-F]+$', re.I) 
    6464wkt_regex = re.compile(r'^(?P<type>POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+$', re.I) 
     65json_regex = re.compile(r'^\{.+\}$') 
    6566 
    6667#### OGRGeometry Class #### 
     
    7273 
    7374        self._ptr = c_void_p(None) # Initially NULL 
    74  
    75         # Checking if unicode 
    76         if isinstance(geom_input, UnicodeType): 
    77             # Encoding to ASCII, WKT or HEX doesn't need any more. 
    78             geo_input = geo_input.encode('ascii') 
     75        str_instance = isinstance(geom_input, basestring) 
    7976 
    8077        # If HEX, unpack input to to a binary buffer. 
    81         if isinstance(geom_input, StringType) and hex_regex.match(geom_input): 
     78        if str_instance and hex_regex.match(geom_input): 
    8279            geom_input = buffer(a2b_hex(geom_input.upper())) 
    83  
    84         if isinstance(geom_input, StringType): 
    85             m = wkt_regex.match(geom_input) 
    86             if m: 
    87                 if m.group('type').upper() == 'LINEARRING': 
     80            str_instance = False 
     81 
     82        # Constructing the geometry,  
     83        if str_instance: 
     84            # Checking if unicode 
     85            if isinstance(geom_input, UnicodeType): 
     86                # Encoding to ASCII, WKT or HEX doesn't need any more. 
     87                geo_input = geo_input.encode('ascii') 
     88 
     89            wkt_m = wkt_regex.match(geom_input) 
     90            json_m = json_regex.match(geom_input) 
     91            if wkt_m: 
     92                if wkt_m.group('type').upper() == 'LINEARRING': 
    8893                    # OGR_G_CreateFromWkt doesn't work with LINEARRING WKT. 
    8994                    #  See http://trac.osgeo.org/gdal/ticket/1992. 
    90                     g = create_geom(OGRGeomType(m.group('type')).num) 
     95                    g = create_geom(OGRGeomType(wkt_m.group('type')).num) 
    9196                    import_wkt(g, byref(c_char_p(geom_input))) 
    9297                else: 
    9398                    g = from_wkt(byref(c_char_p(geom_input)), None, byref(c_void_p())) 
     99            elif json_m: 
     100                if GEOJSON: 
     101                    g = from_json(geom_input) 
     102                else: 
     103                    raise NotImplementedError('GeoJSON input only supported on GDAL 1.5+.') 
    94104            else: 
    95105                # Seeing if the input is a valid short-hand string 
     
    97107                ogr_t = OGRGeomType(geom_input) 
    98108                g = create_geom(OGRGeomType(geom_input).num) 
    99         elif isinstance(geom_input, BufferType): 
     109        elif isinstance(geom_input, buffer): 
    100110            # WKB was passed in 
    101111            g = from_wkb(str(geom_input), None, byref(c_void_p()), len(geom_input)) 
     
    224234        if isinstance(srs, SpatialReference): 
    225235            srs_ptr = clone_srs(srs._ptr) 
    226         elif isinstance(srs, (StringType, UnicodeType, IntType)): 
     236        elif isinstance(srs, (int, long, basestring)): 
    227237            sr = SpatialReference(srs) 
    228238            srs_ptr = clone_srs(sr._ptr) 
     
    239249 
    240250    def set_srid(self, srid): 
    241         if isinstance(srid, IntType): 
     251        if isinstance(srid, (int, long)): 
    242252            self.srs = srid 
    243253        else: 
     
    263273        return str(self.wkb).encode('hex').upper() 
    264274        #return b2a_hex(self.wkb).upper() 
     275 
     276    @property 
     277    def json(self): 
     278        if GEOJSON:  
     279            return to_json(self._ptr) 
     280        else: 
     281            raise NotImplementedError('GeoJSON output only supported on GDAL 1.5+.') 
     282    geojson = json 
    265283 
    266284    @property 
     
    311329        elif isinstance(coord_trans, SpatialReference): 
    312330            geom_transform_to(self._ptr, coord_trans._ptr) 
    313         elif isinstance(coord_trans, (int, basestring)): 
     331        elif isinstance(coord_trans, (int, long, basestring)): 
    314332            sr = SpatialReference(coord_trans) 
    315333            geom_transform_to(self._ptr, sr._ptr) 
     
    543561            else: 
    544562                add_geom(self._ptr, geom._ptr) 
    545         elif isinstance(geom, (StringType, UnicodeType)): 
     563        elif isinstance(geom, basestring): 
    546564            tmp = OGRGeometry(geom) 
    547565            add_geom(self._ptr, tmp._ptr) 
  • django/branches/gis/django/contrib/gis/gdal/libgdal.py

    r6993 r7107  
    11import os, sys 
    2 from ctypes import CDLL, string_at 
     2from ctypes import c_char_p, CDLL 
    33from ctypes.util import find_library 
    44from django.contrib.gis.gdal.error import OGRException 
     
    4949 
    5050#### Version-information functions. #### 
    51 def _version_info(key): 
    52     "Returns GDAL library version information with the given key." 
    53     buf = lgdal.GDALVersionInfo(key) 
    54     if buf: return string_at(buf) 
     51 
     52# Returns GDAL library version information with the given key. 
     53_version_info = lgdal.GDALVersionInfo 
     54_version_info.argtypes = [c_char_p] 
     55_version_info.restype = c_char_p 
    5556 
    5657def gdal_version(): 
     
    6869    will be returned instead. 
    6970    """ 
    70     from datetime import datetim
     71    from datetime import date as date_typ
    7172    rel = _version_info('RELEASE_DATE') 
    7273    yy, mm, dd = map(int, (rel[0:4], rel[4:6], rel[6:8])) 
    73     d = datetime(yy, mm, dd) 
     74    d = date_type(yy, mm, dd) 
    7475    if date: return d 
    7576    else: return d.strftime('%Y/%m/%d') 
  • django/branches/gis/django/contrib/gis/gdal/prototypes/geom.py

    r6914 r7107  
     1from datetime import date 
    12from ctypes import c_char, c_char_p, c_double, c_int, c_ubyte, c_void_p, POINTER 
    23from django.contrib.gis.gdal.envelope import OGREnvelope 
    3 from django.contrib.gis.gdal.libgdal import lgdal 
     4from django.contrib.gis.gdal.libgdal import lgdal, gdal_version 
    45from django.contrib.gis.gdal.prototypes.errcheck import check_bool, check_envelope 
    56from django.contrib.gis.gdal.prototypes.generation import \ 
    67    const_string_output, double_output, geom_output, int_output, \ 
    78    srs_output, string_output, void_output 
     9 
     10# Some prototypes need to be aware of what version GDAL we have. 
     11major, minor1, minor2 = map(int, gdal_version().split('.')) 
     12if major <= 1 and minor1 <= 4: 
     13    GEOJSON = False 
     14else: 
     15    GEOJSON = True 
    816 
    917### Generation routines specific to this module ### 
     
    2634 
    2735### OGR_G ctypes function prototypes ### 
     36 
     37# GeoJSON routines, if supported. 
     38if GEOJSON: 
     39    from_json = geom_output(lgdal.OGR_G_CreateGeometryFromJson, [c_char_p]) 
     40    to_json = string_output(lgdal.OGR_G_ExportToJson, [c_void_p], str_result=True) 
     41else: 
     42    from_json = False 
     43    to_json = False 
    2844 
    2945# GetX, GetY, GetZ all return doubles. 
  • django/branches/gis/django/contrib/gis/tests/geometries.py

    r6440 r7107  
    152152                 ) 
    153153 
     154json_geoms = (TestGeom('POINT(100 0)', json='{ "type": "Point", "coordinates": [ 100.000000, 0.000000 ] }'), 
     155              TestGeom('MULTIPOLYGON(((102 2, 103 2, 103 3, 102 3, 102 2)), ((100.0 0.0, 101.0 0.0, 101.0 1.0, 100.0 1.0, 100.0 0.0), (100.2 0.2, 100.8 0.2, 100.8 0.8, 100.2 0.8, 100.2 0.2)))', json='{ "type": "MultiPolygon", "coordinates": [ [ [ [ 102.000000, 2.000000 ], [ 103.000000, 2.000000 ], [ 103.000000, 3.000000 ], [ 102.000000, 3.000000 ], [ 102.000000, 2.000000 ] ] ], [ [ [ 100.000000, 0.000000 ], [ 101.000000, 0.000000 ], [ 101.000000, 1.000000 ], [ 100.000000, 1.000000 ], [ 100.000000, 0.000000 ] ], [ [ 100.200000, 0.200000 ], [ 100.800000, 0.200000 ], [ 100.800000, 0.800000 ], [ 100.200000, 0.800000 ], [ 100.200000, 0.200000 ] ] ] ] }'), 
     156              ) 
  • django/branches/gis/django/contrib/gis/tests/test_gdal_geom.py

    r7012 r7107  
    6363            geom2 = OGRGeometry(wkb) 
    6464            self.assertEqual(geom1, geom2) 
     65 
     66    def test01e_json(self): 
     67        "Testing GeoJSON input/output." 
     68        from django.contrib.gis.gdal.prototypes.geom import GEOJSON 
     69        if not GEOJSON: return 
     70        for g in json_geoms: 
     71            geom = OGRGeometry(g.wkt) 
     72            self.assertEqual(g.json, geom.json) 
     73            self.assertEqual(g.json, geom.geojson) 
     74            self.assertEqual(OGRGeometry(g.wkt), OGRGeometry(geom.json)) 
    6575 
    6676    def test02_points(self):