@@ -6,8 +6,13 @@ from collections import namedtuple
6
6
from libc.stdlib cimport free, malloc
7
7
8
8
from pyproj._compat cimport cstrdecode, cstrencode
9
- from pyproj._datadir cimport pyproj_context_create, pyproj_context_destroy
9
+ from pyproj._datadir cimport (
10
+ _clear_proj_error,
11
+ pyproj_context_create,
12
+ pyproj_context_destroy,
13
+ )
10
14
15
+ from pyproj._crs import _CRS
11
16
from pyproj.aoi import AreaOfUse
12
17
from pyproj.enums import PJType
13
18
@@ -483,3 +488,105 @@ def get_database_metadata(str key not None):
483
488
return metadata
484
489
finally :
485
490
pyproj_context_destroy(context)
491
+
492
+
493
+ def query_geodetic_crs_from_datum (
494
+ str crs_auth_name ,
495
+ str datum_auth_name not None ,
496
+ str datum_code not None ,
497
+ pj_type = None
498
+ ):
499
+ """
500
+ .. versionadded:: 3.7.0
501
+
502
+ Return GeodeticCRS that use the specified datum
503
+
504
+ See: :c:func:`proj_query_geodetic_crs_from_datum`
505
+
506
+ Parameters
507
+ ----------
508
+ crs_auth_name: str | None
509
+ The authority name to filter by (e.g. EPSG, ESRI). None is all.
510
+ datum_auth_name: str
511
+ The authority of the datum
512
+ datum_code: str
513
+ Datum code
514
+ pj_type: pyproj.enums.PJType | None, optional
515
+ The type of object to get the CRSs. Can be PJType.GEOCENTRIC_CRS,
516
+ PJType.GEOGRAPHIC_3D_CRS, PJType.GEOGRAPHIC_2D_CRS or None for all.
517
+
518
+ Returns
519
+ -------
520
+ list[_CRS]
521
+ """
522
+
523
+ cdef const char * c_crs_type = NULL
524
+ cdef bytes b_crs_type
525
+ cdef str crs_type = " "
526
+ if pj_type is None :
527
+ pass
528
+ elif pj_type == PJType.GEOCENTRIC_CRS:
529
+ crs_type = " geocentric"
530
+ elif pj_type == PJType.GEOGRAPHIC_2D_CRS:
531
+ crs_type = " geographic 2D"
532
+ elif pj_type == PJType.GEOGRAPHIC_3D_CRS:
533
+ crs_type = " geographic 3D"
534
+ else :
535
+ raise ValueError (" type must be GEOCENTRIC_CRS, GEOGRAPHIC_2D_CRS, GEOGRAPHIC_3D_CRS or None" )
536
+
537
+ if pj_type is not None :
538
+ b_crs_type = cstrencode(crs_type)
539
+ c_crs_type = b_crs_type
540
+
541
+ cdef const char * c_crs_auth_name = NULL
542
+ cdef const char * c_datum_auth_name = NULL
543
+ cdef const char * c_datum_code = NULL
544
+ cdef bytes b_crs_auth_name
545
+ cdef bytes b_datum_auth_name
546
+ cdef bytes b_datum_code
547
+
548
+ if crs_auth_name is not None :
549
+ b_crs_auth_name = cstrencode(crs_auth_name)
550
+ c_crs_auth_name = b_crs_auth_name
551
+
552
+ if datum_auth_name is not None :
553
+ b_datum_auth_name = cstrencode(datum_auth_name)
554
+ c_datum_auth_name = b_datum_auth_name
555
+
556
+ if datum_code is not None :
557
+ b_datum_code = cstrencode(datum_code)
558
+ c_datum_code = b_datum_code
559
+
560
+ ret_list = []
561
+
562
+ cdef PJ_OBJ_LIST * proj_list = NULL
563
+ cdef int num_proj_objects = 0
564
+
565
+ cdef PJ_CONTEXT* context = pyproj_context_create()
566
+ proj_list = proj_query_geodetic_crs_from_datum(
567
+ context,
568
+ c_crs_auth_name,
569
+ c_datum_auth_name,
570
+ c_datum_code,
571
+ c_crs_type
572
+ )
573
+
574
+ if proj_list != NULL :
575
+ num_proj_objects = proj_list_get_count(proj_list)
576
+
577
+ cdef PJ* proj = NULL
578
+ try :
579
+ for iii in range (num_proj_objects):
580
+ proj = proj_list_get(context, proj_list, iii)
581
+ ret_list.append(_CRS(proj_as_wkt(context, proj, PJ_WKT2_2019, NULL )))
582
+ proj_destroy(proj)
583
+ proj = NULL
584
+ finally :
585
+ # If there was an error we have to call proj_destroy
586
+ # If there was none, calling it on NULL does nothing
587
+ proj_destroy(proj)
588
+ proj_list_destroy(proj_list)
589
+ pyproj_context_destroy(context)
590
+ _clear_proj_error()
591
+
592
+ return ret_list
0 commit comments