11
11
from ctypes.util import find_library
12
12
from django.contrib.gis.geos.error import GEOSException
16
from numpy import array, ndarray
21
14
# Custom library path set?
23
16
from django.conf import settings
33
26
lib_names = ['libgeos_c-1']
34
27
elif os.name == 'posix':
36
lib_names = ['geos_c']
29
lib_names = ['geos_c', 'GEOS']
38
31
raise ImportError('Unsupported OS "%s"' % os.name)
40
# Using the ctypes `find_library` utility to find the the path to the GEOS
41
# shared library. This is better than manually specifiying each library name
33
# Using the ctypes `find_library` utility to find the path to the GEOS
34
# shared library. This is better than manually specifiying each library name
42
35
# and extension (e.g., libgeos_c.[so|so.1|dylib].).
44
37
for lib_name in lib_names:
45
38
lib_path = find_library(lib_name)
46
39
if not lib_path is None: break
48
41
# No GEOS library could be found.
50
43
raise ImportError('Could not find the GEOS library (tried "%s"). '
51
'Try setting GEOS_LIBRARY_PATH in your settings.' %
44
'Try setting GEOS_LIBRARY_PATH in your settings.' %
52
45
'", "'.join(lib_names))
54
47
# Getting the GEOS C library. The C interface (CDLL) is used for
89
82
# Opaque GEOS geometry structures, used for GEOM_PTR and CS_PTR
90
83
class GEOSGeom_t(Structure): pass
84
class GEOSPrepGeom_t(Structure): pass
91
85
class GEOSCoordSeq_t(Structure): pass
93
87
# Pointers to opaque GEOS geometry structures.
94
88
GEOM_PTR = POINTER(GEOSGeom_t)
89
PREPGEOM_PTR = POINTER(GEOSPrepGeom_t)
95
90
CS_PTR = POINTER(GEOSCoordSeq_t)
97
# Used specifically by the GEOSGeom_createPolygon and GEOSGeom_createCollection
92
# Used specifically by the GEOSGeom_createPolygon and GEOSGeom_createCollection
99
94
def get_pointer_arr(n):
100
95
"Gets a ctypes pointer array (of length `n`) for GEOSGeom_t opaque pointer."
101
96
GeomArr = GEOM_PTR * n
104
# Returns the string version of the GEOS library. Have to set the restype
99
# Returns the string version of the GEOS library. Have to set the restype
105
100
# explicitly to c_char_p to ensure compatibility accross 32 and 64-bit platforms.
106
101
geos_version = lgeos.GEOSversion
107
geos_version.argtypes = None
102
geos_version.argtypes = None
108
103
geos_version.restype = c_char_p
110
105
# Regular expression should be able to parse version strings such as
111
106
# '3.0.0rc4-CAPI-1.3.3', or '3.0.0-CAPI-1.4.1'
112
version_regex = re.compile(r'^(?P<version>\d+\.\d+\.\d+)(rc(?P<release_candidate>\d+))?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)$')
107
version_regex = re.compile(r'^(?P<version>(?P<major>\d+)\.(?P<minor>\d+)\.\d+)(rc(?P<release_candidate>\d+))?-CAPI-(?P<capi_version>\d+\.\d+\.\d+)$')
113
108
def geos_version_info():
115
110
Returns a dictionary containing the various version metadata parsed from
120
115
ver = geos_version()
121
116
m = version_regex.match(ver)
122
117
if not m: raise GEOSException('Could not parse version info string "%s"' % ver)
123
return dict((key, m.group(key)) for key in ('version', 'release_candidate', 'capi_version'))
118
return dict((key, m.group(key)) for key in ('version', 'release_candidate', 'capi_version', 'major', 'minor'))
120
# Version numbers and whether or not prepared geometry support is available.
121
_verinfo = geos_version_info()
122
GEOS_MAJOR_VERSION = int(_verinfo['major'])
123
GEOS_MINOR_VERSION = int(_verinfo['minor'])
125
GEOS_PREPARE = GEOS_MAJOR_VERSION > 3 or GEOS_MAJOR_VERSION == 3 and GEOS_MINOR_VERSION >= 1
125
127
# Calling the finishGEOS() upon exit of the interpreter.
126
128
atexit.register(lgeos.finishGEOS)