|
1 from ctypes import c_char_p, c_int, c_size_t, c_uint, POINTER |
|
2 from django.contrib.gis.geos.libgeos import lgeos, CS_PTR, GEOM_PTR |
|
3 from django.contrib.gis.geos.prototypes.errcheck import \ |
|
4 check_geom, check_minus_one, check_sized_string, check_string, check_zero |
|
5 |
|
6 ### ctypes generation functions ### |
|
7 def bin_constructor(func): |
|
8 "Generates a prototype for binary construction (HEX, WKB) GEOS routines." |
|
9 func.argtypes = [c_char_p, c_size_t] |
|
10 func.restype = GEOM_PTR |
|
11 func.errcheck = check_geom |
|
12 return func |
|
13 |
|
14 # HEX & WKB output |
|
15 def bin_output(func): |
|
16 "Generates a prototype for the routines that return a a sized string." |
|
17 func.argtypes = [GEOM_PTR, POINTER(c_size_t)] |
|
18 func.errcheck = check_sized_string |
|
19 return func |
|
20 |
|
21 def geom_output(func, argtypes): |
|
22 "For GEOS routines that return a geometry." |
|
23 if argtypes: func.argtypes = argtypes |
|
24 func.restype = GEOM_PTR |
|
25 func.errcheck = check_geom |
|
26 return func |
|
27 |
|
28 def geom_index(func): |
|
29 "For GEOS routines that return geometries from an index." |
|
30 return geom_output(func, [GEOM_PTR, c_int]) |
|
31 |
|
32 def int_from_geom(func, zero=False): |
|
33 "Argument is a geometry, return type is an integer." |
|
34 func.argtypes = [GEOM_PTR] |
|
35 func.restype = c_int |
|
36 if zero: |
|
37 func.errcheck = check_zero |
|
38 else: |
|
39 func.errcheck = check_minus_one |
|
40 return func |
|
41 |
|
42 def string_from_geom(func): |
|
43 "Argument is a Geometry, return type is a string." |
|
44 # We do _not_ specify an argument type because we want just an |
|
45 # address returned from the function. |
|
46 func.argtypes = [GEOM_PTR] |
|
47 func.errcheck = check_string |
|
48 return func |
|
49 |
|
50 ### ctypes prototypes ### |
|
51 |
|
52 # TODO: Tell all users to use GEOS 3.0.0, instead of the release |
|
53 # candidates, and use the new Reader and Writer APIs (e.g., |
|
54 # GEOSWKT[Reader|Writer], GEOSWKB[Reader|Writer]). A good time |
|
55 # to do this will be when Refractions releases a Windows PostGIS |
|
56 # installer using GEOS 3.0.0. |
|
57 |
|
58 # Creation routines from WKB, HEX, WKT |
|
59 from_hex = bin_constructor(lgeos.GEOSGeomFromHEX_buf) |
|
60 from_wkb = bin_constructor(lgeos.GEOSGeomFromWKB_buf) |
|
61 from_wkt = geom_output(lgeos.GEOSGeomFromWKT, [c_char_p]) |
|
62 |
|
63 # Output routines |
|
64 to_hex = bin_output(lgeos.GEOSGeomToHEX_buf) |
|
65 to_wkb = bin_output(lgeos.GEOSGeomToWKB_buf) |
|
66 to_wkt = string_from_geom(lgeos.GEOSGeomToWKT) |
|
67 |
|
68 # The GEOS geometry type, typeid, num_coordites and number of geometries |
|
69 geos_normalize = int_from_geom(lgeos.GEOSNormalize) |
|
70 geos_type = string_from_geom(lgeos.GEOSGeomType) |
|
71 geos_typeid = int_from_geom(lgeos.GEOSGeomTypeId) |
|
72 get_dims = int_from_geom(lgeos.GEOSGeom_getDimensions, zero=True) |
|
73 get_num_coords = int_from_geom(lgeos.GEOSGetNumCoordinates) |
|
74 get_num_geoms = int_from_geom(lgeos.GEOSGetNumGeometries) |
|
75 |
|
76 # Geometry creation factories |
|
77 create_point = geom_output(lgeos.GEOSGeom_createPoint, [CS_PTR]) |
|
78 create_linestring = geom_output(lgeos.GEOSGeom_createLineString, [CS_PTR]) |
|
79 create_linearring = geom_output(lgeos.GEOSGeom_createLinearRing, [CS_PTR]) |
|
80 |
|
81 # Polygon and collection creation routines are special and will not |
|
82 # have their argument types defined. |
|
83 create_polygon = geom_output(lgeos.GEOSGeom_createPolygon, None) |
|
84 create_collection = geom_output(lgeos.GEOSGeom_createCollection, None) |
|
85 |
|
86 # Ring routines |
|
87 get_extring = geom_output(lgeos.GEOSGetExteriorRing, [GEOM_PTR]) |
|
88 get_intring = geom_index(lgeos.GEOSGetInteriorRingN) |
|
89 get_nrings = int_from_geom(lgeos.GEOSGetNumInteriorRings) |
|
90 |
|
91 # Collection Routines |
|
92 get_geomn = geom_index(lgeos.GEOSGetGeometryN) |
|
93 |
|
94 # Cloning |
|
95 geom_clone = lgeos.GEOSGeom_clone |
|
96 geom_clone.argtypes = [GEOM_PTR] |
|
97 geom_clone.restype = GEOM_PTR |
|
98 |
|
99 # Destruction routine. |
|
100 destroy_geom = lgeos.GEOSGeom_destroy |
|
101 destroy_geom.argtypes = [GEOM_PTR] |
|
102 destroy_geom.restype = None |
|
103 |
|
104 # SRID routines |
|
105 geos_get_srid = lgeos.GEOSGetSRID |
|
106 geos_get_srid.argtypes = [GEOM_PTR] |
|
107 geos_get_srid.restype = c_int |
|
108 |
|
109 geos_set_srid = lgeos.GEOSSetSRID |
|
110 geos_set_srid.argtypes = [GEOM_PTR, c_int] |
|
111 geos_set_srid.restype = None |