Simplified GEOSFuncFactory.
This commit is contained in:
parent
4ac2ab30f5
commit
ff17ef1ada
@ -12,7 +12,7 @@ from ctypes import CDLL, CFUNCTYPE, POINTER, Structure, c_char_p
|
|||||||
from ctypes.util import find_library
|
from ctypes.util import find_library
|
||||||
|
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.utils.functional import SimpleLazyObject
|
from django.utils.functional import SimpleLazyObject, cached_property
|
||||||
from django.utils.version import get_version_tuple
|
from django.utils.version import get_version_tuple
|
||||||
|
|
||||||
logger = logging.getLogger('django.contrib.gis')
|
logger = logging.getLogger('django.contrib.gis')
|
||||||
@ -148,14 +148,12 @@ class GEOSFuncFactory:
|
|||||||
self.argtypes = argtypes
|
self.argtypes = argtypes
|
||||||
self.args = args
|
self.args = args
|
||||||
self.kwargs = kwargs
|
self.kwargs = kwargs
|
||||||
self.func = None
|
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
if self.func is None:
|
|
||||||
self.func = self.get_func(*self.args, **self.kwargs)
|
|
||||||
return self.func(*args, **kwargs)
|
return self.func(*args, **kwargs)
|
||||||
|
|
||||||
def get_func(self, *args, **kwargs):
|
@cached_property
|
||||||
|
def func(self):
|
||||||
from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
|
from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
|
||||||
func = GEOSFunc(self.func_name)
|
func = GEOSFunc(self.func_name)
|
||||||
func.argtypes = self.argtypes or []
|
func.argtypes = self.argtypes or []
|
||||||
|
@ -34,30 +34,27 @@ class CsOperation(GEOSFuncFactory):
|
|||||||
"For coordinate sequence operations."
|
"For coordinate sequence operations."
|
||||||
restype = c_int
|
restype = c_int
|
||||||
|
|
||||||
def get_func(self, ordinate=False, get=False):
|
def __init__(self, *args, ordinate=False, get=False, **kwargs):
|
||||||
if get:
|
if get:
|
||||||
# Get routines have double parameter passed-in by reference.
|
# Get routines have double parameter passed-in by reference.
|
||||||
self.errcheck = check_cs_get
|
errcheck = check_cs_get
|
||||||
dbl_param = POINTER(c_double)
|
dbl_param = POINTER(c_double)
|
||||||
else:
|
else:
|
||||||
self.errcheck = check_cs_op
|
errcheck = check_cs_op
|
||||||
dbl_param = c_double
|
dbl_param = c_double
|
||||||
|
|
||||||
if ordinate:
|
if ordinate:
|
||||||
# Get/Set ordinate routines have an extra uint parameter.
|
# Get/Set ordinate routines have an extra uint parameter.
|
||||||
self.argtypes = [CS_PTR, c_uint, c_uint, dbl_param]
|
argtypes = [CS_PTR, c_uint, c_uint, dbl_param]
|
||||||
else:
|
else:
|
||||||
self.argtypes = [CS_PTR, c_uint, dbl_param]
|
argtypes = [CS_PTR, c_uint, dbl_param]
|
||||||
return super().get_func()
|
|
||||||
|
super().__init__(*args, **dict(kwargs, errcheck=errcheck, argtypes=argtypes))
|
||||||
|
|
||||||
|
|
||||||
class CsOutput(GEOSFuncFactory):
|
class CsOutput(GEOSFuncFactory):
|
||||||
restype = CS_PTR
|
restype = CS_PTR
|
||||||
|
|
||||||
def get_func(self, argtypes):
|
|
||||||
self.argtypes = argtypes
|
|
||||||
return super().get_func()
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def errcheck(result, func, cargs):
|
def errcheck(result, func, cargs):
|
||||||
if not result:
|
if not result:
|
||||||
@ -71,9 +68,9 @@ class CsOutput(GEOSFuncFactory):
|
|||||||
# ## Coordinate Sequence ctypes prototypes ##
|
# ## Coordinate Sequence ctypes prototypes ##
|
||||||
|
|
||||||
# Coordinate Sequence constructors & cloning.
|
# Coordinate Sequence constructors & cloning.
|
||||||
cs_clone = CsOutput('GEOSCoordSeq_clone', [CS_PTR])
|
cs_clone = CsOutput('GEOSCoordSeq_clone', argtypes=[CS_PTR])
|
||||||
create_cs = CsOutput('GEOSCoordSeq_create', [c_uint, c_uint])
|
create_cs = CsOutput('GEOSCoordSeq_create', argtypes=[c_uint, c_uint])
|
||||||
get_cs = CsOutput('GEOSGeom_getCoordSeq', [GEOM_PTR])
|
get_cs = CsOutput('GEOSGeom_getCoordSeq', argtypes=[GEOM_PTR])
|
||||||
|
|
||||||
# Getting, setting ordinate
|
# Getting, setting ordinate
|
||||||
cs_getordinate = CsOperation('GEOSCoordSeq_getOrdinate', ordinate=True, get=True)
|
cs_getordinate = CsOperation('GEOSCoordSeq_getOrdinate', ordinate=True, get=True)
|
||||||
|
@ -81,11 +81,3 @@ def check_string(result, func, cargs):
|
|||||||
# Freeing the memory allocated within GEOS
|
# Freeing the memory allocated within GEOS
|
||||||
free(result)
|
free(result)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
|
|
||||||
def check_zero(result, func, cargs):
|
|
||||||
"Error checking on routines that should not return 0."
|
|
||||||
if result == 0:
|
|
||||||
raise GEOSException('Error encountered in GEOS C function "%s".' % func.__name__)
|
|
||||||
else:
|
|
||||||
return result
|
|
||||||
|
@ -2,7 +2,7 @@ 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, GEOSFuncFactory
|
from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, GEOSFuncFactory
|
||||||
from django.contrib.gis.geos.prototypes.errcheck import (
|
from django.contrib.gis.geos.prototypes.errcheck import (
|
||||||
check_geom, check_minus_one, check_sized_string, check_string, check_zero,
|
check_geom, check_minus_one, check_sized_string, check_string,
|
||||||
)
|
)
|
||||||
|
|
||||||
# This is the return type used by binary output (WKB, HEX) routines.
|
# This is the return type used by binary output (WKB, HEX) routines.
|
||||||
@ -41,22 +41,12 @@ class GeomOutput(GEOSFuncFactory):
|
|||||||
restype = GEOM_PTR
|
restype = GEOM_PTR
|
||||||
errcheck = staticmethod(check_geom)
|
errcheck = staticmethod(check_geom)
|
||||||
|
|
||||||
def get_func(self, argtypes):
|
|
||||||
self.argtypes = argtypes
|
|
||||||
return super().get_func()
|
|
||||||
|
|
||||||
|
|
||||||
class IntFromGeom(GEOSFuncFactory):
|
class IntFromGeom(GEOSFuncFactory):
|
||||||
"Argument is a geometry, return type is an integer."
|
"Argument is a geometry, return type is an integer."
|
||||||
argtypes = [GEOM_PTR]
|
argtypes = [GEOM_PTR]
|
||||||
restype = c_int
|
restype = c_int
|
||||||
|
errcheck = staticmethod(check_minus_one)
|
||||||
def get_func(self, zero=False):
|
|
||||||
if zero:
|
|
||||||
self.errcheck = check_zero
|
|
||||||
else:
|
|
||||||
self.errcheck = check_minus_one
|
|
||||||
return super().get_func()
|
|
||||||
|
|
||||||
|
|
||||||
class StringFromGeom(GEOSFuncFactory):
|
class StringFromGeom(GEOSFuncFactory):
|
||||||
@ -77,23 +67,23 @@ get_num_coords = IntFromGeom('GEOSGetNumCoordinates')
|
|||||||
get_num_geoms = IntFromGeom('GEOSGetNumGeometries')
|
get_num_geoms = IntFromGeom('GEOSGetNumGeometries')
|
||||||
|
|
||||||
# Geometry creation factories
|
# Geometry creation factories
|
||||||
create_point = GeomOutput('GEOSGeom_createPoint', [CS_PTR])
|
create_point = GeomOutput('GEOSGeom_createPoint', argtypes=[CS_PTR])
|
||||||
create_linestring = GeomOutput('GEOSGeom_createLineString', [CS_PTR])
|
create_linestring = GeomOutput('GEOSGeom_createLineString', argtypes=[CS_PTR])
|
||||||
create_linearring = GeomOutput('GEOSGeom_createLinearRing', [CS_PTR])
|
create_linearring = GeomOutput('GEOSGeom_createLinearRing', argtypes=[CS_PTR])
|
||||||
|
|
||||||
# Polygon and collection creation routines are special and will not
|
# Polygon and collection creation routines are special and will not
|
||||||
# have their argument types defined.
|
# have their argument types defined.
|
||||||
create_polygon = GeomOutput('GEOSGeom_createPolygon', None)
|
create_polygon = GeomOutput('GEOSGeom_createPolygon')
|
||||||
create_empty_polygon = GeomOutput('GEOSGeom_createEmptyPolygon', None)
|
create_empty_polygon = GeomOutput('GEOSGeom_createEmptyPolygon')
|
||||||
create_collection = GeomOutput('GEOSGeom_createCollection', None)
|
create_collection = GeomOutput('GEOSGeom_createCollection')
|
||||||
|
|
||||||
# Ring routines
|
# Ring routines
|
||||||
get_extring = GeomOutput('GEOSGetExteriorRing', [GEOM_PTR])
|
get_extring = GeomOutput('GEOSGetExteriorRing', argtypes=[GEOM_PTR])
|
||||||
get_intring = GeomOutput('GEOSGetInteriorRingN', [GEOM_PTR, c_int])
|
get_intring = GeomOutput('GEOSGetInteriorRingN', argtypes=[GEOM_PTR, c_int])
|
||||||
get_nrings = IntFromGeom('GEOSGetNumInteriorRings')
|
get_nrings = IntFromGeom('GEOSGetNumInteriorRings')
|
||||||
|
|
||||||
# Collection Routines
|
# Collection Routines
|
||||||
get_geomn = GeomOutput('GEOSGetGeometryN', [GEOM_PTR, c_int])
|
get_geomn = GeomOutput('GEOSGetGeometryN', argtypes=[GEOM_PTR, c_int])
|
||||||
|
|
||||||
# Cloning
|
# Cloning
|
||||||
geom_clone = GEOSFuncFactory('GEOSGeom_clone', argtypes=[GEOM_PTR], restype=GEOM_PTR)
|
geom_clone = GEOSFuncFactory('GEOSGeom_clone', argtypes=[GEOM_PTR], restype=GEOM_PTR)
|
||||||
|
@ -118,9 +118,7 @@ class IOBase(GEOSBase):
|
|||||||
self.ptr = self._constructor()
|
self.ptr = self._constructor()
|
||||||
# Loading the real destructor function at this point as doing it in
|
# Loading the real destructor function at this point as doing it in
|
||||||
# __del__ is too late (import error).
|
# __del__ is too late (import error).
|
||||||
self.destructor.func = self.destructor.get_func(
|
self.destructor.func
|
||||||
*self.destructor.args, **self.destructor.kwargs
|
|
||||||
)
|
|
||||||
|
|
||||||
# ### Base WKB/WKT Reading and Writing objects ###
|
# ### Base WKB/WKT Reading and Writing objects ###
|
||||||
|
|
||||||
|
@ -19,19 +19,13 @@ class DblFromGeom(GEOSFuncFactory):
|
|||||||
restype = c_int # Status code returned
|
restype = c_int # Status code returned
|
||||||
errcheck = staticmethod(check_dbl)
|
errcheck = staticmethod(check_dbl)
|
||||||
|
|
||||||
def get_func(self, num_geom=1):
|
|
||||||
argtypes = [GEOM_PTR for i in range(num_geom)]
|
|
||||||
argtypes += [POINTER(c_double)]
|
|
||||||
self.argtypes = argtypes
|
|
||||||
return super().get_func()
|
|
||||||
|
|
||||||
|
|
||||||
# ### ctypes prototypes ###
|
# ### ctypes prototypes ###
|
||||||
|
|
||||||
# Area, distance, and length prototypes.
|
# Area, distance, and length prototypes.
|
||||||
geos_area = DblFromGeom('GEOSArea')
|
geos_area = DblFromGeom('GEOSArea', argtypes=[GEOM_PTR, POINTER(c_double)])
|
||||||
geos_distance = DblFromGeom('GEOSDistance', num_geom=2)
|
geos_distance = DblFromGeom('GEOSDistance', argtypes=[GEOM_PTR, GEOM_PTR, POINTER(c_double)])
|
||||||
geos_length = DblFromGeom('GEOSLength')
|
geos_length = DblFromGeom('GEOSLength', argtypes=[GEOM_PTR, POINTER(c_double)])
|
||||||
geos_isvalidreason = GEOSFuncFactory(
|
geos_isvalidreason = GEOSFuncFactory(
|
||||||
'GEOSisValidReason', restype=geos_char_p, errcheck=check_string, argtypes=[GEOM_PTR]
|
'GEOSisValidReason', restype=geos_char_p, errcheck=check_string, argtypes=[GEOM_PTR]
|
||||||
)
|
)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user