Codebase list python-pyproj / 9262659
New upstream version 2.6.0~rc0+ds Bas Couwenberg 4 years ago
52 changed file(s) with 1814 addition(s) and 623 deletion(s). Raw diff Collapse all Expand all
6767 "doc",
6868 "code",
6969 "ideas",
70 "review"
70 "review",
71 "question"
7172 ]
7273 },
7374 {
183184 "profile": "https://github.com/sebastic",
184185 "contributions": [
185186 "code",
186 "platform"
187 "platform",
188 "test"
187189 ]
188190 },
189191 {
316318 "contributions": [
317319 "doc"
318320 ]
321 },
322 {
323 "login": "jranalli",
324 "name": "Joe Ranalli",
325 "avatar_url": "https://avatars2.githubusercontent.com/u/7864460?v=4",
326 "profile": "http://www.personal.psu.edu/jar339",
327 "contributions": [
328 "bug",
329 "code",
330 "test"
331 ]
332 },
333 {
334 "login": "gberardinelli",
335 "name": "Greg Berardinelli",
336 "avatar_url": "https://avatars0.githubusercontent.com/u/13799588?v=4",
337 "profile": "https://github.com/gberardinelli",
338 "contributions": [
339 "bug",
340 "code",
341 "ideas",
342 "test"
343 ]
319344 }
320345 ],
321346 "contributorsPerLine": 7
1313
1414 ```python
1515 # Your code here
16
1716 ```
1817 #### Problem description
1918
5958
6059 ```
6160 </details>
62
55
66 <!-- Please search existing issues to avoid creating duplicates. -->
77
8 <!-- Describe the feature you'd like. -->
8 <!-- Describe the feature you'd like. -->
99
1010 Issues installing pyproj?
1111 Have you seen: http://pyproj4.github.io/pyproj/stable/installation.html
12 -->
12 -->
11
22 - [ ] Closes #xxxx
33 - [ ] Tests added
4 - [ ] Fully documented, including `history.rst` for all changes and `api/*.rst` for new API
4 - [ ] Fully documented, including `history.rst` for all changes and `api/*.rst` for new API
116116
117117 # vscode
118118 .vscode/
119
0 [settings]
1 line_length=88
2 multi_line_output=3
3 known_third_party=mock,numpy,pkg_resources,pytest,setuptools,test
4 include_trailing_comma=true
0 repos:
1 - repo: https://github.com/pre-commit/pre-commit-hooks
2 rev: v2.5.0
3 hooks:
4 - id: check-yaml
5 - id: end-of-file-fixer
6 - id: trailing-whitespace
7 - repo: https://github.com/psf/black
8 rev: 19.10b0
9 hooks:
10 - id: black
11 - repo: https://github.com/timothycrosley/isort
12 rev: 4.3.21
13 hooks:
14 - id: isort
15 args: [setup.py, pyproj/, test/, docs/]
16 - repo: https://github.com/asottile/blacken-docs
17 rev: v1.6.0
18 hooks:
19 - id: blacken-docs
20 args: [--skip-errors]
66 - $PROJ_BASE_DIR
77 - $HOME/.cache/pip
88
9 env:
10 global:
9 env:
10 global:
1111 - PROJ_BASE_DIR=$HOME/proj_install
1212 - CYTHON_COVERAGE=True
13 - PROJSOURCE=6.3.1
13 - PROJSOURCE=7.0.0
1414 # Following generated with
1515 - WHEELHOUSE_UPLOADER_USERNAME=travis-worker
1616 # Following generated by
3636 - python: 3.6
3737 env:
3838 - PROJSOURCE=6.3.0
39 - python: 3.6
40 env:
41 - PROJSOURCE=6.3.1
3942 - python: 3.7
4043 env:
4144 - DOC=true
4649 # - python: "nightly"
4750 # env:
4851 # - PROJSOURCE=git
49
52
5053 allow_failures:
5154 # - python: "nightly"
5255 # env:
6063 - |
6164 if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
6265 brew update
63 brew install sqlite3 wget openssl readline
66 brew install sqlite3 wget openssl readline libtiff
6467 # from https://pythonhosted.org/CodeChat/.travis.yml.html
6568 brew outdated pyenv || brew upgrade pyenv
6669 # virtualenv doesn't work without pyenv knowledge. venv in Python 3.3
7780 # A manual check that the correct version of Python is running.
7881 python --version
7982 else
80 sudo apt-get install -qq sqlite3 libsqlite3-dev
83 sudo apt-get install -qq sqlite3 libsqlite3-dev libtiff-dev libcurl4-openssl-dev
8184 fi
8285 - |
8386 if [[ "$TRAVIS_OS_NAME" == "osx" && -n "$PYPROJ_OMP" ]]; then
114117 script:
115118 - python -c "import pyproj; pyproj.Proj('epsg:4269')"
116119 - make test-coverage
120 - |
121 if [ "$TRAVIS_PYTHON_VERSION" = "3.5" ]; then
122 make check-type;
123 else
124 make check;
125 fi
117126 # Building and uploading docs with doctr
118127 - set -e
119128 - |
00 # Contributors Guide
1
2 Based on the guide from: https://github.com/Unidata/MetPy
13
24 Interested in helping build pyproj? Have code from your research that you believe others will find useful? Have a few minutes to tackle an issue? In this guide we will get you setup and integrated into contributing to pyproj!
35
7476 ``cd pyproj``
7577 * Connect your repository to the upstream (main project).
7678 ``git remote add upstream https://github.com/pyproj4/pyproj.git``
77 * Create the development environment by running ``conda create -n devel -c conda-forge python proj4``.
79 * Create the development environment by running ``conda create -n devel -c conda-forge cython proj numpy shapely``.
7880 * Activate our new development environment ``conda activate devel`` on Mac/Linux or
7981 ``activate devel`` on Windows.
82 * Install development requirements ``pip install -r requirements-dev.txt``
8083 * Make an editable install of pyproj by running ``pip install -e .``
84 * Setup pre-commit hooks ``pre-commit install`` and ``pre-commit autoupdate``
8185
8286 Now you're all set! You have an environment called ``devel`` that you can work in. You'll need
8387 to make sure to activate that environment next time you want to use it after closing the
106110
107111 You can build the documentation locally to see how your changes will look.
108112 * Install docs requirements: ``make install-docs``
109 * Build the docs: ``make docs``
113 * Build the docs: ``make docs``
110114 * Or, to build and open in a browser: ``make docs-browser``
111115
112116 ## Tests
00
1 All source, data files and other contents of the PROJ.4 package are
1 All source, data files and other contents of the PROJ.4 package are
22 available under the following terms. Note that the PROJ 4.3 and earlier
33 was "public domain" as is common with US government work, but apparently
4 this is not a well defined legal term in many countries. I am placing
4 this is not a well defined legal term in many countries. I am placing
55 everything under the following MIT style license because I believe it is
66 effectively the same as public domain, allowing anyone to use the code as
7 they wish, including making proprietary derivatives.
7 they wish, including making proprietary derivatives.
88
99 Though I have put my own name as copyright holder, I don't mean to imply
10 I did the work. Essentially all work was done by Gerald Evenden.
10 I did the work. Essentially all work was done by Gerald Evenden.
1111
1212 --------------
1313
3030 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
3131 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
3232 DEALINGS IN THE SOFTWARE.
33
66 include pyproj/*.pyx
77 include pyproj/*.pxd
88 include pyproj/*.pxi
9 include pyproj/*.pyi
910 include test/sample.out
1011 include test/conftest.py
1112 recursive-include docs *
6262 lint: ## check style with flake8
6363 flake8 --max-line-length 88 setup.py pyproj/ test/ docs/
6464
65 check: lint ## flake8 black isort check
65 check-type:
66 mypy pyproj
67
68 check: lint check-type ## flake8 black isort check
6669 black --check setup.py pyproj/ test/ docs/
67 isort --check --recursive -m 3 -w 88 -tc -p test setup.py pyproj/ test/ docs/
70 isort --check --recursive setup.py pyproj/ test/ docs/
6871
6972 isort: ## order imports
70 isort --recursive -m 3 -w 88 -tc -p test setup.py pyproj/ test/ docs/
73 isort --recursive setup.py pyproj/ test/ docs/
7174
7275 black: ## black format files
7376 black setup.py pyproj/ test/ docs/
00 # pyproj
1
1
22 Python interface to [PROJ](http://proj.org) (cartographic projections and coordinate transformations library).
33
44 <p align="center">
1111 <a href="https://pepy.tech/project/pyproj"><img alt="Downloads" src="https://pepy.tech/badge/pyproj"></a>
1212 <a href="https://anaconda.org/conda-forge/pyproj"><img alt="Anaconda-Server Badge" src="https://anaconda.org/conda-forge/pyproj/badges/version.svg"></a>
1313 <a href="https://github.com/python/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>
14 <a href="https://github.com/pre-commit/pre-commit"><img alt="pre-commit" src="https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white"></a>
1415 <a href="https://zenodo.org/badge/latestdoi/28607354"><img alt="DOI" src="https://zenodo.org/badge/28607354.svg"></a>
1516 </p>
1617
3839 <td align="center"><a href="https://github.com/jswhit"><img src="https://avatars2.githubusercontent.com/u/579593?v=4" width="100px;" alt="Jeff Whitaker"/><br /><sub><b>Jeff Whitaker</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=jswhit" title="Documentation">📖</a> <a href="https://github.com/pyproj4/pyproj/commits?author=jswhit" title="Tests">⚠️</a> <a href="https://github.com/pyproj4/pyproj/commits?author=jswhit" title="Code">💻</a> <a href="#example-jswhit" title="Examples">💡</a> <a href="#ideas-jswhit" title="Ideas, Planning, & Feedback">🤔</a> <a href="#review-jswhit" title="Reviewed Pull Requests">👀</a> <a href="#question-jswhit" title="Answering Questions">💬</a> <a href="#maintenance-jswhit" title="Maintenance">🚧</a> <a href="#infra-jswhit" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
3940 <td align="center"><a href="https://github.com/snowman2"><img src="https://avatars3.githubusercontent.com/u/8699967?v=4" width="100px;" alt="Alan D. Snow"/><br /><sub><b>Alan D. Snow</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=snowman2" title="Documentation">📖</a> <a href="https://github.com/pyproj4/pyproj/commits?author=snowman2" title="Tests">⚠️</a> <a href="https://github.com/pyproj4/pyproj/commits?author=snowman2" title="Code">💻</a> <a href="#example-snowman2" title="Examples">💡</a> <a href="#maintenance-snowman2" title="Maintenance">🚧</a> <a href="#infra-snowman2" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#ideas-snowman2" title="Ideas, Planning, & Feedback">🤔</a> <a href="#review-snowman2" title="Reviewed Pull Requests">👀</a> <a href="#question-snowman2" title="Answering Questions">💬</a></td>
4041 <td align="center"><a href="https://github.com/micahcochran"><img src="https://avatars0.githubusercontent.com/u/7433104?v=4" width="100px;" alt="Micah Cochran"/><br /><sub><b>Micah Cochran</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=micahcochran" title="Documentation">📖</a> <a href="https://github.com/pyproj4/pyproj/commits?author=micahcochran" title="Tests">⚠️</a> <a href="https://github.com/pyproj4/pyproj/commits?author=micahcochran" title="Code">💻</a> <a href="#maintenance-micahcochran" title="Maintenance">🚧</a> <a href="#infra-micahcochran" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#review-micahcochran" title="Reviewed Pull Requests">👀</a> <a href="#question-micahcochran" title="Answering Questions">💬</a></td>
41 <td align="center"><a href="https://jorisvandenbossche.github.io/"><img src="https://avatars2.githubusercontent.com/u/1020496?v=4" width="100px;" alt="Joris Van den Bossche"/><br /><sub><b>Joris Van den Bossche</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=jorisvandenbossche" title="Documentation">📖</a> <a href="https://github.com/pyproj4/pyproj/commits?author=jorisvandenbossche" title="Code">💻</a> <a href="#ideas-jorisvandenbossche" title="Ideas, Planning, & Feedback">🤔</a> <a href="#review-jorisvandenbossche" title="Reviewed Pull Requests">👀</a></td>
42 <td align="center"><a href="https://jorisvandenbossche.github.io/"><img src="https://avatars2.githubusercontent.com/u/1020496?v=4" width="100px;" alt="Joris Van den Bossche"/><br /><sub><b>Joris Van den Bossche</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=jorisvandenbossche" title="Documentation">📖</a> <a href="https://github.com/pyproj4/pyproj/commits?author=jorisvandenbossche" title="Code">💻</a> <a href="#ideas-jorisvandenbossche" title="Ideas, Planning, & Feedback">🤔</a> <a href="#review-jorisvandenbossche" title="Reviewed Pull Requests">👀</a> <a href="#question-jorisvandenbossche" title="Answering Questions">💬</a></td>
4243 <td align="center"><a href="https://github.com/cjmayo"><img src="https://avatars1.githubusercontent.com/u/921089?v=4" width="100px;" alt="Chris Mayo"/><br /><sub><b>Chris Mayo</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=cjmayo" title="Tests">⚠️</a></td>
4344 <td align="center"><a href="https://www.petrel.org"><img src="https://avatars1.githubusercontent.com/u/2298266?v=4" width="100px;" alt="Charles Karney"/><br /><sub><b>Charles Karney</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=cffk" title="Code">💻</a> <a href="https://github.com/pyproj4/pyproj/commits?author=cffk" title="Tests">⚠️</a></td>
4445 <td align="center"><a href="http://www.justaprogrammer.net/profile/justin"><img src="https://avatars3.githubusercontent.com/u/146930?v=4" width="100px;" alt="Justin Dearing"/><br /><sub><b>Justin Dearing</b></sub></a><br /><a href="#infra-zippy1981" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a></td>
5455 </tr>
5556 <tr>
5657 <td align="center"><a href="https://github.com/heitorPB"><img src="https://avatars2.githubusercontent.com/u/13461702?v=4" width="100px;" alt="Heitor"/><br /><sub><b>Heitor</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=heitorPB" title="Documentation">📖</a></td>
57 <td align="center"><a href="https://github.com/sebastic"><img src="https://avatars3.githubusercontent.com/u/4605306?v=4" width="100px;" alt="Bas Couwenberg"/><br /><sub><b>Bas Couwenberg</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=sebastic" title="Code">💻</a> <a href="#platform-sebastic" title="Packaging/porting to new platform">📦</a></td>
58 <td align="center"><a href="https://github.com/sebastic"><img src="https://avatars3.githubusercontent.com/u/4605306?v=4" width="100px;" alt="Bas Couwenberg"/><br /><sub><b>Bas Couwenberg</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=sebastic" title="Code">💻</a> <a href="#platform-sebastic" title="Packaging/porting to new platform">📦</a> <a href="https://github.com/pyproj4/pyproj/commits?author=sebastic" title="Tests">⚠️</a></td>
5859 <td align="center"><a href="https://github.com/nickeubank"><img src="https://avatars0.githubusercontent.com/u/9683693?v=4" width="100px;" alt="Nick Eubank"/><br /><sub><b>Nick Eubank</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=nickeubank" title="Code">💻</a></td>
5960 <td align="center"><a href="https://www.math.uwaterloo.ca/~mdunphy/"><img src="https://avatars3.githubusercontent.com/u/9088426?v=4" width="100px;" alt="Michael Dunphy"/><br /><sub><b>Michael Dunphy</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=mdunphy" title="Documentation">📖</a></td>
6061 <td align="center"><a href="http://matthew.dynevor.org"><img src="https://avatars2.githubusercontent.com/u/67612?v=4" width="100px;" alt="Matthew Brett"/><br /><sub><b>Matthew Brett</b></sub></a><br /><a href="#infra-matthew-brett" title="Infrastructure (Hosting, Build-Tools, etc)">🚇</a> <a href="#platform-matthew-brett" title="Packaging/porting to new platform">📦</a></td>
7374 <tr>
7475 <td align="center"><a href="https://github.com/glostis"><img src="https://avatars0.githubusercontent.com/u/25295717?v=4" width="100px;" alt="Guillaume Lostis"/><br /><sub><b>Guillaume Lostis</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=glostis" title="Documentation">📖</a></td>
7576 <td align="center"><a href="https://github.com/edpop"><img src="https://avatars3.githubusercontent.com/u/13479292?v=4" width="100px;" alt="Eduard Popov"/><br /><sub><b>Eduard Popov</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/commits?author=edpop" title="Documentation">📖</a></td>
77 <td align="center"><a href="http://www.personal.psu.edu/jar339"><img src="https://avatars2.githubusercontent.com/u/7864460?v=4" width="100px;" alt="Joe Ranalli"/><br /><sub><b>Joe Ranalli</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/issues?q=author%3Ajranalli" title="Bug reports">🐛</a> <a href="https://github.com/pyproj4/pyproj/commits?author=jranalli" title="Code">💻</a> <a href="https://github.com/pyproj4/pyproj/commits?author=jranalli" title="Tests">⚠️</a></td>
78 <td align="center"><a href="https://github.com/gberardinelli"><img src="https://avatars0.githubusercontent.com/u/13799588?v=4" width="100px;" alt="Greg Berardinelli"/><br /><sub><b>Greg Berardinelli</b></sub></a><br /><a href="https://github.com/pyproj4/pyproj/issues?q=author%3Agberardinelli" title="Bug reports">🐛</a> <a href="https://github.com/pyproj4/pyproj/commits?author=gberardinelli" title="Code">💻</a> <a href="#ideas-gberardinelli" title="Ideas, Planning, & Feedback">🤔</a> <a href="https://github.com/pyproj4/pyproj/commits?author=gberardinelli" title="Tests">⚠️</a></td>
7679 </tr>
7780 </table>
7881
00 platform:
11 - x64
22
3 # This is based on file and files in ci/appveyor are from
3 # This is based on file and files in ci/appveyor are from
44 # https://github.com/ogrisel/python-appveyor-demo
55 environment:
66 global:
1414 # Pre-installed Python versions
1515 # See: http://www.appveyor.com/docs/installed-software#python
1616 # build is limited to 60 minutes, without caching each build takes 10-30 minutes
17 # with caching build takes less than 1 minute
18 # - PYTHON: "C:\\Python35-x64"
19 # PYTHON_VERSION: "3.5"
20 # PYTHON_ARCH: "64"
21 # VS_VERSION: Visual Studio 14
22 # APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
23 # PROJSOURCE: 6.3.0
17 # with caching build takes less than 1 minute
2418 - PYTHON: "C:\\Python36-x64"
2519 PYTHON_VERSION: "3.6"
2620 PYTHON_ARCH: "64"
2721 VS_VERSION: Visual Studio 14
2822 APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
29 PROJSOURCE: 6.3.1
23 PROJSOURCE: 7.0.0
3024 # - PYTHON: "C:\\Python37-x64"
3125 # PYTHON_VERSION: "3.7"
3226 # PYTHON_ARCH: "64"
5650
5751 build_script:
5852 # setup sqlite3
53 - vcpkg install sqlite3[core,tool]:"%platform%"-windows
54 - vcpkg install tiff:"%platform%"-windows
55 - vcpkg install curl:"%platform%"-windows
56 - dir C:\Tools\vcpkg\installed\%platform%-windows\bin
57 - set PATH=C:\Tools\vcpkg\installed\%platform%-windows\bin;%PATH%
58 # setup PROJ.4
5959 - set PROJ_DIR=%PROJ_BASE_DIR%\proj-%PROJSOURCE:~0,5%
60 - vcpkg install sqlite3:"%platform%"-windows
61 - set SQLITE3_BIN=%APPVEYOR_BUILD_FOLDER%\sqlite3\bin
62 - mkdir %SQLITE3_BIN%
63 - copy c:\tools\vcpkg\installed\"%platform%"-windows\bin\sqlite3.dll %SQLITE3_BIN%
64 - ps: |
65 appveyor DownloadFile https://sqlite.org/2018/sqlite-tools-win32-x86-3250100.zip
66 7z x sqlite-tools-win32-x86-3250100.zip
67 - copy "%APPVEYOR_BUILD_FOLDER%"\sqlite-tools-win32-x86-3250100\sqlite3.exe %SQLITE3_BIN%
68 - set PATH=%SQLITE3_BIN%;%PATH%
69 # setup PROJ.4
7060 - if "%PROJSOURCE%" == "git" git clone https://github.com/OSGeo/proj.4.git proj-git
7161 - if not "%PROJSOURCE%" == "git" if not exist %PROJ_DIR% set BUILD_PROJ_STABLE=1
7262 - if defined BUILD_PROJ_STABLE curl -o "proj-%PROJSOURCE:~0,5%.zip" "https://download.osgeo.org/proj/proj-%PROJSOURCE%.zip"
7363 - if defined BUILD_PROJ_STABLE 7z x -aoa -y "proj-%PROJSOURCE:~0,5%.zip"
7464 - if not exist %PROJ_DIR% cd "%APPVEYOR_BUILD_FOLDER%\proj-%PROJSOURCE:~0,5%"
7565 - if "%platform%" == "x64" SET VS_FULL=%VS_VERSION% Win64
76 - if "%platform%" == "x64" SET BUILD_LIBPROJ_SHARED=ON
66 - if "%platform%" == "x64" SET BUILD_SHARED_LIBS=ON
7767 - if "%platform%" == "x86" SET VS_FULL=%VS_VERSION%
78 - if "%platform%" == "x86" SET BUILD_LIBPROJ_SHARED=OFF
68 - if "%platform%" == "x86" SET BUILD_SHARED_LIBS=OFF
7969 - echo "%VS_FULL%"
8070 #
8171 - if "%PROJSOURCE%" == "git" set BUILD_PROJ=1
8272 - if defined BUILD_PROJ_STABLE set BUILD_PROJ=1
8373 - if defined BUILD_PROJ mkdir build
8474 - if defined BUILD_PROJ cd build
85 - if defined BUILD_PROJ cmake -G "%VS_FULL%" .. -DCMAKE_BUILD_TYPE=Release -DBUILD_LIBPROJ_SHARED="%BUILD_LIBPROJ_SHARED%" -DCMAKE_C_FLAGS="/WX" -DCMAKE_CXX_FLAGS="/WX" -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_INSTALL_PREFIX="%PROJ_DIR%"
75 - if defined BUILD_PROJ cmake -G "%VS_FULL%" .. -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS="%BUILD_SHARED_LIBS%" -DCMAKE_C_FLAGS="/WX" -DCMAKE_CXX_FLAGS="/WX" -DCMAKE_TOOLCHAIN_FILE=c:/tools/vcpkg/scripts/buildsystems/vcpkg.cmake -DCMAKE_INSTALL_PREFIX="%PROJ_DIR%"
8676 - if defined BUILD_PROJ cmake --build . --config Release --target install
8777 - set PATH=%PROJ_DIR%\bin;%PATH%
8878 - set PROJ_LIB=%PROJ_DIR%\share\proj
119109 # Upgrade to the latest version of pip to avoid it displaying warnings
120110 # about it being out of date.
121111 - "python -m pip install --disable-pip-version-check --user --upgrade pip==19.0.3"
122
112
123113 # install wheel, caching
124114 - "python -m pip install wheel"
125115 # update vcpkg
1919 # build using autotools
2020 sh autogen.sh
2121 ./configure --prefix=$PROJ_DIR
22 make
22 make
2323 make install
2424 # build using cmake
2525 #cmake . -DCMAKE_INSTALL_PREFIX=$PROJ_DIR
0 gAAAAABcv0vdkreKT0kDO9nMioPyB2R66eYGDtTK08mBxWq1dvzZ_aK2HEVvJ0e7nZtpTGdQuR6GTq5_6yA2iYScVK7Z4LoOqw3dDaQX6ssnYdcmTzdiAVRDE-kZ9WXUxf7izcBsafLmNgizctJ2MT23AQ30CEYb0J4C1Akq9PThRoIdJ3P4jhyztlTjPv4PxcCrA2Gl_x0pJsAS-vpC38A6n41ZxiKQrkBqoKwem11p7Ui4vjv6mcARSuRXHWpiQSHuJXpLfMZv0_GM7VYxdVo04WZA-dPv6RyER4rPlJwvpdWQ2GNN3ZyfYW4-EiSdNuoCe8idQM2cZr5ZoMLSAtZUFlfORVqWV7eyU1HYbaoicfqwMTgOijy06u7ifn60Yg-C-D2GwWNHYgDZm-JPYoaarn47bJqlrdhQaCSif1mrGThGcbtsIhnnH0yJXpj6fdhi4QhaksoLe2cOi9mBYB0WbM-JYDyfIdRDyfnos40iOk5PJe-dj51AdDcDOLk7gegCiTt_MDQKrLt1GnEfPlo5EBa7BqT7Ws38mAY2UG28BoMfHDhV2JYWspDGGZ7EDi8T-IQAwe2z3swCLh1EW7TT9CcTwxYMqX-y0Kj99bcZHoiFvG76u78fsNe1fIPLmGFJ7zyfR_sTBt08rDyWR1B_Ssspk66xedVttWt_cCn_FHJQIyD7dufz_X4dnxV9qPykVzJ9T6Z45eLSSC38M8QPa9oZIuoTWJnbNKWjIC8B_0MZk3QXjI3ZiMFvrWic5CZjHk84VKEwbkxvfZhZwXiY5bK4bLI2eCJatipAhjH3TKwAZIzYiIQv_yswaUQ7I77pMGaFwgLx7cLjIFnBpOYzow9VeT7bTZWIydNMtwU7QeYCsLtcJj99bmj45egzlLWWsZQjasZ6uZ9atRKeQPpoqnCnTMpdx_v7WHTO2PuBaH6_9vvIJdi1foVmeGMmnbq-hvvdoFdt7bevlSFN_f1Izcf1OGME_3tEHvHp2gssbtaQ2kZw5Bfj4eBCnqC-GBLztg_aykKAs_A3DF2gXo-4j2Yc30dzdtXS2yscopJudW7GywEJD2wpVEX-zN8DXL_lfW7nCRSaMWi42EdrSIFNwxvMWKZXGAIhld_29U3zq-faxA6qq5nDsj1roygVu-oXUP2Icqstje2OucMOfdkOEDdB-mvGCnNYIffthdlw6NbCes82Zsjqmk08Ms1Hrwxeh_vrO3Vrip3IEgeGIdtu8I-K-pGUDRVikLeaNyrx88jggsog-GF1N86OsjdYueV-eCsuq3rV_fuFDt76v_a0HV3FjFq6eZc3bB7pgBarFlRTQsRGHM5q_XaVY_Tp_iJBYlZbFjsMY5RSF_OGvdeVtkL4g7Rgyhj8WgVYfz4Ykrp_vZuAYWQE3LYpuqCq5tjFOm9nFcPxpwjEoV3rlMijiOwTdCg7Kg3QMRcDjnloIDzBa7mpvuuNgou4tCehzh83kFlw3oskHQgQkRXwKDreLoxDlgxxXu-zQGRz7zLOf0xJii6ZGSIdCBEJvCndF8AAHSA5ReTyFPlLwiQAEQ5zvUAuQ9rVrYaYG1SeFqhtxkuAUvhxRdIzg2ICKpASkI52EpvhXbeJe8JcMBOwKRXiB6XcdtOffX9eYVm1gp0wZ-1rmWa8Uqg3flTzls9ug2kgRzbJN5vsBoSLVJXwzBZjacZ9ZQ7ZciwUK0_Dg-D2emCymkVcFUrnB2OsnE4rNIkfhUpTG9vXp-n1tVnzm8UXoLLvfldDtjxdz9sQsj9hORkxkVcpDpeqE1I7UdmBHCCz_bZ7bj230KTfdEXQMWcQWfWFl4U8KiaSnJBBjwAjMIHbT7UxJzbsOpl7cN_WuObrvGLWUnByXILW7QDe8XQwfSYwX75l05g9a7PHNXhfX61DUFcw2asY1m9UP4WPljFfgcR46xcHfkwQjGE232wfQ5hPfiVoskTLmBP-EdAd-gc6aWVb6hIv55p0iNRlkNs4fMmQNejmQjwIGRvZgYq99MSdhocG5yueJaEAMAaXpAawXm54Sh1Aw9fYSyMYe0p6glKqil-_Eck3Lx1RFaXfvOK0ICgsnSaqN7n7QDJ5TjE8yVxJjBTCEMbKJU5m57DRjRezKK35LN-ZfpQH3eINTLbjYN3FII-aycNrjP5uev9fSceNrq9JWGoYIVDeBqJV3akai9a2tvGXJh7Dn3alvMOzPzqJKhC4mO5T0bCtAcN_8SAI87E77Ver9D6nyvk1Jvul18Ax50ta7paJ1jZWKL_gjFCfVm5m9FWlXx3ytDzEO8HSNd4uI_u6iKqZf9btBFJZu0P8vtvSVAGBj-D5Gty99gTy9V0qZSPmOmf2vqMeIpFHXTzJ8HKEDvGms0o4ymSY3YP3UPvQivqnP5ggIccZgvGlaRoWHUOMyFNRRCc8gr_s2-gO4mixXtonjnaw1l1HOXKrykVvnWCdEgkMFsYJRl-2ob4BeJDisus3g7gRKBgP9h1KSMtFokkeFkRmnDvdWximbs5kXibfz_4GbK7sGuWUF6kbvE4lEKYADPdRbtSCEZCTqcVgyUOclz-fbUgaeXwazC-xMclXhdFfJl4eSGhs7-60GVHErJZBMoVTr3-fdPsEpJrGa4etr2MRtW-XuOrSIMxgiyAoLm6ZFu5gqoQCKTil69-rpHHGIDmLZeJ4mNckoq7VGHAIWooj35jnnExBqwzh6mKack6THi2W3buzFlKbI7BRpXxbRktDgOLCx8hRJe2B1RrdUHuraa8kEqq-UHSiL59YvhnVwWUXwQs_ppX6L0_qAg3AvCACrLNJV3FlChJ7H0xGT7ZhYmJzrTfE7gJnVweLTQQCxFJEnIyB7jBCaWArttTGJZ4tiX_Z3Du4KertA2sodEz7TPnPAuQH6ZWgRXsA0XsOWGVmBlT00REN7hIKGY41o-2zaLOJ0ATAMVNGg6572sge5M8QXPO24_ekWX82NWwKMdm0MfCuKMlTRdclFFgQ5YCEDENJyv3RYQ2hItX8hrBFJ-r8rcd-AUjHJnFNnHhQ9P6f6J7JzMl4vWTYD6lwWIV2SmlVZZlHtVIcMYKaCJTHorWs7RHhxa4sJBP8Z2h_U69Xs1KDBUJrRaA9--TT3MHNwFZVPAfsD0ARjyjoBc53mMMNOhyF9Zkwla90cezdKMPnKh0eE68-0AejMhpFFTdOnOLKSvmBHGDKo9I9tiDBgDKp_vamJIoxeBk1Tn1s6GVC0HSKJOGqBBfKqNtliIrJ0F4i_AAzYeIdJnDwpWIzanWZwm216N6gqHMZdIjl32rwfi5MiT9hcgySIwEe76R1WcVdhnMxtCtivbEWh-d7IzpoD8jEN6ljUG7D41mwPrfyQ0NpwzUubNPiFWApdAwsuiof7E70u4N-7eS1rIlUtlt5x_hGr6OB9eDES9THlK2zJqEojbv7Sx5SO9E3N1LT3-FCiLcZoHObW5hFe_MD4YRLO47nAoTcnmWPb6E2TK40glcepdZfcfam6sox3CX9e25QTs2yYm5pnDLvW6cqQOTkAJ5d2kcUXiUGTKAg4dCJDyjakquCwh5UZtfpKq9zusOrxGzq5Hv4p7oWfOCTjupxA2LHozt22Lv10uOTBiVdyJ0_Ik0T3tbDYegcHZlt5inXvtIc6drsNLQDCjCzSEWbdiyzq3VHHEeGgN9IP9NXOfwssWWxeJtD39IUL6SQ6C1LpVWXJ_oBQLnc131d0fBgT86iWHntC5w-zAbGvcxB2kz9CxzejBffCurVTXVh0dCm33CFd3DhGptn2oSI_r63YD8VFWtM0Q9NEWI61r9fuo6zIY6E1AQgNqsPQSkFExrcq6WqNqfbbq7BFR63MPiGhE2lBvIb6jIgn1B9R1hOB99lxaz6d-5FxqFfzUCyPILgX3kF3u509l4yd7ZXmjKJDo_YMEca5J21OAtmsqLVRQ4dYKsEMH7_SrvQLF2UY9fmkPD8OfW0tcDZHLMYZ-ZusqCPmpzwsTBQWxNkACwhuLBP_oeQbzuXIvhNl1mxQzz9NTImuRwfgr5S_E-zHiizdTqVzSTrVb1q2tsacOZn4Y9nPMVG4qejrcEq1qSZHpg1hYr_4D8g-0OOO3OrChRdWPS3T2IqTcqf74IBq-QZ_5nF_2csXUlOSv436G_LbS35jUz231rML25chdNGqVA16MM_huOWL6ertJoxMEiFt5mMSu7mi5ZfvRZVar5uf_yY4rU0_uafMPve45qIZJmGeHhqAdw1Moet0TFk3OuJKsQki37BGFjbYlFNpTp_3uKUuUmzdsbRnQGgMgQ9GwA1ICejVuYxCDOxGFr8LkXrZgiy8EaCLoxhvMWshHtzBmGua2c0fx-qfC3lY9be25ouFYv6gH_sIJQZRGpMR-t5AZ0GC2QdSCuEIfWCKX6pZQUZkYr5sfZQnYKwnVMufZGHHc_70Pcb90J3kVI-pNIlWqmRSw==
0 gAAAAABcv0vdkreKT0kDO9nMioPyB2R66eYGDtTK08mBxWq1dvzZ_aK2HEVvJ0e7nZtpTGdQuR6GTq5_6yA2iYScVK7Z4LoOqw3dDaQX6ssnYdcmTzdiAVRDE-kZ9WXUxf7izcBsafLmNgizctJ2MT23AQ30CEYb0J4C1Akq9PThRoIdJ3P4jhyztlTjPv4PxcCrA2Gl_x0pJsAS-vpC38A6n41ZxiKQrkBqoKwem11p7Ui4vjv6mcARSuRXHWpiQSHuJXpLfMZv0_GM7VYxdVo04WZA-dPv6RyER4rPlJwvpdWQ2GNN3ZyfYW4-EiSdNuoCe8idQM2cZr5ZoMLSAtZUFlfORVqWV7eyU1HYbaoicfqwMTgOijy06u7ifn60Yg-C-D2GwWNHYgDZm-JPYoaarn47bJqlrdhQaCSif1mrGThGcbtsIhnnH0yJXpj6fdhi4QhaksoLe2cOi9mBYB0WbM-JYDyfIdRDyfnos40iOk5PJe-dj51AdDcDOLk7gegCiTt_MDQKrLt1GnEfPlo5EBa7BqT7Ws38mAY2UG28BoMfHDhV2JYWspDGGZ7EDi8T-IQAwe2z3swCLh1EW7TT9CcTwxYMqX-y0Kj99bcZHoiFvG76u78fsNe1fIPLmGFJ7zyfR_sTBt08rDyWR1B_Ssspk66xedVttWt_cCn_FHJQIyD7dufz_X4dnxV9qPykVzJ9T6Z45eLSSC38M8QPa9oZIuoTWJnbNKWjIC8B_0MZk3QXjI3ZiMFvrWic5CZjHk84VKEwbkxvfZhZwXiY5bK4bLI2eCJatipAhjH3TKwAZIzYiIQv_yswaUQ7I77pMGaFwgLx7cLjIFnBpOYzow9VeT7bTZWIydNMtwU7QeYCsLtcJj99bmj45egzlLWWsZQjasZ6uZ9atRKeQPpoqnCnTMpdx_v7WHTO2PuBaH6_9vvIJdi1foVmeGMmnbq-hvvdoFdt7bevlSFN_f1Izcf1OGME_3tEHvHp2gssbtaQ2kZw5Bfj4eBCnqC-GBLztg_aykKAs_A3DF2gXo-4j2Yc30dzdtXS2yscopJudW7GywEJD2wpVEX-zN8DXL_lfW7nCRSaMWi42EdrSIFNwxvMWKZXGAIhld_29U3zq-faxA6qq5nDsj1roygVu-oXUP2Icqstje2OucMOfdkOEDdB-mvGCnNYIffthdlw6NbCes82Zsjqmk08Ms1Hrwxeh_vrO3Vrip3IEgeGIdtu8I-K-pGUDRVikLeaNyrx88jggsog-GF1N86OsjdYueV-eCsuq3rV_fuFDt76v_a0HV3FjFq6eZc3bB7pgBarFlRTQsRGHM5q_XaVY_Tp_iJBYlZbFjsMY5RSF_OGvdeVtkL4g7Rgyhj8WgVYfz4Ykrp_vZuAYWQE3LYpuqCq5tjFOm9nFcPxpwjEoV3rlMijiOwTdCg7Kg3QMRcDjnloIDzBa7mpvuuNgou4tCehzh83kFlw3oskHQgQkRXwKDreLoxDlgxxXu-zQGRz7zLOf0xJii6ZGSIdCBEJvCndF8AAHSA5ReTyFPlLwiQAEQ5zvUAuQ9rVrYaYG1SeFqhtxkuAUvhxRdIzg2ICKpASkI52EpvhXbeJe8JcMBOwKRXiB6XcdtOffX9eYVm1gp0wZ-1rmWa8Uqg3flTzls9ug2kgRzbJN5vsBoSLVJXwzBZjacZ9ZQ7ZciwUK0_Dg-D2emCymkVcFUrnB2OsnE4rNIkfhUpTG9vXp-n1tVnzm8UXoLLvfldDtjxdz9sQsj9hORkxkVcpDpeqE1I7UdmBHCCz_bZ7bj230KTfdEXQMWcQWfWFl4U8KiaSnJBBjwAjMIHbT7UxJzbsOpl7cN_WuObrvGLWUnByXILW7QDe8XQwfSYwX75l05g9a7PHNXhfX61DUFcw2asY1m9UP4WPljFfgcR46xcHfkwQjGE232wfQ5hPfiVoskTLmBP-EdAd-gc6aWVb6hIv55p0iNRlkNs4fMmQNejmQjwIGRvZgYq99MSdhocG5yueJaEAMAaXpAawXm54Sh1Aw9fYSyMYe0p6glKqil-_Eck3Lx1RFaXfvOK0ICgsnSaqN7n7QDJ5TjE8yVxJjBTCEMbKJU5m57DRjRezKK35LN-ZfpQH3eINTLbjYN3FII-aycNrjP5uev9fSceNrq9JWGoYIVDeBqJV3akai9a2tvGXJh7Dn3alvMOzPzqJKhC4mO5T0bCtAcN_8SAI87E77Ver9D6nyvk1Jvul18Ax50ta7paJ1jZWKL_gjFCfVm5m9FWlXx3ytDzEO8HSNd4uI_u6iKqZf9btBFJZu0P8vtvSVAGBj-D5Gty99gTy9V0qZSPmOmf2vqMeIpFHXTzJ8HKEDvGms0o4ymSY3YP3UPvQivqnP5ggIccZgvGlaRoWHUOMyFNRRCc8gr_s2-gO4mixXtonjnaw1l1HOXKrykVvnWCdEgkMFsYJRl-2ob4BeJDisus3g7gRKBgP9h1KSMtFokkeFkRmnDvdWximbs5kXibfz_4GbK7sGuWUF6kbvE4lEKYADPdRbtSCEZCTqcVgyUOclz-fbUgaeXwazC-xMclXhdFfJl4eSGhs7-60GVHErJZBMoVTr3-fdPsEpJrGa4etr2MRtW-XuOrSIMxgiyAoLm6ZFu5gqoQCKTil69-rpHHGIDmLZeJ4mNckoq7VGHAIWooj35jnnExBqwzh6mKack6THi2W3buzFlKbI7BRpXxbRktDgOLCx8hRJe2B1RrdUHuraa8kEqq-UHSiL59YvhnVwWUXwQs_ppX6L0_qAg3AvCACrLNJV3FlChJ7H0xGT7ZhYmJzrTfE7gJnVweLTQQCxFJEnIyB7jBCaWArttTGJZ4tiX_Z3Du4KertA2sodEz7TPnPAuQH6ZWgRXsA0XsOWGVmBlT00REN7hIKGY41o-2zaLOJ0ATAMVNGg6572sge5M8QXPO24_ekWX82NWwKMdm0MfCuKMlTRdclFFgQ5YCEDENJyv3RYQ2hItX8hrBFJ-r8rcd-AUjHJnFNnHhQ9P6f6J7JzMl4vWTYD6lwWIV2SmlVZZlHtVIcMYKaCJTHorWs7RHhxa4sJBP8Z2h_U69Xs1KDBUJrRaA9--TT3MHNwFZVPAfsD0ARjyjoBc53mMMNOhyF9Zkwla90cezdKMPnKh0eE68-0AejMhpFFTdOnOLKSvmBHGDKo9I9tiDBgDKp_vamJIoxeBk1Tn1s6GVC0HSKJOGqBBfKqNtliIrJ0F4i_AAzYeIdJnDwpWIzanWZwm216N6gqHMZdIjl32rwfi5MiT9hcgySIwEe76R1WcVdhnMxtCtivbEWh-d7IzpoD8jEN6ljUG7D41mwPrfyQ0NpwzUubNPiFWApdAwsuiof7E70u4N-7eS1rIlUtlt5x_hGr6OB9eDES9THlK2zJqEojbv7Sx5SO9E3N1LT3-FCiLcZoHObW5hFe_MD4YRLO47nAoTcnmWPb6E2TK40glcepdZfcfam6sox3CX9e25QTs2yYm5pnDLvW6cqQOTkAJ5d2kcUXiUGTKAg4dCJDyjakquCwh5UZtfpKq9zusOrxGzq5Hv4p7oWfOCTjupxA2LHozt22Lv10uOTBiVdyJ0_Ik0T3tbDYegcHZlt5inXvtIc6drsNLQDCjCzSEWbdiyzq3VHHEeGgN9IP9NXOfwssWWxeJtD39IUL6SQ6C1LpVWXJ_oBQLnc131d0fBgT86iWHntC5w-zAbGvcxB2kz9CxzejBffCurVTXVh0dCm33CFd3DhGptn2oSI_r63YD8VFWtM0Q9NEWI61r9fuo6zIY6E1AQgNqsPQSkFExrcq6WqNqfbbq7BFR63MPiGhE2lBvIb6jIgn1B9R1hOB99lxaz6d-5FxqFfzUCyPILgX3kF3u509l4yd7ZXmjKJDo_YMEca5J21OAtmsqLVRQ4dYKsEMH7_SrvQLF2UY9fmkPD8OfW0tcDZHLMYZ-ZusqCPmpzwsTBQWxNkACwhuLBP_oeQbzuXIvhNl1mxQzz9NTImuRwfgr5S_E-zHiizdTqVzSTrVb1q2tsacOZn4Y9nPMVG4qejrcEq1qSZHpg1hYr_4D8g-0OOO3OrChRdWPS3T2IqTcqf74IBq-QZ_5nF_2csXUlOSv436G_LbS35jUz231rML25chdNGqVA16MM_huOWL6ertJoxMEiFt5mMSu7mi5ZfvRZVar5uf_yY4rU0_uafMPve45qIZJmGeHhqAdw1Moet0TFk3OuJKsQki37BGFjbYlFNpTp_3uKUuUmzdsbRnQGgMgQ9GwA1ICejVuYxCDOxGFr8LkXrZgiy8EaCLoxhvMWshHtzBmGua2c0fx-qfC3lY9be25ouFYv6gH_sIJQZRGpMR-t5AZ0GC2QdSCuEIfWCKX6pZQUZkYr5sfZQnYKwnVMufZGHHc_70Pcb90J3kVI-pNIlWqmRSw==
4646 LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
4747 NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
4848 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """
49 __version__ = "2.5.0"
49 __version__ = "2.6.0rc0"
5050 __all__ = [
5151 "Proj",
5252 "Geod",
3232 cdef readonly object name
3333 cdef readonly object _remarks
3434 cdef readonly object _scope
35
35 cdef _set_base_info(self)
3636
3737 cdef class _CRSParts(Base):
3838 pass
0 from typing import Any, Iterable, List, Optional, Tuple, Union
1
2 from pyproj.crs.enums import CoordinateOperationType
3 from pyproj.enums import ProjVersion, WktVersion
4
5 class Axis:
6 name: str
7 abbrev: str
8 direction: str
9 unit_conversion_factor: float
10 unit_name: str
11 unit_auth_code: str
12 unit_code: str
13 def __str__(self) -> str: ...
14 def __repr__(self) -> str: ...
15
16 class AreaOfUse:
17 west: float
18 south: float
19 east: float
20 north: float
21 name: str
22 def __str__(self) -> str: ...
23 def __repr__(self) -> str: ...
24 @property
25 def bounds(self) -> tuple[float]: ...
26
27 class Base:
28 name: str
29 @property
30 def remarks(self) -> str: ...
31 @property
32 def scope(self) -> str: ...
33 def to_wkt(
34 self,
35 version: Union[WktVersion, str] = WktVersion.WKT2_2019,
36 pretty: bool = False,
37 ) -> str: ...
38 def to_json(self, pretty: bool = False, indentation: int = 2) -> str: ...
39 def to_json_dict(self) -> dict: ...
40 def __str__(self) -> str: ...
41 def __repr__(self) -> str: ...
42 def __eq__(self, other: Any) -> bool: ...
43 def is_exact_same(self, other: Any) -> bool: ...
44
45 class _CRSParts(Base):
46 @classmethod
47 def from_user_input(cls, user_input: Any) -> "_CRSParts": ...
48
49 class Ellipsoid(_CRSParts):
50 semi_major_metre: float
51 semi_minor_metre: float
52 is_semi_minor_computed: float
53 inverse_flattening: float
54 @staticmethod
55 def from_authority(auth_name: str, code: Union[int, str]) -> "Ellipsoid": ...
56 @staticmethod
57 def from_epsg(code: Union[int, str]) -> "Ellipsoid": ...
58 @staticmethod
59 def from_string(ellipsoid_string: str) -> "Ellipsoid": ...
60 @staticmethod
61 def from_json_dict(ellipsoid_dict: dict) -> "Ellipsoid": ...
62 @staticmethod
63 def from_json(ellipsoid_json_str: str) -> "Ellipsoid": ...
64 @staticmethod
65 def from_name(
66 ellipsoid_name: str, auth_name: Optional[str] = None
67 ) -> "Ellipsoid": ...
68
69 class PrimeMeridian(_CRSParts):
70 longitude: float
71 unit_conversion_factor: str
72 unit_name: str
73 @staticmethod
74 def from_authority(auth_name: str, code: Union[int, str]) -> "PrimeMeridian": ...
75 @staticmethod
76 def from_epsg(code: Union[int, str]) -> "PrimeMeridian": ...
77 @staticmethod
78 def from_string(prime_meridian_string: str) -> "PrimeMeridian": ...
79 @staticmethod
80 def from_json_dict(prime_meridian_dict: dict) -> "PrimeMeridian": ...
81 @staticmethod
82 def from_json(prime_meridian_json_str: str) -> "PrimeMeridian": ...
83 @staticmethod
84 def from_name(
85 prime_meridian_name: str, auth_name: Optional[str] = None
86 ) -> "PrimeMeridian": ...
87
88 class Datum(_CRSParts):
89 type_name: str
90 @property
91 def ellipsoid(self) -> Optional[Ellipsoid]: ...
92 @property
93 def prime_meridian(self) -> Optional[PrimeMeridian]: ...
94 @staticmethod
95 def from_authority(auth_name: str, code: Union[int, str]) -> "Datum": ...
96 @staticmethod
97 def from_epsg(code: Union[int, str]) -> "Datum": ...
98 @staticmethod
99 def from_string(datum_string: str) -> "Datum": ...
100 @staticmethod
101 def from_json_dict(datum_dict: dict) -> "Datum": ...
102 @staticmethod
103 def from_json(datum_json_str: str) -> "Datum": ...
104 @staticmethod
105 def from_name(datum_name: str, auth_name: Optional[str] = None) -> "Datum": ...
106
107 class CoordinateSystem(_CRSParts):
108 def __init__(self) -> None: ...
109 @property
110 def axis_list(self) -> Iterable[Axis]: ...
111 @staticmethod
112 def from_string(coordinate_system_string: str) -> "CoordinateSystem": ...
113 @staticmethod
114 def from_json_dict(coordinate_system_dict: dict) -> "CoordinateSystem": ...
115 @staticmethod
116 def from_json(coordinate_system_json_str: str) -> "CoordinateSystem": ...
117
118 class Param:
119 name: str
120 auth_name: str
121 code: str
122 value: str
123 unit_conversion_factor: float
124 unit_name: str
125 unit_auth_name: str
126 unit_code: str
127 unit_category: str
128 def __str__(self) -> str: ...
129 def __repr__(self) -> str: ...
130
131 class Grid:
132 short_name: str
133 full_name: str
134 package_name: str
135 url: str
136 direct_download: str
137 open_license: str
138 available: str
139 def __str__(self) -> str: ...
140 def __repr__(self) -> str: ...
141
142 class CoordinateOperation(_CRSParts):
143 method_name: str
144 method_auth_name: str
145 method_code: str
146 accuracy: float
147 is_instantiable: bool
148 has_ballpark_transformation: bool
149 type_name: str
150 @property
151 def params(self) -> Iterable[Param]: ...
152 @property
153 def grids(self) -> Iterable[Grid]: ...
154 @property
155 def area_of_use(self) -> Optional[AreaOfUse]: ...
156 @property
157 def towgs84(self) -> Iterable[float]: ...
158 @property
159 def operations(self) -> Tuple["CoordinateOperation"]: ...
160 def __init__(self) -> None: ...
161 def __repr__(self) -> str: ...
162 @staticmethod
163 def from_authority(
164 auth_name: str, code: Union[int, str]
165 ) -> "CoordinateOperation": ...
166 @staticmethod
167 def from_epsg(code: Union[int, str]) -> "CoordinateOperation": ...
168 @staticmethod
169 def from_string(ellipsoid_string: str) -> "CoordinateOperation": ...
170 @staticmethod
171 def from_json_dict(ellipsoid_dict: dict) -> "CoordinateOperation": ...
172 @staticmethod
173 def from_json(ellipsoid_json_str: str) -> "CoordinateOperation": ...
174 def to_proj4(
175 self, version: Union[ProjVersion, int] = ProjVersion.PROJ_5
176 ) -> str: ...
177 @staticmethod
178 def from_name(
179 coordinate_operation_name: str,
180 auth_name: Optional[str] = None,
181 coordinate_operation_type: Union[
182 CoordinateOperationType, str
183 ] = CoordinateOperationType.CONVERSION,
184 ) -> "CoordinateOperation": ...
185
186 class _CRS(Base):
187 srs: str
188 type_name: str
189 def __init__(self, proj_string: str) -> None: ...
190 @property
191 def ellipsoid(self) -> Optional[Ellipsoid]: ...
192 @property
193 def area_of_use(self) -> Optional[AreaOfUse]: ...
194 @property
195 def axis_info(self) -> List[Axis]: ...
196 @property
197 def prime_meridian(self) -> Optional[PrimeMeridian]: ...
198 @property
199 def datum(self) -> Optional[Datum]: ...
200 @property
201 def sub_crs_list(self) -> Iterable["_CRS"]: ...
202 @property
203 def source_crs(self) -> Optional["_CRS"]: ...
204 @property
205 def target_crs(self) -> Optional["_CRS"]: ...
206 @property
207 def geodetic_crs(self) -> Optional["_CRS"]: ...
208 @property
209 def coordinate_system(self) -> Optional[CoordinateSystem]: ...
210 @property
211 def coordinate_operation(self) -> Optional[CoordinateOperation]: ...
212 def to_proj4(
213 self, version: Union[ProjVersion, int] = ProjVersion.PROJ_5
214 ) -> str: ...
215 def to_epsg(self, min_confidence: int = 70) -> Optional[int]: ...
216 def to_authority(
217 self, auth_name: Optional[str] = None, min_confidence: int = 70
218 ): ...
219 @property
220 def is_geographic(self) -> bool: ...
221 @property
222 def is_projected(self) -> bool: ...
223 @property
224 def is_vertical(self) -> bool: ...
225 @property
226 def is_bound(self) -> bool: ...
227 @property
228 def is_engineering(self) -> bool: ...
229 @property
230 def is_geocentric(self) -> bool: ...
231 def equals(self, other: Any, ignore_axis_order: bool) -> bool: ...
232
233 def is_proj(proj_string: str) -> bool: ...
234 def is_wkt(proj_string: str) -> bool: ...
235 def _load_proj_json(in_proj_json: str) -> dict: ...
101101 }
102102 cdef PJ_WKT_TYPE wkt_out_type
103103 wkt_out_type = supported_wkt_types[WktVersion.create(version)]
104
104
105105 cdef const char* options_wkt[2]
106106 multiline = b"MULTILINE=NO"
107107 if pretty:
128128 context: PJ_CONTEXT*
129129 projobj: PJ*
130130 version: pyproj.enums.ProjVersion
131 The version of the PROJ string output.
131 The version of the PROJ string output.
132132
133133 Returns
134134 -------
388388 if self.context != NULL:
389389 proj_context_destroy(self.context)
390390
391 def _set_base_info(self):
391 cdef _set_base_info(self):
392392 """
393393 Set the name of the PJ
394394 """
409409 """
410410 .. versionadded:: 2.4.0
411411
412 str: Remarks about object.
412 Returns
413 -------
414 str:
415 Remarks about object.
413416 """
414417 return self._remarks
415418
418421 """
419422 .. versionadded:: 2.4.0
420423
421 str: Scope of object.
424 Returns
425 -------
426 str:
427 Scope of object.
422428 """
423429 return self._scope
424430
442448 Default is :attr:`pyproj.enums.WktVersion.WKT2_2019`.
443449 pretty: bool
444450 If True, it will set the output to be a multiline string. Defaults to False.
445
446 Returns
447 -------
448 str: The WKT string.
451
452 Returns
453 -------
454 str
449455 """
450456 return _to_wkt(self.context, self.projobj, version, pretty=pretty)
451457
461467 If True, it will set the output to be a multiline string. Defaults to False.
462468 indentation: int
463469 If pretty is True, it will set the width of the indentation. Default is 2.
464
465 Returns
466 -------
467 str: The JSON string.
470
471 Returns
472 -------
473 str
468474 """
469475 cdef const char* options[3]
470476 multiline = b"MULTILINE=NO"
493499
494500 Returns
495501 -------
496 dict: The JSON dictionary.
502 dict
497503 """
498504 return json.loads(self.to_json())
499505
618624 """
619625 Returns
620626 -------
621 list[Axis]: The Axis list for the coordinate system.
627 list[Axis]:
628 The Axis list for the coordinate system.
622629 """
623630 if self._axis_list is not None:
624631 return self._axis_list
682689 .. versionadded:: 2.5.0
683690
684691 Create Coordinate System from a JSON dictionary.
685
692
686693 Parameters
687694 ----------
688695 coordinate_system_dict: str
893900 .. versionadded:: 2.4.0
894901
895902 Create Ellipsoid from a JSON dictionary.
896
903
897904 Parameters
898905 ----------
899906 ellipsoid_dict: str
15931600 """
15941601 Returns
15951602 -------
1596 Ellipsoid: The ellipsoid object with associated attributes.
1603 Ellipsoid:
1604 The ellipsoid object with associated attributes.
15971605 """
15981606 if self._ellipsoid is not None:
15991607 return None if self._ellipsoid is False else self._ellipsoid
16161624 """
16171625 Returns
16181626 -------
1619 PrimeMeridian: The CRS prime meridian object with associated attributes.
1627 PrimeMeridian:
1628 The CRS prime meridian object with associated attributes.
16201629 """
16211630 if self._prime_meridian is not None:
16221631 return None if self._prime_meridian is False else self._prime_meridian
16631672 unit_code: str
16641673 The code of the unit (i.e. 9807).
16651674 unit_category: str
1666 The category of the unit (“unknown”, “none”, “linear”,
1675 The category of the unit (“unknown”, “none”, “linear”,
16671676 “angular”, “scale”, “time” or “parametric”).
16681677
16691678 """
17571766 open_license: int
17581767 If 1, the grid is released with an open license.
17591768 available: int
1760 If 1, the grid is available at runtime.
1769 If 1, the grid is available at runtime.
17611770
17621771 """
17631772 def __cinit__(self):
18511860 The method code.
18521861 is_instantiable: int
18531862 If 1, a coordinate operation can be instantiated as a PROJ pipeline.
1854 This also checks that referenced grids are available.
1863 This also checks that referenced grids are available.
18551864 has_ballpark_transformation: int
1856 If 1, the coordinate operation has a “ballpark” transformation,
1857 that is a very approximate one, due to lack of more accurate transformations.
1865 If 1, the coordinate operation has a “ballpark” transformation,
1866 that is a very approximate one, due to lack of more accurate transformations.
18581867 accuracy: float
1859 The accuracy (in metre) of a coordinate operation.
1868 The accuracy (in metre) of a coordinate operation.
18601869
18611870 """
18621871 def __cinit__(self):
21362145 """
21372146 Returns
21382147 -------
2139 list[Param]: The coordinate operation parameters.
2148 List[Param]:
2149 The coordinate operation parameters.
21402150 """
21412151 if self._params is not None:
21422152 return self._params
21622172 """
21632173 Returns
21642174 -------
2165 list[Grid]: The coordinate operation grids.
2175 List[Grid]:
2176 The coordinate operation grids.
21662177 """
21672178 if self._grids is not None:
21682179 return self._grids
21882199 """
21892200 Returns
21902201 -------
2191 AreaOfUse: The area of use object with associated attributes.
2202 AreaOfUse:
2203 The area of use object with associated attributes.
21922204 """
21932205 if self._area_of_use is not None:
21942206 return self._area_of_use
22022214 Parameters
22032215 ----------
22042216 version: pyproj.enums.ProjVersion
2205 The version of the PROJ string output.
2217 The version of the PROJ string output.
22062218 Default is :attr:`pyproj.enums.ProjVersion.PROJ_5`.
22072219
22082220 Returns
22092221 -------
2210 str: The PROJ string.
2222 str:
2223 The PROJ string.
2224
22112225 """
22122226 return _to_proj4(self.context, self.projobj, version)
22132227
22162230 """
22172231 Returns
22182232 -------
2219 list(float): A list of 3 or 7 towgs84 values if they exist.
2220 Otherwise an empty list.
2233 List[float]:
2234 A list of 3 or 7 towgs84 values if they exist.
2235
22212236 """
22222237 if self._towgs84 is not None:
22232238 return self._towgs84
22242239 towgs84_dict = OrderedDict(
22252240 (
2226 ('X-axis translation', None),
2241 ('X-axis translation', None),
22272242 ('Y-axis translation', None),
22282243 ('Z-axis translation', None),
22292244 ('X-axis rotation', None),
22432258 """
22442259 .. versionadded:: 2.4.0
22452260
2246 tuple[CoordinateOperation]: The operations in a concatenated operation.
2261 Returns
2262 -------
2263 Tuple[CoordinateOperation]:
2264 The operations in a concatenated operation.
2265
22472266 """
22482267 if self._operations is not None:
22492268 return self._operations
22532272 def __repr__(self):
22542273 return (
22552274 "<Coordinate Operation: {type_name}>\n"
2256 "{name}\n"
2275 "Name: {name}\n"
2276 "Method: {method_name}\n"
22572277 "Area of Use:\n{area_of_use}"
22582278 ).format(
22592279 type_name=self.type_name,
22602280 name=self.name,
2281 method_name=self.method_name,
22612282 area_of_use=self.area_of_use or "- undefined",
22622283 )
22632284
23242345 @property
23252346 def axis_info(self):
23262347 """
2327 Returns
2328 -------
2329 list[Axis]: The list of axis information.
2330 """
2331 return self.coordinate_system.axis_list if self.coordinate_system else []
2348 Retrieves all relevant axis information in the CRS.
2349 If it is a Bound CRS, it gets the axis list from the Source CRS.
2350 If it is a Compound CRS, it gets the axis list from the Sub CRS list.
2351
2352 Returns
2353 -------
2354 List[Axis]:
2355 The list of axis information.
2356 """
2357 axis_info_list = []
2358 if self.coordinate_system:
2359 axis_info_list.extend(self.coordinate_system.axis_list)
2360 elif self.is_bound and self.source_crs:
2361 axis_info_list.extend(self.source_crs.axis_info)
2362 else:
2363 for sub_crs in self.sub_crs_list:
2364 axis_info_list.extend(sub_crs.axis_info)
2365 return axis_info_list
23322366
23332367 @property
23342368 def area_of_use(self):
23352369 """
23362370 Returns
23372371 -------
2338 AreaOfUse: The area of use object with associated attributes.
2372 AreaOfUse:
2373 The area of use object with associated attributes.
23392374 """
23402375 if self._area_of_use is not None:
23412376 return self._area_of_use
23492384
23502385 Returns
23512386 -------
2352 Ellipsoid: The ellipsoid object with associated attributes.
2387 Ellipsoid:
2388 The ellipsoid object with associated attributes.
23532389 """
23542390 if self._ellipsoid is not None:
23552391 return None if self._ellipsoid is False else self._ellipsoid
23742410
23752411 Returns
23762412 -------
2377 PrimeMeridian: The prime meridian object with associated attributes.
2413 PrimeMeridian:
2414 The prime meridian object with associated attributes.
23782415 """
23792416 if self._prime_meridian is not None:
23802417 return None if self._prime_meridian is True else self._prime_meridian
23992436
24002437 Returns
24012438 -------
2402 Datum: The datum.
2439 Datum
24032440 """
24042441 if self._datum is not None:
24052442 return None if self._datum is False else self._datum
24292466
24302467 Returns
24312468 -------
2432 CoordinateSystem: The coordinate system.
2469 CoordinateSystem
24332470 """
24342471 if self._coordinate_system is not None:
24352472 return None if self._coordinate_system is False else self._coordinate_system
24582495
24592496 Returns
24602497 -------
2461 CoordinateOperation: The coordinate operation.
2498 CoordinateOperation
24622499 """
24632500 if self._coordinate_operation is not None:
24642501 return (
24652502 None
2466 if self._coordinate_operation is False
2503 if self._coordinate_operation is False
24672504 else self._coordinate_operation
24682505 )
24692506 cdef PJ_CONTEXT* context = proj_context_create()
24862523 @property
24872524 def source_crs(self):
24882525 """
2489 Returns
2490 -------
2491 _CRS: The the base CRS of a BoundCRS or a DerivedCRS/ProjectedCRS,
2492 or the source CRS of a CoordinateOperation.
2526 The the base CRS of a BoundCRS or a DerivedCRS/ProjectedCRS,
2527 or the source CRS of a CoordinateOperation.
2528
2529 Returns
2530 -------
2531 _CRS
24932532 """
24942533 if self._source_crs is not None:
24952534 return None if self._source_crs is False else self._source_crs
25112550
25122551 Returns
25132552 -------
2514 _CRS: The hub CRS of a BoundCRS or the target CRS of a CoordinateOperation.
2553 _CRS:
2554 The hub CRS of a BoundCRS or the target CRS of a CoordinateOperation.
25152555 """
25162556 if self._target_crs is not None:
25172557 return None if self._target_crs is False else self._target_crs
25332573
25342574 Returns
25352575 -------
2536 list[_CRS]
2576 List[_CRS]
25372577 """
25382578 if self._sub_crs_list is not None:
25392579 return self._sub_crs_list
25632603 """
25642604 .. versionadded:: 2.2.0
25652605
2566 Returns
2567 -------
2568 _CRS: The the geodeticCRS / geographicCRS from the CRS.
2606 The the geodeticCRS / geographicCRS from the CRS.
2607
2608 Returns
2609 -------
2610 _CRS
25692611 """
25702612 if self._geodetic_crs is not None:
25712613 return self._geodetic_crs if self. _geodetic_crs is not False else None
25912633 Parameters
25922634 ----------
25932635 version: pyproj.enums.ProjVersion
2594 The version of the PROJ string output.
2636 The version of the PROJ string output.
25952637 Default is :attr:`pyproj.enums.ProjVersion.PROJ_4`.
25962638
25972639 Returns
25982640 -------
2599 str: The PROJ string.
2641 str
26002642 """
26012643 warnings.warn(
26022644 "You will likely lose important projection information when "
26052647 "coordinate-reference-systems"
26062648 )
26072649 return _to_proj4(self.context, self.projobj, version)
2608
2650
26092651 def to_epsg(self, min_confidence=70):
26102652 """
26112653 Return the EPSG code best matching the CRS
26122654 or None if it a match is not found.
26132655
2614 Example:
2656 Example:
26152657
26162658 >>> from pyproj import CRS
26172659 >>> ccs = CRS("epsg:4328")
26382680
26392681 Returns
26402682 -------
2641 int or None: The best matching EPSG code matching the confidence level.
2683 Optional[int]:
2684 The best matching EPSG code matching the confidence level.
26422685 """
26432686 auth_info = self.to_authority(
26442687 auth_name="EPSG",
26552698 Return the authority name and code best matching the CRS
26562699 or None if it a match is not found.
26572700
2658 Example:
2701 Example:
26592702
26602703 >>> from pyproj import CRS
26612704 >>> ccs = CRS("epsg:4328")
26832726
26842727 Returns
26852728 -------
2686 tuple(str, str) or None: The best matching (<auth_name>, <code>)
2687 matching the confidence level.
2729 tuple(str, str) or None:
2730 The best matching (<auth_name>, <code>) for the confidence level.
26882731 """
26892732 # get list of possible matching projections
26902733 cdef PJ_OBJ_LIST *proj_list = NULL
27672810
27682811 Returns
27692812 -------
2770 bool: True if the CRS has this property.
2813 bool:
2814 True if the CRS has this property.
27712815 """
27722816 if self.sub_crs_list:
27732817 sub_crs = self.sub_crs_list[sub_crs_index]
27862830 """
27872831 This checks if the CRS is geographic.
27882832 It will check if it has a geographic CRS
2789 in the sub CRS if it is a compount CRS and will check if
2833 in the sub CRS if it is a compount CRS and will check if
27902834 the source CRS is geographic if it is a bound CRS.
27912835
27922836 Returns
27932837 -------
2794 bool: True if the CRS is in geographic (lon/lat) coordinates.
2838 bool:
2839 True if the CRS is in geographic (lon/lat) coordinates.
27952840 """
27962841 return self._is_crs_property(
2797 "is_geographic",
2842 "is_geographic",
27982843 (
27992844 PJ_TYPE_GEOGRAPHIC_CRS,
28002845 PJ_TYPE_GEOGRAPHIC_2D_CRS,
28122857
28132858 Returns
28142859 -------
2815 bool: True if CRS is projected.
2860 bool:
2861 True if CRS is projected.
28162862 """
28172863 return self._is_crs_property(
2818 "is_projected",
2864 "is_projected",
28192865 (PJ_TYPE_PROJECTED_CRS,)
28202866 )
28212867
28262872
28272873 This checks if the CRS is vertical.
28282874 It will check if it has a vertical CRS
2829 in the sub CRS if it is a compount CRS and will check if
2875 in the sub CRS if it is a compount CRS and will check if
28302876 the source CRS is vertical if it is a bound CRS.
28312877
28322878 Returns
28332879 -------
2834 bool: True if CRS is vertical.
2880 bool:
2881 True if CRS is vertical.
28352882 """
28362883 return self._is_crs_property(
2837 "is_vertical",
2884 "is_vertical",
28382885 (PJ_TYPE_VERTICAL_CRS,),
28392886 sub_crs_index=1
28402887 )
28442891 """
28452892 Returns
28462893 -------
2847 bool: True if CRS is bound.
2894 bool:
2895 True if CRS is bound.
28482896 """
28492897 return self._type == PJ_TYPE_BOUND_CRS
28502898
28552903
28562904 Returns
28572905 -------
2858 bool: True if CRS is local/engineering.
2906 bool:
2907 True if CRS is local/engineering.
28592908 """
28602909 return self._type == PJ_TYPE_ENGINEERING_CRS
28612910
28672916
28682917 Returns
28692918 -------
2870 bool: True if CRS is in geocentric (x/y) coordinates.
2919 bool:
2920 True if CRS is in geocentric (x/y) coordinates.
28712921 """
28722922 if self.is_bound:
28732923 return self.source_crs.is_geocentric
22 cdef void pyproj_context_initialize(PJ_CONTEXT* context, bint free_context_on_error) except *
33
44 cdef class ContextManager:
5 cdef PJ_CONTEXT *context
5 cdef PJ_CONTEXT *context
0 def pyproj_global_context_initialize() -> None: ...
2727 cdef class Geod:
2828 cdef geod_geodesic _geod_geodesic
2929 cdef readonly object initstring
30 cdef readonly object a
31 cdef readonly object b
32 cdef readonly object f
33 cdef readonly object es
34 cdef readonly object sphere
30 cdef readonly double a
31 cdef readonly double b
32 cdef readonly double f
33 cdef readonly double es
34 cdef readonly bint sphere
0 from typing import Any, Tuple, Type
1
2 geodesic_version_str: str
3
4 class Geod:
5 initstring: str
6 a: float
7 b: float
8 f: float
9 es: float
10 sphere: bool
11 def __init__(
12 self, a: float, f: float, sphere: bool, b: float, es: float
13 ) -> None: ...
14 def __reduce__(self) -> Tuple[Type["Geod"], str]: ...
15 def __repr__(self) -> str: ...
16 def _fwd(
17 self, lons: Any, lats: Any, az: Any, dist: Any, radians: bool = False
18 ) -> None: ...
19 def _inv(
20 self, lons1: Any, lats1: Any, lons2: Any, lats2: Any, radians: bool = False
21 ) -> None: ...
22 def _npts(
23 self,
24 lon1: float,
25 lat1: float,
26 lon2: float,
27 lat2: float,
28 npts: int,
29 radians: bool = False,
30 ) -> Tuple[Tuple[float], Tuple[float]]: ...
31 def _line_length(self, lons: Any, lats: Any, radians: bool = False) -> float: ...
32 def _polygon_area_perimeter(
33 self, lons: Any, lats: Any, radians: bool = False
34 ) -> Tuple[float, float]: ...
1111 )
1212
1313 cdef class Geod:
14 def __init__(self, a, f, sphere, b, es):
14 def __init__(self, double a, double f, bint sphere, double b, double es):
1515 geod_init(&self._geod_geodesic, <double> a, <double> f)
1616 self.a = a
1717 self.f = f
18 if isinstance(a, float) and a.is_integer():
19 # convert 'a' only for initstring
20 a = int(a)
21 if f == 0.0:
22 f = 0
23 self.initstring = pystrdecode(cstrencode("+a=%s +f=%s" % (a, f)))
18 # convert 'a' only for initstring
19 a_str = int(a) if a.is_integer() else a
20 f_str = int(f) if f.is_integer() else f
21 self.initstring = pystrdecode(cstrencode("+a=%s +f=%s" % (a_str, f_str)))
2422 self.sphere = sphere
2523 self.b = b
2624 self.es = es
4240 cdef PyBuffWriteManager latbuff = PyBuffWriteManager(lats)
4341 cdef PyBuffWriteManager azbuff = PyBuffWriteManager(az)
4442 cdef PyBuffWriteManager distbuff = PyBuffWriteManager(dist)
45
43
4644 # process data in buffer
4745 if not lonbuff.len == latbuff.len == azbuff.len == distbuff.len:
4846 raise GeodError("Array lengths are not the same.")
188186
189187 Returns
190188 -------
191 float: The total distance.
192
189 float:
190 The total distance.
191
193192 """
194193 cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(lons)
195194 cdef PyBuffWriteManager latbuff = PyBuffWriteManager(lats)
231230 def _polygon_area_perimeter(self, object lons, object lats, bint radians=False):
232231 """
233232 A simple interface for computing the area of a geodesic polygon.
234
233
235234 lats should be in the range [-90 deg, 90 deg].
236
235
237236 Only simple polygons (which are not self-intersecting) are allowed.
238237 There's no need to "close" the polygon by repeating the first vertex.
239238 The area returned is signed with counter-clockwise traversal being treated as
250249
251250 Returns
252251 -------
253 (float, float): The area (meter^2) and permimeter (meters) of the polygon.
252 (float, float):
253 The area (meter^2) and permimeter (meters) of the polygon.
254254
255255 """
256256 cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(lons)
272272
273273 geod_polygonarea(
274274 &self._geod_geodesic,
275 latbuff.data, lonbuff.data, lonbuff.len,
275 latbuff.data, lonbuff.data, lonbuff.len,
276276 &polygon_area, &polygon_perimeter
277277 )
278278 return (polygon_area, polygon_perimeter)
0 from typing import Dict, List, NamedTuple, Union
1
2 from pyproj.enums import PJType
3
4 def get_proj_operations_map() -> Dict[str, str]: ...
5 def get_ellps_map() -> Dict[str, Dict[str, float]]: ...
6 def get_prime_meridians_map() -> Dict[str, str]: ...
7
8 class Unit(NamedTuple):
9 id: str
10 to_meter: str
11 name: str
12 factor: float
13
14 def get_units_map() -> Dict[str, Unit]: ...
15 def get_angular_units_map() -> Dict[str, Unit]: ...
16 def get_authorities() -> List[str]: ...
17 def get_codes(
18 auth_name: str, pj_type: Union[PJType, str], allow_deprecated: bool = False
19 ) -> List[str]: ...
1010 """
1111 Returns
1212 -------
13 dict: operations supported by PROJ.
13 dict:
14 Operations supported by PROJ.
1415 """
1516 cdef PJ_OPERATIONS *proj_operations = proj_list_operations()
1617 cdef int iii = 0
2627 """
2728 Returns
2829 -------
29 dict: ellipsoids supported by PROJ.
30 dict:
31 Ellipsoids supported by PROJ.
3032 """
3133 cdef PJ_ELLPS *proj_ellps = proj_list_ellps()
3234 cdef int iii = 0
4749 """
4850 Returns
4951 -------
50 dict: prime meridians supported by PROJ.
52 dict:
53 Prime Meridians supported by PROJ.
5154 """
5255 cdef PJ_PRIME_MERIDIANS *prime_meridians = proj_list_prime_meridians()
5356 cdef int iii = 0
6669 """
6770 Returns
6871 -------
69 dict: units supported by PROJ
72 dict:
73 Units supported by PROJ
7074 """
7175 cdef PJ_UNITS *proj_units = proj_list_units()
7276 cdef int iii = 0
8690 """
8791 Returns
8892 -------
89 dict: angular units supported by PROJ
93 dict:
94 Angular units supported by PROJ
9095 """
9196 cdef PJ_UNITS *proj_units = proj_list_angular_units()
9297 cdef int iii = 0
108113
109114 Returns
110115 -------
111 list[str]: Authorities in PROJ database.
116 List[str]:
117 Authorities in PROJ database.
112118 """
113119 cdef PJ_CONTEXT* context = proj_context_create()
114120 pyproj_context_initialize(context, True)
171177
172178 Returns
173179 -------
174 list[str]: Codes associated with authorities in PROJ database.
180 List[str]:
181 Codes associated with authorities in PROJ database.
175182 """
176183 cdef PJ_CONTEXT* context = NULL
177184 cdef PJ_TYPE cpj_type = PJ_TYPE_MAP[PJType.create(pj_type)]
00 include "proj.pxi"
11
2 cdef class Proj:
2 cdef class _Proj:
33 cdef PJ * projobj
44 cdef PJ_CONTEXT* context
55 cdef PJ_PROJ_INFO projobj_info
0 from typing import Any, NamedTuple
1
2 proj_version_str: str
3
4 class Factors(NamedTuple):
5 meridional_scale: float
6 parallel_scale: float
7 areal_scale: float
8 angular_distortion: float
9 meridian_parallel_angle: float
10 meridian_convergence: float
11 tissot_semimajor: float
12 tissot_semiminor: float
13 dx_dlam: float
14 dx_dphi: float
15 dy_dlam: float
16 dy_dphi: float
17
18 class _Proj:
19 srs: str
20 def __init__(self, proj_string: str) -> None: ...
21 @property
22 def definition(self) -> str: ...
23 @property
24 def has_inverse(self) -> bool: ...
25 def _fwd(self, lons: Any, lats: Any, errcheck: bool = False) -> None: ...
26 def _inv(self, x: Any, y: Any, errcheck: bool = False) -> None: ...
27 def _get_factors(
28 self, longitude: Any, latitude: Any, radians: bool, errcheck: bool
29 ) -> Factors: ...
30 def __repr__(self) -> str: ...
31 def _is_equivalent(self, other: "_Proj") -> bool: ...
32 def is_exact_same(self, other: Any) -> bool: ...
00 include "base.pxi"
11
2 import copy
23 import warnings
4 from collections import namedtuple
35
46 cimport cython
57
79 from pyproj.compat import cstrencode, pystrdecode
810 from pyproj.exceptions import ProjError
911
10 # # version number string for PROJ
12 # version number string for PROJ
1113 proj_version_str = "{0}.{1}.{2}".format(
1214 PROJ_VERSION_MAJOR,
1315 PROJ_VERSION_MINOR,
1416 PROJ_VERSION_PATCH
1517 )
1618
17 cdef class Proj:
19
20 Factors = namedtuple("Factors",
21 [
22 "meridional_scale",
23 "parallel_scale",
24 "areal_scale",
25 "angular_distortion",
26 "meridian_parallel_angle",
27 "meridian_convergence",
28 "tissot_semimajor",
29 "tissot_semiminor",
30 "dx_dlam",
31 "dx_dphi",
32 "dy_dlam",
33 "dy_dphi",
34 ]
35 )
36 Factors.__doc__ = """
37 .. versionadded:: 2.6.0
38
39 These are the scaling and angular distortion factors.
40
41 See `PJ_FACTORS documentation <https://proj.org/development/reference/datatypes.html?highlight=pj_factors#c.PJ_FACTORS>`__
42
43 Parameters
44 ----------
45 meridional_scale: List[float]
46 Meridional scale at coordinate.
47 parallel_scale: List[float]
48 Parallel scale at coordinate.
49 areal_scale: List[float]
50 Areal scale factor at coordinate.
51 angular_distortion: List[float]
52 Angular distortion at coordinate.
53 meridian_parallel_angle: List[float]
54 Meridian/parallel angle at coordinate.
55 meridian_convergence: List[float]
56 Meridian convergence at coordinate. Sometimes also described as *grid declination*.
57 tissot_semimajor: List[float]
58 Maximum scale factor.
59 tissot_semiminor: List[float]
60 Minimum scale factor.
61 dx_dlam: List[float]
62 Partial derivative of coordinate.
63 dx_dphi: List[float]
64 Partial derivative of coordinate.
65 dy_dlam: List[float]
66 Partial derivative of coordinate.
67 dy_dphi: List[float]
68 Partial derivative of coordinate.
69 """
70
71
72 cdef class _Proj:
1873 def __cinit__(self):
1974 self.projobj = NULL
2075 self.context = NULL
186241 ybuff.data[iii] = projlonlatout.uv.v
187242 ProjError.clear()
188243
244 @cython.boundscheck(False)
245 @cython.wraparound(False)
246 def _get_factors(self, longitude, latitude, bint radians, bint errcheck):
247 """
248 Calculates the projection factors PJ_FACTORS
249
250 Equivalent to `proj -S` command line.
251 """
252 cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(longitude)
253 cdef PyBuffWriteManager latbuff = PyBuffWriteManager(longitude)
254
255 if not lonbuff.len or not (lonbuff.len == latbuff.len):
256 raise ProjError('longitude and latitude must be same size')
257
258 # prepare the factors output
259 meridional_scale = copy.copy(longitude)
260 parallel_scale = copy.copy(longitude)
261 areal_scale = copy.copy(longitude)
262 angular_distortion = copy.copy(longitude)
263 meridian_parallel_angle = copy.copy(longitude)
264 meridian_convergence = copy.copy(longitude)
265 tissot_semimajor = copy.copy(longitude)
266 tissot_semiminor = copy.copy(longitude)
267 dx_dlam = copy.copy(longitude)
268 dx_dphi = copy.copy(longitude)
269 dy_dlam = copy.copy(longitude)
270 dy_dphi = copy.copy(longitude)
271 cdef PyBuffWriteManager meridional_scale_buff = PyBuffWriteManager(meridional_scale)
272 cdef PyBuffWriteManager parallel_scale_buff = PyBuffWriteManager(parallel_scale)
273 cdef PyBuffWriteManager areal_scale_buff = PyBuffWriteManager(areal_scale)
274 cdef PyBuffWriteManager angular_distortion_buff = PyBuffWriteManager(angular_distortion)
275 cdef PyBuffWriteManager meridian_parallel_angle_buff = PyBuffWriteManager(meridian_parallel_angle)
276 cdef PyBuffWriteManager meridian_convergence_buff = PyBuffWriteManager(meridian_convergence)
277 cdef PyBuffWriteManager tissot_semimajor_buff = PyBuffWriteManager(tissot_semimajor)
278 cdef PyBuffWriteManager tissot_semiminor_buff = PyBuffWriteManager(tissot_semiminor)
279 cdef PyBuffWriteManager dx_dlam_buff = PyBuffWriteManager(dx_dlam)
280 cdef PyBuffWriteManager dx_dphi_buff = PyBuffWriteManager(dx_dphi)
281 cdef PyBuffWriteManager dy_dlam_buff = PyBuffWriteManager(dy_dlam)
282 cdef PyBuffWriteManager dy_dphi_buff = PyBuffWriteManager(dy_dphi)
283
284 # calculate the factors
285 cdef PJ_COORD pj_coord = proj_coord(0, 0, 0, HUGE_VAL)
286 cdef PJ_FACTORS pj_factors
287 cdef int errno = 0
288 cdef bint invalid_coord = 0
289 cdef Py_ssize_t iii
290 with nogil:
291 for iii in range(lonbuff.len):
292 pj_coord.uv.u = lonbuff.data[iii]
293 pj_coord.uv.v = latbuff.data[iii]
294 if not radians:
295 pj_coord.uv.u *= _DG2RAD
296 pj_coord.uv.v *= _DG2RAD
297
298 # set both to HUGE_VAL if inf or nan
299 proj_errno_reset(self.projobj)
300 if pj_coord.uv.v == HUGE_VAL \
301 or pj_coord.uv.v != pj_coord.uv.v \
302 or pj_coord.uv.u == HUGE_VAL \
303 or pj_coord.uv.u != pj_coord.uv.u:
304 invalid_coord = True
305 else:
306 invalid_coord = False
307 pj_factors = proj_factors(self.projobj, pj_coord)
308
309 errno = proj_errno(self.projobj)
310 if errcheck and errno:
311 with gil:
312 raise ProjError("proj error: {}".format(
313 pystrdecode(proj_errno_string(errno))))
314
315 if errno or invalid_coord:
316 meridional_scale_buff.data[iii] = HUGE_VAL
317 parallel_scale_buff.data[iii] = HUGE_VAL
318 areal_scale_buff.data[iii] = HUGE_VAL
319 angular_distortion_buff.data[iii] = HUGE_VAL
320 meridian_parallel_angle_buff.data[iii] = HUGE_VAL
321 meridian_convergence_buff.data[iii] = HUGE_VAL
322 tissot_semimajor_buff.data[iii] = HUGE_VAL
323 tissot_semiminor_buff.data[iii] = HUGE_VAL
324 dx_dlam_buff.data[iii] = HUGE_VAL
325 dx_dphi_buff.data[iii] = HUGE_VAL
326 dy_dlam_buff.data[iii] = HUGE_VAL
327 dy_dphi_buff.data[iii] = HUGE_VAL
328 else:
329 meridional_scale_buff.data[iii] = pj_factors.meridional_scale
330 parallel_scale_buff.data[iii] = pj_factors.parallel_scale
331 areal_scale_buff.data[iii] = pj_factors.areal_scale
332 angular_distortion_buff.data[iii] = pj_factors.angular_distortion * _RAD2DG
333 meridian_parallel_angle_buff.data[iii] = pj_factors.meridian_parallel_angle * _RAD2DG
334 meridian_convergence_buff.data[iii] = pj_factors.meridian_convergence * _RAD2DG
335 tissot_semimajor_buff.data[iii] = pj_factors.tissot_semimajor
336 tissot_semiminor_buff.data[iii] = pj_factors.tissot_semiminor
337 dx_dlam_buff.data[iii] = pj_factors.dx_dlam
338 dx_dphi_buff.data[iii] = pj_factors.dx_dphi
339 dy_dlam_buff.data[iii] = pj_factors.dy_dlam
340 dy_dphi_buff.data[iii] = pj_factors.dy_dphi
341
342 ProjError.clear()
343
344 return Factors(
345 meridional_scale=meridional_scale,
346 parallel_scale=parallel_scale,
347 areal_scale=areal_scale,
348 angular_distortion=angular_distortion,
349 meridian_parallel_angle=meridian_parallel_angle,
350 meridian_convergence=meridian_convergence,
351 tissot_semimajor=tissot_semimajor,
352 tissot_semiminor=tissot_semiminor,
353 dx_dlam=dx_dlam,
354 dx_dphi=dx_dphi,
355 dy_dlam=dy_dlam,
356 dy_dphi=dy_dphi,
357 )
358
189359 def __repr__(self):
190360 return "Proj('{srs}', preserve_units=True)".format(srs=self.srs)
191361
192 def _is_exact_same(self, Proj other):
362 def _is_exact_same(self, _Proj other):
193363 return proj_is_equivalent_to(
194364 self.projobj, other.projobj, PJ_COMP_STRICT) == 1
195365
196 def _is_equivalent(self, Proj other):
366 def _is_equivalent(self, _Proj other):
197367 return proj_is_equivalent_to(
198368 self.projobj, other.projobj, PJ_COMP_EQUIVALENT) == 1
199369
200370 def is_exact_same(self, other):
201371 """Compares Proj objects to see if they are exactly the same."""
202 if not isinstance(other, Proj):
372 if not isinstance(other, _Proj):
203373 return False
204374 return self._is_exact_same(other)
1818 cdef readonly skip_equivalent
1919 cdef readonly projections_equivalent
2020 cdef readonly projections_exact_same
21 cdef readonly type_name
21 cdef readonly type_name
2222 cdef readonly object _operations
2323
2424 @staticmethod
2929 _CRS crs_to,
3030 skip_equivalent,
3131 always_xy,
32 )
32 )
0 from typing import Any, Iterable, List, NamedTuple, Optional, Tuple, Union
1
2 from pyproj._crs import _CRS, AreaOfUse, Base, CoordinateOperation
3 from pyproj.enums import TransformDirection
4
5 class AreaOfInterest(NamedTuple):
6 west_lon_degree: float
7 south_lat_degree: float
8 east_lon_degree: float
9 north_lat_degree: float
10
11 class _TransformerGroup:
12 _transformers: Any
13 _unavailable_operations: List[CoordinateOperation]
14 _best_available: bool
15 def __init__(
16 self,
17 crs_from: _CRS,
18 crs_to: _CRS,
19 skip_equivalent: bool = False,
20 always_xy: bool = False,
21 area_of_interest: Optional[AreaOfInterest] = None,
22 ) -> None: ...
23
24 class _Transformer(Base):
25 input_geographic: bool
26 output_geographic: bool
27 is_pipeline: bool
28 skip_equivalent: bool
29 projections_equivalent: bool
30 projections_exact_same: bool
31 type_name: str
32 @property
33 def id(self) -> str: ...
34 @property
35 def description(self) -> str: ...
36 @property
37 def definition(self) -> str: ...
38 @property
39 def has_inverse(self) -> bool: ...
40 @property
41 def accuracy(self) -> float: ...
42 @property
43 def area_of_use(self) -> AreaOfUse: ...
44 @property
45 def operations(self) -> Union[Tuple[CoordinateOperation], None]: ...
46 @staticmethod
47 def from_crs(
48 crs_from: _CRS,
49 crs_to: _CRS,
50 skip_equivalent: bool = False,
51 always_xy: bool = False,
52 area_of_interest: Optional[AreaOfInterest] = None,
53 ) -> "_Transformer": ...
54 @staticmethod
55 def from_pipeline(proj_pipeline: str) -> "_Transformer": ...
56 def _transform(
57 self,
58 inx: Any,
59 iny: Any,
60 inz: Any,
61 intime: Any,
62 direction: Union[TransformDirection, str],
63 radians: bool,
64 errcheck: bool,
65 ) -> None: ...
66 def _transform_sequence(
67 self,
68 stride: int,
69 inseq: Iterable[Iterable[float]],
70 switch: bool,
71 direction: Union[TransformDirection, str],
72 time_3rd: bool,
73 radians: bool,
74 errcheck: bool,
75 ) -> None: ...
171171 if pj_operations != NULL:
172172 proj_list_destroy(pj_operations)
173173 ProjError.clear()
174
174
175175
176176 cdef _CRS get_transform_crs(_CRS in_crs):
177177 for sub_crs in in_crs.sub_crs_list:
237237 @property
238238 def accuracy(self):
239239 return self.proj_info.accuracy
240
240
241241 @property
242242 def area_of_use(self):
243243 """
244244 Returns
245245 -------
246 AreaOfUse: The area of use object with associated attributes.
246 AreaOfUse:
247 The area of use object with associated attributes.
247248 """
248249 if self._area_of_use is not None:
249250 return self._area_of_use
255256 """
256257 .. versionadded:: 2.4.0
257258
258 tuple[CoordinateOperation]: The operations in a concatenated operation.
259 Tuple[CoordinateOperation]:
260 The operations in a concatenated operation.
259261 """
260262 if self._operations is not None:
261263 return self._operations
398400
399401 @cython.boundscheck(False)
400402 @cython.wraparound(False)
401 def _transform(self, inx, iny, inz, intime, direction, radians, errcheck):
403 def _transform(
404 self,
405 object inx,
406 object iny,
407 object inz,
408 object intime,
409 object direction,
410 bint radians,
411 bint errcheck,
412 ):
402413 if self.projections_exact_same or (self.projections_equivalent and self.skip_equivalent):
403414 return
415 if radians and self.is_pipeline:
416 warnings.warn(
417 "radian input with pipelines is not supported and may result "
418 "in unexpected transformations."
419 )
420
404421 tmp_pj_direction = _PJ_DIRECTION_MAP[TransformDirection.create(direction)]
405422 cdef PJ_DIRECTION pj_direction = <PJ_DIRECTION>tmp_pj_direction
406423 cdef PyBuffWriteManager xbuff = PyBuffWriteManager(inx)
433450
434451 cdef Py_ssize_t iii
435452 # degrees to radians
436 if not self.is_pipeline and not radians\
437 and self._input_radians[pj_direction]:
453 if not radians and self._input_radians[pj_direction]:
438454 with nogil:
439455 for iii in range(xbuff.len):
440456 xbuff.data[iii] = xbuff.data[iii]*_DG2RAD
441457 ybuff.data[iii] = ybuff.data[iii]*_DG2RAD
442458 # radians to degrees
443 elif not self.is_pipeline and radians\
444 and not self._input_radians[pj_direction]\
445 and self.input_geographic:
459 elif self.input_geographic and radians\
460 and not self._input_radians[pj_direction]:
446461 with nogil:
447462 for iii in range(xbuff.len):
448463 xbuff.data[iii] = xbuff.data[iii]*_RAD2DG
465480 raise ProjError("transform error")
466481
467482 # radians to degrees
468 if not self.is_pipeline and not radians\
469 and self._output_radians[pj_direction]:
483 if not radians and self._output_radians[pj_direction]:
470484 with nogil:
471485 for iii in range(xbuff.len):
472486 xbuff.data[iii] = xbuff.data[iii]*_RAD2DG
473487 ybuff.data[iii] = ybuff.data[iii]*_RAD2DG
474488 # degrees to radians
475 elif not self.is_pipeline and radians\
476 and not self._output_radians[pj_direction]\
477 and self.output_geographic:
489 elif self.output_geographic and radians\
490 and not self._output_radians[pj_direction]:
478491 with nogil:
479492 for iii in range(xbuff.len):
480493 xbuff.data[iii] = xbuff.data[iii]*_DG2RAD
484497 @cython.boundscheck(False)
485498 @cython.wraparound(False)
486499 def _transform_sequence(
487 self, Py_ssize_t stride, object inseq, bint switch,
488 direction, time_3rd, radians, errcheck
500 self,
501 Py_ssize_t stride,
502 object inseq,
503 bint switch,
504 object direction,
505 bint time_3rd,
506 bint radians,
507 bint errcheck,
489508 ):
490509 if self.projections_exact_same or (self.projections_equivalent and self.skip_equivalent):
491510 return
499518
500519 if stride < 2:
501520 raise ProjError("coordinates must contain at least 2 values")
502
521
503522 cdef PyBuffWriteManager coordbuff = PyBuffWriteManager(inseq)
504523 cdef Py_ssize_t npts, iii, jjj
505524 npts = coordbuff.len // stride
506525 # degrees to radians
507 if not self.is_pipeline and not radians\
508 and self._input_radians[pj_direction]:
526 if not radians and self._input_radians[pj_direction]:
509527 with nogil:
510528 for iii in range(npts):
511529 jjj = stride * iii
512530 coordbuff.data[jjj] *= _DG2RAD
513531 coordbuff.data[jjj + 1] *= _DG2RAD
514532 # radians to degrees
515 elif not self.is_pipeline and radians\
516 and not self._input_radians[pj_direction]\
517 and self.input_geographic:
533 elif self.input_geographic and radians\
534 and not self._input_radians[pj_direction]:
518535 with nogil:
519536 for iii in range(npts):
520537 jjj = stride * iii
560577
561578
562579 # radians to degrees
563 if not self.is_pipeline and not radians\
564 and self._output_radians[pj_direction]:
580 if not radians and self._output_radians[pj_direction]:
565581 with nogil:
566582 for iii in range(npts):
567583 jjj = stride * iii
568584 coordbuff.data[jjj] *= _RAD2DG
569585 coordbuff.data[jjj + 1] *= _RAD2DG
570586 # degrees to radians
571 elif not self.is_pipeline and radians\
572 and not self._output_radians[pj_direction]\
573 and self.output_geographic:
587 elif self.output_geographic and radians\
588 and not self._output_radians[pj_direction]:
574589 with nogil:
575590 for iii in range(npts):
576591 jjj = stride * iii
3030
3131 def __dealloc__(self):
3232 PyBuffer_Release(&self.buffer)
33 self.data = NULL
33 self.data = NULL
00 import warnings
11 from distutils.version import LooseVersion
2 from typing import Any
23
34 from pyproj._crs import CoordinateOperation
45 from pyproj._proj import proj_version_str
1617
1718 def __new__(
1819 cls,
19 latitude_first_parallel,
20 latitude_second_parallel,
21 latitude_false_origin=0.0,
22 longitude_false_origin=0.0,
23 easting_false_origin=0.0,
24 northing_false_origin=0.0,
20 latitude_first_parallel: float,
21 latitude_second_parallel: float,
22 latitude_false_origin: float = 0.0,
23 longitude_false_origin: float = 0.0,
24 easting_false_origin: float = 0.0,
25 northing_false_origin: float = 0.0,
2526 ):
2627 """
2728 Parameters
108109
109110 def __new__(
110111 cls,
111 latitude_natural_origin=0.0,
112 longitude_natural_origin=0.0,
113 false_easting=0.0,
114 false_northing=0.0,
112 latitude_natural_origin: float = 0.0,
113 longitude_natural_origin: float = 0.0,
114 false_easting: float = 0.0,
115 false_northing: float = 0.0,
115116 ):
116117 """
117118 Parameters
175176
176177 def __new__(
177178 cls,
178 sweep_angle_axis,
179 satellite_height,
180 latitude_natural_origin=0.0,
181 longitude_natural_origin=0.0,
182 false_easting=0.0,
183 false_northing=0.0,
179 sweep_angle_axis: str,
180 satellite_height: float,
181 latitude_natural_origin: float = 0.0,
182 longitude_natural_origin: float = 0.0,
183 false_easting: float = 0.0,
184 false_northing: float = 0.0,
184185 ):
185186 """
186187 Parameters
264265
265266 def __new__(
266267 cls,
267 latitude_natural_origin=0.0,
268 longitude_natural_origin=0.0,
269 false_easting=0.0,
270 false_northing=0.0,
268 latitude_natural_origin: float = 0.0,
269 longitude_natural_origin: float = 0.0,
270 false_easting: float = 0.0,
271 false_northing: float = 0.0,
271272 ):
272273 """
273274 Parameters
331332
332333 def __new__(
333334 cls,
334 latitude_first_parallel,
335 latitude_second_parallel,
336 latitude_false_origin=0.0,
337 longitude_false_origin=0.0,
338 easting_false_origin=0.0,
339 northing_false_origin=0.0,
335 latitude_first_parallel: float,
336 latitude_second_parallel: float,
337 latitude_false_origin: float = 0.0,
338 longitude_false_origin: float = 0.0,
339 easting_false_origin: float = 0.0,
340 northing_false_origin: float = 0.0,
340341 ):
341342 """
342343 Parameters
416417
417418 def __new__(
418419 cls,
419 latitude_natural_origin=0.0,
420 longitude_natural_origin=0.0,
421 false_easting=0.0,
422 false_northing=0.0,
423 scale_factor_natural_origin=1.0,
420 latitude_natural_origin: float = 0.0,
421 longitude_natural_origin: float = 0.0,
422 false_easting: float = 0.0,
423 false_northing: float = 0.0,
424 scale_factor_natural_origin: float = 1.0,
424425 ):
425426 """
426427 Parameters
492493
493494 def __new__(
494495 cls,
495 latitude_first_parallel=0.0,
496 longitude_natural_origin=0.0,
497 false_easting=0.0,
498 false_northing=0.0,
496 latitude_first_parallel: float = 0.0,
497 longitude_natural_origin: float = 0.0,
498 false_easting: float = 0.0,
499 false_northing: float = 0.0,
499500 ):
500501 """
501502 Parameters
565566
566567 def __new__(
567568 cls,
568 longitude_natural_origin=0.0,
569 false_easting=0.0,
570 false_northing=0.0,
571 scale_factor_natural_origin=1.0,
569 longitude_natural_origin: float = 0.0,
570 false_easting: float = 0.0,
571 false_northing: float = 0.0,
572 scale_factor_natural_origin: float = 1.0,
572573 ):
573574 """
574575 Parameters
600601 )
601602 )
602603 if LooseVersion(proj_version_str) >= LooseVersion("6.3.1"):
603 return cls.from_json(CRS(proj_string).coordinate_operation.to_json())
604 return cls.from_json(
605 CRS(proj_string).coordinate_operation.to_json() # type: ignore
606 )
604607 return cls.from_string(proj_string)
605608
606609
615618
616619 def __new__(
617620 cls,
618 latitude_natural_origin=0.0,
619 longitude_natural_origin=0.0,
620 false_easting=0.0,
621 false_northing=0.0,
622 scale_factor_natural_origin=1.0,
621 latitude_natural_origin: float = 0.0,
622 longitude_natural_origin: float = 0.0,
623 false_easting: float = 0.0,
624 false_northing: float = 0.0,
625 scale_factor_natural_origin: float = 1.0,
623626 ):
624627 """
625628 Parameters
691694
692695 def __new__(
693696 cls,
694 latitude_first_parallel=0.0,
695 longitude_natural_origin=0.0,
696 false_easting=0.0,
697 false_northing=0.0,
697 latitude_first_parallel: float = 0.0,
698 longitude_natural_origin: float = 0.0,
699 false_easting: float = 0.0,
700 false_northing: float = 0.0,
698701 ):
699702 """
700703 Parameters
758761
759762 def __new__(
760763 cls,
761 latitude_projection_centre,
762 longitude_projection_centre,
763 azimuth_initial_line,
764 angle_from_rectified_to_skew_grid,
765 scale_factor_on_initial_line=1.0,
766 easting_projection_centre=0.0,
767 northing_projection_centre=0.0,
764 latitude_projection_centre: float,
765 longitude_projection_centre: float,
766 azimuth_initial_line: float,
767 angle_from_rectified_to_skew_grid: float,
768 scale_factor_on_initial_line: float = 1.0,
769 easting_projection_centre: float = 0.0,
770 northing_projection_centre: float = 0.0,
768771 ):
769772 """
770773 Parameters
851854
852855 def __new__(
853856 cls,
854 latitude_natural_origin=0.0,
855 longitude_natural_origin=0.0,
856 false_easting=0.0,
857 false_northing=0.0,
857 latitude_natural_origin: float = 0.0,
858 longitude_natural_origin: float = 0.0,
859 false_easting: float = 0.0,
860 false_northing: float = 0.0,
858861 ):
859862 """
860863 Parameters
918921
919922 def __new__(
920923 cls,
921 latitude_natural_origin,
922 longitude_natural_origin=0.0,
923 false_easting=0.0,
924 false_northing=0.0,
925 scale_factor_natural_origin=1.0,
924 latitude_natural_origin: float,
925 longitude_natural_origin: float = 0.0,
926 false_easting: float = 0.0,
927 false_northing: float = 0.0,
928 scale_factor_natural_origin: float = 1.0,
926929 ):
927930 """
928931 Parameters
995998
996999 def __new__(
9971000 cls,
998 latitude_standard_parallel=0.0,
999 longitude_origin=0.0,
1000 false_easting=0.0,
1001 false_northing=0.0,
1001 latitude_standard_parallel: float = 0.0,
1002 longitude_origin: float = 0.0,
1003 false_easting: float = 0.0,
1004 false_northing: float = 0.0,
10021005 ):
10031006 """
10041007 Parameters
10611064 """
10621065
10631066 def __new__(
1064 cls, longitude_natural_origin=0.0, false_easting=0.0, false_northing=0.0
1067 cls,
1068 longitude_natural_origin: float = 0.0,
1069 false_easting: float = 0.0,
1070 false_northing: float = 0.0,
10651071 ):
10661072 """
10671073 Parameters
11141120
11151121 def __new__(
11161122 cls,
1117 latitude_natural_origin=0.0,
1118 longitude_natural_origin=0.0,
1119 false_easting=0.0,
1120 false_northing=0.0,
1121 scale_factor_natural_origin=1.0,
1123 latitude_natural_origin: float = 0.0,
1124 longitude_natural_origin: float = 0.0,
1125 false_easting: float = 0.0,
1126 false_northing: float = 0.0,
1127 scale_factor_natural_origin: float = 1.0,
11221128 ):
11231129 """
11241130 Parameters
11861192 https://proj.org/operations/projections/utm.html
11871193 """
11881194
1189 def __new__(cls, zone, hemisphere="N"):
1195 def __new__(cls, zone: str, hemisphere: str = "N"):
11901196 """
11911197 Parameters
11921198 ----------
12111217
12121218 def __new__(
12131219 cls,
1214 latitude_natural_origin=0.0,
1215 longitude_natural_origin=0.0,
1216 false_easting=0.0,
1217 false_northing=0.0,
1218 scale_factor_natural_origin=1.0,
1220 latitude_natural_origin: float = 0.0,
1221 longitude_natural_origin: float = 0.0,
1222 false_easting: float = 0.0,
1223 false_northing: float = 0.0,
1224 scale_factor_natural_origin: float = 1.0,
12191225 ):
12201226 """
12211227 Parameters
12871293
12881294 def __new__(
12891295 cls,
1290 viewpoint_height,
1291 latitude_topocentric_origin=0.0,
1292 longitude_topocentric_origin=0.0,
1293 ellipsoidal_height_topocentric_origin=0.0,
1294 false_easting=0.0,
1295 false_northing=0.0,
1296 viewpoint_height: float,
1297 latitude_topocentric_origin: float = 0.0,
1298 longitude_topocentric_origin: float = 0.0,
1299 ellipsoidal_height_topocentric_origin: float = 0.0,
1300 false_easting: float = 0.0,
1301 false_northing: float = 0.0,
12961302 ):
12971303 """
12981304 Parameters
13701376 https://proj.org/operations/projections/ob_tran.html
13711377 """
13721378
1373 def __new__(cls, o_lat_p, o_lon_p, lon_0=0.0):
1379 def __new__(cls, o_lat_p: float, o_lon_p: float, lon_0: float = 0.0):
13741380 """
13751381 Parameters
13761382 ----------
13771383 o_lat_p: float
13781384 Latitude of the North pole of the unrotated source CRS,
13791385 expressed in the rotated geographic CRS.
1380 o_lon_p:
1386 o_lon_p: float
13811387 Longitude of the North pole of the unrotated source CRS,
13821388 expressed in the rotated geographic CRS.
13831389 lon_0: float, optional
14091415
14101416 def __new__(
14111417 cls,
1412 latitude_first_parallel=0.0,
1413 latitude_natural_origin=0.0,
1414 longitude_natural_origin=0.0,
1415 false_easting=0.0,
1416 false_northing=0.0,
1418 latitude_first_parallel: float = 0.0,
1419 latitude_natural_origin: float = 0.0,
1420 longitude_natural_origin: float = 0.0,
1421 false_easting: float = 0.0,
1422 false_northing: float = 0.0,
14171423 ):
14181424 """
14191425 Parameters
14861492
14871493 def __new__(
14881494 cls,
1489 source_crs,
1490 x_axis_translation=0,
1491 y_axis_translation=0,
1492 z_axis_translation=0,
1493 x_axis_rotation=0,
1494 y_axis_rotation=0,
1495 z_axis_rotation=0,
1496 scale_difference=0,
1497 ):
1498 """
1499 Parameters
1500 ----------
1495 source_crs: Any,
1496 x_axis_translation: float = 0,
1497 y_axis_translation: float = 0,
1498 z_axis_translation: float = 0,
1499 x_axis_rotation: float = 0,
1500 y_axis_rotation: float = 0,
1501 z_axis_rotation: float = 0,
1502 scale_difference: float = 0,
1503 ):
1504 """
1505 Parameters
1506 ----------
1507 source_crs: Any
1508 Input to create the Source CRS.
15011509 x_axis_translation: float, optional
15021510 X-axis translation. Defaults to 0.0.
15031511 y_axis_translation: float, optional
0 from typing import Union
1
02 from pyproj._crs import CoordinateSystem
13 from pyproj.crs.enums import (
24 Cartesian2DCSAxis,
5456 This generates an Ellipsoidal 2D Coordinate System
5557 """
5658
57 def __new__(cls, axis=Ellipsoidal2DCSAxis.LONGITUDE_LATITUDE):
59 def __new__(
60 cls,
61 axis: Union[Ellipsoidal2DCSAxis, str] = Ellipsoidal2DCSAxis.LONGITUDE_LATITUDE,
62 ):
5863 """
5964 Parameters
6065 ----------
121126 This generates an Ellipsoidal 3D Coordinate System
122127 """
123128
124 def __new__(cls, axis=Ellipsoidal3DCSAxis.LONGITUDE_LATITUDE_HEIGHT):
129 def __new__(
130 cls,
131 axis: Union[
132 Ellipsoidal3DCSAxis, str
133 ] = Ellipsoidal3DCSAxis.LONGITUDE_LATITUDE_HEIGHT,
134 ):
125135 """
126136 Parameters
127137 ----------
264274 This generates an Cartesian 2D Coordinate System
265275 """
266276
267 def __new__(cls, axis=Cartesian2DCSAxis.EASTING_NORTHING):
277 def __new__(
278 cls, axis: Union[Cartesian2DCSAxis, str] = Cartesian2DCSAxis.EASTING_NORTHING
279 ):
268280 """
269281 Parameters
270282 ----------
345357 This generates an Vertical Coordinate System
346358 """
347359
348 def __new__(cls, axis=VerticalCSAxis.GRAVITY_HEIGHT):
360 def __new__(cls, axis: Union[VerticalCSAxis, str] = VerticalCSAxis.GRAVITY_HEIGHT):
349361 """
350362 Parameters
351363 ----------
33 to the coordinate reference system (CRS) information.
44
55 Original Author: Alan D. Snow [github.com/snowman2] (2019)
6
67 """
78 import json
89 import re
910 import warnings
11 from typing import Any, Callable, Dict, List, Optional, Tuple, Type, Union
1012
1113 from pyproj._crs import ( # noqa
1214 _CRS,
3436 from pyproj.geod import Geod
3537
3638
37 def _prepare_from_dict(projparams):
39 def _prepare_from_dict(projparams: dict, allow_json: bool = True) -> str:
3840 # check if it is a PROJ JSON dict
39 if "proj" not in projparams and "init" not in projparams:
41 if "proj" not in projparams and "init" not in projparams and allow_json:
4042 return json.dumps(projparams)
4143 # convert a dict to a proj string.
4244 pjargs = []
4749 # issue 183 (+ no_rot)
4850 if value is None or value is True:
4951 pjargs.append("+{key}".format(key=key))
50 elif value is False:
52 elif str(value) == str(False):
5153 pass
5254 else:
5355 pjargs.append("+{key}={value}".format(key=key, value=value))
5456 return _prepare_from_string(" ".join(pjargs))
5557
5658
57 def _prepare_from_string(in_crs_string):
59 def _prepare_from_string(in_crs_string: str) -> str:
5860 if not in_crs_string:
5961 raise CRSError("CRS is empty or invalid: {!r}".format(in_crs_string))
6062 elif "{" in in_crs_string:
7274 # make sure the projection starts with +proj or +init
7375 starting_params = ("+init", "+proj", "init", "proj")
7476 if not in_crs_string.startswith(starting_params):
75 kvpairs = []
77 kvpairs = [] # type: List[str]
7678 first_item_inserted = False
7779 for kvpair in in_crs_string.split():
7880 if not first_item_inserted and (kvpair.startswith(starting_params)):
105107 return in_crs_string
106108
107109
108 def _prepare_from_authority(auth_name, auth_code):
110 def _prepare_from_authority(auth_name: str, auth_code: Union[str, int]):
109111 return "{}:{}".format(auth_name, auth_code)
110112
111113
112 def _prepare_from_epsg(auth_code):
114 def _prepare_from_epsg(auth_code: Union[str, int]):
113115 return _prepare_from_authority("epsg", auth_code)
114116
115117
136138
137139 """
138140
139 def __init__(self, projparams=None, **kwargs):
141 def __init__(self, projparams: Any = None, **kwargs) -> None:
140142 """
141143 Initialize a CRS class instance with:
142144 - PROJ string
274276 >>> crs.is_geographic
275277 False
276278 """
277 if isinstance(projparams, str):
278 projstring = _prepare_from_string(projparams)
279 elif isinstance(projparams, dict):
280 projstring = _prepare_from_dict(projparams)
281 elif kwargs:
282 projstring = _prepare_from_dict(kwargs)
283 elif isinstance(projparams, int):
284 projstring = _prepare_from_epsg(projparams)
285 elif isinstance(projparams, (list, tuple)) and len(projparams) == 2:
286 projstring = _prepare_from_authority(*projparams)
287 elif hasattr(projparams, "to_wkt"):
288 projstring = projparams.to_wkt()
289 else:
290 raise CRSError("Invalid CRS input: {!r}".format(projparams))
279 projstring = ""
280
281 if projparams:
282 if isinstance(projparams, str):
283 projstring = _prepare_from_string(projparams)
284 elif isinstance(projparams, dict):
285 projstring = _prepare_from_dict(projparams)
286 elif isinstance(projparams, int):
287 projstring = _prepare_from_epsg(projparams)
288 elif isinstance(projparams, (list, tuple)) and len(projparams) == 2:
289 projstring = _prepare_from_authority(*projparams)
290 elif hasattr(projparams, "to_wkt"):
291 projstring = projparams.to_wkt() # type: ignore
292 else:
293 raise CRSError("Invalid CRS input: {!r}".format(projparams))
294
295 if kwargs:
296 projkwargs = _prepare_from_dict(kwargs, allow_json=False)
297 projstring = _prepare_from_string(" ".join((projstring, projkwargs)))
291298
292299 super().__init__(projstring)
293300
294301 @staticmethod
295 def from_authority(auth_name, code):
302 def from_authority(auth_name: str, code: Union[str, int]) -> "CRS":
296303 """
297304 .. versionadded:: 2.2.0
298305
312319 return CRS(_prepare_from_authority(auth_name, code))
313320
314321 @staticmethod
315 def from_epsg(code):
322 def from_epsg(code: Union[str, int]) -> "CRS":
316323 """Make a CRS from an EPSG code
317324
318325 Parameters
327334 return CRS(_prepare_from_epsg(code))
328335
329336 @staticmethod
330 def from_proj4(in_proj_string):
337 def from_proj4(in_proj_string: str) -> "CRS":
331338 """
332339 .. versionadded:: 2.2.0
333340
347354 return CRS(_prepare_from_string(in_proj_string))
348355
349356 @staticmethod
350 def from_wkt(in_wkt_string):
357 def from_wkt(in_wkt_string: str) -> "CRS":
351358 """
352359 .. versionadded:: 2.2.0
353360
367374 return CRS(_prepare_from_string(in_wkt_string))
368375
369376 @staticmethod
370 def from_string(in_crs_string):
377 def from_string(in_crs_string: str) -> "CRS":
371378 """
372379 Make a CRS from:
373380
388395 """
389396 return CRS(_prepare_from_string(in_crs_string))
390397
391 def to_string(self):
398 def to_string(self) -> str:
392399 """
393400 .. versionadded:: 2.2.0
394401
400407
401408 Returns
402409 -------
403 str: String representation of the CRS.
410 str
404411 """
405412 auth_info = self.to_authority(min_confidence=100)
406413 if auth_info:
408415 return self.srs
409416
410417 @staticmethod
411 def from_user_input(value):
418 def from_user_input(value: Any, **kwargs) -> "CRS":
412419 """
413420 Initialize a CRS class instance with:
414421 - PROJ string
433440 """
434441 if isinstance(value, CRS):
435442 return value
436 return CRS(value)
437
438 def get_geod(self):
439 """
440 Returns
441 -------
442 pyproj.geod.Geod: Geod object based on the ellipsoid.
443 return CRS(value, **kwargs)
444
445 def get_geod(self) -> Optional[Geod]:
446 """
447 Returns
448 -------
449 pyproj.geod.Geod:
450 Geod object based on the ellipsoid.
443451 """
444452 if self.ellipsoid is None:
445453 return None
446 in_kwargs = {
447 "a": self.ellipsoid.semi_major_metre,
448 "rf": self.ellipsoid.inverse_flattening,
449 "b": self.ellipsoid.semi_minor_metre,
450 }
451 return Geod(**in_kwargs)
454 return Geod(
455 a=self.ellipsoid.semi_major_metre,
456 rf=self.ellipsoid.inverse_flattening,
457 b=self.ellipsoid.semi_minor_metre,
458 )
452459
453460 @staticmethod
454 def from_dict(proj_dict):
461 def from_dict(proj_dict: dict) -> "CRS":
455462 """
456463 .. versionadded:: 2.2.0
457464
469476 return CRS(_prepare_from_dict(proj_dict))
470477
471478 @staticmethod
472 def from_json(crs_json):
479 def from_json(crs_json: str) -> "CRS":
473480 """
474481 .. versionadded:: 2.4.0
475482
487494 return CRS.from_json_dict(_load_proj_json(crs_json))
488495
489496 @staticmethod
490 def from_json_dict(crs_dict):
497 def from_json_dict(crs_dict: dict) -> "CRS":
491498 """
492499 .. versionadded:: 2.4.0
493500
504511 """
505512 return CRS(json.dumps(crs_dict))
506513
507 def to_dict(self):
514 def to_dict(self) -> dict:
508515 """
509516 .. versionadded:: 2.2.0
510517
516523
517524 Returns
518525 -------
519 dict: PROJ params in dict format.
526 dict:
527 PROJ params in dict format.
520528
521529 """
522530
546554
547555 return {key: value for key, value in items if value is not False}
548556
549 def to_cf(self, wkt_version=WktVersion.WKT2_2019, errcheck=False):
557 def to_cf(
558 self,
559 wkt_version: Union[WktVersion, str] = WktVersion.WKT2_2019,
560 errcheck: bool = False,
561 ) -> dict:
550562 """
551563 .. versionadded:: 2.2.0
552564
567579
568580 Returns
569581 -------
570 dict: CF-1.8 version of the projection.
582 dict:
583 CF-1.8 version of the projection.
571584
572585 """
573586 unknown_names = ("unknown", "undefined")
574 cf_dict = {"crs_wkt": self.to_wkt(wkt_version)}
587 cf_dict = {"crs_wkt": self.to_wkt(wkt_version)} # type: Dict[str, Any]
575588
576589 # handle bound CRS
577 if self.is_bound and self.coordinate_operation.towgs84:
578 sub_cf = self.source_crs.to_cf(errcheck=errcheck)
590 if (
591 self.is_bound
592 and self.coordinate_operation
593 and self.coordinate_operation.towgs84
594 ):
595 sub_cf = self.source_crs.to_cf(errcheck=errcheck) # type: ignore
579596 sub_cf.pop("crs_wkt")
580597 cf_dict.update(sub_cf)
581598 cf_dict["towgs84"] = self.coordinate_operation.towgs84
594611 vert_json = self.to_json_dict()
595612 if "geoid_model" in vert_json:
596613 cf_dict["geoid_name"] = vert_json["geoid_model"]["name"]
597 if self.datum.name not in unknown_names:
614 if self.datum and self.datum.name not in unknown_names:
598615 cf_dict["geopotential_datum_name"] = self.datum.name
599616 return cf_dict
600617
623640 self.coordinate_operation.method_name.lower()
624641 ](self.coordinate_operation)
625642 )
626 if self.datum.name not in unknown_names:
643 if self.datum and self.datum.name not in unknown_names:
627644 cf_dict["horizontal_datum_name"] = self.datum.name
628645 else:
629646 cf_dict["grid_mapping_name"] = "latitude_longitude"
630647 return cf_dict
631648
632649 # handle projected CRS
633 if self.is_projected and self.datum.name not in unknown_names:
650 if self.is_projected and self.datum and self.datum.name not in unknown_names:
634651 cf_dict["horizontal_datum_name"] = self.datum.name
635652 coordinate_operation = None
636653 if not self.is_bound and self.is_projected:
663680 return cf_dict
664681
665682 @staticmethod
666 def from_cf(in_cf, errcheck=False):
683 def from_cf(in_cf: dict, errcheck=False) -> "CRS":
667684 """
668685 .. versionadded:: 2.2.0
669686
702719 try:
703720 geographic_conversion_method = _GEOGRAPHIC_GRID_MAPPING_NAME_MAP[
704721 grid_mapping_name
705 ]
722 ] # type: Optional[Callable]
706723 except KeyError:
707724 geographic_conversion_method = None
708725
710727 if datum:
711728 geographic_crs = GeographicCRS(
712729 name=geographic_crs_name or "undefined", datum=datum,
713 )
730 ) # type: CRS
714731 elif geographic_crs_name:
715732 geographic_crs = CRS(geographic_crs_name)
716733 else:
760777 name="undefined", components=[bound_crs or projected_crs, vertical_crs]
761778 )
762779
763 def is_exact_same(self, other, ignore_axis_order=False):
780 def is_exact_same(self, other: Any, ignore_axis_order: bool = False) -> bool:
764781 """
765782 Check if the CRS objects are the exact same.
766783
781798 return False
782799 return super().is_exact_same(other)
783800
784 def equals(self, other, ignore_axis_order=False):
801 def equals(self, other: Any, ignore_axis_order: bool = False) -> bool:
785802 """
786803
787804 .. versionadded:: 2.5.0
809826 return super().equals(other, ignore_axis_order=ignore_axis_order)
810827
811828 @property
812 def geodetic_crs(self):
829 def geodetic_crs(self) -> Optional["CRS"]:
813830 """
814831 .. versionadded:: 2.2.0
815832
816833 Returns
817834 -------
818 CRS: The the geodeticCRS / geographicCRS from the CRS.
819 """
820 if super().geodetic_crs is None:
835 CRS:
836 The the geodeticCRS / geographicCRS from the CRS.
837
838 """
839 geodetic_crs = super().geodetic_crs
840 if geodetic_crs is None:
821841 return None
822 return CRS(super().geodetic_crs.srs)
842 return CRS(geodetic_crs.srs)
823843
824844 @property
825 def source_crs(self):
826 """
827 Returns
828 -------
829 CRS: The the base CRS of a BoundCRS or a DerivedCRS/ProjectedCRS,
830 or the source CRS of a CoordinateOperation.
831 """
832 if super().source_crs is None:
845 def source_crs(self) -> Optional["CRS"]:
846 """
847 The the base CRS of a BoundCRS or a DerivedCRS/ProjectedCRS,
848 or the source CRS of a CoordinateOperation.
849
850 Returns
851 -------
852 CRS
853 """
854 source_crs = super().source_crs
855 if source_crs is None:
833856 return None
834 return CRS(super().source_crs.srs)
857 return CRS(source_crs.srs)
835858
836859 @property
837 def target_crs(self):
860 def target_crs(self) -> Optional["CRS"]:
838861 """
839862 .. versionadded:: 2.2.0
840863
841864 Returns
842865 -------
843 CRS: The hub CRS of a BoundCRS or the target CRS of a CoordinateOperation.
844 """
845 if super().target_crs is None:
866 CRS:
867 The hub CRS of a BoundCRS or the target CRS of a CoordinateOperation.
868
869 """
870 target_crs = super().target_crs
871 if target_crs is None:
846872 return None
847 return CRS(super().target_crs.srs)
873 return CRS(target_crs.srs)
848874
849875 @property
850 def sub_crs_list(self):
876 def sub_crs_list(self) -> List["CRS"]:
851877 """
852878 If the CRS is a compound CRS, it will return a list of sub CRS objects.
853879
854880 Returns
855881 -------
856 list[CRS]
882 List[CRS]
857883 """
858884 return [CRS(sub_crs.srs) for sub_crs in super().sub_crs_list]
859885
860 def __eq__(self, other):
886 @property
887 def utm_zone(self) -> Optional[str]:
888 """
889 .. versionadded:: 2.6.0
890
891 Finds the UTM zone in a Projected CRS, Bound CRS, or Compound CRS
892
893 Returns
894 -------
895 Optional[str]:
896 The UTM zone number and letter if applicable.
897 """
898 if self.is_bound and self.source_crs:
899 return self.source_crs.utm_zone
900 elif self.sub_crs_list:
901 for sub_crs in self.sub_crs_list:
902 if sub_crs.utm_zone:
903 return sub_crs.utm_zone
904 elif (
905 self.coordinate_operation
906 and "UTM ZONE" in self.coordinate_operation.name.upper()
907 ):
908 return self.coordinate_operation.name.upper().split("UTM ZONE ")[-1]
909 return None
910
911 def __eq__(self, other: Any) -> bool:
861912 return self.equals(other)
862913
863 def __reduce__(self):
914 def __reduce__(self) -> Tuple[Type["CRS"], Tuple[str]]:
864915 """special method that allows CRS instance to be pickled"""
865916 return self.__class__, (self.srs,)
866917
867 def __hash__(self):
918 def __hash__(self) -> int:
868919 return hash(self.to_wkt())
869920
870 def __str__(self):
921 def __str__(self) -> str:
871922 return self.srs
872923
873 def __repr__(self):
874 # get axis/coordinate system information
875 axis_info_list = []
876
877 def extent_axis(axis_list):
878 for axis_info in axis_list:
879 axis_info_list.extend(["- ", str(axis_info), "\n"])
880
924 def __repr__(self) -> str:
925 # get axis information
926 axis_info_list = [] # type: List[str]
927 for axis in self.axis_info:
928 axis_info_list.extend(["- ", str(axis), "\n"])
929 axis_info_str = "".join(axis_info_list)
930
931 # get coordinate system & sub CRS info
881932 source_crs_repr = ""
882933 sub_crs_repr = ""
883 if self.axis_info:
884 extent_axis(self.axis_info)
934 if self.coordinate_system and self.coordinate_system.axis_list:
885935 coordinate_system_name = str(self.coordinate_system)
886 elif self.is_bound:
887 extent_axis(self.source_crs.axis_info)
936 elif self.is_bound and self.source_crs:
888937 coordinate_system_name = str(self.source_crs.coordinate_system)
889938 source_crs_repr = "Source CRS: {}\n".format(self.source_crs.name)
890939 else:
891940 coordinate_system_names = []
892941 sub_crs_repr_list = ["Sub CRS:\n"]
893942 for sub_crs in self.sub_crs_list:
894 extent_axis(sub_crs.axis_info)
895943 coordinate_system_names.append(str(sub_crs.coordinate_system))
896944 sub_crs_repr_list.extend(["- ", sub_crs.name, "\n"])
897945 coordinate_system_name = "|".join(coordinate_system_names)
898946 sub_crs_repr = "".join(sub_crs_repr_list)
899 axis_info_str = "".join(axis_info_list)
900947
901948 # get coordinate operation repr
902949 coordinate_operation = ""
9541001
9551002 def __init__(
9561003 self,
957 name="undefined",
958 datum="urn:ogc:def:datum:EPSG::6326",
959 ellipsoidal_cs=Ellipsoidal2DCS(),
960 ):
1004 name: str = "undefined",
1005 datum: Any = "urn:ogc:def:datum:EPSG::6326",
1006 ellipsoidal_cs: Any = None,
1007 ) -> None:
9611008 """
9621009 Parameters
9631010 ----------
9771024 "name": name,
9781025 "datum": Datum.from_user_input(datum).to_json_dict(),
9791026 "coordinate_system": CoordinateSystem.from_user_input(
980 ellipsoidal_cs
1027 ellipsoidal_cs or Ellipsoidal2DCS()
9811028 ).to_json_dict(),
9821029 }
9831030 super().__init__(geographic_crs_json)
9911038 """
9921039
9931040 def __init__(
994 self, base_crs, conversion, ellipsoidal_cs=Ellipsoidal2DCS(), name="undefined",
995 ):
1041 self,
1042 base_crs: Any,
1043 conversion: Any,
1044 ellipsoidal_cs: Any = None,
1045 name: str = "undefined",
1046 ) -> None:
9961047 """
9971048 Parameters
9981049 ----------
10181069 conversion
10191070 ).to_json_dict(),
10201071 "coordinate_system": CoordinateSystem.from_user_input(
1021 ellipsoidal_cs
1072 ellipsoidal_cs or Ellipsoidal2DCS()
10221073 ).to_json_dict(),
10231074 }
10241075 super().__init__(derived_geographic_crs_json)
10331084
10341085 def __init__(
10351086 self,
1036 conversion,
1037 name="undefined",
1038 cartesian_cs=Cartesian2DCS(),
1039 geodetic_crs=GeographicCRS(),
1040 ):
1087 conversion: Any,
1088 name: str = "undefined",
1089 cartesian_cs: Any = None,
1090 geodetic_crs: Any = None,
1091 ) -> None:
10411092 """
10421093 Parameters
10431094 ----------
10581109 "$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
10591110 "type": "ProjectedCRS",
10601111 "name": name,
1061 "base_crs": CRS.from_user_input(geodetic_crs).to_json_dict(),
1112 "base_crs": CRS.from_user_input(
1113 geodetic_crs or GeographicCRS()
1114 ).to_json_dict(),
10621115 "conversion": CoordinateOperation.from_user_input(
10631116 conversion
10641117 ).to_json_dict(),
10651118 "coordinate_system": CoordinateSystem.from_user_input(
1066 cartesian_cs
1119 cartesian_cs or Cartesian2DCS()
10671120 ).to_json_dict(),
10681121 }
10691122 super().__init__(proj_crs_json)
10791132
10801133 """
10811134
1082 def __init__(self, name, datum, vertical_cs=VerticalCS(), geoid_model=None):
1135 def __init__(
1136 self,
1137 name: str,
1138 datum: Any,
1139 vertical_cs: Any = None,
1140 geoid_model: Optional[str] = None,
1141 ) -> None:
10831142 """
10841143 Parameters
10851144 ----------
11001159 "name": name,
11011160 "datum": Datum.from_user_input(datum).to_json_dict(),
11021161 "coordinate_system": CoordinateSystem.from_user_input(
1103 vertical_cs
1162 vertical_cs or VerticalCS()
11041163 ).to_json_dict(),
11051164 }
11061165 if geoid_model is not None:
11161175 This class is for building a Compound CRS.
11171176 """
11181177
1119 def __init__(self, name, components):
1178 def __init__(self, name: str, components: List[Any]) -> None:
11201179 """
11211180 Parameters
11221181 ----------
11461205 This class is for building a Bound CRS.
11471206 """
11481207
1149 def __init__(self, source_crs, target_crs, transformation):
1208 def __init__(self, source_crs: Any, target_crs: Any, transformation: Any) -> None:
11501209 """
11511210 Parameters
11521211 ----------
0 from typing import Any, Dict, Optional, Union
1
02 from pyproj._crs import Datum, Ellipsoid, PrimeMeridian
13
24
79 Class to build a datum based on an ellipsoid and prime meridian.
810 """
911
10 def __new__(cls, name="undefined", ellipsoid="WGS 84", prime_meridian="Greenwich"):
12 def __new__(
13 cls,
14 name: str = "undefined",
15 ellipsoid: Any = "WGS 84",
16 prime_meridian: Any = "Greenwich",
17 ):
1118 """
1219 Parameters
1320 ----------
4047
4148 def __new__(
4249 cls,
43 name="undefined",
44 semi_major_axis=None,
45 inverse_flattening=None,
46 semi_minor_axis=None,
47 radius=None,
50 name: str = "undefined",
51 semi_major_axis: Optional[float] = None,
52 inverse_flattening: Optional[float] = None,
53 semi_minor_axis: Optional[float] = None,
54 radius: Optional[float] = None,
4855 ):
4956 """
5057 Parameters
6774 "$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
6875 "type": "Ellipsoid",
6976 "name": name,
70 }
77 } # type: Dict[str, Union[float, str]]
7178 if semi_major_axis is not None:
7279 ellipsoid_json["semi_major_axis"] = semi_major_axis
7380 if inverse_flattening is not None:
8693 Class to build a prime meridian based on a longitude.
8794 """
8895
89 def __new__(cls, longitude, name="undefined"):
96 def __new__(cls, longitude: float, name: str = "undefined"):
9097 """
9198 Parameters
9299 ----------
1010 _VALIDATED_PROJ_DATA = None
1111
1212
13 def set_data_dir(proj_data_dir):
13 def set_data_dir(proj_data_dir: str) -> None:
1414 """
1515 Set the data directory for PROJ to use.
1616
3232 pyproj_global_context_initialize()
3333
3434
35 def append_data_dir(proj_data_dir):
35 def append_data_dir(proj_data_dir: str) -> None:
3636 """
3737 Add an additional data directory for PROJ to use.
3838
4444 set_data_dir(os.pathsep.join([get_data_dir(), proj_data_dir]))
4545
4646
47 def get_data_dir():
47 def get_data_dir() -> str:
4848 """
4949 The order of preference for the data directory is:
5050
5656
5757 Returns
5858 -------
59 str: The valid data directory.
59 str:
60 The valid data directory.
6061
6162 """
6263 # to avoid re-validating
8384 for proj_data_dir in potential_data_dirs.split(os.pathsep):
8485 if valid_data_dir(proj_data_dir):
8586 return True
86 break
8787 return None
8888
8989 if valid_data_dirs(_USER_PROJ_DATA):
88
99 internal_proj_error = None
1010
11 def __init__(self, error_message):
11 def __init__(self, error_message: str) -> None:
1212 if self.internal_proj_error is not None:
1313 error_message = (
1414 "{error_message}: (Internal Proj Error: {internal_proj_error})"
2020 super().__init__(error_message)
2121
2222 @staticmethod
23 def clear():
23 def clear() -> None:
2424 """
2525 This will clear the internal PROJ erro message.
2626 """
3131 __all__ = ["Geod", "pj_ellps", "geodesic_version_str"]
3232
3333 import math
34 from typing import Any, Dict, List, Optional, Tuple, Union
3435
3536 from pyproj._geod import Geod as _Geod
3637 from pyproj._geod import geodesic_version_str
4445 class Geod(_Geod):
4546 """
4647 performs forward and inverse geodetic, or Great Circle,
47 computations. The forward computation (using the 'fwd' method)
48 involves determining latitude, longitude and back azimuth of a
4948 computations. The forward computation (using the 'fwd' method)
5049 involves determining latitude, longitude and back azimuth of a
5150 terminus point given the latitude and longitude of an initial
7170
7271 """
7372
74 def __init__(self, initstring=None, **kwargs):
73 def __init__(self, initstring: Optional[str] = None, **kwargs) -> None:
7574 """
7675 initialize a Geod class instance.
7776
128127 """
129128 # if initparams is a proj-type init string,
130129 # convert to dict.
131 ellpsd = {}
130 ellpsd = {} # type: Dict[str, Union[str, float]]
132131 if initstring is not None:
133132 for kvpair in initstring.split():
134133 # Actually only +a and +b are needed
138137 k, v = kvpair.split("=")
139138 k = k.lstrip("+")
140139 if k in ["a", "b", "rf", "f", "es", "e"]:
141 v = float(v)
142 ellpsd[k] = v
140 ellpsd[k] = float(v)
141 else:
142 ellpsd[k] = v
143143 # merge this dict with kwargs dict.
144144 kwargs = dict(list(kwargs.items()) + list(ellpsd.items()))
145145 sphere = False
146146 if "ellps" in kwargs:
147147 # ellipse name given, look up in pj_ellps dict
148148 ellps_dict = pj_ellps[kwargs["ellps"]]
149 a = ellps_dict["a"]
149 a = ellps_dict["a"] # type: float
150150 if ellps_dict["description"] == "Normal Sphere":
151151 sphere = True
152152 if "b" in ellps_dict:
153 b = ellps_dict["b"]
154 es = 1.0 - (b * b) / (a * a)
155 f = (a - b) / a
153 b = ellps_dict["b"] # type: float
154 es = 1.0 - (b * b) / (a * a) # type: float
155 f = (a - b) / a # type: float
156156 elif "rf" in ellps_dict:
157157 f = 1.0 / ellps_dict["rf"]
158158 b = a * (1.0 - f)
196196
197197 super().__init__(a, f, sphere, b, es)
198198
199 def fwd(self, lons, lats, az, dist, radians=False):
200 """
201 forward transformation - Returns longitudes, latitudes and back
202 azimuths of terminus points given longitudes (lons) and
203 latitudes (lats) of initial points, plus forward azimuths (az)
204 and distances (dist).
205 latitudes (lats) of initial points, plus forward azimuths (az)
206 and distances (dist).
207
208 Works with numpy and regular python array objects, python
209 sequences and scalars.
210
211 if radians=True, lons/lats and azimuths are radians instead of
212 degrees. Distances are in meters.
199 def fwd(
200 self, lons: Any, lats: Any, az: Any, dist: Any, radians=False
201 ) -> Tuple[Any, Any, Any]:
202 """
203 Forward transformation
204
205 Determine longitudes, latitudes and back azimuths of terminus
206 points given longitudes and latitudes of initial points,
207 plus forward azimuths and distances.
208
209 Parameters
210 ----------
211 lons: array, :class:`numpy.ndarray`, list, tuple, or scalar
212 Longitude(s) of initial point(s)
213 lats: array, :class:`numpy.ndarray`, list, tuple, or scalar
214 Latitude(s) of initial point(s)
215 az: array, :class:`numpy.ndarray`, list, tuple, or scalar
216 Forward azimuth(s)
217 dist: array, :class:`numpy.ndarray`, list, tuple, or scalar
218 Distance(s) between initial and terminus point(s)
219 in meters
220 radians: bool, optional
221 If True, the input data is assumed to be in radians.
222
223 Returns
224 -------
225 array, :class:`numpy.ndarray`, list, tuple, or scalar:
226 Longitude(s) of terminus point(s)
227 array, :class:`numpy.ndarray`, list, tuple, or scalar:
228 Latitude(s) of terminus point(s)
229 array, :class:`numpy.ndarray`, list, tuple, or scalar:
230 Back azimuth(s)
213231 """
214232 # process inputs, making copies that support buffer API.
215233 inx, xisfloat, xislist, xistuple = _copytobuffer(lons)
223241 outz = _convertback(zisfloat, zislist, zistuple, inz)
224242 return outx, outy, outz
225243
226 def inv(self, lons1, lats1, lons2, lats2, radians=False):
227 """
228 inverse transformation - Returns forward and back azimuths, plus
229 distances between initial points (specified by lons1, lats1) and
230 terminus points (specified by lons2, lats2).
231
232 Works with numpy and regular python array objects, python
233 sequences and scalars.
234
235 if radians=True, lons/lats and azimuths are radians instead of
236 degrees. Distances are in meters.
244 def inv(
245 self, lons1: Any, lats1: Any, lons2: Any, lats2: Any, radians=False
246 ) -> Tuple[Any, Any, Any]:
247 """
248 Inverse transformation
249
250 Determine forward and back azimuths, plus distances
251 between initial points and terminus points.
252
253 Parameters
254 ----------
255 lons1: array, :class:`numpy.ndarray`, list, tuple, or scalar
256 Longitude(s) of initial point(s)
257 lats1: array, :class:`numpy.ndarray`, list, tuple, or scalar
258 Latitude(s) of initial point(s)
259 lons2: array, :class:`numpy.ndarray`, list, tuple, or scalar
260 Longitude(s) of terminus point(s)
261 lats2: array, :class:`numpy.ndarray`, list, tuple, or scalar
262 Latitude(s) of terminus point(s)
263 radians: bool, optional
264 If True, the input data is assumed to be in radians.
265
266 Returns
267 -------
268 array, :class:`numpy.ndarray`, list, tuple, or scalar:
269 Forward azimuth(s)
270 array, :class:`numpy.ndarray`, list, tuple, or scalar:
271 Back azimuth(s)
272 array, :class:`numpy.ndarray`, list, tuple, or scalar:
273 Distance(s) between initial and terminus point(s)
274 in meters
237275 """
238276 # process inputs, making copies that support buffer API.
239277 inx, xisfloat, xislist, xistuple = _copytobuffer(lons1)
247285 outz = _convertback(zisfloat, zislist, zistuple, inz)
248286 return outx, outy, outz
249287
250 def npts(self, lon1, lat1, lon2, lat2, npts, radians=False):
251 """
252 Given a single initial point and terminus point (specified by
253 python floats lon1,lat1 and lon2,lat2), returns a list of
254 longitude/latitude pairs describing npts equally spaced
255 intermediate points along the geodesic between the initial and
256 terminus points.
257
258 if radians=True, lons/lats are radians instead of degrees.
288 def npts(
289 self,
290 lon1: float,
291 lat1: float,
292 lon2: float,
293 lat2: float,
294 npts: int,
295 radians: bool = False,
296 ) -> List:
297 """
298 Given a single initial point and terminus point, returns
299 a list of longitude/latitude pairs describing npts equally
300 spaced intermediate points along the geodesic between the
301 initial and terminus points.
259302
260303 Example usage:
261304
300343 '47.136 -109.100'
301344 '46.805 -114.051'
302345 '46.262 -118.924'
346
347 Parameters
348 ----------
349 lon1: float
350 Longitude of the initial point
351 lat1: float
352 Latitude of the initial point
353 lon2: float
354 Longitude of the terminus point
355 lat2: float
356 Latitude of the terminus point
357 npts: int
358 Number of points to be returned
359 radians: bool, optional
360 If True, the input data is assumed to be in radians.
361
362 Returns
363 -------
364 list of tuples:
365 list of (lon, lat) points along the geodesic
366 between the initial and terminus points.
303367 """
304368 lons, lats = super()._npts(lon1, lat1, lon2, lat2, npts, radians=radians)
305369 return list(zip(lons, lats))
306370
307 def line_length(self, lons, lats, radians=False):
371 def line_length(self, lons: Any, lats: Any, radians: bool = False) -> float:
308372 """
309373 .. versionadded:: 2.3.0
310374
332396
333397 Returns
334398 -------
335 float: The total length of the line.
399 float:
400 The total length of the line.
336401 """
337402 # process inputs, making copies that support buffer API.
338403 inx, xisfloat, xislist, xistuple = _copytobuffer(lons)
339404 iny, yisfloat, yislist, yistuple = _copytobuffer(lats)
340405 return self._line_length(inx, iny, radians=radians)
341406
342 def line_lengths(self, lons, lats, radians=False):
407 def line_lengths(self, lons: Any, lats: Any, radians: bool = False) -> Any:
343408 """
344409 .. versionadded:: 2.3.0
345410
375440 line_lengths = _convertback(xisfloat, xislist, xistuple, inx)
376441 return line_lengths if xisfloat else line_lengths[:-1]
377442
378 def polygon_area_perimeter(self, lons, lats, radians=False):
443 def polygon_area_perimeter(
444 self, lons: Any, lats: Any, radians: bool = False
445 ) -> Tuple[float, float]:
379446 """
380447 .. versionadded:: 2.3.0
381448
421488 _copytobuffer(lons)[0], _copytobuffer(lats)[0], radians=radians
422489 )
423490
424 def geometry_length(self, geometry, radians=False):
491 def geometry_length(self, geometry, radians: bool = False) -> float:
425492 """
426493 .. versionadded:: 2.3.0
427494
450517
451518 Returns
452519 -------
453 float: The total geodesic length of the geometry (meters).
454
520 float:
521 The total geodesic length of the geometry (meters).
455522 """
456523 try:
457 return self.line_length(*geometry.xy, radians=radians)
524 return self.line_length(*geometry.xy, radians=radians) # type: ignore
458525 except (AttributeError, NotImplementedError):
459526 pass
460527 if hasattr(geometry, "exterior"):
466533 return total_length
467534 raise GeodError("Invalid geometry provided.")
468535
469 def geometry_area_perimeter(self, geometry, radians=False):
536 def geometry_area_perimeter(
537 self, geometry, radians: bool = False
538 ) -> Tuple[float, float]:
470539 """
471540 .. versionadded:: 2.3.0
472541
511580 radians: bool, optional
512581 If True, the input data is assumed to be in radians.
513582
514 Returns
583 Returns
515584 -------
516585 (float, float):
517586 The geodesic area (meters^2) and permimeter (meters) of the polygon.
518587 """
519588 try:
520 return self.polygon_area_perimeter(*geometry.xy, radians=radians)
589 return self.polygon_area_perimeter( # type: ignore
590 *geometry.xy, radians=radians,
591 )
521592 except (AttributeError, NotImplementedError):
522593 pass
523594 # polygon
541612 return total_area, total_perimeter
542613 raise GeodError("Invalid geometry provided.")
543614
544 def __repr__(self):
615 def __repr__(self) -> str:
545616 # search for ellipse name
546617 for (ellps, vals) in pj_ellps.items():
547618 if self.a == vals["a"]:
557628 # no ellipse name found, call super class
558629 return super().__repr__()
559630
560 def __eq__(self, other):
631 def __eq__(self, other: Any) -> bool:
561632 """
562633 equality operator == for Geod objects
563634
433433 PROJ_GRID_AVAILABILITY_USED_FOR_SORTING
434434 PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID
435435 PROJ_GRID_AVAILABILITY_IGNORED
436
437 ctypedef struct PJ_FACTORS:
438 double meridional_scale
439 double parallel_scale
440 double areal_scale
441 double angular_distortion
442 double meridian_parallel_angle
443 double meridian_convergence
444 double tissot_semimajor
445 double tissot_semiminor
446 double dx_dlam
447 double dx_dphi
448 double dy_dlam
449 double dy_dphi
450
451 PJ_FACTORS proj_factors(PJ *P, PJ_COORD lp) nogil
3535 CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """
3636 import re
3737 import warnings
38
39 from pyproj import _proj
38 from typing import Any, Optional, Tuple, Type
39
4040 from pyproj._list import get_proj_operations_map
41 from pyproj._proj import Factors, _Proj, proj_version_str # noqa: F401
4142 from pyproj.compat import cstrencode, pystrdecode
4243 from pyproj.crs import CRS
4344 from pyproj.utils import _convertback, _copytobuffer
4445
45 # import numpy as np
46 proj_version_str = _proj.proj_version_str
47
4846 pj_list = get_proj_operations_map()
4947
5048
51 class Proj(_proj.Proj):
49 class Proj(_Proj):
5250 """
5351 Performs cartographic transformations (converts from
5452 longitude,latitude to native map projection x,y coordinates and
8482
8583 """
8684
87 def __init__(self, projparams=None, preserve_units=True, **kwargs):
85 def __init__(
86 self, projparams: Any = None, preserve_units: bool = True, **kwargs
87 ) -> None:
8888 """
8989 initialize a Proj class instance.
9090
9494 Parameters
9595 ----------
9696 projparams: int, str, dict, pyproj.CRS
97 A PROJ or WKT string, PROJ dict, EPSG integer, or a pyproj.CRS instnace.
97 A PROJ or WKT string, PROJ dict, EPSG integer, or a pyproj.CRS instance.
9898 preserve_units: bool
9999 If false, will ensure +units=m.
100100 **kwargs:
142142 >>> '{:.3f} {:.3f}'.format(x2, y2)
143143 '116.366 39.867'
144144 """
145 self.crs = CRS.from_user_input(projparams if projparams is not None else kwargs)
145 self.crs = CRS.from_user_input(projparams, **kwargs)
146146 # make sure units are meters if preserve_units is False.
147147 if not preserve_units and "foot" in self.crs.axis_info[0].unit_name:
148148 # ignore export to PROJ string deprecation warning
169169 projstring = re.sub(r"\s\+?type=crs", "", projstring)
170170 super().__init__(cstrencode(projstring.strip()))
171171
172 def __call__(self, *args, **kw):
172 def __call__(self, *args, **kw) -> Tuple[Any, Any]:
173173 # ,lon,lat,inverse=False,errcheck=False):
174174 """
175175 Calling a Proj class instance with the arguments lon, lat will
203203 outy = _convertback(yisfloat, yislist, xistuple, iny)
204204 return outx, outy
205205
206 def definition_string(self):
206 def get_factors(
207 self,
208 longitude: Any,
209 latitude: Any,
210 radians: bool = False,
211 errcheck: bool = False,
212 ) -> Factors:
213 """
214 .. versionadded:: 2.6.0
215
216 Calculate various cartographic properties, such as scale factors, angular
217 distortion and meridian convergence. Depending on the underlying projection
218 values will be calculated either numerically (default) or analytically.
219
220 The function also calculates the partial derivatives of the given
221 coordinate.
222
223 Parameters
224 ----------
225 longitude: scalar or array (numpy or python)
226 Input longitude coordinate(s).
227 latitude: scalar or array (numpy or python)
228 Input latitude coordinate(s).
229 radians: boolean, optional
230 If True, will expect input data to be in radians.
231 Default is False (degrees).
232 errcheck: boolean, optional (default False)
233 If True an exception is raised if the errors are found in the process.
234 By default errcheck=False and ``inf`` is returned.
235
236 Returns
237 -------
238 Factors
239 """
240 # process inputs, making copies that support buffer API.
241 inx, xisfloat, xislist, xistuple = _copytobuffer(longitude)
242 iny, yisfloat, yislist, yistuple = _copytobuffer(latitude)
243
244 # calculate the factors
245 factors = self._get_factors(inx, iny, radians=radians, errcheck=errcheck)
246
247 # if inputs were lists, tuples or floats, convert back.
248 return Factors(
249 meridional_scale=_convertback(
250 xisfloat, xislist, xistuple, factors.meridional_scale
251 ),
252 parallel_scale=_convertback(
253 xisfloat, xislist, xistuple, factors.parallel_scale
254 ),
255 areal_scale=_convertback(xisfloat, xislist, xistuple, factors.areal_scale),
256 angular_distortion=_convertback(
257 xisfloat, xislist, xistuple, factors.angular_distortion
258 ),
259 meridian_parallel_angle=_convertback(
260 xisfloat, xislist, xistuple, factors.meridian_parallel_angle
261 ),
262 meridian_convergence=_convertback(
263 xisfloat, xislist, xistuple, factors.meridian_convergence
264 ),
265 tissot_semimajor=_convertback(
266 xisfloat, xislist, xistuple, factors.tissot_semimajor
267 ),
268 tissot_semiminor=_convertback(
269 xisfloat, xislist, xistuple, factors.tissot_semiminor
270 ),
271 dx_dlam=_convertback(xisfloat, xislist, xistuple, factors.dx_dlam),
272 dx_dphi=_convertback(xisfloat, xislist, xistuple, factors.dx_dphi),
273 dy_dlam=_convertback(xisfloat, xislist, xistuple, factors.dy_dlam),
274 dy_dphi=_convertback(xisfloat, xislist, xistuple, factors.dy_dphi),
275 )
276
277 def definition_string(self) -> str:
207278 """Returns formal definition string for projection
208279
209280 >>> Proj("epsg:4326").definition_string()
210281 'proj=longlat datum=WGS84 no_defs ellps=WGS84 towgs84=0,0,0'
211 >>>
212282 """
213283 return pystrdecode(self.definition)
214284
215 def to_latlong_def(self):
285 def to_latlong_def(self) -> Optional[str]:
216286 """return the definition string of the geographic (lat/lon)
217287 coordinate version of the current projection"""
218 return self.crs.geodetic_crs.to_proj4(4)
219
220 def to_latlong(self):
288 return self.crs.geodetic_crs.to_proj4(4) if self.crs.geodetic_crs else None
289
290 def to_latlong(self) -> "Proj":
221291 """return a new Proj instance which is the geographic (lat/lon)
222292 coordinate version of the current projection"""
223293 return Proj(self.crs.geodetic_crs)
224294
225 def __reduce__(self):
295 def __reduce__(self) -> Tuple[Type["Proj"], Tuple[str]]:
226296 """special method that allows pyproj.Proj instance to be pickled"""
227297 return self.__class__, (self.crs.srs,)
228298
229 def __repr__(self):
299 def __repr__(self) -> str:
230300 return "Proj('{srs}', preserve_units=True)".format(srs=self.srs)
231301
232 def __eq__(self, other):
302 def __eq__(self, other: Any) -> bool:
233303 if not isinstance(other, Proj):
234304 return False
235305 return self._is_equivalent(other)
2323 "TransformerGroup",
2424 "AreaOfInterest",
2525 ]
26
2726 from array import array
2827 from itertools import chain, islice
28 from typing import Any, Iterable, Iterator, List, Optional, Tuple, Union
2929
3030 from pyproj import CRS, Proj
31 from pyproj._crs import AreaOfUse, CoordinateOperation
3132 from pyproj._transformer import AreaOfInterest, _Transformer, _TransformerGroup # noqa
3233 from pyproj.compat import cstrencode
3334 from pyproj.enums import TransformDirection, WktVersion
5354
5455 def __init__(
5556 self,
56 crs_from,
57 crs_to,
58 skip_equivalent=False,
59 always_xy=False,
60 area_of_interest=None,
61 ):
57 crs_from: Any,
58 crs_to: Any,
59 skip_equivalent: bool = False,
60 always_xy: bool = False,
61 area_of_interest: Optional[AreaOfInterest] = None,
62 ) -> None:
6263 """Get all possible transformations from a :obj:`pyproj.crs.CRS`
6364 or input used to create one.
6465
103104 self._transformers[iii] = Transformer(transformer)
104105
105106 @property
106 def transformers(self):
107 def transformers(self) -> List["Transformer"]:
107108 """
108109 list[:obj:`Transformer`]:
109110 List of available :obj:`Transformer`
112113 return self._transformers
113114
114115 @property
115 def unavailable_operations(self):
116 def unavailable_operations(self) -> List[CoordinateOperation]:
116117 """
117118 list[:obj:`pyproj.crs.CoordinateOperation`]:
118119 List of :obj:`pyproj.crs.CoordinateOperation` that are not
121122 return self._unavailable_operations
122123
123124 @property
124 def best_available(self):
125 def best_available(self) -> bool:
125126 """
126127 bool: If True, the best possible transformer is available.
127128 """
128129 return self._best_available
129130
130 def __repr__(self):
131 def __repr__(self) -> str:
131132 return (
132133 "<TransformerGroup: best_available={best_available}>\n"
133134 "- transformers: {transformers}\n"
151152
152153 """
153154
154 def __init__(self, base_transformer=None):
155 def __init__(self, base_transformer: Optional[_Transformer] = None) -> None:
155156 if not isinstance(base_transformer, _Transformer):
156157 ProjError.clear()
157158 raise ProjError(
161162 self._transformer = base_transformer
162163
163164 @property
164 def name(self):
165 def name(self) -> str:
165166 """
166167 str: Name of the projection.
167168 """
168169 return self._transformer.id
169170
170171 @property
171 def description(self):
172 def description(self) -> str:
172173 """
173174 str: Description of the projection.
174175 """
175176 return self._transformer.description
176177
177178 @property
178 def definition(self):
179 def definition(self) -> str:
179180 """
180181 str: Definition of the projection.
181182 """
182183 return self._transformer.definition
183184
184185 @property
185 def has_inverse(self):
186 def has_inverse(self) -> bool:
186187 """
187188 bool: True if an inverse mapping exists.
188189 """
189190 return self._transformer.has_inverse
190191
191192 @property
192 def accuracy(self):
193 def accuracy(self) -> float:
193194 """
194195 float: Expected accuracy of the transformation. -1 if unknown.
195196 """
196197 return self._transformer.accuracy
197198
198199 @property
199 def area_of_use(self):
200 def area_of_use(self) -> AreaOfUse:
200201 """
201202 .. versionadded:: 2.3.0
202203
203204 Returns
204205 -------
205 AreaOfUse: The area of use object with associated attributes.
206 AreaOfUse:
207 The area of use object with associated attributes.
206208 """
207209 return self._transformer.area_of_use
208210
209211 @property
210 def remarks(self):
212 def remarks(self) -> str:
211213 """
212214 .. versionadded:: 2.4.0
213215
214 str: Remarks about object.
216 Returns
217 -------
218 str:
219 Remarks about object.
215220 """
216221 return self._transformer.remarks
217222
218223 @property
219 def scope(self):
224 def scope(self) -> str:
220225 """
221226 .. versionadded:: 2.4.0
222227
223 str: Scope of object.
228 Returns
229 -------
230 str:
231 Scope of object.
224232 """
225233 return self._transformer.scope
226234
227235 @property
228 def operations(self):
236 def operations(self) -> Optional[Tuple[CoordinateOperation]]:
229237 """
230238 .. versionadded:: 2.4.0
231239
232 tuple[CoordinateOperation]: The operations in a concatenated operation.
240 Returns
241 -------
242 Tuple[CoordinateOperation]:
243 The operations in a concatenated operation.
233244 """
234245 return self._transformer.operations
235246
236247 @staticmethod
237248 def from_proj(
238 proj_from,
239 proj_to,
240 skip_equivalent=False,
241 always_xy=False,
242 area_of_interest=None,
243 ):
249 proj_from: Any,
250 proj_to: Any,
251 skip_equivalent: bool = False,
252 always_xy: bool = False,
253 area_of_interest: Optional[AreaOfInterest] = None,
254 ) -> "Transformer":
244255 """Make a Transformer from a :obj:`pyproj.proj.Proj` or input used to create one.
245256
246257 .. versionadded:: 2.1.2 skip_equivalent
266277
267278 Returns
268279 -------
269 :obj:`Transformer`
280 Transformer
270281
271282 """
272283 if not isinstance(proj_from, Proj):
284295
285296 @staticmethod
286297 def from_crs(
287 crs_from, crs_to, skip_equivalent=False, always_xy=False, area_of_interest=None
288 ):
298 crs_from: Any,
299 crs_to: Any,
300 skip_equivalent: bool = False,
301 always_xy: bool = False,
302 area_of_interest: Optional[AreaOfInterest] = None,
303 ) -> "Transformer":
289304 """Make a Transformer from a :obj:`pyproj.crs.CRS` or input used to create one.
290305
291306 .. versionadded:: 2.1.2 skip_equivalent
311326
312327 Returns
313328 -------
314 :obj:`Transformer`
329 Transformer
315330
316331 """
317332 return Transformer(
325340 )
326341
327342 @staticmethod
328 def from_pipeline(proj_pipeline):
343 def from_pipeline(proj_pipeline: str) -> "Transformer":
329344 """Make a Transformer from a PROJ pipeline string.
330345
331346 https://proj.org/operations/pipeline.html
344359
345360 def transform(
346361 self,
347 xx,
348 yy,
349 zz=None,
350 tt=None,
351 radians=False,
352 errcheck=False,
353 direction=TransformDirection.FORWARD,
354 ):
362 xx: Any,
363 yy: Any,
364 zz: Any = None,
365 tt: Any = None,
366 radians: bool = False,
367 errcheck: bool = False,
368 direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
369 ) -> Any:
355370 """
356371 Transform points between two coordinate systems.
357372
395410 >>> pipe_trans = Transformer.from_pipeline(pipeline_str)
396411 >>> xt, yt = pipe_trans.transform(2.1, 0.001)
397412 >>> "%.3f %.3f" % (xt, yt)
398 '120.321 0.057'
413 '2.100 0.001'
399414 >>> transproj = Transformer.from_crs(
400415 ... {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
401416 ... "EPSG:4326",
449464 outy = _convertback(yisfloat, yislist, xistuple, iny)
450465 return_data = (outx, outy)
451466 if inz is not None:
452 return_data += (_convertback(zisfloat, zislist, zistuple, inz),)
467 return_data += ( # type: ignore
468 _convertback(zisfloat, zislist, zistuple, inz),
469 )
453470 if intime is not None:
454 return_data += (_convertback(tisfloat, tislist, tistuple, intime),)
471 return_data += ( # type: ignore
472 _convertback(tisfloat, tislist, tistuple, intime),
473 )
455474 return return_data
456475
457476 def itransform(
458477 self,
459 points,
460 switch=False,
461 time_3rd=False,
462 radians=False,
463 errcheck=False,
464 direction=TransformDirection.FORWARD,
465 ):
478 points: Any,
479 switch: bool = False,
480 time_3rd: bool = False,
481 radians: bool = False,
482 errcheck: bool = False,
483 direction: Union[TransformDirection, str] = TransformDirection.FORWARD,
484 ) -> Iterator[Iterable]:
466485 """
467486 Iterator/generator version of the function pyproj.Transformer.transform.
468487
507526 >>> pipe_trans = Transformer.from_pipeline(pipeline_str)
508527 >>> for pt in pipe_trans.itransform([(2.1, 0.001)]):
509528 ... '{:.3f} {:.3f}'.format(*pt)
510 '120.321 0.057'
529 '2.100 0.001'
511530 >>> transproj = Transformer.from_crs(
512531 ... {"proj":'geocent', "ellps":'WGS84', "datum":'WGS84'},
513532 ... "EPSG:4326",
579598 for pt in zip(*([iter(buff)] * stride)):
580599 yield pt
581600
582 def to_wkt(self, version=WktVersion.WKT2_2019, pretty=False):
601 def to_wkt(
602 self,
603 version: Union[WktVersion, str] = WktVersion.WKT2_2019,
604 pretty: bool = False,
605 ):
583606 """
584607 Convert the projection to a WKT string.
585608
602625
603626 Returns
604627 -------
605 str: The WKT string.
628 str:
629 The WKT string.
606630 """
607631 return self._transformer.to_wkt(version=version, pretty=pretty)
608632
609 def to_json(self, pretty=False, indentation=2):
633 def to_json(self, pretty: bool = False, indentation: int = 2) -> str:
610634 """
611635 Convert the projection to a JSON string.
612636
621645
622646 Returns
623647 -------
624 str: The JSON string.
648 str:
649 The JSON string.
625650 """
626651 return self._transformer.to_json(pretty=pretty, indentation=indentation)
627652
628 def to_json_dict(self):
653 def to_json_dict(self) -> dict:
629654 """
630655 Convert the projection to a JSON dictionary.
631656
633658
634659 Returns
635660 -------
636 dict: The JSON dictionary.
661 dict:
662 The JSON dictionary.
637663 """
638664 return self._transformer.to_json_dict()
639665
640 def __str__(self):
666 def __str__(self) -> str:
641667 return self.definition
642668
643 def __repr__(self):
669 def __repr__(self) -> str:
644670 return (
645671 "<{type_name}: {name}>\nDescription: {description}\n"
646672 "Area of Use:\n{area_of_use}"
651677 area_of_use=self.area_of_use or "- undefined",
652678 )
653679
680 def __eq__(self, other: Any) -> bool:
681 if not isinstance(other, Transformer):
682 return False
683 return self._transformer.__eq__(other._transformer)
684
654685
655686 def transform(
656 p1,
657 p2,
658 x,
659 y,
660 z=None,
661 tt=None,
662 radians=False,
663 errcheck=False,
664 skip_equivalent=False,
665 always_xy=False,
687 p1: Any,
688 p2: Any,
689 x: Any,
690 y: Any,
691 z: Any = None,
692 tt: Any = None,
693 radians: bool = False,
694 errcheck: bool = False,
695 skip_equivalent: bool = False,
696 always_xy: bool = False,
666697 ):
667698 """
668699 .. versionadded:: 2.1.2 skip_equivalent
743774
744775
745776 def itransform(
746 p1,
747 p2,
748 points,
749 switch=False,
750 time_3rd=False,
751 radians=False,
752 errcheck=False,
753 skip_equivalent=False,
754 always_xy=False,
777 p1: Any,
778 p2: Any,
779 points: Iterable[Iterable],
780 switch: bool = False,
781 time_3rd: bool = False,
782 radians: bool = False,
783 errcheck: bool = False,
784 skip_equivalent: bool = False,
785 always_xy: bool = False,
755786 ):
756787 """
757788 .. versionadded:: 2.1.2 skip_equivalent
00 from array import array
1 from typing import Any, Tuple
12
23
3 def _copytobuffer_return_scalar(x):
4 def _copytobuffer_return_scalar(xx: Any) -> Tuple[array, bool, bool, bool]:
5 """
6 Parameters
7 -----------
8 xx: float or 0-d numpy array
9 """
410 try:
511 # inx,isfloat,islist,istuple
6 return array("d", (float(x),)), True, False, False
12 return array("d", (float(xx),)), True, False, False
713 except Exception:
8 raise TypeError("input must be an array, list, tuple or scalar")
14 raise TypeError("input must be a scalar")
915
1016
11 def _copytobuffer(x):
17 def _copytobuffer(xx: Any) -> Tuple[Any, bool, bool, bool]:
1218 """
13 return a copy of x as an object that supports the python Buffer
19 return a copy of xx as an object that supports the python Buffer
1420 API (python array if input is float, list or tuple, numpy array
1521 if input is a numpy array). returns copyofx, isfloat, islist,
1622 istuple (islist is True if input is a list, istuple is true if
2228 istuple = False
2329 # first, if it's a numpy array scalar convert to float
2430 # (array scalars don't support buffer API)
25 if hasattr(x, "shape"):
26 if x.shape == ():
27 return _copytobuffer_return_scalar(x)
31 if hasattr(xx, "shape"):
32 if xx.shape == ():
33 return _copytobuffer_return_scalar(xx)
2834 else:
2935 try:
3036 # typecast numpy arrays to double.
3137 # (this makes a copy - which is crucial
3238 # since buffer is modified in place)
33 x.dtype.char
39 xx.dtype.char
3440 # Basemap issue
3541 # https://github.com/matplotlib/basemap/pull/223/files
3642 # (deal with input array in fortran order)
37 inx = x.copy(order="C").astype("d")
43 inx = xx.copy(order="C").astype("d")
3844 # inx,isfloat,islist,istuple
3945 return inx, False, False, False
4046 except Exception:
4147 try: # perhaps they are Numeric/numarrays?
4248 # sorry, not tested yet.
4349 # i don't know Numeric/numarrays has `shape'.
44 x.typecode()
45 inx = x.astype("d")
50 xx.typecode()
51 inx = xx.astype("d")
4652 # inx,isfloat,islist,istuple
4753 return inx, False, False, False
4854 except Exception:
4955 raise TypeError("input must be an array, list, tuple or scalar")
5056 else:
5157 # perhaps they are regular python arrays?
52 if hasattr(x, "typecode"):
53 # x.typecode
54 inx = array("d", x)
58 if hasattr(xx, "typecode"):
59 # xx.typecode
60 inx = array("d", xx)
5561 # try to convert to python array
5662 # a list.
57 elif type(x) == list:
58 inx = array("d", x)
63 elif type(xx) == list:
64 inx = array("d", xx)
5965 islist = True
6066 # a tuple.
61 elif type(x) == tuple:
62 inx = array("d", x)
67 elif type(xx) == tuple:
68 inx = array("d", xx)
6369 istuple = True
6470 # a scalar?
6571 else:
66 return _copytobuffer_return_scalar(x)
72 return _copytobuffer_return_scalar(xx)
6773 return inx, isfloat, islist, istuple
6874
6975
70 def _convertback(isfloat, islist, istuple, inx):
76 def _convertback(isfloat: bool, islist: bool, istuple: bool, inx: Any) -> Any:
7177 # if inputs were lists, tuples or floats, convert back to original type.
7278 if isfloat:
7379 return inx[0]
00 [build-system]
11 # Minimum requirements for the build system to execute.
2 requires = ["setuptools", "wheel", "cython>=0.28.4"]
2 requires = ["setuptools", "wheel", "cython>=0.28.4"]
11 black; python_version >= '3.6'
22 flake8
33 mock
4 mypy
45 numpy
56 pylint
67 pytest>3.6
78 pytest-cov
8 shapely; sys_platform != 'win32' # shapely wheels not on Windows
9 shapely; sys_platform != 'win32' # shapely wheels not on Windows
10 pre-commit
7474 epsg_init_crs.to_proj4()
7575 == "+proj=utm +zone=11 +datum=NAD83 +units=m +no_defs +type=crs"
7676 )
77
78
79 def test_initialize_projparams_with_kwargs():
80 crs_mixed_args = CRS("+proj=utm +zone=10", ellps="WGS84")
81 crs_positional = CRS("+proj=utm +zone=10 +ellps=WGS84")
82 assert crs_mixed_args.is_exact_same(crs_positional)
7783
7884
7985 def test_bare_parameters():
276282 )
277283
278284
285 def test_axis_info_compound():
286 assert [axis.direction for axis in CRS.from_epsg(3901).axis_info] == [
287 "north",
288 "east",
289 "up",
290 ]
291
292
279293 def test_dunder_str():
280294 with pytest.warns(FutureWarning):
281295 assert str(CRS({"init": "EPSG:4326"})) == CRS({"init": "EPSG:4326"}).srs
489503 crs = CRS.from_epsg(26915)
490504 assert repr(crs.coordinate_operation) == (
491505 "<Coordinate Operation: Conversion>\n"
492 "UTM zone 15N\n"
506 "Name: UTM zone 15N\n"
507 "Method: Transverse Mercator\n"
493508 "Area of Use:\n"
494509 "- name: World - N hemisphere - 96°W to 90°W\n"
495510 "- bounds: (-96.0, 0.0, -90.0, 84.0)"
792807 ]
793808
794809
810 def test_axis_info_bound():
811 crs = CRS(
812 "+proj=tmerc +lat_0=0 +lon_0=15 +k=0.9996 +x_0=2520000 +y_0=0 "
813 "+ellps=intl +towgs84=-122.74,-34.27,-22.83,-1.884,-3.400,-3.030,-15.62"
814 )
815 assert [axis.direction for axis in crs.axis_info] == ["east", "north"]
816
817
795818 def test_coordinate_operation_towgs84_missing():
796819 crs = CRS("epsg:3004")
797820 assert crs.coordinate_operation.towgs84 == []
12381261 def test_crs_equals__ignore_axis_order():
12391262 with pytest.warns(FutureWarning):
12401263 assert CRS("epsg:4326").equals("+init=epsg:4326", ignore_axis_order=True)
1264
1265
1266 @pytest.mark.parametrize(
1267 "crs_input",
1268 [
1269 "+proj=utm +zone=15",
1270 26915,
1271 "+proj=utm +zone=15 +towgs84=0,0,0",
1272 "EPSG:26915+5717",
1273 ],
1274 )
1275 def test_utm_zone(crs_input):
1276 assert CRS(crs_input).utm_zone == "15N"
1277
1278
1279 @pytest.mark.parametrize("crs_input", ["+proj=tmerc", "epsg:4326"])
1280 def test_utm_zone__none(crs_input):
1281 assert CRS(crs_input).utm_zone is None
22 import sys
33 import unittest
44
5 import numpy as np
56 import pytest
7 from numpy.testing import assert_almost_equal
68
79 from pyproj import Geod, Proj, pj_ellps, pj_list, transform
8 from pyproj.crs import CRSError
10 from pyproj.exceptions import CRSError, ProjError
911
1012
1113 class BasicTest(unittest.TestCase):
395397 assert proj.crs.srs == "proj=lonlat type=crs"
396398
397399
400 def test_initialize_projparams_with_kwargs():
401 proj_mixed_args = Proj("+proj=utm +zone=10", ellps="WGS84")
402 proj_positional = Proj("+proj=utm +zone=10 +ellps=WGS84")
403 assert proj_mixed_args.is_exact_same(proj_positional)
404
405
398406 def test_equals_different_type():
399407 assert Proj("epsg:4326") != ""
400408
411419 assert proj(0, 0, inverse=True, errcheck=True) == (0.0, -90.0)
412420
413421
414 if __name__ == "__main__":
415 unittest.main()
422 @pytest.mark.parametrize("radians", [False, True])
423 def test_get_factors__2d_input(radians):
424 transformer = Proj(3857)
425 longitude = np.array([[0, 1], [2, 3]])
426 latitude = np.array([[1, 2], [3, 4]])
427 if radians:
428 longitude = np.radians(longitude)
429 latitude = np.radians(latitude)
430 factors = transformer.get_factors(
431 longitude=longitude, latitude=latitude, radians=radians
432 )
433 assert_almost_equal(
434 factors.meridional_scale, [[1.0, 1.00015233], [1.00060954, 1.00137235]],
435 )
436 assert_almost_equal(
437 factors.parallel_scale, [[1.0, 1.00015233], [1.00060954, 1.00137235]],
438 )
439 assert_almost_equal(
440 factors.areal_scale, [[1.0, 1.00030468], [1.00121946, 1.00274658]],
441 )
442 assert_almost_equal(factors.angular_distortion, [[0, 0], [0, 0]], decimal=5)
443 assert_almost_equal(
444 factors.meridian_parallel_angle, [[90, 90], [90, 90]],
445 )
446 assert_almost_equal(factors.meridian_convergence, [[0, 0], [0, 0]])
447 assert_almost_equal(
448 factors.tissot_semimajor, [[1.0, 1.00015233], [1.00060955, 1.00137235]],
449 )
450 assert_almost_equal(
451 factors.tissot_semiminor, [[1.0, 1.00015233], [1.00060953, 1.00137235]],
452 )
453 assert_almost_equal(
454 factors.dx_dlam, [[1, 1], [1, 1]],
455 )
456 assert_almost_equal(factors.dx_dphi, [[0, 0], [0, 0]])
457 assert_almost_equal(factors.dy_dlam, [[0, 0], [0, 0]])
458 assert_almost_equal(
459 factors.dy_dphi, [[1.0, 1.00015233], [1.00060954, 1.00137235]],
460 )
461
462
463 def test_get_factors__nan_inf():
464 transformer = Proj(3857)
465 factors = transformer.get_factors(
466 longitude=[0, np.nan, np.inf, 0], latitude=[np.nan, 2, 2, np.inf]
467 )
468 assert_almost_equal(factors.meridional_scale, [1, np.inf, np.inf, 1])
469 assert_almost_equal(factors.parallel_scale, [1, np.inf, np.inf, 1])
470 assert_almost_equal(factors.areal_scale, [1, np.inf, np.inf, 1])
471 assert_almost_equal(factors.angular_distortion, [0, np.inf, np.inf, 0])
472 assert_almost_equal(factors.meridian_parallel_angle, [90, np.inf, np.inf, 90])
473 assert_almost_equal(factors.meridian_convergence, [0.0, np.inf, np.inf, 0.0])
474 assert_almost_equal(factors.tissot_semimajor, [1, np.inf, np.inf, 1])
475 assert_almost_equal(factors.tissot_semiminor, [1, np.inf, np.inf, 1])
476 assert_almost_equal(factors.dx_dlam, [1, np.inf, np.inf, 1])
477 assert_almost_equal(factors.dx_dphi, [0.0, np.inf, np.inf, 0.0])
478 assert_almost_equal(factors.dy_dlam, [0.0, np.inf, np.inf, 0.0])
479 assert_almost_equal(factors.dy_dphi, [1, np.inf, np.inf, 1])
480
481
482 def test_get_factors__errcheck():
483 transformer = Proj(3857)
484 with pytest.raises(ProjError):
485 transformer.get_factors(longitude=40, latitude=70, errcheck=True, radians=True)
486
487
488 def test_numpy_bool_kwarg():
489 # Issue 546
490 south = np.array(50) < 0
491 proj = Proj(
492 proj="utm", zone=32, ellipsis="WGS84", datum="WGS84", units="m", south=south
493 )
494 assert "south" not in proj.srs
584584 def test_transformer_group__area_of_interest__invalid(aoi_data_directory):
585585 with pytest.raises(ProjError):
586586 TransformerGroup(4326, 2964, area_of_interest=(-136.46, 49.0, -60.72, 83.17))
587
588
589 def test_transformer_equals():
590 assert Transformer.from_crs(28356, 7856) == Transformer.from_crs(28356, 7856)
591
592
593 @pytest.mark.parametrize(
594 "comparison",
595 [Transformer.from_pipeline("+proj=pipeline +ellps=GRS80 +step +proj=cart"), 22],
596 )
597 def test_transformer_not_equals(comparison):
598 assert Transformer.from_crs(28356, 7856) != comparison
599
600
601 @pytest.mark.parametrize(
602 "pipeline_str",
603 [
604 "+proj=pipeline +ellps=GRS80 +step +proj=cart",
605 "+proj=pipeline +step +proj=unitconvert +xy_in=deg "
606 "+xy_out=rad +ellps=GRS80 +step +proj=cart",
607 ],
608 )
609 def test_pipeline_transform(pipeline_str):
610 trans = Transformer.from_pipeline(pipeline_str)
611 assert_almost_equal(
612 trans.transform(50, 25, 0),
613 (3717892.6072086394, 4430811.87152035, 2679074.4628772778),
614 )
615
616
617 @pytest.mark.parametrize(
618 "pipeline_str",
619 [
620 "+proj=pipeline +ellps=GRS80 +step +proj=cart",
621 "+proj=pipeline +step +proj=unitconvert +xy_in=deg "
622 "+xy_out=rad +ellps=GRS80 +step +proj=cart",
623 ],
624 )
625 def test_pipeline_itransform(pipeline_str):
626 trans = Transformer.from_pipeline(pipeline_str)
627 assert_almost_equal(
628 list(trans.itransform([(50, 25, 0)])),
629 [(3717892.6072086394, 4430811.87152035, 2679074.4628772778)],
630 )
631
632
633 def test_pipeline_radian_transform_warning():
634 trans = Transformer.from_pipeline("+proj=pipeline +ellps=GRS80 +step +proj=cart")
635 with pytest.warns(UserWarning):
636 trans.transform(0.1, 0.1, 0, radians=True)
0 from array import array
1
2 import numpy
3 import pytest
4
5 from pyproj.utils import _copytobuffer, _copytobuffer_return_scalar
6
7
8 @pytest.mark.parametrize("in_data", [numpy.array(1), 1])
9 def test__copytobuffer_return_scalar(in_data):
10 assert _copytobuffer_return_scalar(in_data) == (array("d", [1]), True, False, False)
11
12
13 def test__copytobuffer_return_scalar__invalid():
14 with pytest.raises(TypeError):
15 _copytobuffer_return_scalar("invalid")
16
17
18 @pytest.mark.parametrize(
19 "in_data, is_float, is_list, is_tuple",
20 [
21 (numpy.array(1), True, False, False),
22 (1, True, False, False),
23 ([1], False, True, False),
24 ((1,), False, False, True),
25 ],
26 )
27 def test__copytobuffer(in_data, is_float, is_list, is_tuple):
28 assert _copytobuffer(in_data) == (array("d", [1]), is_float, is_list, is_tuple)
29
30
31 def test__copytobuffer__numpy_array():
32 in_arr = numpy.array([1])
33 assert _copytobuffer(in_arr) == (in_arr.astype("d"), False, False, False)
34
35
36 def test__copytobuffer__invalid():
37 with pytest.raises(TypeError):
38 _copytobuffer("invalid")