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