22Set the datadir path to the local data directory
33"""
44import os
5+ from distutils .spawn import find_executable
56
67from pyproj .exceptions import DataDirError
78
89_USER_PROJ_DATA = None
10+ _VALIDATED_PROJ_DATA = None
911
1012
1113def set_data_dir (proj_data_dir ):
@@ -18,7 +20,22 @@ def set_data_dir(proj_data_dir):
1820 The path to rhe PROJ.4 data directory.
1921 """
2022 global _USER_PROJ_DATA
23+ global _VALIDATED_PROJ_DATA
2124 _USER_PROJ_DATA = proj_data_dir
25+ # set to none to re-validate
26+ _VALIDATED_PROJ_DATA = None
27+
28+
29+ def append_data_dir (proj_data_dir ):
30+ """
31+ Add an additional data directory for PROJ.4 to use.
32+
33+ Parameters
34+ ----------
35+ proj_data_dir: str
36+ The path to rhe PROJ.4 data directory.
37+ """
38+ set_data_dir (";" .join ([get_data_dir (), proj_data_dir ]))
2239
2340
2441def get_data_dir ():
@@ -27,17 +44,24 @@ def get_data_dir():
2744
2845 1. The one set by pyproj.datadir.set_data_dir (if exists & valid)
2946 2. The internal proj directory (if exists & valid)
30- 3. The directory in PROJ_LIB
47+ 3. The directory in PROJ_LIB (if exists & valid)
48+ 4. The directory on the PATH (if exists & valid)
3149
3250 Returns
3351 -------
3452 str: The valid data directory.
3553
3654 """
55+ # to avoid re-validating
56+ global _VALIDATED_PROJ_DATA
57+ if _VALIDATED_PROJ_DATA is not None :
58+ return _VALIDATED_PROJ_DATA
59+
3760 global _USER_PROJ_DATA
3861 internal_datadir = os .path .join (
3962 os .path .dirname (os .path .abspath (__file__ )), "proj_dir" , "share" , "proj"
4063 )
64+ proj_lib_dirs = os .environ .get ("PROJ_LIB" , "" )
4165
4266 def valid_data_dir (potential_data_dir ):
4367 if potential_data_dir is not None and os .path .exists (
@@ -46,21 +70,34 @@ def valid_data_dir(potential_data_dir):
4670 return True
4771 return False
4872
49- proj_data_dir = None
50- if valid_data_dir (_USER_PROJ_DATA ):
51- proj_data_dir = _USER_PROJ_DATA
73+ def valid_data_dirs (potential_data_dirs ):
74+ if potential_data_dirs is None :
75+ return False
76+ for proj_data_dir in potential_data_dirs .split (";" ):
77+ if valid_data_dir (proj_data_dir ):
78+ return True
79+ break
80+ return None
81+
82+ if valid_data_dirs (_USER_PROJ_DATA ):
83+ _VALIDATED_PROJ_DATA = _USER_PROJ_DATA
5284 elif valid_data_dir (internal_datadir ):
53- proj_data_dir = internal_datadir
85+ _VALIDATED_PROJ_DATA = internal_datadir
86+ elif valid_data_dirs (proj_lib_dirs ):
87+ _VALIDATED_PROJ_DATA = proj_lib_dirs
5488 else :
55- proj_lib_dirs = os .environ .get ("PROJ_LIB" , "" )
56- for proj_lib_dir in proj_lib_dirs .split (";" ):
57- if valid_data_dir (proj_lib_dir ):
58- proj_data_dir = proj_lib_dir
59- break
60- if proj_data_dir is None :
89+ proj_exe = find_executable ("proj" )
90+ if proj_exe is not None :
91+ system_proj_dir = os .path .join (
92+ os .path .dirname (os .path .dirname (proj_exe )), "share" , "proj"
93+ )
94+ if valid_data_dir (system_proj_dir ):
95+ _VALIDATED_PROJ_DATA = system_proj_dir
96+
97+ if _VALIDATED_PROJ_DATA is None :
6198 raise DataDirError (
6299 "Valid PROJ.4 data directory not found."
63100 "Either set the path using the environmental variable PROJ_LIB or "
64101 "with `pyproj.datadir.set_data_dir`."
65102 )
66- return proj_data_dir
103+ return _VALIDATED_PROJ_DATA
0 commit comments