0
# Utility Functions
1
2
PyProj provides various utility functions for version information, data management, network configuration, and package diagnostics. These functions support package administration, debugging, and integration with other geospatial workflows.
3
4
## Capabilities
5
6
### Version Information
7
8
Access version details for PyProj and underlying PROJ library components.
9
10
```python { .api }
11
def show_versions() -> None:
12
"""
13
Print comprehensive version information for PyProj and dependencies.
14
15
Displays:
16
- PyProj version
17
- PROJ library version (runtime and compile-time)
18
- Python version and platform information
19
- PROJ data directory location
20
- Available optional dependencies
21
22
Note:
23
Useful for debugging compatibility issues and system configuration.
24
Output includes both PyProj package version and underlying PROJ C library version.
25
"""
26
27
# Version constants available at module level
28
__version__: str # PyProj package version (e.g., "3.7.2")
29
__proj_version__: str # Runtime PROJ library version
30
__proj_compiled_version__: str # Compile-time PROJ library version
31
proj_version_str: str # Alias for __proj_version__ (legacy compatibility)
32
33
# Additional version constants (importable but not in __all__)
34
PROJ_VERSION: tuple[int, ...] # Runtime PROJ library version as tuple
35
PROJ_VERSION_STR: str # Runtime PROJ library version as string
36
PROJ_COMPILED_VERSION: tuple[int, ...] # Compile-time PROJ version as tuple
37
PROJ_COMPILED_VERSION_STR: str # Compile-time PROJ version as string
38
```
39
40
### Data Directory Management
41
42
Configure and query PROJ data directory locations for grid files and database access.
43
44
```python { .api }
45
def get_data_dir() -> str:
46
"""
47
Get current PROJ data directory path.
48
49
Returns:
50
Path to PROJ data directory as string
51
52
Note:
53
This directory contains PROJ database and transformation grid files.
54
Location affects available CRS definitions and transformation accuracy.
55
"""
56
57
def set_data_dir(proj_data_dir: str | Path) -> None:
58
"""
59
Set PROJ data directory path.
60
61
Args:
62
proj_data_dir: Path to PROJ data directory
63
64
Raises:
65
DataDirError: If directory doesn't exist or doesn't contain required files
66
67
Note:
68
Changes affect all subsequent PyProj operations.
69
Directory must contain proj.db and associated PROJ resources.
70
"""
71
72
def append_data_dir(proj_data_dir: str | Path) -> None:
73
"""
74
Add additional PROJ data directory to search path.
75
76
Args:
77
proj_data_dir: Path to additional PROJ data directory
78
79
Raises:
80
DataDirError: If directory is invalid
81
82
Note:
83
Enables access to supplementary grid files and custom CRS definitions.
84
Directories are searched in order they were added.
85
"""
86
87
def get_user_data_dir() -> str:
88
"""
89
Get user-specific PROJ data directory.
90
91
Returns:
92
Path to user PROJ data directory
93
94
Note:
95
Location for user-installed grid files and custom definitions.
96
Automatically created if it doesn't exist.
97
"""
98
```
99
100
### Network Configuration
101
102
Configure network access for downloading transformation grids and accessing remote PROJ resources.
103
104
```python { .api }
105
def is_network_enabled() -> bool:
106
"""
107
Check if network access is enabled for PROJ operations.
108
109
Returns:
110
True if network access is enabled, False otherwise
111
112
Note:
113
Network access enables automatic download of transformation grids
114
and access to CDN-hosted PROJ resources.
115
"""
116
117
def set_network_enabled(enabled: bool) -> None:
118
"""
119
Enable or disable network access for PROJ operations.
120
121
Args:
122
enabled: Whether to enable network access
123
124
Note:
125
When enabled, PROJ can download missing transformation grids
126
and access remote resources for improved accuracy.
127
Disabled by default for security and performance reasons.
128
"""
129
130
def set_ca_bundle_path(ca_bundle_path: str | None = None) -> None:
131
"""
132
Set certificate authority bundle path for network operations.
133
134
Args:
135
ca_bundle_path: Path to CA certificate bundle file,
136
or None to use system default
137
138
Note:
139
Required for secure HTTPS connections when downloading grids.
140
Typically needed in restricted network environments.
141
"""
142
143
# Context management (importable but not in __all__)
144
def set_use_global_context(active: bool | None = None) -> None:
145
"""
146
Configure use of global PROJ context vs per-thread contexts.
147
148
Args:
149
active: True to use global context, False for per-thread contexts,
150
None to query current setting
151
152
Note:
153
Global context can improve performance but may cause thread safety issues.
154
Per-thread contexts (default) are safer for multithreaded applications.
155
"""
156
```
157
158
### Global Transformation Functions
159
160
Standalone transformation functions providing direct coordinate conversion without object creation.
161
162
```python { .api }
163
def transform(
164
p1: Proj | Transformer | CRS | str,
165
p2: Proj | Transformer | CRS | str,
166
x,
167
y,
168
z=None,
169
tt=None,
170
radians: bool = False,
171
errcheck: bool = False,
172
always_xy: bool = False,
173
**kwargs
174
) -> tuple:
175
"""
176
Transform coordinates between projections or coordinate systems.
177
178
Args:
179
p1: Source projection, CRS, or definition string
180
p2: Target projection, CRS, or definition string
181
x: X coordinate(s) (longitude, easting, etc.)
182
y: Y coordinate(s) (latitude, northing, etc.)
183
z: Z coordinate(s) (height, elevation, etc.), optional
184
tt: Time coordinate(s), optional
185
radians: Input coordinates are in radians (for geographic CRS)
186
errcheck: Raise exception on transformation errors
187
always_xy: Force x,y axis order regardless of CRS definitions
188
**kwargs: Additional transformation parameters
189
190
Returns:
191
Tuple of transformed coordinates matching input dimensions
192
193
Raises:
194
ProjError: If transformation fails (when errcheck=True)
195
196
Note:
197
Convenience function that creates temporary transformer internally.
198
For multiple transformations, use Transformer class for better performance.
199
"""
200
201
def itransform(
202
p1: Proj | Transformer | CRS | str,
203
p2: Proj | Transformer | CRS | str,
204
points,
205
switch: bool = False,
206
time_3rd: bool = False,
207
radians: bool = False,
208
errcheck: bool = False,
209
always_xy: bool = False,
210
**kwargs
211
) -> Iterator:
212
"""
213
Transform iterator of coordinate points between projections.
214
215
Args:
216
p1: Source projection, CRS, or definition string
217
p2: Target projection, CRS, or definition string
218
points: Iterable of coordinate tuples [(x1,y1), (x2,y2), ...]
219
switch: Switch x,y coordinate order in input points
220
time_3rd: Treat third coordinate as time instead of height
221
radians: Input coordinates are in radians
222
errcheck: Raise exception on transformation errors
223
always_xy: Force x,y axis order regardless of CRS definitions
224
**kwargs: Additional transformation parameters
225
226
Yields:
227
Transformed coordinate tuples
228
229
Raises:
230
ProjError: If transformation fails for any point (when errcheck=True)
231
232
Note:
233
Memory-efficient for processing large coordinate datasets.
234
Creates temporary transformer internally for each call.
235
"""
236
```
237
238
### Utility Classes and Functions
239
240
Helper classes and functions for data processing and type conversion.
241
242
```python { .api }
243
def is_null(value: Any) -> bool:
244
"""
245
Check if value represents null/missing data.
246
247
Args:
248
value: Value to check
249
250
Returns:
251
True if value is NaN, None, or represents missing data
252
253
Note:
254
Handles numpy NaN values and Python None consistently.
255
Used internally for coordinate validation.
256
"""
257
258
def strtobool(value: Any) -> bool:
259
"""
260
Convert string-like value to boolean.
261
262
Args:
263
value: String, boolean, or numeric value to convert
264
265
Returns:
266
Boolean interpretation of input value
267
268
Raises:
269
ValueError: If value cannot be interpreted as boolean
270
271
Note:
272
Accepts 'true'/'false', 'yes'/'no', '1'/'0', and variations.
273
Case-insensitive string comparison.
274
"""
275
276
class NumpyEncoder(json.JSONEncoder):
277
"""
278
JSON encoder that handles NumPy data types.
279
280
Converts NumPy arrays and scalars to JSON-serializable types.
281
Used for exporting coordinate data and CRS information as JSON.
282
"""
283
284
def default(self, obj):
285
"""
286
Convert NumPy objects to JSON-serializable equivalents.
287
288
Args:
289
obj: Object to serialize
290
291
Returns:
292
JSON-serializable representation of object
293
"""
294
295
class DataType(Enum):
296
"""Enumeration of data types for internal processing."""
297
FLOAT = "FLOAT"
298
LIST = "LIST"
299
TUPLE = "TUPLE"
300
ARRAY = "ARRAY"
301
```
302
303
### Constants and Module Variables
304
305
Package-level constants and pre-computed data for common operations.
306
307
```python { .api }
308
# Ellipsoid parameter dictionary (from geod.py)
309
pj_ellps: dict[str, dict[str, float]]
310
"""
311
Dictionary of ellipsoid parameters.
312
313
Maps ellipsoid names to parameter dictionaries containing:
314
- 'a': Semi-major axis in meters
315
- 'b': Semi-minor axis in meters
316
- 'f': Flattening
317
- Other ellipsoid-specific parameters
318
"""
319
320
# PROJ operations dictionary (from proj.py)
321
pj_list: dict[str, str]
322
"""
323
Dictionary of available PROJ operations.
324
325
Maps operation names to descriptions of available
326
projections and coordinate operations.
327
"""
328
329
# Geodesic library version (from geod.py)
330
geodesic_version_str: str
331
"""Version string of GeographicLib used for geodesic calculations."""
332
333
# Functions to access PROJ reference data
334
def get_ellps_map() -> dict[str, dict[str, float]]:
335
"""
336
Get dictionary of ellipsoid parameters from PROJ database.
337
338
Returns:
339
Dictionary mapping ellipsoid names to parameter dictionaries.
340
Each ellipsoid entry contains keys like 'a', 'b', 'f' for
341
semi-major axis, semi-minor axis, and flattening.
342
343
Note:
344
This is the source data for the pj_ellps module variable.
345
"""
346
347
def get_prime_meridians_map() -> dict[str, str]:
348
"""
349
Get dictionary of prime meridian definitions from PROJ database.
350
351
Returns:
352
Dictionary mapping prime meridian names to their definitions.
353
Contains standard prime meridians like 'Greenwich', 'Paris', etc.
354
355
Note:
356
Values are PROJ-format definitions of prime meridian locations.
357
"""
358
359
def get_proj_operations_map() -> dict[str, str]:
360
"""
361
Get dictionary of available PROJ operations from PROJ database.
362
363
Returns:
364
Dictionary mapping operation names to their descriptions.
365
Includes projections, transformations, and other coordinate operations.
366
367
Note:
368
This is the source data for the pj_list module variable.
369
"""
370
```
371
372
## Usage Examples
373
374
### Version and System Information
375
376
```python
377
import pyproj
378
from pyproj import show_versions
379
380
# Display comprehensive version information
381
show_versions()
382
383
# Access version constants
384
print(f"PyProj version: {pyproj.__version__}")
385
print(f"PROJ runtime version: {pyproj.__proj_version__}")
386
print(f"PROJ compiled version: {pyproj.__proj_compiled_version__}")
387
388
# Check geodesic library version
389
from pyproj.geod import geodesic_version_str
390
print(f"GeographicLib version: {geodesic_version_str}")
391
```
392
393
### Data Directory Configuration
394
395
```python
396
from pyproj.datadir import get_data_dir, set_data_dir, append_data_dir, get_user_data_dir
397
from pathlib import Path
398
399
# Check current data directory
400
current_dir = get_data_dir()
401
print(f"Current PROJ data directory: {current_dir}")
402
403
# Get user data directory
404
user_dir = get_user_data_dir()
405
print(f"User PROJ data directory: {user_dir}")
406
407
# Add supplementary data directory
408
# (Useful for custom grids or organization-specific CRS definitions)
409
try:
410
custom_data_path = Path("/path/to/custom/proj/data")
411
if custom_data_path.exists():
412
append_data_dir(custom_data_path)
413
print(f"Added custom data directory: {custom_data_path}")
414
except Exception as e:
415
print(f"Could not add custom directory: {e}")
416
417
# Set different data directory (use with caution)
418
# set_data_dir("/alternative/proj/data/path")
419
```
420
421
### Network Configuration
422
423
```python
424
from pyproj.network import is_network_enabled, set_network_enabled, set_ca_bundle_path
425
426
# Check network status
427
network_status = is_network_enabled()
428
print(f"Network access enabled: {network_status}")
429
430
# Enable network for grid downloads
431
if not network_status:
432
set_network_enabled(True)
433
print("Network access enabled for grid downloads")
434
435
# Configure CA certificate bundle for secure connections
436
# set_ca_bundle_path("/path/to/ca-bundle.crt")
437
438
# Disable network access for security/offline operation
439
# set_network_enabled(False)
440
```
441
442
### Global Transformation Functions
443
444
```python
445
from pyproj import transform, itransform
446
447
# Single point transformation
448
x, y = transform('EPSG:4326', 'EPSG:32633', 10.0, 60.0, always_xy=True)
449
print(f"Transformed coordinates: {x:.2f}, {y:.2f}")
450
451
# Multiple points using iterator
452
points = [(10.0, 60.0), (11.0, 61.0), (12.0, 62.0)]
453
transformed = list(itransform('EPSG:4326', 'EPSG:32633', points, always_xy=True))
454
455
print("Transformed points:")
456
for i, (x, y) in enumerate(transformed):
457
print(f" Point {i+1}: {x:.2f}, {y:.2f}")
458
459
# Transform with height coordinates
460
x, y, z = transform(
461
'EPSG:4326', # WGS84 geographic
462
'EPSG:4978', # WGS84 geocentric
463
10.0, 60.0, 100.0, # lon, lat, height
464
always_xy=True
465
)
466
print(f"Geocentric coordinates: {x:.2f}, {y:.2f}, {z:.2f}")
467
```
468
469
### Data Validation and Type Checking
470
471
```python
472
from pyproj.utils import is_null, strtobool, DataType
473
import numpy as np
474
475
# Check for null/missing values
476
test_values = [0.0, np.nan, None, 42.0, float('inf')]
477
for value in test_values:
478
null_status = is_null(value)
479
print(f"is_null({value}): {null_status}")
480
481
# String to boolean conversion
482
bool_strings = ['true', 'FALSE', 'yes', 'NO', '1', '0', 'on', 'off']
483
for string in bool_strings:
484
try:
485
bool_value = strtobool(string)
486
print(f"strtobool('{string}'): {bool_value}")
487
except ValueError as e:
488
print(f"strtobool('{string}'): Error - {e}")
489
```
490
491
### Working with Package Constants
492
493
```python
494
from pyproj.geod import pj_ellps
495
from pyproj.proj import pj_list
496
497
# Explore available ellipsoids
498
print("Available ellipsoids:")
499
for name, params in list(pj_ellps.items())[:5]:
500
a = params.get('a', 'N/A')
501
b = params.get('b', 'N/A')
502
print(f" {name}: a={a}, b={b}")
503
504
# Explore available projections
505
print(f"\nTotal PROJ operations: {len(pj_list)}")
506
print("Sample operations:")
507
for name, desc in list(pj_list.items())[:5]:
508
print(f" {name}: {desc}")
509
510
# Find specific projection types
511
utm_ops = {k: v for k, v in pj_list.items() if 'utm' in k.lower()}
512
print(f"\nUTM-related operations: {len(utm_ops)}")
513
```
514
515
### JSON Serialization with NumPy Support
516
517
```python
518
from pyproj.utils import NumpyEncoder
519
import json
520
import numpy as np
521
522
# Data with NumPy arrays
523
coordinate_data = {
524
'points': np.array([[10.0, 60.0], [11.0, 61.0]]),
525
'elevation': np.array([100.0, 150.0]),
526
'metadata': {
527
'crs': 'EPSG:4326',
528
'accuracy': np.float64(1.5)
529
}
530
}
531
532
# Serialize with NumPy support
533
json_string = json.dumps(coordinate_data, cls=NumpyEncoder, indent=2)
534
print("JSON with NumPy support:")
535
print(json_string)
536
537
# Load back from JSON
538
loaded_data = json.loads(json_string)
539
print(f"Loaded points: {loaded_data['points']}")
540
```
541
542
### Error Handling and Diagnostics
543
544
```python
545
from pyproj import ProjError, CRSError, GeodError, DataDirError
546
from pyproj import transform
547
import logging
548
549
# Configure logging for debugging
550
logging.basicConfig(level=logging.DEBUG)
551
552
# Error handling examples
553
try:
554
# Invalid CRS code
555
result = transform('INVALID:999', 'EPSG:4326', 0.0, 0.0, errcheck=True)
556
except (ProjError, CRSError) as e:
557
print(f"Transformation error: {e}")
558
559
try:
560
# Invalid data directory
561
from pyproj.datadir import set_data_dir
562
set_data_dir("/nonexistent/path")
563
except DataDirError as e:
564
print(f"Data directory error: {e}")
565
566
# Validate transformations with error checking
567
try:
568
x, y = transform(
569
'EPSG:4326',
570
'EPSG:32633',
571
180.0, 85.0, # Extreme coordinates
572
errcheck=True,
573
always_xy=True
574
)
575
print(f"Transformation successful: {x:.2f}, {y:.2f}")
576
except ProjError as e:
577
print(f"Transformation failed: {e}")
578
```
579
580
## Types
581
582
```python { .api }
583
# Exception classes
584
class ProjError(RuntimeError):
585
"""General PROJ library errors."""
586
587
class CRSError(ProjError):
588
"""CRS-specific errors (invalid definitions, unsupported operations)."""
589
590
class GeodError(RuntimeError):
591
"""Geodesic computation errors."""
592
593
class DataDirError(RuntimeError):
594
"""PROJ data directory errors (missing files, invalid paths)."""
595
596
# Utility enumerations
597
class DataType(Enum):
598
"""Data type classification for internal processing."""
599
FLOAT = "FLOAT"
600
LIST = "LIST"
601
TUPLE = "TUPLE"
602
ARRAY = "ARRAY"
603
604
# Type aliases for common patterns
605
ProjectionLike = Union[Proj, Transformer, CRS, str]
606
"""Type hint for objects that can be used as projection definitions."""
607
608
CoordinateSequence = Union[list, tuple, np.ndarray]
609
"""Type hint for coordinate data containers."""
610
```