Skip to content
Commits on Source (3)
build/
nad2bin*
*.obj
*.o
*.pyc
pyproj/proj_dir/
pyproj/*.c
proj-*/
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
*.c*
!*.css
docs/doctrees/
.coverage
# Distribution / packaging
wheelhouse/
.Python
env/
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# dotenv
.env
# virtualenv
.venv
venv/
pyproj.egg-info/
pyproj/proj_dir/
pyproj/datadir.py.save
ENV/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
# pycharm
.idea/
# pytest
.pytest_cache/
# vscode
.vscode/
linters:
black:
flake8:
python: 3
max-line-length: 88
......@@ -6,34 +6,36 @@ cache: pip
env:
global:
- CYTHON_COVERAGE=True
- PROJSOURCE=6.0.0
- PROJSOURCE=6.1.0
# Following generated with
- WHEELHOUSE_UPLOADER_USERNAME=travis-worker
# Following generated by
# travis encrypt -r jswhit/pyproj WHEELHOUSE_UPLOADER_SECRET=<api key>
- secure: "IoTBjr6e/eBQWtGleP1X36SpocljQxsmJZ+EcVGhJ4v3GZaECLLklKtrWf8DyygFNPFIZ5Tri/C5rPTbuioG6gWtrL8QPgXOK9MI1QZqmfx/kNi0tmH0g9BxL0jlhP8SInZFsfO4m8qJkYJwh3DqBudQhmbDabnMbX2h7hKKTSA="
# Doctr deploy key for pyproj4/pyproj
- secure: "V9hQpdQmIOlk/Wvy0NIntlwSI1OvJ12cTrNPBIvwOy86kyPSk4qFj2YMixvcViM235iiCehN+Ray7FIeeHkPVZe9S+zFgVDxFf/RcgBt7tuhLrOoD1AH6pk9/h+z1owZYAboseLU05wv2+T+am0gCz40kES8As7v6bP+xsw69rw="
matrix:
include:
- language: cpp
os: osx
env:
- PYTHON=3.6
- PROJSOURCE=6.0.0
- PYTHON=3.6.8
- PROJSOURCE=6.1.0
- python: 2.7
env:
- PROJSOURCE=6.0.0
- PROJSOURCE=6.1.0
- python: 3.5
env:
- PROJSOURCE=6.0.0
- PROJSOURCE=6.1.0
- python: 3.6
env:
- PROJSOURCE=6.0.0
- PROJSOURCE=6.1.0
- python: 3.7
dist: xenial
sudo: true
env:
- PROJSOURCE=6.0.0
- PROJSOURCE=6.1.0
- DOC=true
- python: "nightly"
env:
- PROJSOURCE=git
......@@ -73,7 +75,7 @@ before_install:
install:
# coverage report requires a local install
- pip install "pip>=10.0.1"
- pip install "pip>=10.0.1,<19.1"
- PYPROJ_FULL_COVERAGE=YES pip install -e .
- pip install -r requirements-dev.txt
- pip install coveralls
......@@ -81,6 +83,19 @@ install:
script:
- python -c "import pyproj; pyproj.Proj(init='epsg:4269')"
- py.test --cov-report term-missing --cov=pyproj -v -s
# Building and uploading docs with doctr
- set -e
- |
if [ "$DOC" ]; then
bash create_docs.sh
pip install doctr
if [[ -z "$TRAVIS_TAG" ]]; then
DEPLOY_DIR=dev;
else
DEPLOY_DIR="$TRAVIS_TAG";
fi
doctr deploy --build-tags --built-docs docs/_build/html $DEPLOY_DIR
fi
after_success:
- coveralls
......
......@@ -7,15 +7,6 @@ include pyproj/*.pyd
include pyproj/*.pyx
include pyproj/*.pxd
include pyproj/*.pxi
include test/test.py
include test/test2.py
include test/sample.out
include test/datum_shift.py
include test/test_transform.py
include test/geodtest.py
include test/test_datum.py
recursive-include docs *
recursive-include unittest *
prune proj.4/*
prune pyproj/proj_dir
prune */__pycache__/
pyproj
======
# pyproj
Python interface to [PROJ](http://proj.org) (cartographic projections and coordinate transformations library).
[![Join the chat at https://gitter.im/pyproj4-pyproj/community](https://badges.gitter.im/pyproj4-pyproj/community.svg)](https://gitter.im/pyproj4-pyproj/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Build Status](https://travis-ci.org/pyproj4/pyproj.svg)](https://travis-ci.org/pyproj4/pyproj)
[![Build status](https://ci.appveyor.com/api/projects/status/8xkka4s97uwhkc64/branch/master?svg=true
)](https://ci.appveyor.com/project/jswhit/pyproj)
[![Coverage Status](https://coveralls.io/repos/github/pyproj4/pyproj/badge.svg?branch=master)](https://coveralls.io/github/pyproj4/pyproj?branch=master)
[![PyPI version](https://badge.fury.io/py/pyproj.svg)](https://badge.fury.io/py/pyproj)
[![Anaconda-Server Badge](https://anaconda.org/conda-forge/pyproj/badges/version.svg)](https://anaconda.org/conda-forge/pyproj)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.2592232.svg)](https://doi.org/10.5281/zenodo.2592232)
Python interface to [PROJ.4](https://github.com/OSGeo/proj.4).
## Documentation
[Installation](https://pyproj4.github.io/pyproj/html/installation.html)
------------
- Stable: http://pyproj4.github.io/pyproj
- Latest: https://pyproj4.github.io/pyproj/dev
[Documentation](http://pyproj4.github.io/pyproj)
-------------
## Bugs/Questions
Bugs/Questions
--------------
Report bugs/ask questions at https://github.com/pyproj4/pyproj/issues.
- Report bugs at: https://github.com/pyproj4/pyproj/issues
- Ask questions at: https://gitter.im/pyproj4-pyproj/community
\ No newline at end of file
......@@ -20,19 +20,19 @@ environment:
# PYTHON_ARCH: "64"
# VS_VERSION: Visual Studio 14
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# PROJSOURCE: 6.0.0
# PROJSOURCE: 6.1.0
- PYTHON: "C:\\Python36-x64"
PYTHON_VERSION: "3.6"
PYTHON_ARCH: "64"
VS_VERSION: Visual Studio 14
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
PROJSOURCE: 6.0.0
PROJSOURCE: 6.1.0
# - PYTHON: "C:\\Python37-x64"
# PYTHON_VERSION: "3.7"
# PYTHON_ARCH: "64"
# VS_VERSION: Visual Studio 14
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# PROJSOURCE: 6.0.0
# PROJSOURCE: 6.1.0
# - PYTHON: "C:\\Python36-x64"
# PYTHON_VERSION: "3.6"
# PYTHON_ARCH: "64"
......@@ -84,7 +84,7 @@ build_script:
- cd %APPVEYOR_BUILD_FOLDER%
- proj
# Build and install pyproj
- "%CMD_IN_ENV% pip install \"pip>=10.0.1\""
- "%CMD_IN_ENV% pip install \"pip>=10.0.1,<19.1\""
- set PYPROJ_FULL_COVERAGE=YES
- "%CMD_IN_ENV% pip install -e ."
- "%CMD_IN_ENV% pip install -r requirements-dev.txt"
......@@ -109,7 +109,7 @@ install:
# Upgrade to the latest version of pip to avoid it displaying warnings
# about it being out of date.
- "pip install --disable-pip-version-check --user --upgrade pip"
- "pip install --disable-pip-version-check --user --upgrade pip==19.0.3"
# install wheel, caching
- "%CMD_IN_ENV% pip install wheel"
......@@ -134,7 +134,7 @@ after_test:
# - "%CMD_IN_ENV% python setup.py bdist_wininst"
# - "%CMD_IN_ENV% python setup.py bdist_msi"
# test wheel
- pip install pyproj --ignore-installed --no-index -f dist
- pip install pyproj --ignore-installed -f dist
- python -c "import pyproj; pyproj.Proj(init='epsg:4269')"
# cleanup for test dir
- if %PROJSOURCE% == git del /F /Q dist\*
......
#!/bin/sh
pip install sphinx
cd sphinx && make html && cd ..
#!/bin/bash
pip install sphinx sphinx_rtd_theme
cd docs && make html && cd ..
python-pyproj (2.2.0+ds-1) UNRELEASED; urgency=medium
* New upstream release.
-- Bas Couwenberg <sebastic@debian.org> Sun, 02 Jun 2019 06:35:40 +0200
python-pyproj (2.1.3+ds-1~exp1) experimental; urgency=medium
* New upstream release.
......
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==
\ No newline at end of file
# -*- coding: utf-8 -*-
"""
Cython wrapper to provide python interfaces to
PROJ.4 (https://github.com/OSGeo/proj.4/wiki) functions.
PROJ (https://proj.org) functions.
Performs cartographic transformations and geodetic computations.
......@@ -47,7 +47,7 @@ CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. """
__version__ = "2.1.3"
__version__ = "2.2.0"
__all__ = [
"Proj",
"Geod",
......@@ -57,13 +57,26 @@ __all__ = [
"itransform",
"pj_ellps",
"pj_list",
"get_angular_units_map",
"get_ellps_map",
"get_prime_meridians_map",
"get_proj_operations_map",
"get_units_map",
]
from pyproj.crs import CRS
from pyproj.exceptions import ProjError
from pyproj.geod import Geod, geodesic_version_str, pj_ellps
from pyproj.proj import Proj, pj_list, proj_version_str
from pyproj.transformer import Transformer, itransform, transform
import sys
from pyproj._list import ( # noqa
get_angular_units_map,
get_ellps_map,
get_prime_meridians_map,
get_proj_operations_map,
get_units_map,
)
from pyproj.crs import CRS # noqa
from pyproj.exceptions import ProjError # noqa
from pyproj.geod import Geod, geodesic_version_str, pj_ellps # noqa
from pyproj.proj import Proj, pj_list, proj_version_str # noqa
from pyproj.transformer import Transformer, itransform, transform # noqa
def test(**kwargs):
......@@ -79,7 +92,9 @@ def test(**kwargs):
pyproj.transformer, verbose=verbose
)
return failure_count + failure_count_crs + failure_count_geod + failure_count_transform
return (
failure_count + failure_count_crs + failure_count_geod + failure_count_transform
)
if __name__ == "__main__":
......
include "proj.pxi"
cdef class AxisInfo:
cdef class Axis:
cdef public object name
cdef public object abbrev
cdef public object direction
......@@ -22,35 +22,103 @@ cdef class AreaOfUse:
@staticmethod
cdef create(PJ_CONTEXT* projcontext, PJ* projobj)
cdef class Ellipsoid:
cdef class Base:
cdef PJ *projobj
cdef PJ_CONTEXT *projctx
cdef public object name
cdef class Ellipsoid(Base):
cdef double _semi_major_metre
cdef double _semi_minor_metre
cdef public int is_semi_minor_computed
cdef public object is_semi_minor_computed
cdef double _inv_flattening
cdef public int ellipsoid_loaded
cdef public object ellipsoid_loaded
@staticmethod
cdef create(PJ_CONTEXT* projcontext, PJ* projobj)
cdef create(PJ* ellipsoid_pj)
cdef class PrimeMeridian:
cdef class PrimeMeridian(Base):
cdef public double longitude
cdef public double unit_conversion_factor
cdef public object unit_name
@staticmethod
cdef create(PJ_CONTEXT* projcontext, PJ* projobj)
cdef create(PJ* prime_meridian_pj)
cdef class Datum(Base):
cdef public object _ellipsoid
cdef public object _prime_meridian
@staticmethod
cdef create(PJ* datum_pj)
cdef class _CRS:
cdef PJ * projobj
cdef PJ_CONTEXT * projctx
cdef PJ_TYPE proj_type
cdef class CoordinateSystem(Base):
cdef public object _axis_list
@staticmethod
cdef create(PJ* coordinate_system_pj)
cdef class Param:
cdef public object name
cdef public object auth_name
cdef public object code
cdef public object value
cdef public double unit_conversion_factor
cdef public object unit_name
cdef public object unit_auth_name
cdef public object unit_code
cdef public object unit_category
@staticmethod
cdef create(PJ_CONTEXT* projcontext, PJ* projobj, int param_idx)
cdef class Grid:
cdef public object short_name
cdef public object full_name
cdef public object package_name
cdef public object url
cdef public object direct_download
cdef public object open_license
cdef public object available
@staticmethod
cdef create(PJ_CONTEXT* projcontext, PJ* projobj, int grid_idx)
cdef class CoordinateOperation(Base):
cdef public object _params
cdef public object _grids
cdef public object method_name
cdef public object method_auth_name
cdef public object method_code
cdef public double accuracy
cdef public object is_instantiable
cdef public object has_ballpark_transformation
cdef public object _towgs84
@staticmethod
cdef create(PJ* coordinate_operation_pj)
cdef class _CRS(Base):
cdef PJ_TYPE _type
cdef PJ_PROJ_INFO projpj_info
cdef public object proj_version
cdef char *pjinitstring
cdef public object name
cdef public object srs
cdef public object _ellipsoid
cdef public object _area_of_use
cdef public object _prime_meridian
cdef public object _axis_info
cdef public object type_name
cdef object _ellipsoid
cdef object _area_of_use
cdef object _prime_meridian
cdef object _datum
cdef object _sub_crs_list
cdef object _source_crs
cdef object _target_crs
cdef object _geodetic_crs
cdef object _coordinate_system
cdef object _coordinate_operation
\ No newline at end of file
This diff is collapsed.
......@@ -8,7 +8,7 @@ from pyproj.exceptions import ProjError
cdef void pyproj_log_function(void *user_data, int level, const char *error_msg):
"""
Log function for proj.4 errors with CRS class.
Log function for catching PROJ errors.
"""
if level == PJ_LOG_ERROR:
ProjError.internal_proj_error = pystrdecode(error_msg)
......
include "proj.pxi"
from collections import namedtuple
from pyproj.compat import pystrdecode
def get_proj_operations_map():
"""
Returns
-------
dict: operations supported by PROJ.
"""
cdef PJ_OPERATIONS *proj_operations = proj_list_operations()
cdef int iii = 0
operations_map = {}
while proj_operations[iii].id != NULL:
operations_map[pystrdecode(proj_operations[iii].id)] = \
pystrdecode(proj_operations[iii].descr[0]).split("\n\t")[0]
iii += 1
return operations_map
def get_ellps_map():
"""
Returns
-------
dict: ellipsoids supported by PROJ.
"""
cdef PJ_ELLPS *proj_ellps = proj_list_ellps()
cdef int iii = 0
ellps_map = {}
while proj_ellps[iii].id != NULL:
major_key, major_val = pystrdecode(proj_ellps[iii].major).split("=")
ell_key, ell_val = pystrdecode(proj_ellps[iii].ell).split("=")
ellps_map[pystrdecode(proj_ellps[iii].id)] = {
major_key: float(major_val),
ell_key: float(ell_val),
"description": pystrdecode(proj_ellps[iii].name)
}
iii += 1
return ellps_map
def get_prime_meridians_map():
"""
Returns
-------
dict: prime meridians supported by PROJ.
"""
cdef PJ_PRIME_MERIDIANS *prime_meridians = proj_list_prime_meridians()
cdef int iii = 0
prime_meridians_map = {}
while prime_meridians[iii].id != NULL:
prime_meridians_map[pystrdecode(prime_meridians[iii].id)] = \
pystrdecode(prime_meridians[iii].defn)
iii += 1
return prime_meridians_map
Unit = namedtuple("Unit", ["id", "to_meter", "name", "factor"])
def get_units_map():
"""
Returns
-------
dict: units supported by PROJ
"""
cdef PJ_UNITS *proj_units = proj_list_units()
cdef int iii = 0
units_map = {}
while proj_units[iii].id != NULL:
units_map[pystrdecode(proj_units[iii].id)] = Unit(
id=pystrdecode(proj_units[iii].id),
to_meter=pystrdecode(proj_units[iii].to_meter),
name=pystrdecode(proj_units[iii].name),
factor=proj_units[iii].factor,
)
iii += 1
return units_map
def get_angular_units_map():
"""
Returns
-------
dict: angular units supported by PROJ
"""
cdef PJ_UNITS *proj_units = proj_list_angular_units()
cdef int iii = 0
units_map = {}
while proj_units[iii].id != NULL:
units_map[pystrdecode(proj_units[iii].id)] = Unit(
id=pystrdecode(proj_units[iii].id),
to_meter=pystrdecode(proj_units[iii].to_meter),
name=pystrdecode(proj_units[iii].name),
factor=proj_units[iii].factor,
)
iii += 1
return units_map
......@@ -7,7 +7,3 @@ cdef class Proj:
cdef char *pjinitstring
cdef public object proj_version
cdef class TransProj:
cdef PJ * projpj
cdef PJ_CONTEXT * projctx
cdef public object error_str
......@@ -5,7 +5,7 @@ from pyproj._datadir cimport get_pyproj_context
from pyproj.exceptions import ProjError
# # version number strings for proj.4 and Geod
# # version number string for PROJ
proj_version_str = "{0}.{1}.{2}".format(
PROJ_VERSION_MAJOR,
PROJ_VERSION_MINOR,
......@@ -171,12 +171,21 @@ cdef class Proj:
def __repr__(self):
return "Proj('{srs}', preserve_units=True)".format(srs=self.srs)
def is_exact_same(self, Proj other):
"""Compares projections to see if they are exactly the same."""
def _is_exact_same(self, Proj other):
return proj_is_equivalent_to(
self.projpj, other.projpj, PJ_COMP_STRICT) == 1
def __eq__(self, Proj other):
"""Compares projections to see if they are equivalent."""
def _is_equivalent(self, Proj other):
return proj_is_equivalent_to(
self.projpj, other.projpj, PJ_COMP_EQUIVALENT) == 1
def __eq__(self, other):
if not isinstance(other, Proj):
return False
return self._is_equivalent(other)
def is_exact_same(self, other):
"""Compares Proj objects to see if they are exactly the same."""
if not isinstance(other, Proj):
return False
return self._is_exact_same(other)
include "proj.pxi"
cdef class _Transformer:
cdef PJ * projpj
cdef PJ_CONTEXT * projctx
from pyproj._crs cimport Base
cdef class _Transformer(Base):
cdef PJ_PROJ_INFO proj_info
cdef public object input_geographic
cdef public object output_geographic
cdef public object input_radians
cdef public object output_radians
cdef object _input_radians
cdef object _output_radians
cdef public object is_pipeline
cdef public object skip_equivalent
cdef public object projections_equivalent
cdef public object projections_exact_same
cdef public object type_name
include "base.pxi"
from pyproj.crs import CRS
from pyproj.proj import Proj
from pyproj.compat import cstrencode, pystrdecode
from pyproj._crs cimport Base, _CRS
from pyproj._datadir cimport get_pyproj_context
from pyproj.compat import cstrencode, pystrdecode
from pyproj.enums import ProjVersion, TransformDirection
from pyproj.exceptions import ProjError
cdef class _Transformer:
_PJ_DIRECTION_MAP = {
TransformDirection.FORWARD: PJ_FWD,
TransformDirection.INVERSE: PJ_INV,
TransformDirection.IDENT: PJ_IDENT,
}
_TRANSFORMER_TYPE_MAP = {
PJ_TYPE_UNKNOWN: "Unknown Transformer",
PJ_TYPE_CONVERSION: "Conversion Transformer",
PJ_TYPE_TRANSFORMATION: "Transformation Transformer",
PJ_TYPE_CONCATENATED_OPERATION: "Concatenated Operation Transformer",
PJ_TYPE_OTHER_COORDINATE_OPERATION: "Other Coordinate Operation Transformer",
}
cdef class _Transformer(Base):
def __cinit__(self):
self.projpj = NULL
self.projctx = NULL
self.input_geographic = False
self.output_geographic = False
self.input_radians = False
self.output_radians = False
self._input_radians = {}
self._output_radians = {}
self.is_pipeline = False
self.skip_equivalent = False
self.projections_equivalent = False
self.projections_exact_same = False
self.type_name = "Unknown Transformer"
def _set_radians_io(self):
self._input_radians.update({
PJ_FWD: proj_angular_input(self.projobj, PJ_FWD),
PJ_INV: proj_angular_input(self.projobj, PJ_INV),
PJ_IDENT: proj_angular_input(self.projobj, PJ_IDENT),
})
self._output_radians.update({
PJ_FWD: proj_angular_output(self.projobj, PJ_FWD),
PJ_INV: proj_angular_output(self.projobj, PJ_INV),
PJ_IDENT: proj_angular_output(self.projobj, PJ_IDENT),
})
def _initialize_from_projobj(self):
self.proj_info = proj_pj_info(self.projobj)
if self.proj_info.id == NULL:
ProjError.clear()
raise ProjError("Input is not a transformation.")
cdef PJ_TYPE transformer_type = proj_get_type(self.projobj)
self.type_name = _TRANSFORMER_TYPE_MAP[transformer_type]
def __init__(self):
# set up the context
self.projctx = get_pyproj_context()
@property
def id(self):
return pystrdecode(self.proj_info.id)
@property
def description(self):
return pystrdecode(self.proj_info.description)
def __dealloc__(self):
"""destroy projection definition"""
if self.projpj is not NULL:
proj_destroy(self.projpj)
if self.projctx is not NULL:
proj_context_destroy(self.projctx)
@property
def definition(self):
return pystrdecode(self.proj_info.definition)
def set_radians_io(self):
self.input_radians = proj_angular_input(self.projpj, PJ_FWD)
self.output_radians = proj_angular_output(self.projpj, PJ_FWD)
@property
def has_inverse(self):
return self.proj_info.has_inverse == 1
@property
def accuracy(self):
return self.proj_info.accuracy
@staticmethod
def _init_crs_to_crs(proj_from, proj_to, skip_equivalent=False):
def from_crs(_CRS crs_from, _CRS crs_to, skip_equivalent=False, always_xy=False):
cdef _Transformer transformer = _Transformer()
transformer.projpj = proj_create_crs_to_crs(
transformer.projobj = proj_create_crs_to_crs(
transformer.projctx,
cstrencode(proj_from.crs.srs),
cstrencode(proj_to.crs.srs),
cstrencode(crs_from.srs),
cstrencode(crs_to.srs),
NULL)
if transformer.projpj is NULL:
if transformer.projobj is NULL:
raise ProjError("Error creating CRS to CRS.")
transformer.set_radians_io()
transformer.projections_exact_same = proj_from.crs.is_exact_same(proj_to.crs)
transformer.projections_equivalent = proj_from.crs == proj_to.crs
cdef PJ* always_xy_pj = NULL
if always_xy:
always_xy_pj = proj_normalize_for_visualization(
transformer.projctx,
transformer.projobj
)
proj_destroy(transformer.projobj)
transformer.projobj = always_xy_pj
transformer._initialize_from_projobj()
transformer._set_radians_io()
transformer.projections_exact_same = crs_from.is_exact_same(crs_to)
transformer.projections_equivalent = crs_from == crs_to
transformer.input_geographic = crs_from.is_geographic
transformer.output_geographic = crs_to.is_geographic
transformer.skip_equivalent = skip_equivalent
transformer.is_pipeline = False
return transformer
@staticmethod
def from_proj(proj_from, proj_to, skip_equivalent=False):
if not isinstance(proj_from, Proj):
proj_from = Proj(proj_from)
if not isinstance(proj_to, Proj):
proj_to = Proj(proj_to)
transformer = _Transformer._init_crs_to_crs(proj_from, proj_to, skip_equivalent=skip_equivalent)
transformer.input_geographic = proj_from.crs.is_geographic
transformer.output_geographic = proj_to.crs.is_geographic
return transformer
@staticmethod
def from_pipeline(const char *proj_pipeline):
cdef _Transformer transformer = _Transformer()
# initialize projection
transformer.projpj = proj_create(transformer.projctx, proj_pipeline)
if transformer.projpj is NULL:
transformer.projobj = proj_create(transformer.projctx, proj_pipeline)
if transformer.projobj is NULL:
raise ProjError("Invalid projection {}.".format(proj_pipeline))
transformer.set_radians_io()
transformer._initialize_from_projobj()
transformer._set_radians_io()
transformer.is_pipeline = True
return transformer
def _transform(self, inx, iny, inz, intime, radians, errcheck=False):
def _transform(self, inx, iny, inz, intime, direction, radians, errcheck):
if self.projections_exact_same or (self.projections_equivalent and self.skip_equivalent):
return
tmp_pj_direction = _PJ_DIRECTION_MAP[TransformDirection(direction)]
cdef PJ_DIRECTION pj_direction = <PJ_DIRECTION>tmp_pj_direction
# private function to call pj_transform
cdef void *xdata
cdef void *ydata
......@@ -118,47 +162,58 @@ cdef class _Transformer:
npts = buflenx//8
# degrees to radians
if not self.is_pipeline and not radians and self.input_radians:
if not self.is_pipeline and not radians\
and self._input_radians[pj_direction]:
for iii from 0 <= iii < npts:
xx[iii] = xx[iii]*_DG2RAD
yy[iii] = yy[iii]*_DG2RAD
# radians to degrees
elif not self.is_pipeline and radians and not self.input_radians and self.input_geographic:
elif not self.is_pipeline and radians\
and not self._input_radians[pj_direction]\
and self.input_geographic:
for iii from 0 <= iii < npts:
xx[iii] = xx[iii]*_RAD2DG
yy[iii] = yy[iii]*_RAD2DG
cdef int err_count = proj_trans_generic(
self.projpj,
PJ_FWD,
ProjError.clear()
proj_trans_generic(
self.projobj,
pj_direction,
xx, _DOUBLESIZE, npts,
yy, _DOUBLESIZE, npts,
zz, _DOUBLESIZE, npts,
tt, _DOUBLESIZE, npts,
)
cdef int errno = proj_errno(self.projpj)
if errno and errcheck:
raise ProjError("proj_trans_generic error: {}".format(
cdef int errno = proj_errno(self.projobj)
if errcheck and errno:
raise ProjError("transform error: {}".format(
pystrdecode(proj_errno_string(errno))))
elif err_count and errcheck:
raise ProjError("{} proj_trans_generic error(s)".format(err_count))
elif errcheck and ProjError.internal_proj_error is not None:
raise ProjError("transform error")
# radians to degrees
if not self.is_pipeline and not radians and self.output_radians:
if not self.is_pipeline and not radians\
and self._output_radians[pj_direction]:
for iii from 0 <= iii < npts:
xx[iii] = xx[iii]*_RAD2DG
yy[iii] = yy[iii]*_RAD2DG
# degrees to radians
elif not self.is_pipeline and radians and not self.output_radians and self.output_geographic:
elif not self.is_pipeline and radians\
and not self._output_radians[pj_direction]\
and self.output_geographic:
for iii from 0 <= iii < npts:
xx[iii] = xx[iii]*_DG2RAD
yy[iii] = yy[iii]*_DG2RAD
def _transform_sequence(self, Py_ssize_t stride, inseq, bint switch,
time_3rd, radians, errcheck=False):
def _transform_sequence(
self, Py_ssize_t stride, inseq, bint switch,
direction, time_3rd, radians, errcheck
):
if self.projections_exact_same or (self.projections_equivalent and self.skip_equivalent):
return
tmp_pj_direction = _PJ_DIRECTION_MAP[TransformDirection(direction)]
cdef PJ_DIRECTION pj_direction = <PJ_DIRECTION>tmp_pj_direction
# private function to itransform function
cdef:
void *buffer
......@@ -179,13 +234,16 @@ cdef class _Transformer:
npts = buflen // (stride * _DOUBLESIZE)
# degrees to radians
if not self.is_pipeline and not radians and self.input_radians:
if not self.is_pipeline and not radians\
and self._input_radians[pj_direction]:
for iii from 0 <= iii < npts:
jjj = stride*iii
coords[jjj] *= _DG2RAD
coords[jjj+1] *= _DG2RAD
# radians to degrees
elif not self.is_pipeline and radians and not self.input_radians and self.input_geographic:
elif not self.is_pipeline and radians\
and not self._input_radians[pj_direction]\
and self.input_geographic:
for iii from 0 <= iii < npts:
jjj = stride*iii
coords[jjj] *= _RAD2DG
......@@ -211,30 +269,34 @@ cdef class _Transformer:
else:
tt = NULL
cdef int err_count = proj_trans_generic (
self.projpj,
PJ_FWD,
ProjError.clear()
proj_trans_generic (
self.projobj,
pj_direction,
x, stride*_DOUBLESIZE, npts,
y, stride*_DOUBLESIZE, npts,
z, stride*_DOUBLESIZE, npts,
tt, stride*_DOUBLESIZE, npts,
)
cdef int errno = proj_errno(self.projpj)
if errno and errcheck:
raise ProjError("proj_trans_generic error: {}".format(
cdef int errno = proj_errno(self.projobj)
if errcheck and errno:
raise ProjError("itransform error: {}".format(
pystrdecode(proj_errno_string(errno))))
elif err_count and errcheck:
raise ProjError("{} proj_trans_generic error(s)".format(err_count))
elif errcheck and ProjError.internal_proj_error is not None:
raise ProjError("itransform error")
# radians to degrees
if not self.is_pipeline and not radians and self.output_radians:
if not self.is_pipeline and not radians\
and self._output_radians[pj_direction]:
for iii from 0 <= iii < npts:
jjj = stride*iii
coords[jjj] *= _RAD2DG
coords[jjj+1] *= _RAD2DG
# degrees to radians
elif not self.is_pipeline and radians and not self.output_radians and self.output_geographic:
elif not self.is_pipeline and radians\
and not self._output_radians[pj_direction]\
and self.output_geographic:
for iii from 0 <= iii < npts:
jjj = stride*iii
coords[jjj] *= _DG2RAD
......
"""
This module contains mappings necessary to convert from
a CRS to a CF-1.8 compliant projection.
http://cfconventions.org/cf-conventions/cf-conventions.html#appendix-grid-mappings
It is not complete and does not support all projections.
CF PARAMS (NOT SURE OF THE MAPPING):
------------------------------------
geoid_name (OGC WKT VERT_DATUM - ex GEOID12B)
geopotential_datum_name (OGC WKT VERT_DATUM - ex NAVD88)
"""
GRID_MAPPING_NAME_MAP = {
"albers_conical_equal_area": "aea",
"azimuthal_equidistant": "aeqd",
"geostationary": "geos",
"lambert_azimuthal_equal_area": "laea",
"lambert_conformal_conic": "lcc",
"lambert_cylindrical_equal_area": "cea",
"mercator": "merc",
"oblique_mercator": "omerc",
"orthographic": "ortho",
"polar_stereographic": "stere",
"sinusoidal": "sinu",
"stereographic": "stere",
"transverse_mercator": "tmerc",
"vertical_perspective": "nsper",
"rotated_latitude_longitude": "ob_tran",
"latitude_longitude": "latlon",
}
INVERSE_GRID_MAPPING_NAME_MAP = {
value: key for key, value in GRID_MAPPING_NAME_MAP.items()
}
PROJ_PARAM_MAP = {
"azimuth_of_central_line": "alpha",
"earth_radius": "R",
"fase_easting": "x_0",
"fase_northing": "y_0",
"latitude_of_projection_origin": "lat_0",
"north_pole_grid_longitude": "lon_0",
"straight_vertical_longitude_from_pole": "lon_0",
"longitude_of_central_meridian": "lon_0",
"longitude_of_projection_origin": "lon_0",
"horizontal_datum_name": "datum",
"reference_ellipsoid_name": "ellps",
"towgs84": "towgs84",
"prime_meridian_name": "pm",
"scale_factor_at_central_meridian": "k_0",
"scale_factor_at_projection_origin": "k_0",
"unit": "units",
"perspective_point_height": "h",
"grid_north_pole_longitude": "o_lon_p",
"grid_north_pole_latitude": "o_lat_p",
"semi_major_axis": "a",
"semi_minor_axis": "b",
"inverse_flattening": "rf",
"sweep_angle_axis": "sweep",
}
INVERSE_PROJ_PARAM_MAP = {value: key for key, value in PROJ_PARAM_MAP.items()}
INVERSE_PROJ_PARAM_MAP.update(lonc="longitude_of_projection_origin")
LON_0_MAP = {
"DEFAULT": "longitude_of_projection_origin",
"rotated_latitude_longitude": "north_pole_grid_longitude",
"polar_stereographic": "straight_vertical_longitude_from_pole",
"transverse_mercator": "longitude_of_central_meridian",
"lambert_cylindrical_equal_area": "longitude_of_central_meridian",
"lambert_conformal_conic": "longitude_of_central_meridian",
"albers_conical_equal_area": "longitude_of_central_meridian",
}
K_0_MAP = {
"DEFAULT": "scale_factor_at_projection_origin",
"transverse_mercator": "scale_factor_at_central_meridian",
}
This diff is collapsed.