/django/contrib/gis/geos/prototypes/geom.py
Python | 119 lines | 77 code | 20 blank | 22 comment | 2 complexity | 7b48cc04eff355e1e3fd736ff223beb3 MD5 | raw file
1from ctypes import c_char_p, c_int, c_size_t, c_ubyte, c_uint, POINTER 2from django.contrib.gis.geos.libgeos import CS_PTR, GEOM_PTR, PREPGEOM_PTR, GEOS_PREPARE 3from django.contrib.gis.geos.prototypes.errcheck import \ 4 check_geom, check_minus_one, check_sized_string, check_string, check_zero 5from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc 6 7# This is the return type used by binary output (WKB, HEX) routines. 8c_uchar_p = POINTER(c_ubyte) 9 10# We create a simple subclass of c_char_p here because when the response 11# type is set to c_char_p, you get a _Python_ string and there's no way 12# to access the string's address inside the error checking function. 13# In other words, you can't free the memory allocated inside GEOS. Previously, 14# the return type would just be omitted and the integer address would be 15# used -- but this allows us to be specific in the function definition and 16# keeps the reference so it may be free'd. 17class geos_char_p(c_char_p): 18 pass 19 20### ctypes generation functions ### 21def bin_constructor(func): 22 "Generates a prototype for binary construction (HEX, WKB) GEOS routines." 23 func.argtypes = [c_char_p, c_size_t] 24 func.restype = GEOM_PTR 25 func.errcheck = check_geom 26 return func 27 28# HEX & WKB output 29def bin_output(func): 30 "Generates a prototype for the routines that return a a sized string." 31 func.argtypes = [GEOM_PTR, POINTER(c_size_t)] 32 func.errcheck = check_sized_string 33 func.restype = c_uchar_p 34 return func 35 36def geom_output(func, argtypes): 37 "For GEOS routines that return a geometry." 38 if argtypes: func.argtypes = argtypes 39 func.restype = GEOM_PTR 40 func.errcheck = check_geom 41 return func 42 43def geom_index(func): 44 "For GEOS routines that return geometries from an index." 45 return geom_output(func, [GEOM_PTR, c_int]) 46 47def int_from_geom(func, zero=False): 48 "Argument is a geometry, return type is an integer." 49 func.argtypes = [GEOM_PTR] 50 func.restype = c_int 51 if zero: 52 func.errcheck = check_zero 53 else: 54 func.errcheck = check_minus_one 55 return func 56 57def string_from_geom(func): 58 "Argument is a Geometry, return type is a string." 59 func.argtypes = [GEOM_PTR] 60 func.restype = geos_char_p 61 func.errcheck = check_string 62 return func 63 64### ctypes prototypes ### 65 66# Deprecated creation routines from WKB, HEX, WKT 67from_hex = bin_constructor(GEOSFunc('GEOSGeomFromHEX_buf')) 68from_wkb = bin_constructor(GEOSFunc('GEOSGeomFromWKB_buf')) 69from_wkt = geom_output(GEOSFunc('GEOSGeomFromWKT'), [c_char_p]) 70 71# Deprecated output routines 72to_hex = bin_output(GEOSFunc('GEOSGeomToHEX_buf')) 73to_wkb = bin_output(GEOSFunc('GEOSGeomToWKB_buf')) 74to_wkt = string_from_geom(GEOSFunc('GEOSGeomToWKT')) 75 76# The GEOS geometry type, typeid, num_coordites and number of geometries 77geos_normalize = int_from_geom(GEOSFunc('GEOSNormalize')) 78geos_type = string_from_geom(GEOSFunc('GEOSGeomType')) 79geos_typeid = int_from_geom(GEOSFunc('GEOSGeomTypeId')) 80get_dims = int_from_geom(GEOSFunc('GEOSGeom_getDimensions'), zero=True) 81get_num_coords = int_from_geom(GEOSFunc('GEOSGetNumCoordinates')) 82get_num_geoms = int_from_geom(GEOSFunc('GEOSGetNumGeometries')) 83 84# Geometry creation factories 85create_point = geom_output(GEOSFunc('GEOSGeom_createPoint'), [CS_PTR]) 86create_linestring = geom_output(GEOSFunc('GEOSGeom_createLineString'), [CS_PTR]) 87create_linearring = geom_output(GEOSFunc('GEOSGeom_createLinearRing'), [CS_PTR]) 88 89# Polygon and collection creation routines are special and will not 90# have their argument types defined. 91create_polygon = geom_output(GEOSFunc('GEOSGeom_createPolygon'), None) 92create_collection = geom_output(GEOSFunc('GEOSGeom_createCollection'), None) 93 94# Ring routines 95get_extring = geom_output(GEOSFunc('GEOSGetExteriorRing'), [GEOM_PTR]) 96get_intring = geom_index(GEOSFunc('GEOSGetInteriorRingN')) 97get_nrings = int_from_geom(GEOSFunc('GEOSGetNumInteriorRings')) 98 99# Collection Routines 100get_geomn = geom_index(GEOSFunc('GEOSGetGeometryN')) 101 102# Cloning 103geom_clone = GEOSFunc('GEOSGeom_clone') 104geom_clone.argtypes = [GEOM_PTR] 105geom_clone.restype = GEOM_PTR 106 107# Destruction routine. 108destroy_geom = GEOSFunc('GEOSGeom_destroy') 109destroy_geom.argtypes = [GEOM_PTR] 110destroy_geom.restype = None 111 112# SRID routines 113geos_get_srid = GEOSFunc('GEOSGetSRID') 114geos_get_srid.argtypes = [GEOM_PTR] 115geos_get_srid.restype = c_int 116 117geos_set_srid = GEOSFunc('GEOSSetSRID') 118geos_set_srid.argtypes = [GEOM_PTR, c_int] 119geos_set_srid.restype = None