Loading django/contrib/gis/db/backends/spatialite/features.py +2 −3 Original line number Diff line number Diff line from django.contrib.gis.db.backends.base.features import BaseSpatialFeatures from django.contrib.gis.geos import geos_version from django.contrib.gis.geos import geos_version_info from django.db.backends.sqlite3.features import \ DatabaseFeatures as SQLiteDatabaseFeatures from django.utils.encoding import force_text from django.utils.functional import cached_property Loading @@ -20,4 +19,4 @@ class DatabaseFeatures(BaseSpatialFeatures, SQLiteDatabaseFeatures): @cached_property def supports_3d_storage(self): return force_text(geos_version()) >= '3.3' return geos_version_info()['version'] >= '3.3' django/contrib/gis/geos/libgeos.py +86 −60 Original line number Diff line number Diff line Loading @@ -14,9 +14,12 @@ from ctypes.util import find_library from django.contrib.gis.geos.error import GEOSException from django.core.exceptions import ImproperlyConfigured from django.utils.functional import SimpleLazyObject logger = logging.getLogger('django.contrib.gis') def load_geos(): # Custom library path set? try: from django.conf import settings Loading Loading @@ -53,12 +56,19 @@ if lib_path is None: 'Try setting GEOS_LIBRARY_PATH in your settings.' % '", "'.join(lib_names) ) # Getting the GEOS C library. The C interface (CDLL) is used for # both *NIX and Windows. # See the GEOS C API source code for more details on the library function calls: # http://geos.refractions.net/ro/doxygen_docs/html/geos__c_8h-source.html lgeos = CDLL(lib_path) _lgeos = CDLL(lib_path) # Here we set up the prototypes for the initGEOS_r and finishGEOS_r # routines. These functions aren't actually called until they are # attached to a GEOS context handle -- this actually occurs in # geos/prototypes/threadsafe.py. _lgeos.initGEOS_r.restype = CONTEXT_PTR _lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR] return _lgeos # The notice and error handler C function callback definitions. # Supposed to mimic the GEOS message handler (C below): Loading Loading @@ -120,11 +130,42 @@ def get_pointer_arr(n): GeomArr = GEOM_PTR * n return GeomArr() lgeos = SimpleLazyObject(load_geos) class GEOSFuncFactory(object): argtypes = None restype = None errcheck = None def __init__(self, func_name, *args, **kwargs): self.func_name = func_name self.restype = kwargs.pop('restype', self.restype) self.errcheck = kwargs.pop('errcheck', self.errcheck) self.argtypes = kwargs.pop('argtypes', self.argtypes) self.args = args self.kwargs = kwargs self.func = None def __call__(self, *args, **kwargs): if self.func is None: self.func = self.get_func(*self.args, **self.kwargs) return self.func(*args, **kwargs) def get_func(self, *args, **kwargs): from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc func = GEOSFunc(self.func_name) func.argtypes = self.argtypes or [] func.restype = self.restype if self.errcheck: func.errcheck = self.errcheck return func # Returns the string version of the GEOS library. Have to set the restype # explicitly to c_char_p to ensure compatibility across 32 and 64-bit platforms. geos_version = lgeos.GEOSversion geos_version.argtypes = None geos_version.restype = c_char_p geos_version = GEOSFuncFactory('GEOSversion', restype=c_char_p) # Regular expression should be able to parse version strings such as # '3.0.0rc4-CAPI-1.3.3', '3.0.0-CAPI-1.4.1', '3.4.0dev-CAPI-1.8.0' or '3.4.0dev-CAPI-1.8.0 r0' Loading @@ -147,18 +188,3 @@ def geos_version_info(): raise GEOSException('Could not parse version info string "%s"' % ver) return {key: m.group(key) for key in ( 'version', 'release_candidate', 'capi_version', 'major', 'minor', 'subminor')} # Version numbers and whether or not prepared geometry support is available. _verinfo = geos_version_info() GEOS_MAJOR_VERSION = int(_verinfo['major']) GEOS_MINOR_VERSION = int(_verinfo['minor']) GEOS_SUBMINOR_VERSION = int(_verinfo['subminor']) del _verinfo GEOS_VERSION = (GEOS_MAJOR_VERSION, GEOS_MINOR_VERSION, GEOS_SUBMINOR_VERSION) # Here we set up the prototypes for the initGEOS_r and finishGEOS_r # routines. These functions aren't actually called until they are # attached to a GEOS context handle -- this actually occurs in # geos/prototypes/threadsafe.py. lgeos.initGEOS_r.restype = CONTEXT_PTR lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR] django/contrib/gis/geos/prototypes/coordseq.py +54 −55 Original line number Diff line number Diff line from ctypes import POINTER, c_double, c_int, c_uint from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, GEOSFuncFactory from django.contrib.gis.geos.prototypes.errcheck import ( GEOSException, last_arg_byref, ) from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc # ## Error-checking routines specific to coordinate sequences. ## def check_cs_ptr(result, func, cargs): "Error checking on routines that return Geometries." if not result: raise GEOSException( 'Error encountered checking Coordinate Sequence returned from GEOS ' 'C function "%s".' % func.__name__ ) return result def check_cs_op(result, func, cargs): "Checks the status code of a coordinate sequence operation." if result == 0: Loading @@ -33,63 +22,73 @@ def check_cs_get(result, func, cargs): return last_arg_byref(cargs) # ## Coordinate sequence prototype generation functions. ## def cs_int(func): # ## Coordinate sequence prototype factory classes. ## class CsInt(GEOSFuncFactory): "For coordinate sequence routines that return an integer." func.argtypes = [CS_PTR, POINTER(c_uint)] func.restype = c_int func.errcheck = check_cs_get return func argtypes = [CS_PTR, POINTER(c_uint)] restype = c_int errcheck = staticmethod(check_cs_get) def cs_operation(func, ordinate=False, get=False): class CsOperation(GEOSFuncFactory): "For coordinate sequence operations." restype = c_int def get_func(self, ordinate=False, get=False): if get: # Get routines get double parameter passed-in by reference. func.errcheck = check_cs_get # Get routines have double parameter passed-in by reference. self.errcheck = check_cs_get dbl_param = POINTER(c_double) else: func.errcheck = check_cs_op self.errcheck = check_cs_op dbl_param = c_double if ordinate: # Get/Set ordinate routines have an extra uint parameter. func.argtypes = [CS_PTR, c_uint, c_uint, dbl_param] self.argtypes = [CS_PTR, c_uint, c_uint, dbl_param] else: func.argtypes = [CS_PTR, c_uint, dbl_param] self.argtypes = [CS_PTR, c_uint, dbl_param] return super(CsOperation, self).get_func() func.restype = c_int return func class CsOutput(GEOSFuncFactory): restype = CS_PTR def get_func(self, argtypes): self.argtypes = argtypes return super(CsOutput, self).get_func() @staticmethod def errcheck(result, func, cargs): if not result: raise GEOSException( 'Error encountered checking Coordinate Sequence returned from GEOS ' 'C function "%s".' % func.__name__ ) return result def cs_output(func, argtypes): "For routines that return a coordinate sequence." func.argtypes = argtypes func.restype = CS_PTR func.errcheck = check_cs_ptr return func # ## Coordinate Sequence ctypes prototypes ## # Coordinate Sequence constructors & cloning. cs_clone = cs_output(GEOSFunc('GEOSCoordSeq_clone'), [CS_PTR]) create_cs = cs_output(GEOSFunc('GEOSCoordSeq_create'), [c_uint, c_uint]) get_cs = cs_output(GEOSFunc('GEOSGeom_getCoordSeq'), [GEOM_PTR]) cs_clone = CsOutput('GEOSCoordSeq_clone', [CS_PTR]) create_cs = CsOutput('GEOSCoordSeq_create', [c_uint, c_uint]) get_cs = CsOutput('GEOSGeom_getCoordSeq', [GEOM_PTR]) # Getting, setting ordinate cs_getordinate = cs_operation(GEOSFunc('GEOSCoordSeq_getOrdinate'), ordinate=True, get=True) cs_setordinate = cs_operation(GEOSFunc('GEOSCoordSeq_setOrdinate'), ordinate=True) cs_getordinate = CsOperation('GEOSCoordSeq_getOrdinate', ordinate=True, get=True) cs_setordinate = CsOperation('GEOSCoordSeq_setOrdinate', ordinate=True) # For getting, x, y, z cs_getx = cs_operation(GEOSFunc('GEOSCoordSeq_getX'), get=True) cs_gety = cs_operation(GEOSFunc('GEOSCoordSeq_getY'), get=True) cs_getz = cs_operation(GEOSFunc('GEOSCoordSeq_getZ'), get=True) cs_getx = CsOperation('GEOSCoordSeq_getX', get=True) cs_gety = CsOperation('GEOSCoordSeq_getY', get=True) cs_getz = CsOperation('GEOSCoordSeq_getZ', get=True) # For setting, x, y, z cs_setx = cs_operation(GEOSFunc('GEOSCoordSeq_setX')) cs_sety = cs_operation(GEOSFunc('GEOSCoordSeq_setY')) cs_setz = cs_operation(GEOSFunc('GEOSCoordSeq_setZ')) cs_setx = CsOperation('GEOSCoordSeq_setX') cs_sety = CsOperation('GEOSCoordSeq_setY') cs_setz = CsOperation('GEOSCoordSeq_setZ') # These routines return size & dimensions. cs_getsize = cs_int(GEOSFunc('GEOSCoordSeq_getSize')) cs_getdims = cs_int(GEOSFunc('GEOSCoordSeq_getDimensions')) cs_getsize = CsInt('GEOSCoordSeq_getSize') cs_getdims = CsInt('GEOSCoordSeq_getDimensions') django/contrib/gis/geos/prototypes/errcheck.py +2 −3 Original line number Diff line number Diff line Loading @@ -4,13 +4,12 @@ from ctypes import c_void_p, string_at from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc from django.contrib.gis.geos.libgeos import GEOSFuncFactory # Getting the `free` routine used to free the memory allocated for # string pointers returned by GEOS. free = GEOSFunc('GEOSFree') free = GEOSFuncFactory('GEOSFree') free.argtypes = [c_void_p] free.restype = None def last_arg_byref(args): Loading django/contrib/gis/geos/prototypes/geom.py +56 −70 Original line number Diff line number Diff line from ctypes import POINTER, c_char_p, c_int, c_size_t, c_ubyte from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, GEOSFuncFactory from django.contrib.gis.geos.prototypes.errcheck import ( check_geom, check_minus_one, check_sized_string, check_string, check_zero, ) from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc # This is the return type used by binary output (WKB, HEX) routines. c_uchar_p = POINTER(c_ubyte) Loading @@ -21,109 +20,96 @@ class geos_char_p(c_char_p): pass # ### ctypes generation functions ### def bin_constructor(func): # ### ctypes factory classes ### class BinConstructor(GEOSFuncFactory): "Generates a prototype for binary construction (HEX, WKB) GEOS routines." func.argtypes = [c_char_p, c_size_t] func.restype = GEOM_PTR func.errcheck = check_geom return func argtypes = [c_char_p, c_size_t] restype = GEOM_PTR errcheck = staticmethod(check_geom) # HEX & WKB output def bin_output(func): class BinOutput(GEOSFuncFactory): "Generates a prototype for the routines that return a sized string." func.argtypes = [GEOM_PTR, POINTER(c_size_t)] func.errcheck = check_sized_string func.restype = c_uchar_p return func argtypes = [GEOM_PTR, POINTER(c_size_t)] restype = c_uchar_p errcheck = staticmethod(check_sized_string) def geom_output(func, argtypes): class GeomOutput(GEOSFuncFactory): "For GEOS routines that return a geometry." if argtypes: func.argtypes = argtypes func.restype = GEOM_PTR func.errcheck = check_geom return func restype = GEOM_PTR errcheck = staticmethod(check_geom) def get_func(self, argtypes): self.argtypes = argtypes return super(GeomOutput, self).get_func() def geom_index(func): "For GEOS routines that return geometries from an index." return geom_output(func, [GEOM_PTR, c_int]) def int_from_geom(func, zero=False): class IntFromGeom(GEOSFuncFactory): "Argument is a geometry, return type is an integer." func.argtypes = [GEOM_PTR] func.restype = c_int argtypes = [GEOM_PTR] restype = c_int def get_func(self, zero=False): if zero: func.errcheck = check_zero self.errcheck = check_zero else: func.errcheck = check_minus_one return func self.errcheck = check_minus_one return super(IntFromGeom, self).get_func() def string_from_geom(func): class StringFromGeom(GEOSFuncFactory): "Argument is a Geometry, return type is a string." func.argtypes = [GEOM_PTR] func.restype = geos_char_p func.errcheck = check_string return func argtypes = [GEOM_PTR] restype = geos_char_p errcheck = staticmethod(check_string) # ### ctypes prototypes ### # Deprecated creation routines from WKB, HEX, WKT from_hex = bin_constructor(GEOSFunc('GEOSGeomFromHEX_buf')) from_wkb = bin_constructor(GEOSFunc('GEOSGeomFromWKB_buf')) from_wkt = geom_output(GEOSFunc('GEOSGeomFromWKT'), [c_char_p]) from_hex = BinConstructor('GEOSGeomFromHEX_buf') from_wkb = BinConstructor('GEOSGeomFromWKB_buf') from_wkt = GeomOutput('GEOSGeomFromWKT', [c_char_p]) # Deprecated output routines to_hex = bin_output(GEOSFunc('GEOSGeomToHEX_buf')) to_wkb = bin_output(GEOSFunc('GEOSGeomToWKB_buf')) to_wkt = string_from_geom(GEOSFunc('GEOSGeomToWKT')) to_hex = BinOutput('GEOSGeomToHEX_buf') to_wkb = BinOutput('GEOSGeomToWKB_buf') to_wkt = StringFromGeom('GEOSGeomToWKT') # The GEOS geometry type, typeid, num_coordites and number of geometries geos_normalize = int_from_geom(GEOSFunc('GEOSNormalize')) geos_type = string_from_geom(GEOSFunc('GEOSGeomType')) geos_typeid = int_from_geom(GEOSFunc('GEOSGeomTypeId')) get_dims = int_from_geom(GEOSFunc('GEOSGeom_getDimensions'), zero=True) get_num_coords = int_from_geom(GEOSFunc('GEOSGetNumCoordinates')) get_num_geoms = int_from_geom(GEOSFunc('GEOSGetNumGeometries')) geos_normalize = IntFromGeom('GEOSNormalize') geos_type = StringFromGeom('GEOSGeomType') geos_typeid = IntFromGeom('GEOSGeomTypeId') get_dims = IntFromGeom('GEOSGeom_getDimensions', zero=True) get_num_coords = IntFromGeom('GEOSGetNumCoordinates') get_num_geoms = IntFromGeom('GEOSGetNumGeometries') # Geometry creation factories create_point = geom_output(GEOSFunc('GEOSGeom_createPoint'), [CS_PTR]) create_linestring = geom_output(GEOSFunc('GEOSGeom_createLineString'), [CS_PTR]) create_linearring = geom_output(GEOSFunc('GEOSGeom_createLinearRing'), [CS_PTR]) create_point = GeomOutput('GEOSGeom_createPoint', [CS_PTR]) create_linestring = GeomOutput('GEOSGeom_createLineString', [CS_PTR]) create_linearring = GeomOutput('GEOSGeom_createLinearRing', [CS_PTR]) # Polygon and collection creation routines are special and will not # have their argument types defined. create_polygon = geom_output(GEOSFunc('GEOSGeom_createPolygon'), None) create_collection = geom_output(GEOSFunc('GEOSGeom_createCollection'), None) create_polygon = GeomOutput('GEOSGeom_createPolygon', None) create_collection = GeomOutput('GEOSGeom_createCollection', None) # Ring routines get_extring = geom_output(GEOSFunc('GEOSGetExteriorRing'), [GEOM_PTR]) get_intring = geom_index(GEOSFunc('GEOSGetInteriorRingN')) get_nrings = int_from_geom(GEOSFunc('GEOSGetNumInteriorRings')) get_extring = GeomOutput('GEOSGetExteriorRing', [GEOM_PTR]) get_intring = GeomOutput('GEOSGetInteriorRingN', [GEOM_PTR, c_int]) get_nrings = IntFromGeom('GEOSGetNumInteriorRings') # Collection Routines get_geomn = geom_index(GEOSFunc('GEOSGetGeometryN')) get_geomn = GeomOutput('GEOSGetGeometryN', [GEOM_PTR, c_int]) # Cloning geom_clone = GEOSFunc('GEOSGeom_clone') geom_clone.argtypes = [GEOM_PTR] geom_clone.restype = GEOM_PTR geom_clone = GEOSFuncFactory('GEOSGeom_clone', argtypes=[GEOM_PTR], restype=GEOM_PTR) # Destruction routine. destroy_geom = GEOSFunc('GEOSGeom_destroy') destroy_geom.argtypes = [GEOM_PTR] destroy_geom.restype = None destroy_geom = GEOSFuncFactory('GEOSGeom_destroy', argtypes=[GEOM_PTR]) # SRID routines geos_get_srid = GEOSFunc('GEOSGetSRID') geos_get_srid.argtypes = [GEOM_PTR] geos_get_srid.restype = c_int geos_set_srid = GEOSFunc('GEOSSetSRID') geos_set_srid.argtypes = [GEOM_PTR, c_int] geos_set_srid.restype = None geos_get_srid = GEOSFuncFactory('GEOSGetSRID', argtypes=[GEOM_PTR], restype=c_int) geos_set_srid = GEOSFuncFactory('GEOSSetSRID', argtypes=[GEOM_PTR, c_int]) Loading
django/contrib/gis/db/backends/spatialite/features.py +2 −3 Original line number Diff line number Diff line from django.contrib.gis.db.backends.base.features import BaseSpatialFeatures from django.contrib.gis.geos import geos_version from django.contrib.gis.geos import geos_version_info from django.db.backends.sqlite3.features import \ DatabaseFeatures as SQLiteDatabaseFeatures from django.utils.encoding import force_text from django.utils.functional import cached_property Loading @@ -20,4 +19,4 @@ class DatabaseFeatures(BaseSpatialFeatures, SQLiteDatabaseFeatures): @cached_property def supports_3d_storage(self): return force_text(geos_version()) >= '3.3' return geos_version_info()['version'] >= '3.3'
django/contrib/gis/geos/libgeos.py +86 −60 Original line number Diff line number Diff line Loading @@ -14,9 +14,12 @@ from ctypes.util import find_library from django.contrib.gis.geos.error import GEOSException from django.core.exceptions import ImproperlyConfigured from django.utils.functional import SimpleLazyObject logger = logging.getLogger('django.contrib.gis') def load_geos(): # Custom library path set? try: from django.conf import settings Loading Loading @@ -53,12 +56,19 @@ if lib_path is None: 'Try setting GEOS_LIBRARY_PATH in your settings.' % '", "'.join(lib_names) ) # Getting the GEOS C library. The C interface (CDLL) is used for # both *NIX and Windows. # See the GEOS C API source code for more details on the library function calls: # http://geos.refractions.net/ro/doxygen_docs/html/geos__c_8h-source.html lgeos = CDLL(lib_path) _lgeos = CDLL(lib_path) # Here we set up the prototypes for the initGEOS_r and finishGEOS_r # routines. These functions aren't actually called until they are # attached to a GEOS context handle -- this actually occurs in # geos/prototypes/threadsafe.py. _lgeos.initGEOS_r.restype = CONTEXT_PTR _lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR] return _lgeos # The notice and error handler C function callback definitions. # Supposed to mimic the GEOS message handler (C below): Loading Loading @@ -120,11 +130,42 @@ def get_pointer_arr(n): GeomArr = GEOM_PTR * n return GeomArr() lgeos = SimpleLazyObject(load_geos) class GEOSFuncFactory(object): argtypes = None restype = None errcheck = None def __init__(self, func_name, *args, **kwargs): self.func_name = func_name self.restype = kwargs.pop('restype', self.restype) self.errcheck = kwargs.pop('errcheck', self.errcheck) self.argtypes = kwargs.pop('argtypes', self.argtypes) self.args = args self.kwargs = kwargs self.func = None def __call__(self, *args, **kwargs): if self.func is None: self.func = self.get_func(*self.args, **self.kwargs) return self.func(*args, **kwargs) def get_func(self, *args, **kwargs): from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc func = GEOSFunc(self.func_name) func.argtypes = self.argtypes or [] func.restype = self.restype if self.errcheck: func.errcheck = self.errcheck return func # Returns the string version of the GEOS library. Have to set the restype # explicitly to c_char_p to ensure compatibility across 32 and 64-bit platforms. geos_version = lgeos.GEOSversion geos_version.argtypes = None geos_version.restype = c_char_p geos_version = GEOSFuncFactory('GEOSversion', restype=c_char_p) # Regular expression should be able to parse version strings such as # '3.0.0rc4-CAPI-1.3.3', '3.0.0-CAPI-1.4.1', '3.4.0dev-CAPI-1.8.0' or '3.4.0dev-CAPI-1.8.0 r0' Loading @@ -147,18 +188,3 @@ def geos_version_info(): raise GEOSException('Could not parse version info string "%s"' % ver) return {key: m.group(key) for key in ( 'version', 'release_candidate', 'capi_version', 'major', 'minor', 'subminor')} # Version numbers and whether or not prepared geometry support is available. _verinfo = geos_version_info() GEOS_MAJOR_VERSION = int(_verinfo['major']) GEOS_MINOR_VERSION = int(_verinfo['minor']) GEOS_SUBMINOR_VERSION = int(_verinfo['subminor']) del _verinfo GEOS_VERSION = (GEOS_MAJOR_VERSION, GEOS_MINOR_VERSION, GEOS_SUBMINOR_VERSION) # Here we set up the prototypes for the initGEOS_r and finishGEOS_r # routines. These functions aren't actually called until they are # attached to a GEOS context handle -- this actually occurs in # geos/prototypes/threadsafe.py. lgeos.initGEOS_r.restype = CONTEXT_PTR lgeos.finishGEOS_r.argtypes = [CONTEXT_PTR]
django/contrib/gis/geos/prototypes/coordseq.py +54 −55 Original line number Diff line number Diff line from ctypes import POINTER, c_double, c_int, c_uint from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, GEOSFuncFactory from django.contrib.gis.geos.prototypes.errcheck import ( GEOSException, last_arg_byref, ) from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc # ## Error-checking routines specific to coordinate sequences. ## def check_cs_ptr(result, func, cargs): "Error checking on routines that return Geometries." if not result: raise GEOSException( 'Error encountered checking Coordinate Sequence returned from GEOS ' 'C function "%s".' % func.__name__ ) return result def check_cs_op(result, func, cargs): "Checks the status code of a coordinate sequence operation." if result == 0: Loading @@ -33,63 +22,73 @@ def check_cs_get(result, func, cargs): return last_arg_byref(cargs) # ## Coordinate sequence prototype generation functions. ## def cs_int(func): # ## Coordinate sequence prototype factory classes. ## class CsInt(GEOSFuncFactory): "For coordinate sequence routines that return an integer." func.argtypes = [CS_PTR, POINTER(c_uint)] func.restype = c_int func.errcheck = check_cs_get return func argtypes = [CS_PTR, POINTER(c_uint)] restype = c_int errcheck = staticmethod(check_cs_get) def cs_operation(func, ordinate=False, get=False): class CsOperation(GEOSFuncFactory): "For coordinate sequence operations." restype = c_int def get_func(self, ordinate=False, get=False): if get: # Get routines get double parameter passed-in by reference. func.errcheck = check_cs_get # Get routines have double parameter passed-in by reference. self.errcheck = check_cs_get dbl_param = POINTER(c_double) else: func.errcheck = check_cs_op self.errcheck = check_cs_op dbl_param = c_double if ordinate: # Get/Set ordinate routines have an extra uint parameter. func.argtypes = [CS_PTR, c_uint, c_uint, dbl_param] self.argtypes = [CS_PTR, c_uint, c_uint, dbl_param] else: func.argtypes = [CS_PTR, c_uint, dbl_param] self.argtypes = [CS_PTR, c_uint, dbl_param] return super(CsOperation, self).get_func() func.restype = c_int return func class CsOutput(GEOSFuncFactory): restype = CS_PTR def get_func(self, argtypes): self.argtypes = argtypes return super(CsOutput, self).get_func() @staticmethod def errcheck(result, func, cargs): if not result: raise GEOSException( 'Error encountered checking Coordinate Sequence returned from GEOS ' 'C function "%s".' % func.__name__ ) return result def cs_output(func, argtypes): "For routines that return a coordinate sequence." func.argtypes = argtypes func.restype = CS_PTR func.errcheck = check_cs_ptr return func # ## Coordinate Sequence ctypes prototypes ## # Coordinate Sequence constructors & cloning. cs_clone = cs_output(GEOSFunc('GEOSCoordSeq_clone'), [CS_PTR]) create_cs = cs_output(GEOSFunc('GEOSCoordSeq_create'), [c_uint, c_uint]) get_cs = cs_output(GEOSFunc('GEOSGeom_getCoordSeq'), [GEOM_PTR]) cs_clone = CsOutput('GEOSCoordSeq_clone', [CS_PTR]) create_cs = CsOutput('GEOSCoordSeq_create', [c_uint, c_uint]) get_cs = CsOutput('GEOSGeom_getCoordSeq', [GEOM_PTR]) # Getting, setting ordinate cs_getordinate = cs_operation(GEOSFunc('GEOSCoordSeq_getOrdinate'), ordinate=True, get=True) cs_setordinate = cs_operation(GEOSFunc('GEOSCoordSeq_setOrdinate'), ordinate=True) cs_getordinate = CsOperation('GEOSCoordSeq_getOrdinate', ordinate=True, get=True) cs_setordinate = CsOperation('GEOSCoordSeq_setOrdinate', ordinate=True) # For getting, x, y, z cs_getx = cs_operation(GEOSFunc('GEOSCoordSeq_getX'), get=True) cs_gety = cs_operation(GEOSFunc('GEOSCoordSeq_getY'), get=True) cs_getz = cs_operation(GEOSFunc('GEOSCoordSeq_getZ'), get=True) cs_getx = CsOperation('GEOSCoordSeq_getX', get=True) cs_gety = CsOperation('GEOSCoordSeq_getY', get=True) cs_getz = CsOperation('GEOSCoordSeq_getZ', get=True) # For setting, x, y, z cs_setx = cs_operation(GEOSFunc('GEOSCoordSeq_setX')) cs_sety = cs_operation(GEOSFunc('GEOSCoordSeq_setY')) cs_setz = cs_operation(GEOSFunc('GEOSCoordSeq_setZ')) cs_setx = CsOperation('GEOSCoordSeq_setX') cs_sety = CsOperation('GEOSCoordSeq_setY') cs_setz = CsOperation('GEOSCoordSeq_setZ') # These routines return size & dimensions. cs_getsize = cs_int(GEOSFunc('GEOSCoordSeq_getSize')) cs_getdims = cs_int(GEOSFunc('GEOSCoordSeq_getDimensions')) cs_getsize = CsInt('GEOSCoordSeq_getSize') cs_getdims = CsInt('GEOSCoordSeq_getDimensions')
django/contrib/gis/geos/prototypes/errcheck.py +2 −3 Original line number Diff line number Diff line Loading @@ -4,13 +4,12 @@ from ctypes import c_void_p, string_at from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc from django.contrib.gis.geos.libgeos import GEOSFuncFactory # Getting the `free` routine used to free the memory allocated for # string pointers returned by GEOS. free = GEOSFunc('GEOSFree') free = GEOSFuncFactory('GEOSFree') free.argtypes = [c_void_p] free.restype = None def last_arg_byref(args): Loading
django/contrib/gis/geos/prototypes/geom.py +56 −70 Original line number Diff line number Diff line from ctypes import POINTER, c_char_p, c_int, c_size_t, c_ubyte from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, GEOSFuncFactory from django.contrib.gis.geos.prototypes.errcheck import ( check_geom, check_minus_one, check_sized_string, check_string, check_zero, ) from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc # This is the return type used by binary output (WKB, HEX) routines. c_uchar_p = POINTER(c_ubyte) Loading @@ -21,109 +20,96 @@ class geos_char_p(c_char_p): pass # ### ctypes generation functions ### def bin_constructor(func): # ### ctypes factory classes ### class BinConstructor(GEOSFuncFactory): "Generates a prototype for binary construction (HEX, WKB) GEOS routines." func.argtypes = [c_char_p, c_size_t] func.restype = GEOM_PTR func.errcheck = check_geom return func argtypes = [c_char_p, c_size_t] restype = GEOM_PTR errcheck = staticmethod(check_geom) # HEX & WKB output def bin_output(func): class BinOutput(GEOSFuncFactory): "Generates a prototype for the routines that return a sized string." func.argtypes = [GEOM_PTR, POINTER(c_size_t)] func.errcheck = check_sized_string func.restype = c_uchar_p return func argtypes = [GEOM_PTR, POINTER(c_size_t)] restype = c_uchar_p errcheck = staticmethod(check_sized_string) def geom_output(func, argtypes): class GeomOutput(GEOSFuncFactory): "For GEOS routines that return a geometry." if argtypes: func.argtypes = argtypes func.restype = GEOM_PTR func.errcheck = check_geom return func restype = GEOM_PTR errcheck = staticmethod(check_geom) def get_func(self, argtypes): self.argtypes = argtypes return super(GeomOutput, self).get_func() def geom_index(func): "For GEOS routines that return geometries from an index." return geom_output(func, [GEOM_PTR, c_int]) def int_from_geom(func, zero=False): class IntFromGeom(GEOSFuncFactory): "Argument is a geometry, return type is an integer." func.argtypes = [GEOM_PTR] func.restype = c_int argtypes = [GEOM_PTR] restype = c_int def get_func(self, zero=False): if zero: func.errcheck = check_zero self.errcheck = check_zero else: func.errcheck = check_minus_one return func self.errcheck = check_minus_one return super(IntFromGeom, self).get_func() def string_from_geom(func): class StringFromGeom(GEOSFuncFactory): "Argument is a Geometry, return type is a string." func.argtypes = [GEOM_PTR] func.restype = geos_char_p func.errcheck = check_string return func argtypes = [GEOM_PTR] restype = geos_char_p errcheck = staticmethod(check_string) # ### ctypes prototypes ### # Deprecated creation routines from WKB, HEX, WKT from_hex = bin_constructor(GEOSFunc('GEOSGeomFromHEX_buf')) from_wkb = bin_constructor(GEOSFunc('GEOSGeomFromWKB_buf')) from_wkt = geom_output(GEOSFunc('GEOSGeomFromWKT'), [c_char_p]) from_hex = BinConstructor('GEOSGeomFromHEX_buf') from_wkb = BinConstructor('GEOSGeomFromWKB_buf') from_wkt = GeomOutput('GEOSGeomFromWKT', [c_char_p]) # Deprecated output routines to_hex = bin_output(GEOSFunc('GEOSGeomToHEX_buf')) to_wkb = bin_output(GEOSFunc('GEOSGeomToWKB_buf')) to_wkt = string_from_geom(GEOSFunc('GEOSGeomToWKT')) to_hex = BinOutput('GEOSGeomToHEX_buf') to_wkb = BinOutput('GEOSGeomToWKB_buf') to_wkt = StringFromGeom('GEOSGeomToWKT') # The GEOS geometry type, typeid, num_coordites and number of geometries geos_normalize = int_from_geom(GEOSFunc('GEOSNormalize')) geos_type = string_from_geom(GEOSFunc('GEOSGeomType')) geos_typeid = int_from_geom(GEOSFunc('GEOSGeomTypeId')) get_dims = int_from_geom(GEOSFunc('GEOSGeom_getDimensions'), zero=True) get_num_coords = int_from_geom(GEOSFunc('GEOSGetNumCoordinates')) get_num_geoms = int_from_geom(GEOSFunc('GEOSGetNumGeometries')) geos_normalize = IntFromGeom('GEOSNormalize') geos_type = StringFromGeom('GEOSGeomType') geos_typeid = IntFromGeom('GEOSGeomTypeId') get_dims = IntFromGeom('GEOSGeom_getDimensions', zero=True) get_num_coords = IntFromGeom('GEOSGetNumCoordinates') get_num_geoms = IntFromGeom('GEOSGetNumGeometries') # Geometry creation factories create_point = geom_output(GEOSFunc('GEOSGeom_createPoint'), [CS_PTR]) create_linestring = geom_output(GEOSFunc('GEOSGeom_createLineString'), [CS_PTR]) create_linearring = geom_output(GEOSFunc('GEOSGeom_createLinearRing'), [CS_PTR]) create_point = GeomOutput('GEOSGeom_createPoint', [CS_PTR]) create_linestring = GeomOutput('GEOSGeom_createLineString', [CS_PTR]) create_linearring = GeomOutput('GEOSGeom_createLinearRing', [CS_PTR]) # Polygon and collection creation routines are special and will not # have their argument types defined. create_polygon = geom_output(GEOSFunc('GEOSGeom_createPolygon'), None) create_collection = geom_output(GEOSFunc('GEOSGeom_createCollection'), None) create_polygon = GeomOutput('GEOSGeom_createPolygon', None) create_collection = GeomOutput('GEOSGeom_createCollection', None) # Ring routines get_extring = geom_output(GEOSFunc('GEOSGetExteriorRing'), [GEOM_PTR]) get_intring = geom_index(GEOSFunc('GEOSGetInteriorRingN')) get_nrings = int_from_geom(GEOSFunc('GEOSGetNumInteriorRings')) get_extring = GeomOutput('GEOSGetExteriorRing', [GEOM_PTR]) get_intring = GeomOutput('GEOSGetInteriorRingN', [GEOM_PTR, c_int]) get_nrings = IntFromGeom('GEOSGetNumInteriorRings') # Collection Routines get_geomn = geom_index(GEOSFunc('GEOSGetGeometryN')) get_geomn = GeomOutput('GEOSGetGeometryN', [GEOM_PTR, c_int]) # Cloning geom_clone = GEOSFunc('GEOSGeom_clone') geom_clone.argtypes = [GEOM_PTR] geom_clone.restype = GEOM_PTR geom_clone = GEOSFuncFactory('GEOSGeom_clone', argtypes=[GEOM_PTR], restype=GEOM_PTR) # Destruction routine. destroy_geom = GEOSFunc('GEOSGeom_destroy') destroy_geom.argtypes = [GEOM_PTR] destroy_geom.restype = None destroy_geom = GEOSFuncFactory('GEOSGeom_destroy', argtypes=[GEOM_PTR]) # SRID routines geos_get_srid = GEOSFunc('GEOSGetSRID') geos_get_srid.argtypes = [GEOM_PTR] geos_get_srid.restype = c_int geos_set_srid = GEOSFunc('GEOSSetSRID') geos_set_srid.argtypes = [GEOM_PTR, c_int] geos_set_srid.restype = None geos_get_srid = GEOSFuncFactory('GEOSGetSRID', argtypes=[GEOM_PTR], restype=c_int) geos_set_srid = GEOSFuncFactory('GEOSSetSRID', argtypes=[GEOM_PTR, c_int])