| from ctypes import c_double, c_int, c_uint, POINTER |
| from django.contrib.gis.geos.libgeos import GEOM_PTR, CS_PTR |
| from django.contrib.gis.geos.prototypes.errcheck import last_arg_byref, GEOSException |
| 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: |
| raise GEOSException('Could not set value on coordinate sequence') |
| else: |
| return result |
| |
| def check_cs_get(result, func, cargs): |
| "Checking the coordinate sequence retrieval." |
| check_cs_op(result, func, cargs) |
| # Object in by reference, return its value. |
| return last_arg_byref(cargs) |
| |
| ## Coordinate sequence prototype generation functions. ## |
| def cs_int(func): |
| "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 |
| |
| def cs_operation(func, ordinate=False, get=False): |
| "For coordinate sequence operations." |
| if get: |
| # Get routines get double parameter passed-in by reference. |
| func.errcheck = check_cs_get |
| dbl_param = POINTER(c_double) |
| else: |
| func.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] |
| else: |
| func.argtypes = [CS_PTR, c_uint, dbl_param] |
| |
| func.restype = c_int |
| return func |
| |
| 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]) |
| |
| # Getting, setting ordinate |
| cs_getordinate = cs_operation(GEOSFunc('GEOSCoordSeq_getOrdinate'), ordinate=True, get=True) |
| cs_setordinate = cs_operation(GEOSFunc('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) |
| |
| # 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')) |
| |
| # These routines return size & dimensions. |
| cs_getsize = cs_int(GEOSFunc('GEOSCoordSeq_getSize')) |
| cs_getdims = cs_int(GEOSFunc('GEOSCoordSeq_getDimensions')) |