You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

coordseq.py 2.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. from ctypes import POINTER, c_double, c_int, c_uint
  2. from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, GEOSFuncFactory
  3. from django.contrib.gis.geos.prototypes.errcheck import (
  4. GEOSException, last_arg_byref,
  5. )
  6. # ## Error-checking routines specific to coordinate sequences. ##
  7. def check_cs_op(result, func, cargs):
  8. "Check the status code of a coordinate sequence operation."
  9. if result == 0:
  10. raise GEOSException('Could not set value on coordinate sequence')
  11. else:
  12. return result
  13. def check_cs_get(result, func, cargs):
  14. "Check the coordinate sequence retrieval."
  15. check_cs_op(result, func, cargs)
  16. # Object in by reference, return its value.
  17. return last_arg_byref(cargs)
  18. # ## Coordinate sequence prototype factory classes. ##
  19. class CsInt(GEOSFuncFactory):
  20. "For coordinate sequence routines that return an integer."
  21. argtypes = [CS_PTR, POINTER(c_uint)]
  22. restype = c_int
  23. errcheck = staticmethod(check_cs_get)
  24. class CsOperation(GEOSFuncFactory):
  25. "For coordinate sequence operations."
  26. restype = c_int
  27. def __init__(self, *args, ordinate=False, get=False, **kwargs):
  28. if get:
  29. # Get routines have double parameter passed-in by reference.
  30. errcheck = check_cs_get
  31. dbl_param = POINTER(c_double)
  32. else:
  33. errcheck = check_cs_op
  34. dbl_param = c_double
  35. if ordinate:
  36. # Get/Set ordinate routines have an extra uint parameter.
  37. argtypes = [CS_PTR, c_uint, c_uint, dbl_param]
  38. else:
  39. argtypes = [CS_PTR, c_uint, dbl_param]
  40. super().__init__(*args, **{**kwargs, 'errcheck': errcheck, 'argtypes': argtypes})
  41. class CsOutput(GEOSFuncFactory):
  42. restype = CS_PTR
  43. @staticmethod
  44. def errcheck(result, func, cargs):
  45. if not result:
  46. raise GEOSException(
  47. 'Error encountered checking Coordinate Sequence returned from GEOS '
  48. 'C function "%s".' % func.__name__
  49. )
  50. return result
  51. # ## Coordinate Sequence ctypes prototypes ##
  52. # Coordinate Sequence constructors & cloning.
  53. cs_clone = CsOutput('GEOSCoordSeq_clone', argtypes=[CS_PTR])
  54. create_cs = CsOutput('GEOSCoordSeq_create', argtypes=[c_uint, c_uint])
  55. get_cs = CsOutput('GEOSGeom_getCoordSeq', argtypes=[GEOM_PTR])
  56. # Getting, setting ordinate
  57. cs_getordinate = CsOperation('GEOSCoordSeq_getOrdinate', ordinate=True, get=True)
  58. cs_setordinate = CsOperation('GEOSCoordSeq_setOrdinate', ordinate=True)
  59. # For getting, x, y, z
  60. cs_getx = CsOperation('GEOSCoordSeq_getX', get=True)
  61. cs_gety = CsOperation('GEOSCoordSeq_getY', get=True)
  62. cs_getz = CsOperation('GEOSCoordSeq_getZ', get=True)
  63. # For setting, x, y, z
  64. cs_setx = CsOperation('GEOSCoordSeq_setX')
  65. cs_sety = CsOperation('GEOSCoordSeq_setY')
  66. cs_setz = CsOperation('GEOSCoordSeq_setZ')
  67. # These routines return size & dimensions.
  68. cs_getsize = CsInt('GEOSCoordSeq_getSize')
  69. cs_getdims = CsInt('GEOSCoordSeq_getDimensions')