New upstream version 2.3.1+ds
Bas Couwenberg
4 years ago
46 | 46 | LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, |
47 | 47 | NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN |
48 | 48 | CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """ |
49 | __version__ = "2.3.0" | |
49 | __version__ = "2.3.1" | |
50 | 50 | __all__ = [ |
51 | 51 | "Proj", |
52 | 52 | "Geod", |
65 | 65 | ] |
66 | 66 | import sys |
67 | 67 | |
68 | from pyproj._datadir import PYPROJ_CONTEXT | |
68 | 69 | from pyproj._list import ( # noqa: F401 |
69 | 70 | get_angular_units_map, |
70 | 71 | get_ellps_map, |
78 | 79 | from pyproj.geod import Geod, geodesic_version_str, pj_ellps # noqa: F401 |
79 | 80 | from pyproj.proj import Proj, pj_list, proj_version_str # noqa: F401 |
80 | 81 | from pyproj.transformer import Transformer, itransform, transform # noqa: F401 |
82 | ||
83 | PYPROJ_CONTEXT.set_search_paths() | |
81 | 84 | |
82 | 85 | |
83 | 86 | def test(**kwargs): |
90 | 90 | PROJ_CONTEXT.context, |
91 | 91 | projobj, |
92 | 92 | wkt_out_type, |
93 | options_wkt) | |
93 | options_wkt, | |
94 | ) | |
95 | CRSError.clear() | |
94 | 96 | return cstrdecode(proj_string) |
95 | 97 | |
96 | 98 | |
121 | 123 | PROJ_CONTEXT.context, |
122 | 124 | projobj, |
123 | 125 | proj_out_type, |
124 | NULL) | |
126 | NULL, | |
127 | ) | |
128 | CRSError.clear() | |
125 | 129 | return cstrdecode(proj_string) |
126 | 130 | |
127 | 131 | |
128 | 132 | cdef PJ* _from_authority( |
129 | 133 | auth_name, code, PJ_CATEGORY category, int use_proj_alternative_grid_names=False |
130 | 134 | ): |
131 | CRSError.clear() | |
132 | 135 | b_auth_name = cstrencode(auth_name) |
133 | 136 | cdef char *c_auth_name = b_auth_name |
134 | 137 | b_code = cstrencode(str(code)) |
144 | 147 | |
145 | 148 | |
146 | 149 | cdef PJ* _from_string(proj_string, expected_types): |
147 | CRSError.clear() | |
148 | 150 | cdef PJ* base_pj = proj_create( |
149 | 151 | PROJ_CONTEXT.context, |
150 | 152 | cstrencode(proj_string) |
403 | 405 | coord_system.name = _COORD_SYSTEM_TYPE_MAP[cs_type] |
404 | 406 | except KeyError: |
405 | 407 | raise CRSError("Not a coordinate system.") |
408 | CRSError.clear() | |
406 | 409 | return coord_system |
407 | 410 | |
408 | 411 | @property |
457 | 460 | cdef Ellipsoid ellips = Ellipsoid() |
458 | 461 | ellips.projobj = ellipsoid_pj |
459 | 462 | cdef int is_semi_minor_computed = 0 |
460 | try: | |
461 | proj_ellipsoid_get_parameters( | |
462 | PROJ_CONTEXT.context, | |
463 | ellips.projobj, | |
464 | &ellips._semi_major_metre, | |
465 | &ellips._semi_minor_metre, | |
466 | &is_semi_minor_computed, | |
467 | &ellips._inv_flattening) | |
468 | ellips.ellipsoid_loaded = True | |
469 | ellips.is_semi_minor_computed = is_semi_minor_computed == 1 | |
470 | except Exception: | |
471 | pass | |
463 | proj_ellipsoid_get_parameters( | |
464 | PROJ_CONTEXT.context, | |
465 | ellips.projobj, | |
466 | &ellips._semi_major_metre, | |
467 | &ellips._semi_minor_metre, | |
468 | &is_semi_minor_computed, | |
469 | &ellips._inv_flattening, | |
470 | ) | |
471 | ellips.ellipsoid_loaded = True | |
472 | ellips.is_semi_minor_computed = is_semi_minor_computed == 1 | |
472 | 473 | ellips._set_name() |
474 | CRSError.clear() | |
473 | 475 | return ellips |
474 | 476 | |
475 | 477 | @staticmethod |
497 | 499 | raise CRSError( |
498 | 500 | "Invalid authority or code ({0}, {1})".format(auth_name, code) |
499 | 501 | ) |
502 | CRSError.clear() | |
500 | 503 | return Ellipsoid.create(ellipsoid_pj) |
501 | 504 | |
502 | 505 | @staticmethod |
545 | 548 | pystrdecode(ellipsoid_string) |
546 | 549 | ) |
547 | 550 | ) |
548 | ||
551 | CRSError.clear() | |
549 | 552 | return Ellipsoid.create(ellipsoid_pj) |
550 | 553 | |
551 | 554 | @property |
619 | 622 | ) |
620 | 623 | prime_meridian.unit_name = decode_or_undefined(unit_name) |
621 | 624 | prime_meridian._set_name() |
625 | CRSError.clear() | |
622 | 626 | return prime_meridian |
623 | 627 | |
624 | 628 | @staticmethod |
646 | 650 | raise CRSError( |
647 | 651 | "Invalid authority or code ({0}, {1})".format(auth_name, code) |
648 | 652 | ) |
653 | CRSError.clear() | |
649 | 654 | return PrimeMeridian.create(prime_meridian_pj) |
650 | 655 | |
651 | 656 | @staticmethod |
663 | 668 | PrimeMeridian |
664 | 669 | """ |
665 | 670 | return PrimeMeridian.from_authority("EPSG", code) |
666 | ||
667 | 671 | |
668 | 672 | @staticmethod |
669 | 673 | def from_string(prime_meridian_string): |
695 | 699 | pystrdecode(prime_meridian_string) |
696 | 700 | ) |
697 | 701 | ) |
698 | ||
702 | CRSError.clear() | |
699 | 703 | return PrimeMeridian.create(prime_meridian_pj) |
700 | 704 | |
701 | 705 | |
745 | 749 | raise CRSError( |
746 | 750 | "Invalid authority or code ({0}, {1})".format(auth_name, code) |
747 | 751 | ) |
752 | CRSError.clear() | |
748 | 753 | return Datum.create(datum_pj) |
749 | 754 | |
750 | 755 | @staticmethod |
800 | 805 | pystrdecode(datum_string) |
801 | 806 | ) |
802 | 807 | ) |
803 | ||
808 | CRSError.clear() | |
804 | 809 | return Datum.create(datum_pj) |
805 | 810 | |
806 | 811 | @property |
816 | 821 | PROJ_CONTEXT.context, |
817 | 822 | self.projobj, |
818 | 823 | ) |
824 | CRSError.clear() | |
819 | 825 | if ellipsoid_pj == NULL: |
820 | 826 | self._ellipsoid = False |
821 | 827 | return None |
835 | 841 | PROJ_CONTEXT.context, |
836 | 842 | self.projobj, |
837 | 843 | ) |
844 | CRSError.clear() | |
838 | 845 | if prime_meridian_pj == NULL: |
839 | 846 | self._prime_meridian = False |
840 | 847 | return None |
998 | 1005 | grid.direct_download = direct_download == 1 |
999 | 1006 | grid.open_license = open_license == 1 |
1000 | 1007 | grid.available = available == 1 |
1008 | CRSError.clear() | |
1001 | 1009 | return grid |
1002 | 1010 | |
1003 | 1011 | def __str__(self): |
1084 | 1092 | PROJ_CONTEXT.context, |
1085 | 1093 | coord_operation.projobj |
1086 | 1094 | ) == 1 |
1087 | ||
1095 | CRSError.clear() | |
1088 | 1096 | return coord_operation |
1089 | 1097 | |
1090 | 1098 | @staticmethod |
1115 | 1123 | raise CRSError( |
1116 | 1124 | "Invalid authority or code ({0}, {1})".format(auth_name, code) |
1117 | 1125 | ) |
1126 | CRSError.clear() | |
1118 | 1127 | return CoordinateOperation.create(coord_operation_pj) |
1119 | 1128 | |
1120 | 1129 | @staticmethod |
1169 | 1178 | pystrdecode(coordinate_operation_string) |
1170 | 1179 | ) |
1171 | 1180 | ) |
1172 | ||
1181 | CRSError.clear() | |
1173 | 1182 | return CoordinateOperation.create(coord_operation_pj) |
1174 | 1183 | |
1175 | 1184 | @property |
1194 | 1203 | param_idx |
1195 | 1204 | ) |
1196 | 1205 | ) |
1206 | CRSError.clear() | |
1197 | 1207 | return self._params |
1198 | 1208 | |
1199 | 1209 | @property |
1218 | 1228 | grid_idx |
1219 | 1229 | ) |
1220 | 1230 | ) |
1231 | CRSError.clear() | |
1221 | 1232 | return self._grids |
1222 | 1233 | |
1223 | 1234 | @property |
1330 | 1341 | self._type = proj_get_type(self.projobj) |
1331 | 1342 | self.type_name = _CRS_TYPE_MAP[self._type] |
1332 | 1343 | self._set_name() |
1344 | CRSError.clear() | |
1333 | 1345 | |
1334 | 1346 | @property |
1335 | 1347 | def axis_info(self): |
1365 | 1377 | PROJ_CONTEXT.context, |
1366 | 1378 | self.projobj |
1367 | 1379 | ) |
1380 | CRSError.clear() | |
1368 | 1381 | if ellipsoid_pj == NULL: |
1369 | 1382 | self._ellipsoid = False |
1370 | 1383 | return None |
1384 | 1397 | PROJ_CONTEXT.context, |
1385 | 1398 | self.projobj, |
1386 | 1399 | ) |
1400 | CRSError.clear() | |
1387 | 1401 | if prime_meridian_pj == NULL: |
1388 | 1402 | self._prime_meridian = False |
1389 | 1403 | return None |
1405 | 1419 | PROJ_CONTEXT.context, |
1406 | 1420 | self.projobj, |
1407 | 1421 | ) |
1422 | CRSError.clear() | |
1408 | 1423 | if datum_pj == NULL: |
1409 | 1424 | self._datum = False |
1410 | 1425 | return None |
1425 | 1440 | PROJ_CONTEXT.context, |
1426 | 1441 | self.projobj |
1427 | 1442 | ) |
1443 | CRSError.clear() | |
1428 | 1444 | if coord_system_pj == NULL: |
1429 | 1445 | self._coordinate_system = False |
1430 | 1446 | return None |
1446 | 1462 | PROJ_CONTEXT.context, |
1447 | 1463 | self.projobj |
1448 | 1464 | ) |
1465 | CRSError.clear() | |
1449 | 1466 | if coord_pj == NULL: |
1450 | 1467 | self._coordinate_operation = False |
1451 | 1468 | return None |
1464 | 1481 | return None if self._source_crs is False else self._source_crs |
1465 | 1482 | cdef PJ * projobj |
1466 | 1483 | projobj = proj_get_source_crs(PROJ_CONTEXT.context, self.projobj) |
1484 | CRSError.clear() | |
1467 | 1485 | if projobj == NULL: |
1468 | 1486 | self._source_crs = False |
1469 | 1487 | return None |
1484 | 1502 | return None if self._target_crs is False else self._target_crs |
1485 | 1503 | cdef PJ * projobj |
1486 | 1504 | projobj = proj_get_target_crs(PROJ_CONTEXT.context, self.projobj) |
1505 | CRSError.clear() | |
1487 | 1506 | if projobj == NULL: |
1488 | 1507 | self._target_crs = False |
1489 | 1508 | return None |
1518 | 1537 | proj_destroy(projobj) # deallocate temp proj |
1519 | 1538 | iii += 1 |
1520 | 1539 | projobj = proj_crs_get_sub_crs(PROJ_CONTEXT.context, self.projobj, iii) |
1521 | ||
1540 | CRSError.clear() | |
1522 | 1541 | return self._sub_crs_list |
1523 | 1542 | |
1524 | 1543 | @property |
1532 | 1551 | return self._geodetic_crs if self. _geodetic_crs is not False else None |
1533 | 1552 | cdef PJ * projobj |
1534 | 1553 | projobj = proj_crs_get_geodetic_crs(PROJ_CONTEXT.context, self.projobj) |
1554 | CRSError.clear() | |
1535 | 1555 | if projobj == NULL: |
1536 | 1556 | self._geodetic_crs = False |
1537 | 1557 | return None |
1603 | 1623 | if auth_info is not None and auth_info[0].upper() == "EPSG": |
1604 | 1624 | return int(auth_info[1]) |
1605 | 1625 | return None |
1606 | ||
1626 | ||
1607 | 1627 | def to_authority(self, auth_name=None, min_confidence=70): |
1608 | 1628 | """ |
1609 | 1629 | Return the authority name and code best matching the CRS |
1666 | 1686 | finally: |
1667 | 1687 | if out_confidence_list != NULL: |
1668 | 1688 | proj_int_list_destroy(out_confidence_list) |
1689 | CRSError.clear() | |
1669 | 1690 | |
1670 | 1691 | # check to make sure that the projection found is valid |
1671 | 1692 | if proj_list == NULL or num_proj_objects <= 0 or out_confidence < min_confidence: |
1679 | 1700 | proj = proj_list_get(PROJ_CONTEXT.context, proj_list, 0) |
1680 | 1701 | finally: |
1681 | 1702 | proj_list_destroy(proj_list) |
1703 | CRSError.clear() | |
1682 | 1704 | if proj == NULL: |
1683 | 1705 | return None |
1684 | 1706 | |
1692 | 1714 | return pystrdecode(out_auth_name), pystrdecode(code) |
1693 | 1715 | finally: |
1694 | 1716 | proj_destroy(proj) |
1717 | CRSError.clear() | |
1695 | 1718 | |
1696 | 1719 | return None |
1697 | 1720 | |
1727 | 1750 | is_property = self._type in property_types |
1728 | 1751 | return is_property |
1729 | 1752 | |
1730 | ||
1731 | 1753 | @property |
1732 | 1754 | def is_geographic(self): |
1733 | 1755 | """ |
12 | 12 | if level == PJ_LOG_ERROR: |
13 | 13 | ProjError.internal_proj_error = pystrdecode(error_msg) |
14 | 14 | |
15 | ||
16 | 15 | cdef class ContextManager: |
17 | 16 | def __cinit__(self): |
18 | 17 | self.context = NULL |
24 | 23 | |
25 | 24 | def __init__(self): |
26 | 25 | self.context = proj_context_create() |
27 | self.set_search_paths() | |
26 | self._set_search_paths = False | |
28 | 27 | proj_context_use_proj4_init_rules(self.context, 1) |
29 | 28 | proj_log_func(self.context, NULL, pyproj_log_function) |
30 | 29 | |
31 | def set_search_paths(self): | |
30 | def set_search_paths(self, reset=False): | |
32 | 31 | """ |
33 | 32 | This method sets the search paths |
34 | 33 | based on pyproj.datadir.get_data_dir() |
35 | 34 | """ |
35 | if self._set_search_paths and not reset: | |
36 | return | |
36 | 37 | data_dir_list = get_data_dir().split(os.pathsep) |
37 | 38 | cdef char **c_data_dir = <char **>malloc(len(data_dir_list) * sizeof(char*)) |
38 | 39 | try: |
39 | 40 | for iii in range(len(data_dir_list)): |
40 | 41 | b_data_dir = cstrencode(data_dir_list[iii]) |
41 | 42 | c_data_dir[iii] = b_data_dir |
43 | proj_context_set_search_paths(NULL, len(data_dir_list), c_data_dir) | |
42 | 44 | proj_context_set_search_paths(self.context, len(data_dir_list), c_data_dir) |
43 | 45 | finally: |
44 | 46 | free(c_data_dir) |
47 | self._set_search_paths = True | |
45 | 48 | |
46 | 49 | |
47 | 50 | cdef ContextManager PROJ_CONTEXT = ContextManager() |
0 | 0 | include "proj.pxi" |
1 | 1 | |
2 | 2 | cdef class Proj: |
3 | cdef PJ * projpj | |
4 | cdef PJ_PROJ_INFO projpj_info | |
3 | cdef PJ * projobj | |
4 | cdef PJ_PROJ_INFO projobj_info | |
5 | 5 | cdef readonly srs |
17 | 17 | |
18 | 18 | cdef class Proj: |
19 | 19 | def __cinit__(self): |
20 | self.projpj = NULL | |
20 | self.projobj = NULL | |
21 | 21 | |
22 | 22 | def __init__(self, const char *projstring): |
23 | 23 | self.srs = pystrdecode(projstring) |
24 | 24 | # initialize projection |
25 | self.projpj = proj_create(PROJ_CONTEXT.context, projstring) | |
26 | if self.projpj is NULL: | |
25 | self.projobj = proj_create(PROJ_CONTEXT.context, projstring) | |
26 | if self.projobj is NULL: | |
27 | 27 | raise ProjError("Invalid projection {}.".format(projstring)) |
28 | self.projpj_info = proj_pj_info(self.projpj) | |
28 | self.projobj_info = proj_pj_info(self.projobj) | |
29 | ProjError.clear() | |
29 | 30 | |
30 | 31 | def __dealloc__(self): |
31 | 32 | """destroy projection definition""" |
32 | if self.projpj is not NULL: | |
33 | proj_destroy(self.projpj) | |
34 | self.projpj = NULL | |
33 | if self.projobj is not NULL: | |
34 | proj_destroy(self.projobj) | |
35 | self.projobj = NULL | |
35 | 36 | |
36 | 37 | @property |
37 | 38 | def definition(self): |
38 | return self.projpj_info.definition | |
39 | return self.projobj_info.definition | |
39 | 40 | |
40 | 41 | @property |
41 | 42 | def has_inverse(self): |
42 | 43 | """Returns true if this projection has an inverse""" |
43 | return self.projpj_info.has_inverse == 1 | |
44 | return self.projobj_info.has_inverse == 1 | |
44 | 45 | |
45 | 46 | def __reduce__(self): |
46 | 47 | """special method that allows pyproj.Proj instance to be pickled""" |
62 | 63 | cdef double *latsdata |
63 | 64 | cdef void *londata |
64 | 65 | cdef void *latdata |
65 | cdef int err | |
66 | cdef int errno | |
66 | 67 | # if buffer api is supported, get pointer to data buffers. |
67 | 68 | if PyObject_AsWriteBuffer(lons, &londata, &buflenx) <> 0: |
68 | raise ProjError | |
69 | raise ProjError("object does not provide the python buffer writeable interface") | |
69 | 70 | if PyObject_AsWriteBuffer(lats, &latdata, &bufleny) <> 0: |
70 | raise ProjError | |
71 | raise ProjError("object does not provide the python buffer writeable interface") | |
71 | 72 | # process data in buffer |
72 | 73 | if buflenx != bufleny: |
73 | 74 | raise ProjError("Buffer lengths not the same") |
74 | 75 | ndim = buflenx//_DOUBLESIZE |
75 | 76 | lonsdata = <double *>londata |
76 | 77 | latsdata = <double *>latdata |
78 | proj_errno_reset(self.projobj) | |
77 | 79 | for iii in range(ndim): |
78 | 80 | # if inputs are nan's, return big number. |
79 | 81 | if lonsdata[iii] != lonsdata[iii] or latsdata[iii] != latsdata[iii]: |
81 | 83 | if errcheck: |
82 | 84 | raise ProjError("projection_undefined") |
83 | 85 | continue |
84 | if proj_angular_input(self.projpj, PJ_FWD): | |
86 | if proj_angular_input(self.projobj, PJ_FWD): | |
85 | 87 | projlonlatin.uv.u = _DG2RAD * lonsdata[iii] |
86 | 88 | projlonlatin.uv.v = _DG2RAD * latsdata[iii] |
87 | 89 | else: |
88 | 90 | projlonlatin.uv.u = lonsdata[iii] |
89 | 91 | projlonlatin.uv.v = latsdata[iii] |
90 | projxyout = proj_trans(self.projpj, PJ_FWD, projlonlatin) | |
91 | if errcheck: | |
92 | err = proj_errno(self.projpj) | |
93 | if err != 0: | |
94 | raise ProjError(pystrdecode(proj_errno_string(err))) | |
92 | projxyout = proj_trans(self.projobj, PJ_FWD, projlonlatin) | |
93 | errno = proj_errno(self.projobj) | |
94 | if errcheck and errno: | |
95 | raise ProjError("proj error: {}".format( | |
96 | pystrdecode(proj_errno_string(errno)))) | |
97 | elif errcheck and ProjError.internal_proj_error is not None: | |
98 | raise ProjError("proj error") | |
95 | 99 | # since HUGE_VAL can be 'inf', |
96 | 100 | # change it to a real (but very large) number. |
97 | 101 | # also check for NaNs. |
103 | 107 | raise ProjError("projection_undefined") |
104 | 108 | lonsdata[iii] = 1.e30 |
105 | 109 | latsdata[iii] = 1.e30 |
106 | elif proj_angular_output(self.projpj, PJ_FWD): | |
110 | elif proj_angular_output(self.projobj, PJ_FWD): | |
107 | 111 | lonsdata[iii] = _RAD2DG * projxyout.xy.x |
108 | 112 | latsdata[iii] = _RAD2DG * projxyout.xy.y |
109 | 113 | else: |
110 | 114 | lonsdata[iii] = projxyout.xy.x |
111 | 115 | latsdata[iii] = projxyout.xy.y |
116 | ProjError.clear() | |
112 | 117 | |
113 | 118 | |
114 | 119 | @cython.boundscheck(False) |
130 | 135 | cdef void *ydata |
131 | 136 | cdef double *xdatab |
132 | 137 | cdef double *ydatab |
133 | cdef int err | |
138 | cdef int errno | |
134 | 139 | |
135 | 140 | # if buffer api is supported, get pointer to data buffers. |
136 | 141 | if PyObject_AsWriteBuffer(x, &xdata, &buflenx) <> 0: |
137 | raise ProjError | |
142 | raise ProjError("object does not provide the python buffer writeable interface") | |
138 | 143 | if PyObject_AsWriteBuffer(y, &ydata, &bufleny) <> 0: |
139 | raise ProjError | |
144 | raise ProjError("object does not provide the python buffer writeable interface") | |
140 | 145 | # process data in buffer |
141 | 146 | # (for numpy/regular python arrays). |
142 | 147 | if buflenx != bufleny: |
144 | 149 | ndim = buflenx//_DOUBLESIZE |
145 | 150 | xdatab = <double *>xdata |
146 | 151 | ydatab = <double *>ydata |
152 | # reset errors potentially left over | |
153 | proj_errno_reset(self.projobj) | |
154 | ||
147 | 155 | for iii in range(ndim): |
148 | 156 | # if inputs are nan's, return big number. |
149 | 157 | if xdatab[iii] != xdatab[iii] or ydatab[iii] != ydatab[iii]: |
151 | 159 | if errcheck: |
152 | 160 | raise ProjError("projection_undefined") |
153 | 161 | continue |
154 | if proj_angular_input(self.projpj, PJ_INV): | |
162 | if proj_angular_input(self.projobj, PJ_INV): | |
155 | 163 | projxyin.uv.u = _DG2RAD * xdatab[iii] |
156 | 164 | projxyin.uv.v = _DG2RAD * ydatab[iii] |
157 | 165 | else: |
158 | 166 | projxyin.uv.u = xdatab[iii] |
159 | 167 | projxyin.uv.v = ydatab[iii] |
160 | projlonlatout = proj_trans(self.projpj, PJ_INV, projxyin) | |
161 | if errcheck: | |
162 | err = proj_errno(self.projpj) | |
163 | if err != 0: | |
164 | raise ProjError(pystrdecode(proj_errno_string(err))) | |
168 | projlonlatout = proj_trans(self.projobj, PJ_INV, projxyin) | |
169 | errno = proj_errno(self.projobj) | |
170 | if errcheck and errno: | |
171 | raise ProjError("proj error: {}".format( | |
172 | pystrdecode(proj_errno_string(errno)))) | |
173 | elif errcheck and ProjError.internal_proj_error is not None: | |
174 | raise ProjError("proj error") | |
165 | 175 | # since HUGE_VAL can be 'inf', |
166 | 176 | # change it to a real (but very large) number. |
167 | 177 | # also check for NaNs. |
173 | 183 | raise ProjError("projection_undefined") |
174 | 184 | xdatab[iii] = 1.e30 |
175 | 185 | ydatab[iii] = 1.e30 |
176 | elif proj_angular_output(self.projpj, PJ_INV): | |
186 | elif proj_angular_output(self.projobj, PJ_INV): | |
177 | 187 | xdatab[iii] = _RAD2DG * projlonlatout.uv.u |
178 | 188 | ydatab[iii] = _RAD2DG * projlonlatout.uv.v |
179 | 189 | else: |
180 | 190 | xdatab[iii] = projlonlatout.uv.u |
181 | 191 | ydatab[iii] = projlonlatout.uv.v |
182 | 192 | |
193 | ProjError.clear() | |
194 | ||
183 | 195 | def __repr__(self): |
184 | 196 | return "Proj('{srs}', preserve_units=True)".format(srs=self.srs) |
185 | 197 | |
186 | 198 | def _is_exact_same(self, Proj other): |
187 | 199 | return proj_is_equivalent_to( |
188 | self.projpj, other.projpj, PJ_COMP_STRICT) == 1 | |
200 | self.projobj, other.projobj, PJ_COMP_STRICT) == 1 | |
189 | 201 | |
190 | 202 | def _is_equivalent(self, Proj other): |
191 | 203 | return proj_is_equivalent_to( |
192 | self.projpj, other.projpj, PJ_COMP_EQUIVALENT) == 1 | |
204 | self.projobj, other.projobj, PJ_COMP_EQUIVALENT) == 1 | |
193 | 205 | |
194 | 206 | def __eq__(self, other): |
195 | 207 | if not isinstance(other, Proj): |
66 | 66 | cdef int is_instantiable = 0 |
67 | 67 | cdef CoordinateOperation coordinate_operation |
68 | 68 | cdef double west_lon_degree, south_lat_degree, east_lon_degree, north_lat_degree |
69 | ||
70 | 69 | operations = [] |
71 | 70 | try: |
72 | 71 | operation_factory_context = proj_create_operation_factory_context( |
141 | 140 | if pj_operations != NULL: |
142 | 141 | proj_list_destroy(pj_operations) |
143 | 142 | pj_operations = NULL |
143 | ProjError.clear() | |
144 | ||
144 | 145 | return operations |
145 | 146 | |
146 | 147 | |
182 | 183 | def _initialize_from_projobj(self): |
183 | 184 | self.proj_info = proj_pj_info(self.projobj) |
184 | 185 | if self.proj_info.id == NULL: |
185 | ProjError.clear() | |
186 | 186 | raise ProjError("Input is not a transformation.") |
187 | 187 | cdef PJ_TYPE transformer_type = proj_get_type(self.projobj) |
188 | 188 | self.type_name = _TRANSFORMER_TYPE_MAP[transformer_type] |
189 | ProjError.clear() | |
189 | 190 | |
190 | 191 | @property |
191 | 192 | def id(self): |
227 | 228 | always_xy=False, |
228 | 229 | area_of_interest=None |
229 | 230 | ): |
230 | ProjError.clear() | |
231 | 231 | cdef PJ_AREA *pj_area_of_interest = NULL |
232 | 232 | cdef double west_lon_degree, south_lat_degree, east_lon_degree, north_lat_degree |
233 | 233 | if area_of_interest is not None: |
298 | 298 | |
299 | 299 | @staticmethod |
300 | 300 | def from_pipeline(const char *proj_pipeline): |
301 | ProjError.clear() | |
302 | 301 | cdef _Transformer transformer = _Transformer() |
303 | 302 | # initialize projection |
304 | 303 | transformer.projobj = proj_create(PROJ_CONTEXT.context, proj_pipeline) |
328 | 327 | cdef Py_ssize_t buflenx, bufleny, buflenz, buflent, npts, iii |
329 | 328 | cdef int err |
330 | 329 | if PyObject_AsWriteBuffer(inx, &xdata, &buflenx) <> 0: |
331 | raise ProjError | |
330 | raise ProjError("object does not provide the python buffer writeable interface") | |
332 | 331 | if PyObject_AsWriteBuffer(iny, &ydata, &bufleny) <> 0: |
333 | raise ProjError | |
334 | if inz is not None: | |
335 | if PyObject_AsWriteBuffer(inz, &zdata, &buflenz) <> 0: | |
336 | raise ProjError | |
332 | raise ProjError("object does not provide the python buffer writeable interface") | |
333 | if inz is not None and PyObject_AsWriteBuffer(inz, &zdata, &buflenz) <> 0: | |
334 | raise ProjError("object does not provide the python buffer writeable interface") | |
337 | 335 | else: |
338 | 336 | buflenz = bufleny |
339 | if intime is not None: | |
340 | if PyObject_AsWriteBuffer(intime, &tdata, &buflent) <> 0: | |
341 | raise ProjError | |
337 | if intime is not None and PyObject_AsWriteBuffer(intime, &tdata, &buflent) <> 0: | |
338 | raise ProjError("object does not provide the python buffer writeable interface") | |
342 | 339 | else: |
343 | 340 | buflent = bufleny |
344 | 341 | |
370 | 367 | xx[iii] = xx[iii]*_RAD2DG |
371 | 368 | yy[iii] = yy[iii]*_RAD2DG |
372 | 369 | |
373 | ProjError.clear() | |
374 | 370 | proj_errno_reset(self.projobj) |
375 | 371 | proj_trans_generic( |
376 | 372 | self.projobj, |
400 | 396 | for iii in range(npts): |
401 | 397 | xx[iii] = xx[iii]*_DG2RAD |
402 | 398 | yy[iii] = yy[iii]*_DG2RAD |
399 | ProjError.clear() | |
403 | 400 | |
404 | 401 | @cython.boundscheck(False) |
405 | 402 | @cython.wraparound(False) |
420 | 417 | double *z |
421 | 418 | double *tt |
422 | 419 | Py_ssize_t buflen, npts, iii, jjj |
423 | int err | |
424 | 420 | |
425 | 421 | if stride < 2: |
426 | 422 | raise ProjError("coordinates must contain at least 2 values") |
466 | 462 | else: |
467 | 463 | tt = NULL |
468 | 464 | |
469 | ProjError.clear() | |
470 | 465 | proj_errno_reset(self.projobj) |
471 | 466 | proj_trans_generic ( |
472 | 467 | self.projobj, |
499 | 494 | jjj = stride * iii |
500 | 495 | coords[jjj] *= _DG2RAD |
501 | 496 | coords[jjj + 1] *= _DG2RAD |
497 | ||
498 | ProjError.clear() |
23 | 23 | # reset search paths |
24 | 24 | from pyproj._datadir import PYPROJ_CONTEXT |
25 | 25 | |
26 | PYPROJ_CONTEXT.set_search_paths() | |
26 | PYPROJ_CONTEXT.set_search_paths(reset=True) | |
27 | 27 | |
28 | 28 | |
29 | 29 | def append_data_dir(proj_data_dir): |
395 | 395 | >>> lons = [-74, -102, -102, -131, -163, 163, 172, 140, 113, |
396 | 396 | ... 88, 59, 25, -4, -14, -33, -46, -61] |
397 | 397 | >>> poly_area, poly_perimeter = geod.polygon_area_perimeter(lons, lats) |
398 | >>> "{:.3f} {:.3f}".format(poly_area, poly_perimeter) | |
399 | '13376856682207.406 14710425.407' | |
398 | >>> "{:.1f} {:.1f}".format(poly_area, poly_perimeter) | |
399 | '13376856682207.4 14710425.4' | |
400 | 400 | |
401 | 401 | |
402 | 402 | Parameters |
0 | 0 | import os |
1 | 1 | import shutil |
2 | 2 | import tempfile |
3 | import unittest | |
4 | 3 | from contextlib import contextmanager |
5 | 4 | |
6 | 5 | import pytest |
7 | 6 | from mock import patch |
8 | 7 | |
9 | 8 | from pyproj import CRS |
9 | from pyproj._datadir import ContextManager | |
10 | 10 | from pyproj.datadir import DataDirError, append_data_dir, get_data_dir, set_data_dir |
11 | 11 | |
12 | 12 | |
26 | 26 | """ |
27 | 27 | Ensure environment variable the same at the end of the test. |
28 | 28 | """ |
29 | proj_lib = os.environ.get("PROJ_LIB") | |
30 | 29 | try: |
31 | 30 | yield |
32 | 31 | finally: |
33 | if proj_lib is not None: | |
34 | # add it back if it used to be there | |
35 | os.environ["PROJ_LIB"] = proj_lib | |
36 | else: | |
37 | # remove it if it wasn't there previously | |
38 | os.environ.pop("PROJ_LIB", None) | |
39 | 32 | # make sure the data dir is cleared |
40 | 33 | set_data_dir(None) |
41 | 34 | |
52 | 45 | shutil.rmtree(temp_dir) |
53 | 46 | |
54 | 47 | |
55 | @unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.") | |
48 | _INVALID_PATH = "/invalid/path/to/nowhere" | |
49 | ||
50 | ||
51 | def setup_os_mock(os_mock, abspath_return=_INVALID_PATH, proj_dir=None): | |
52 | os_mock.path.abspath.return_value = abspath_return | |
53 | os_mock.path.join = os.path.join | |
54 | os_mock.path.dirname = os.path.dirname | |
55 | os_mock.path.exists = os.path.exists | |
56 | os_mock.pathsep = os.pathsep | |
57 | if proj_dir is None: | |
58 | os_mock.environ = {} | |
59 | else: | |
60 | os_mock.environ = {"PROJ_LIB": proj_dir} | |
61 | ||
62 | ||
56 | 63 | def test_get_data_dir__missing(): |
57 | 64 | with proj_env(), pytest.raises(DataDirError), patch( |
58 | "pyproj.datadir.os.path.abspath", return_value="INVALID" | |
59 | ), patch("pyproj.datadir.find_executable", return_value=None): | |
65 | "pyproj.datadir.find_executable", return_value=None | |
66 | ), patch("pyproj.datadir.os") as os_mock, patch("pyproj.datadir.sys") as sys_mock: | |
67 | sys_mock.prefix = _INVALID_PATH | |
68 | setup_os_mock(os_mock) | |
60 | 69 | unset_data_dir() |
61 | os.environ.pop("PROJ_LIB", None) | |
62 | 70 | assert get_data_dir() is None |
63 | 71 | |
64 | 72 | |
73 | def test_condext_manager_datadir_missing(): | |
74 | with proj_env(), pytest.raises(DataDirError), patch( | |
75 | "pyproj._datadir.get_data_dir", side_effect=DataDirError("test") | |
76 | ): | |
77 | ContextManager().set_search_paths() | |
78 | ||
79 | ||
65 | 80 | def test_get_data_dir__from_user(): |
66 | with proj_env(), temporary_directory() as tmpdir, temporary_directory() as tmpdir_env: # noqa: E501 | |
81 | with proj_env(), temporary_directory() as tmpdir, patch( | |
82 | "pyproj.datadir.os" | |
83 | ) as os_mock, patch( | |
84 | "pyproj.datadir.sys" | |
85 | ) as sys_mock, temporary_directory() as tmpdir_env: # noqa: E501 | |
86 | setup_os_mock( | |
87 | os_mock, | |
88 | abspath_return=os.path.join(tmpdir, "randomfilename.py"), | |
89 | proj_dir=tmpdir_env, | |
90 | ) | |
91 | sys_mock.prefix = tmpdir_env | |
67 | 92 | create_projdb(tmpdir) |
68 | os.environ["PROJ_LIB"] = tmpdir_env | |
69 | 93 | create_projdb(tmpdir_env) |
70 | 94 | set_data_dir(tmpdir) |
71 | 95 | internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj") |
72 | 96 | os.makedirs(internal_proj_dir) |
73 | 97 | create_projdb(internal_proj_dir) |
74 | with patch("pyproj.datadir.os.path.abspath") as abspath_mock: | |
75 | abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py") | |
76 | assert get_data_dir() == tmpdir | |
98 | assert get_data_dir() == tmpdir | |
77 | 99 | |
78 | 100 | |
79 | 101 | def test_get_data_dir__internal(): |
80 | with proj_env(), temporary_directory() as tmpdir: | |
102 | with proj_env(), temporary_directory() as tmpdir, patch( | |
103 | "pyproj.datadir.os" | |
104 | ) as os_mock, temporary_directory() as tmpdir_fake, patch( | |
105 | "pyproj.datadir.sys" | |
106 | ) as sys_mock: | |
107 | setup_os_mock( | |
108 | os_mock, | |
109 | abspath_return=os.path.join(tmpdir, "randomfilename.py"), | |
110 | proj_dir=tmpdir_fake, | |
111 | ) | |
112 | sys_mock.prefix = tmpdir_fake | |
81 | 113 | unset_data_dir() |
82 | os.environ["PROJ_LIB"] = tmpdir | |
83 | 114 | create_projdb(tmpdir) |
115 | create_projdb(tmpdir_fake) | |
84 | 116 | internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj") |
85 | 117 | os.makedirs(internal_proj_dir) |
86 | 118 | create_projdb(internal_proj_dir) |
87 | with patch("pyproj.datadir.os.path.abspath") as abspath_mock: | |
88 | abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py") | |
89 | assert get_data_dir() == internal_proj_dir | |
119 | assert get_data_dir() == internal_proj_dir | |
90 | 120 | |
91 | 121 | |
92 | @unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.") | |
93 | 122 | def test_get_data_dir__from_env_var(): |
94 | 123 | with proj_env(), temporary_directory() as tmpdir, patch( |
95 | "pyproj.datadir.os.path.abspath", return_value="INVALID" | |
96 | ): | |
124 | "pyproj.datadir.os" | |
125 | ) as os_mock, patch("pyproj.datadir.sys") as sys_mock: | |
126 | setup_os_mock(os_mock, proj_dir=tmpdir) | |
127 | sys_mock.prefix = _INVALID_PATH | |
97 | 128 | unset_data_dir() |
98 | os.environ["PROJ_LIB"] = tmpdir | |
99 | 129 | create_projdb(tmpdir) |
100 | 130 | assert get_data_dir() == tmpdir |
101 | 131 | |
102 | 132 | |
103 | @unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.") | |
104 | 133 | def test_get_data_dir__from_env_var__multiple(): |
105 | 134 | with proj_env(), temporary_directory() as tmpdir, patch( |
106 | "pyproj.datadir.os.path.abspath", return_value="INVALID" | |
107 | ): | |
135 | "pyproj.datadir.os" | |
136 | ) as os_mock, patch("pyproj.datadir.sys") as sys_mock: | |
137 | setup_os_mock(os_mock, proj_dir=os.pathsep.join([tmpdir, tmpdir, tmpdir])) | |
138 | sys_mock.prefix = _INVALID_PATH | |
108 | 139 | unset_data_dir() |
109 | os.environ["PROJ_LIB"] = os.pathsep.join([tmpdir, tmpdir, tmpdir]) | |
110 | 140 | create_projdb(tmpdir) |
111 | 141 | assert get_data_dir() == os.pathsep.join([tmpdir, tmpdir, tmpdir]) |
112 | 142 | |
113 | 143 | |
114 | @unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.") | |
115 | 144 | def test_get_data_dir__from_prefix(): |
116 | 145 | with proj_env(), temporary_directory() as tmpdir, patch( |
117 | "pyproj.datadir.os.path.abspath", return_value="INVALID" | |
118 | ), patch("pyproj.datadir.sys") as sys_mock: | |
146 | "pyproj.datadir.os" | |
147 | ) as os_mock, patch("pyproj.datadir.sys") as sys_mock: | |
148 | setup_os_mock(os_mock) | |
119 | 149 | unset_data_dir() |
120 | os.environ.pop("PROJ_LIB", None) | |
121 | 150 | sys_mock.prefix = tmpdir |
122 | 151 | proj_dir = os.path.join(tmpdir, "share", "proj") |
123 | 152 | os.makedirs(proj_dir) |
125 | 154 | assert get_data_dir() == proj_dir |
126 | 155 | |
127 | 156 | |
128 | @unittest.skipIf(os.name == "nt", reason="Cannot modify Windows environment variables.") | |
129 | 157 | def test_get_data_dir__from_path(): |
130 | 158 | with proj_env(), temporary_directory() as tmpdir, patch( |
131 | "pyproj.datadir.os.path.abspath", return_value="INVALID" | |
132 | ), patch("pyproj.datadir.find_executable") as find_exe: | |
159 | "pyproj.datadir.os" | |
160 | ) as os_mock, patch("pyproj.datadir.sys") as sys_mock, patch( | |
161 | "pyproj.datadir.find_executable" | |
162 | ) as find_exe: | |
163 | setup_os_mock(os_mock) | |
164 | sys_mock.prefix = _INVALID_PATH | |
133 | 165 | unset_data_dir() |
134 | os.environ.pop("PROJ_LIB", None) | |
135 | 166 | find_exe.return_value = os.path.join(tmpdir, "bin", "proj") |
136 | 167 | proj_dir = os.path.join(tmpdir, "share", "proj") |
137 | 168 | os.makedirs(proj_dir) |
140 | 171 | |
141 | 172 | |
142 | 173 | def test_append_data_dir__internal(): |
143 | with proj_env(), temporary_directory() as tmpdir: | |
174 | with proj_env(), temporary_directory() as tmpdir, patch( | |
175 | "pyproj.datadir.os" | |
176 | ) as os_mock: | |
177 | setup_os_mock(os_mock, os.path.join(tmpdir, "randomfilename.py")) | |
144 | 178 | unset_data_dir() |
145 | os.environ["PROJ_LIB"] = tmpdir | |
146 | 179 | create_projdb(tmpdir) |
147 | 180 | internal_proj_dir = os.path.join(tmpdir, "proj_dir", "share", "proj") |
148 | 181 | os.makedirs(internal_proj_dir) |
149 | 182 | create_projdb(internal_proj_dir) |
150 | 183 | extra_datadir = str(os.path.join(tmpdir, "extra_datumgrids")) |
151 | with patch("pyproj.datadir.os.path.abspath") as abspath_mock: | |
152 | abspath_mock.return_value = os.path.join(tmpdir, "randomfilename.py") | |
153 | append_data_dir(extra_datadir) | |
154 | assert get_data_dir() == os.pathsep.join([internal_proj_dir, extra_datadir]) | |
184 | append_data_dir(extra_datadir) | |
185 | assert get_data_dir() == os.pathsep.join([internal_proj_dir, extra_datadir]) | |
155 | 186 | |
156 | 187 | |
157 | 188 | def test_creating_multiple_crs_without_file_limit(): |
2 | 2 | pytest can conveniently run all the tests in a single command line. |
3 | 3 | """ |
4 | 4 | import os |
5 | import platform | |
5 | 6 | |
6 | 7 | import pyproj |
7 | 8 | |
14 | 15 | try: |
15 | 16 | import shapely # noqa |
16 | 17 | except ImportError: |
17 | if os.name == "nt": | |
18 | if os.name == "nt" or platform.uname()[4] != "x86_64": | |
18 | 19 | expected_failure_count = 6 |
19 | 20 | |
20 | 21 | # if the below line fails, doctests have failed |
0 | 0 | import math |
1 | 1 | import os |
2 | 2 | import pickle |
3 | import platform | |
3 | 4 | import shutil |
4 | 5 | import tempfile |
5 | 6 | from contextlib import contextmanager |
25 | 26 | SHAPELY_LOADED = False |
26 | 27 | |
27 | 28 | |
28 | skip_shapely_windows = pytest.mark.skipif( | |
29 | not SHAPELY_LOADED and os.name == "nt", reason="Missing shapely wheels for Windows." | |
29 | skip_shapely = pytest.mark.skipif( | |
30 | not SHAPELY_LOADED and (os.name == "nt" or platform.uname()[4] != "x86_64"), | |
31 | reason="Missing shapely wheels for Windows.", | |
30 | 32 | ) |
31 | 33 | |
32 | 34 | |
170 | 172 | assert perimeter == 0 |
171 | 173 | |
172 | 174 | |
173 | @skip_shapely_windows | |
175 | @skip_shapely | |
174 | 176 | def test_geometry_length__point(): |
175 | 177 | geod = Geod(ellps="WGS84") |
176 | 178 | assert geod.geometry_length(Point(1, 2)) == 0 |
177 | 179 | |
178 | 180 | |
179 | @skip_shapely_windows | |
181 | @skip_shapely | |
180 | 182 | def test_geometry_length__linestring(): |
181 | 183 | geod = Geod(ellps="WGS84") |
182 | 184 | assert_almost_equal( |
183 | 185 | geod.geometry_length(LineString([Point(1, 2), Point(3, 4)])), |
184 | 186 | 313588.39721259556, |
185 | decimal=3, | |
186 | ) | |
187 | ||
188 | ||
189 | @skip_shapely_windows | |
187 | decimal=2, | |
188 | ) | |
189 | ||
190 | ||
191 | @skip_shapely | |
190 | 192 | def test_geometry_length__linestring__radians(): |
191 | 193 | geod = Geod(ellps="WGS84") |
192 | 194 | assert_almost_equal( |
200 | 202 | radians=True, |
201 | 203 | ), |
202 | 204 | 313588.39721259556, |
203 | decimal=3, | |
204 | ) | |
205 | ||
206 | ||
207 | @skip_shapely_windows | |
205 | decimal=2, | |
206 | ) | |
207 | ||
208 | ||
209 | @skip_shapely | |
208 | 210 | def test_geometry_length__linearring(): |
209 | 211 | geod = Geod(ellps="WGS84") |
210 | 212 | assert_almost_equal( |
212 | 214 | LinearRing(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) |
213 | 215 | ), |
214 | 216 | 1072185.2103813463, |
215 | decimal=3, | |
216 | ) | |
217 | ||
218 | ||
219 | @skip_shapely_windows | |
217 | decimal=2, | |
218 | ) | |
219 | ||
220 | ||
221 | @skip_shapely | |
220 | 222 | def test_geometry_length__polygon(): |
221 | 223 | geod = Geod(ellps="WGS84") |
222 | 224 | assert_almost_equal( |
224 | 226 | Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) |
225 | 227 | ), |
226 | 228 | 1072185.2103813463, |
227 | decimal=3, | |
228 | ) | |
229 | ||
230 | ||
231 | @skip_shapely_windows | |
229 | decimal=2, | |
230 | ) | |
231 | ||
232 | ||
233 | @skip_shapely | |
232 | 234 | def test_geometry_length__polygon__radians(): |
233 | 235 | geod = Geod(ellps="WGS84") |
234 | 236 | assert_almost_equal( |
245 | 247 | radians=True, |
246 | 248 | ), |
247 | 249 | 1072185.2103813463, |
248 | decimal=3, | |
249 | ) | |
250 | ||
251 | ||
252 | @skip_shapely_windows | |
250 | decimal=2, | |
251 | ) | |
252 | ||
253 | ||
254 | @skip_shapely | |
253 | 255 | def test_geometry_length__multipolygon(): |
254 | 256 | geod = Geod(ellps="WGS84") |
255 | 257 | polygon = Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) |
256 | 258 | assert_almost_equal( |
257 | 259 | geod.geometry_length(MultiPolygon([polygon, polygon])), |
258 | 260 | 2 * 1072185.2103813463, |
259 | decimal=3, | |
260 | ) | |
261 | ||
262 | ||
263 | @skip_shapely_windows | |
261 | decimal=2, | |
262 | ) | |
263 | ||
264 | ||
265 | @skip_shapely | |
264 | 266 | def test_geometry_length__multipolygon__radians(): |
265 | 267 | geod = Geod(ellps="WGS84") |
266 | 268 | polygon = Polygon( |
275 | 277 | assert_almost_equal( |
276 | 278 | geod.geometry_length(MultiPolygon([polygon, polygon]), radians=True), |
277 | 279 | 2 * 1072185.2103813463, |
278 | decimal=3, | |
279 | ) | |
280 | ||
281 | ||
282 | @skip_shapely_windows | |
280 | decimal=2, | |
281 | ) | |
282 | ||
283 | ||
284 | @skip_shapely | |
283 | 285 | def test_geometry_length__multilinestring(): |
284 | 286 | geod = Geod(ellps="WGS84") |
285 | 287 | line_string = LineString([Point(1, 2), Point(3, 4), Point(5, 2)]) |
286 | 288 | assert_almost_equal( |
287 | 289 | geod.geometry_length(MultiLineString([line_string, line_string])), |
288 | 290 | 1254353.5888503822, |
289 | decimal=3, | |
290 | ) | |
291 | ||
292 | ||
293 | @skip_shapely_windows | |
291 | decimal=2, | |
292 | ) | |
293 | ||
294 | ||
295 | @skip_shapely | |
294 | 296 | def test_geometry_length__multipoint(): |
295 | 297 | geod = Geod(ellps="WGS84") |
296 | 298 | assert ( |
298 | 300 | ) |
299 | 301 | |
300 | 302 | |
301 | @skip_shapely_windows | |
303 | @skip_shapely | |
302 | 304 | def test_geometry_area_perimeter__point(): |
303 | 305 | geod = Geod(ellps="WGS84") |
304 | 306 | assert geod.geometry_area_perimeter(Point(1, 2)) == (0, 0) |
305 | 307 | |
306 | 308 | |
307 | @skip_shapely_windows | |
309 | @skip_shapely | |
308 | 310 | def test_geometry_area_perimeter__linestring(): |
309 | 311 | geod = Geod(ellps="WGS84") |
310 | 312 | assert_almost_equal( |
311 | 313 | geod.geometry_area_perimeter(LineString([Point(1, 2), Point(3, 4)])), |
312 | 314 | (0.0, 627176.7944251911), |
313 | decimal=3, | |
314 | ) | |
315 | ||
316 | ||
317 | @skip_shapely_windows | |
315 | decimal=2, | |
316 | ) | |
317 | ||
318 | ||
319 | @skip_shapely | |
318 | 320 | def test_geometry_area_perimeter__linestring__radians(): |
319 | 321 | geod = Geod(ellps="WGS84") |
320 | 322 | assert_almost_equal( |
328 | 330 | radians=True, |
329 | 331 | ), |
330 | 332 | (0.0, 627176.7944251911), |
331 | decimal=3, | |
332 | ) | |
333 | ||
334 | ||
335 | @skip_shapely_windows | |
333 | decimal=2, | |
334 | ) | |
335 | ||
336 | ||
337 | @skip_shapely | |
336 | 338 | def test_geometry_area_perimeter__linearring(): |
337 | 339 | geod = Geod(ellps="WGS84") |
338 | 340 | assert_almost_equal( |
340 | 342 | LinearRing(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) |
341 | 343 | ), |
342 | 344 | (-49187690467.58623, 1072185.2103813463), |
343 | decimal=3, | |
344 | ) | |
345 | ||
346 | ||
347 | @skip_shapely_windows | |
345 | decimal=2, | |
346 | ) | |
347 | ||
348 | ||
349 | @skip_shapely | |
348 | 350 | def test_geometry_area_perimeter__polygon(): |
349 | 351 | geod = Geod(ellps="WGS84") |
350 | 352 | assert_almost_equal( |
352 | 354 | Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) |
353 | 355 | ), |
354 | 356 | (-49187690467.58623, 1072185.2103813463), |
355 | decimal=3, | |
356 | ) | |
357 | ||
358 | ||
359 | @skip_shapely_windows | |
357 | decimal=2, | |
358 | ) | |
359 | ||
360 | ||
361 | @skip_shapely | |
360 | 362 | def test_geometry_area_perimeter__polygon__radians(): |
361 | 363 | geod = Geod(ellps="WGS84") |
362 | 364 | assert_almost_equal( |
373 | 375 | radians=True, |
374 | 376 | ), |
375 | 377 | (-49187690467.58623, 1072185.2103813463), |
376 | decimal=3, | |
377 | ) | |
378 | ||
379 | ||
380 | @skip_shapely_windows | |
378 | decimal=2, | |
379 | ) | |
380 | ||
381 | ||
382 | @skip_shapely | |
381 | 383 | def test_geometry_area_perimeter__polygon__holes(): |
382 | 384 | geod = Geod(ellps="WGS84") |
383 | 385 | assert_almost_equal( |
388 | 390 | ) |
389 | 391 | ), |
390 | 392 | (-944373881400.3394, 3979008.0359657984), |
391 | ) | |
392 | ||
393 | ||
394 | @skip_shapely_windows | |
393 | decimal=2, | |
394 | ) | |
395 | ||
396 | ||
397 | @skip_shapely | |
395 | 398 | def test_geometry_area_perimeter__multipolygon(): |
396 | 399 | geod = Geod(ellps="WGS84") |
397 | 400 | polygon = Polygon(LineString([Point(1, 2), Point(3, 4), Point(5, 2)])) |
398 | 401 | assert_almost_equal( |
399 | 402 | geod.geometry_area_perimeter(MultiPolygon([polygon, polygon])), |
400 | 403 | (-98375380935.17245, 2144370.4207626926), |
401 | decimal=3, | |
402 | ) | |
403 | ||
404 | ||
405 | @skip_shapely_windows | |
404 | decimal=2, | |
405 | ) | |
406 | ||
407 | ||
408 | @skip_shapely | |
406 | 409 | def test_geometry_area_perimeter__multipolygon__radians(): |
407 | 410 | geod = Geod(ellps="WGS84") |
408 | 411 | polygon = Polygon( |
417 | 420 | assert_almost_equal( |
418 | 421 | geod.geometry_area_perimeter(MultiPolygon([polygon, polygon]), radians=True), |
419 | 422 | (-98375380935.17245, 2144370.4207626926), |
420 | decimal=3, | |
421 | ) | |
422 | ||
423 | ||
424 | @skip_shapely_windows | |
423 | decimal=2, | |
424 | ) | |
425 | ||
426 | ||
427 | @skip_shapely | |
425 | 428 | def test_geometry_area_perimeter__multilinestring(): |
426 | 429 | geod = Geod(ellps="WGS84") |
427 | 430 | line_string = LineString([Point(1, 2), Point(3, 4), Point(5, 2)]) |
428 | 431 | assert_almost_equal( |
429 | 432 | geod.geometry_area_perimeter(MultiLineString([line_string, line_string])), |
430 | 433 | (-98375380935.17245, 2144370.4207626926), |
431 | decimal=3, | |
432 | ) | |
433 | ||
434 | ||
435 | @skip_shapely_windows | |
434 | decimal=2, | |
435 | ) | |
436 | ||
437 | ||
438 | @skip_shapely | |
436 | 439 | def test_geometry_area_perimeter__multipoint(): |
437 | 440 | geod = Geod(ellps="WGS84") |
438 | 441 | assert geod.geometry_area_perimeter( |
402 | 402 | assert not Proj("epsg:4326").is_exact_same(None) |
403 | 403 | |
404 | 404 | |
405 | def test_reset_errno(): | |
406 | proj = Proj( | |
407 | {"proj": "laea", "lat_0": -90, "lon_0": 0, "a": 6371228.0, "units": "m"} | |
408 | ) | |
409 | assert not proj.crs.is_geographic | |
410 | assert proj(0, 0, inverse=True, errcheck=True) == (0.0, -90.0) | |
411 | ||
412 | ||
405 | 413 | if __name__ == "__main__": |
406 | 414 | unittest.main() |
0 | from pkg_resources import parse_version | |
1 | ||
0 | 2 | import numpy as np |
1 | 3 | import pytest |
2 | 4 | from numpy.testing import assert_almost_equal |
92 | 94 | def test_equivalent_proj__disabled(): |
93 | 95 | transformer = Transformer.from_proj(3857, pyproj.Proj(3857).crs.to_proj4()) |
94 | 96 | assert not transformer._transformer.skip_equivalent |
95 | assert not transformer._transformer.projections_equivalent | |
97 | assert transformer._transformer.projections_equivalent == ( | |
98 | parse_version(pyproj.proj_version_str) >= parse_version("6.2.0") | |
99 | ) | |
96 | 100 | assert not transformer._transformer.projections_exact_same |
97 | 101 | |
98 | 102 |