custom library path set windows nt shared libraries nix library names using the ctypes findlibrary utility to find the path to the gdal library from the list of library names this loads the gdalogr c library on windows the gdal binaries have some osr routines exported with stdcall while others are not thus the library will also need to be loaded up as windll for said osr functions that require the different calling convention return the correct stdcall function for certain osr routines on win32 platforms versioninformation functions return gdal library version information with the given key set library error handling so as errors are logged custom library path set windows nt shared libraries nix library names using the ctypes find_library utility to find the path to the gdal library from the list of library names this loads the gdal ogr c library on windows the gdal binaries have some osr routines exported with stdcall while others are not thus the library will also need to be loaded up as windll for said osr functions that require the different calling convention return the correct stdcall function for certain osr routines on win32 platforms version information functions return gdal library version information with the given key set library error handling so as errors are logged
import logging
import os
import re
from ctypes import CDLL, CFUNCTYPE, c_char_p, c_int
from ctypes.util import find_library

from django.contrib.gis.gdal.error import GDALException
from django.core.exceptions import ImproperlyConfigured

logger = logging.getLogger("django.contrib.gis")


try:
    from django.conf import settings

    lib_path = settings.GDAL_LIBRARY_PATH
except (AttributeError, ImportError, ImproperlyConfigured, OSError):
    lib_path = None

if lib_path:
    lib_names = None
elif os.name == "nt":
    
    lib_names = [
        "gdal307",
        "gdal306",
        "gdal305",
        "gdal304",
        "gdal303",
        "gdal302",
        "gdal301",
        "gdal300",
        "gdal204",
    ]
elif os.name == "posix":
    
    lib_names = [
        "gdal",
        "GDAL",
        "gdal3.7.0",
        "gdal3.6.0",
        "gdal3.5.0",
        "gdal3.4.0",
        "gdal3.3.0",
        "gdal3.2.0",
        "gdal3.1.0",
        "gdal3.0.0",
        "gdal2.4.0",
    ]
else:
    raise ImproperlyConfigured('GDAL is unsupported on OS "%s".' % os.name)



if lib_names:
    for lib_name in lib_names:
        lib_path = find_library(lib_name)
        if lib_path is not None:
            break

if lib_path is None:
    raise ImproperlyConfigured(
        'Could not find the GDAL library (tried "%s"). Is GDAL installed? '
        "If it is, try setting GDAL_LIBRARY_PATH in your settings."
        % '", "'.join(lib_names)
    )


lgdal = CDLL(lib_path)





if os.name == "nt":
    from ctypes import WinDLL

    lwingdal = WinDLL(lib_path)


def std_call(func):
    
    if os.name == "nt":
        return lwingdal[func]
    else:
        return lgdal[func]





_version_info = std_call("GDALVersionInfo")
_version_info.argtypes = [c_char_p]
_version_info.restype = c_char_p


def gdal_version():
    "Return only the GDAL version number information."
    return _version_info(b"RELEASE_NAME")


def gdal_full_version():
    "Return the full GDAL version information."
    return _version_info(b"")


def gdal_version_info():
    ver = gdal_version()
    m = re.match(rb"^(?P<major>\d+)\.(?P<minor>\d+)(?:\.(?P<subminor>\d+))?", ver)
    if not m:
        raise GDALException('Could not parse GDAL version string "%s"' % ver)
    major, minor, subminor = m.groups()
    return (int(major), int(minor), subminor and int(subminor))


GDAL_VERSION = gdal_version_info()


CPLErrorHandler = CFUNCTYPE(None, c_int, c_int, c_char_p)


def err_handler(error_class, error_number, message):
    logger.error("GDAL_ERROR %d: %s", error_number, message)


err_handler = CPLErrorHandler(err_handler)


def function(name, args, restype):
    func = std_call(name)
    func.argtypes = args
    func.restype = restype
    return func


set_error_handler = function("CPLSetErrorHandler", [CPLErrorHandler], CPLErrorHandler)
set_error_handler(err_handler)