Skip to content
Commits on Source (20)
pyproj/proj_dir/
pyproj/*.c
pyproj/*/*.c
pyproj/*/*.html
pyproj/*.html
proj-*/
......
......@@ -11,7 +11,7 @@ env:
global:
- PROJ_BASE_DIR=$HOME/proj_install
- CYTHON_COVERAGE=True
- PROJSOURCE=6.2.1
- PROJSOURCE=6.3.1
# Following generated with
- WHEELHOUSE_UPLOADER_USERNAME=travis-worker
# Following generated by
......@@ -26,29 +26,33 @@ matrix:
os: osx
env:
- PYTHON=3.6.8
- PROJSOURCE=6.2.1
- python: 3.5
env:
- PROJSOURCE=6.2.1
- python: 3.6
- python: 3.6
env:
- PROJSOURCE=6.2.0
- python: 3.6
env:
- PROJSOURCE=6.2.1
- python: 3.6
env:
- PROJSOURCE=6.3.0
- python: 3.7
env:
- PROJSOURCE=6.2.1
- DOC=true
- python: 3.8
env:
- PROJSOURCE=6.2.1
- python: "nightly"
- python: 3.8
env:
- PROJSOURCE=git
# - python: "nightly"
# env:
# - PROJSOURCE=git
allow_failures:
- python: "nightly"
# - python: "nightly"
# env:
# - PROJSOURCE=git
- python: 3.8
env:
- PROJSOURCE=git
......
......@@ -8,6 +8,7 @@ include pyproj/*.pyx
include pyproj/*.pxd
include pyproj/*.pxi
include test/sample.out
include test/conftest.py
recursive-include docs *
prune docs/_build
prune pyproj/proj_dir
......@@ -56,6 +56,8 @@ clean-setup: ## run python setup.py clean
clean-cython: ## clean the cython files
rm -f pyproj/*.so
rm -f pyproj/*/*.so
rm -f pyproj/*/*.c
rm -f pyproj/*.c
lint: ## check style with flake8
......
......@@ -5,7 +5,7 @@ Python interface to [PROJ](http://proj.org) (cartographic projections and coordi
<p align="center">
<a href="https://gitter.im/pyproj4-pyproj/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img alt="Join the chat at https://gitter.im/pyproj4-pyproj/community" src="https://badges.gitter.im/pyproj4-pyproj/community.svg"></a>
<a href="#contributors"><img alt="All Contributors" src="https://img.shields.io/badge/all_contributors-28-orange.svg?style=flat-square"></a>
<a href="https://travis-ci.org/pyproj4/pyproj"><img alt="Build Status" src="https://travis-ci.org/pyproj4/pyproj.svg"></a>
<a href="https://travis-ci.org/pyproj4/pyproj"><img alt="Build Status" src="https://travis-ci.org/pyproj4/pyproj.svg?branch=master"></a>
<a href="https://ci.appveyor.com/project/jswhit/pyproj"><img alt="Build Status" src="https://ci.appveyor.com/api/projects/status/8xkka4s97uwhkc64/branch/master?svg=true"></a>
<a href="https://coveralls.io/github/pyproj4/pyproj?branch=master"><img alt="Coverage Status" src="https://coveralls.io/repos/github/pyproj4/pyproj/badge.svg?branch=master"></a>
<a href="https://badge.fury.io/py/pyproj"><img alt="PyPI" src="https://badge.fury.io/py/pyproj.svg"></a>
......
......@@ -21,19 +21,19 @@ environment:
# PYTHON_ARCH: "64"
# VS_VERSION: Visual Studio 14
# APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
# PROJSOURCE: 6.2.1
# PROJSOURCE: 6.3.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.2.1
PROJSOURCE: 6.3.1
# - 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.2.1
# PROJSOURCE: 6.3.1
# - PYTHON: "C:\\Python36-x64"
# PYTHON_VERSION: "3.6"
# PYTHON_ARCH: "64"
......@@ -66,7 +66,7 @@ build_script:
appveyor DownloadFile https://sqlite.org/2018/sqlite-tools-win32-x86-3250100.zip
7z x sqlite-tools-win32-x86-3250100.zip
- copy "%APPVEYOR_BUILD_FOLDER%"\sqlite-tools-win32-x86-3250100\sqlite3.exe %SQLITE3_BIN%
- set PATH=%PATH%;%SQLITE3_BIN%
- set PATH=%SQLITE3_BIN%;%PATH%
# setup PROJ.4
- if "%PROJSOURCE%" == "git" git clone https://github.com/OSGeo/proj.4.git proj-git
- if not "%PROJSOURCE%" == "git" if not exist %PROJ_DIR% set BUILD_PROJ_STABLE=1
......@@ -85,7 +85,7 @@ build_script:
- if defined BUILD_PROJ cd build
- 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%"
- if defined BUILD_PROJ cmake --build . --config Release --target install
- set PATH=%PATH%;%PROJ_DIR%\bin
- set PATH=%PROJ_DIR%\bin;%PATH%
- set PROJ_LIB=%PROJ_DIR%\share\proj
- if defined BUILD_PROJ cd %PROJ_LIB%
- if defined BUILD_PROJ curl -O http://download.osgeo.org/proj/proj-datumgrid-1.8.zip
......
python-pyproj (2.5~rc0+ds-1~exp1) experimental; urgency=medium
* New upstream release candidate.
* Drop patches, included upstream.
-- Bas Couwenberg <sebastic@debian.org> Fri, 21 Feb 2020 06:55:18 +0100
python-pyproj (2.4.2+ds-4) unstable; urgency=medium
* Add upstream patches for PROJ 6.3.x support.
* Add patch to fix test failure with PROJ 7.0.0.
-- Bas Couwenberg <sebastic@debian.org> Wed, 19 Feb 2020 20:09:53 +0100
python-pyproj (2.4.2+ds-3) unstable; urgency=medium
* Drop Name field from upstream metadata.
* Bump Standards-Version to 4.5.0, no changes.
* Add patch to fix FTBFS due to test failures.
(closes: #950660)
-- Bas Couwenberg <sebastic@debian.org> Tue, 04 Feb 2020 16:45:47 +0100
python-pyproj (2.4.2+ds-2) unstable; urgency=medium
* Move from experimental to unstable.
-- Bas Couwenberg <sebastic@debian.org> Mon, 02 Dec 2019 05:46:49 +0100
python-pyproj (2.4.2+ds-1) experimental; urgency=medium
* New upstream release.
-- Bas Couwenberg <sebastic@debian.org> Sun, 01 Dec 2019 06:00:58 +0100
python-pyproj (2.4.2~rc0+ds-1~exp1) experimental; urgency=medium
* New upstream release candidate.
......
......@@ -16,7 +16,7 @@ Build-Depends: debhelper (>= 9),
python3-pytest,
python3-pytest-cov,
python3-shapely
Standards-Version: 4.4.1
Standards-Version: 4.5.0
Vcs-Browser: https://salsa.debian.org/debian-gis-team/python-pyproj
Vcs-Git: https://salsa.debian.org/debian-gis-team/python-pyproj.git -b experimental
Homepage: https://github.com/pyproj4/pyproj
......
---
Bug-Database: https://github.com/pyproj4/pyproj/issues
Bug-Submit: https://github.com/pyproj4/pyproj/issues/new
Name: pyproj
Repository: https://github.com/pyproj4/pyproj.git
Repository-Browse: https://github.com/pyproj4/pyproj
......@@ -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.4.2.rc0"
__version__ = "2.5.rc0"
__all__ = [
"Proj",
"Geod",
......
......@@ -14,7 +14,7 @@ cdef class Axis:
cdef readonly object unit_code
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* projobj, int index)
cdef Axis create(PJ_CONTEXT* context, PJ* projobj, int index)
cdef class AreaOfUse:
cdef readonly double west
......@@ -24,7 +24,7 @@ cdef class AreaOfUse:
cdef readonly object name
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* projobj)
cdef AreaOfUse create(PJ_CONTEXT* context, PJ* projobj)
cdef class Base:
......@@ -35,38 +35,43 @@ cdef class Base:
cdef readonly object _scope
cdef class Ellipsoid(Base):
cdef double _semi_major_metre
cdef double _semi_minor_metre
cdef class _CRSParts(Base):
pass
cdef class Ellipsoid(_CRSParts):
cdef readonly double semi_major_metre
cdef readonly double semi_minor_metre
cdef readonly object is_semi_minor_computed
cdef double _inv_flattening
cdef readonly object ellipsoid_loaded
cdef readonly double inverse_flattening
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* ellipsoid_pj)
cdef Ellipsoid create(PJ_CONTEXT* context, PJ* ellipsoid_pj)
cdef class PrimeMeridian(Base):
cdef class PrimeMeridian(_CRSParts):
cdef readonly double longitude
cdef readonly double unit_conversion_factor
cdef readonly object unit_name
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* prime_meridian_pj)
cdef PrimeMeridian create(PJ_CONTEXT* context, PJ* prime_meridian_pj)
cdef class Datum(Base):
cdef class Datum(_CRSParts):
cdef readonly object type_name
cdef readonly object _ellipsoid
cdef readonly object _prime_meridian
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* datum_pj)
cdef Datum create(PJ_CONTEXT* context, PJ* datum_pj)
cdef class CoordinateSystem(Base):
cdef class CoordinateSystem(_CRSParts):
cdef readonly object _axis_list
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* coordinate_system_pj)
cdef CoordinateSystem create(PJ_CONTEXT* context, PJ* coordinate_system_pj)
cdef class Param:
......@@ -81,7 +86,7 @@ cdef class Param:
cdef readonly object unit_category
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* projobj, int param_idx)
cdef Param create(PJ_CONTEXT* context, PJ* projobj, int param_idx)
cdef class Grid:
......@@ -94,10 +99,10 @@ cdef class Grid:
cdef readonly object available
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* projobj, int grid_idx)
cdef Grid create(PJ_CONTEXT* context, PJ* projobj, int grid_idx)
cdef class CoordinateOperation(Base):
cdef class CoordinateOperation(_CRSParts):
cdef readonly object _params
cdef readonly object _grids
cdef readonly object _area_of_use
......@@ -112,7 +117,7 @@ cdef class CoordinateOperation(Base):
cdef readonly type_name
@staticmethod
cdef create(PJ_CONTEXT* context, PJ* coordinate_operation_pj)
cdef CoordinateOperation create(PJ_CONTEXT* context, PJ* coordinate_operation_pj)
cdef class _CRS(Base):
......
This diff is collapsed.
......@@ -39,61 +39,45 @@ cdef class Geod:
forward azimuth and distance.
if radians=True, lons/lats are radians instead of degrees.
"""
cdef Py_ssize_t buflenlons, buflenlats, buflenaz, buflend, ndim, iii
cdef double lat1,lon1,az1,s12,plon2,plat2,pazi2
cdef double *lonsdata
cdef double *latsdata
cdef double *azdata
cdef double *distdata
cdef void *londata
cdef void *latdata
cdef void *azdat
cdef void *distdat
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(lons, &londata, &buflenlons) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(az, &azdat, &buflenaz) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(dist, &distdat, &buflend) <> 0:
raise GeodError
cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(lons)
cdef PyBuffWriteManager latbuff = PyBuffWriteManager(lats)
cdef PyBuffWriteManager azbuff = PyBuffWriteManager(az)
cdef PyBuffWriteManager distbuff = PyBuffWriteManager(dist)
# process data in buffer
if not buflenlons == buflenlats == buflenaz == buflend:
raise GeodError("Buffer lengths not the same")
ndim = buflenlons//_DOUBLESIZE
lonsdata = <double *>londata
latsdata = <double *>latdata
azdata = <double *>azdat
distdata = <double *>distdat
if not lonbuff.len == latbuff.len == azbuff.len == distbuff.len:
raise GeodError("Array lengths are not the same.")
cdef double lat1, lon1, az1, s12, plon2, plat2, pazi2
cdef Py_ssize_t iii
with nogil:
for iii in range(ndim):
for iii in range(lonbuff.len):
if not radians:
lon1 = lonsdata[iii]
lat1 = latsdata[iii]
az1 = azdata[iii]
s12 = distdata[iii]
lon1 = lonbuff.data[iii]
lat1 = latbuff.data[iii]
az1 = azbuff.data[iii]
s12 = distbuff.data[iii]
else:
lon1 = _RAD2DG * lonsdata[iii]
lat1 = _RAD2DG * latsdata[iii]
az1 = _RAD2DG * azdata[iii]
s12 = distdata[iii]
lon1 = _RAD2DG * lonbuff.data[iii]
lat1 = _RAD2DG * latbuff.data[iii]
az1 = _RAD2DG * azbuff.data[iii]
s12 = distbuff.data[iii]
geod_direct(&self._geod_geodesic, lat1, lon1, az1, s12,\
&plat2, &plon2, &pazi2)
# back azimuth needs to be flipped 180 degrees
# to match what proj4 geod utility produces.
# to match what PROJ geod utility produces.
if pazi2 > 0:
pazi2 = pazi2 - 180.
elif pazi2 <= 0:
pazi2 = pazi2 + 180.
if not radians:
lonsdata[iii] = plon2
latsdata[iii] = plat2
azdata[iii] = pazi2
lonbuff.data[iii] = plon2
latbuff.data[iii] = plat2
azbuff.data[iii] = pazi2
else:
lonsdata[iii] = _DG2RAD * plon2
latsdata[iii] = _DG2RAD * plat2
azdata[iii] = _DG2RAD * pazi2
lonbuff.data[iii] = _DG2RAD * plon2
latbuff.data[iii] = _DG2RAD * plat2
azbuff.data[iii] = _DG2RAD * pazi2
@cython.boundscheck(False)
@cython.wraparound(False)
......@@ -103,45 +87,29 @@ cdef class Geod:
between an initial and terminus lat/lon pair.
if radians=True, lons/lats are radians instead of degree
"""
cdef double lat1,lon1,lat2,lon2,pazi1,pazi2,ps12
cdef Py_ssize_t buflenlons, buflenlats, buflenaz, buflend, ndim, iii
cdef double *lonsdata
cdef double *latsdata
cdef double *azdata
cdef double *distdata
cdef void *londata
cdef void *latdata
cdef void *azdat
cdef void *distdat
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(lons1, &londata, &buflenlons) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(lats1, &latdata, &buflenlats) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(lons2, &azdat, &buflenaz) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(lats2, &distdat, &buflend) <> 0:
raise GeodError
cdef PyBuffWriteManager lon1buff = PyBuffWriteManager(lons1)
cdef PyBuffWriteManager lat1buff = PyBuffWriteManager(lats1)
cdef PyBuffWriteManager lon2buff = PyBuffWriteManager(lons2)
cdef PyBuffWriteManager lat2buff = PyBuffWriteManager(lats2)
# process data in buffer
if not buflenlons == buflenlats == buflenaz == buflend:
raise GeodError("Buffer lengths not the same")
ndim = buflenlons//_DOUBLESIZE
lonsdata = <double *>londata
latsdata = <double *>latdata
azdata = <double *>azdat
distdata = <double *>distdat
if not lon1buff.len == lat1buff.len == lon2buff.len == lat2buff.len:
raise GeodError("Array lengths are not the same.")
cdef double lat1, lon1, lat2, lon2, pazi1, pazi2, ps12
cdef Py_ssize_t iii
with nogil:
for iii in range(ndim):
for iii in range(lon1buff.len):
if radians:
lon1 = _RAD2DG * lonsdata[iii]
lat1 = _RAD2DG * latsdata[iii]
lon2 = _RAD2DG * azdata[iii]
lat2 = _RAD2DG * distdata[iii]
lon1 = _RAD2DG * lon1buff.data[iii]
lat1 = _RAD2DG * lat1buff.data[iii]
lon2 = _RAD2DG * lon2buff.data[iii]
lat2 = _RAD2DG * lat2buff.data[iii]
else:
lon1 = lonsdata[iii]
lat1 = latsdata[iii]
lon2 = azdata[iii]
lat2 = distdata[iii]
lon1 = lon1buff.data[iii]
lat1 = lat1buff.data[iii]
lon2 = lon2buff.data[iii]
lat2 = lat2buff.data[iii]
geod_inverse(
&self._geod_geodesic,
lat1, lon1, lat2, lon2,
......@@ -154,12 +122,13 @@ cdef class Geod:
elif pazi2 <= 0:
pazi2 = pazi2+180.
if radians:
lonsdata[iii] = _DG2RAD * pazi1
latsdata[iii] = _DG2RAD * pazi2
lon1buff.data[iii] = _DG2RAD * pazi1
lat1buff.data[iii] = _DG2RAD * pazi2
else:
lonsdata[iii] = pazi1
latsdata[iii] = pazi2
azdata[iii] = ps12
lon1buff.data[iii] = pazi1
lat1buff.data[iii] = pazi2
# write azimuth data into lon2 buffer
lon2buff.data[iii] = ps12
@cython.boundscheck(False)
@cython.wraparound(False)
......@@ -223,46 +192,38 @@ cdef class Geod:
float: The total distance.
"""
cdef double lat1,lon1,lat2,lon2,pazi1,pazi2,ps12
cdef double total_distance = 0.0
cdef Py_ssize_t buflenlons, buflenlats, ndim, iii
cdef double *lonsdata
cdef double *latsdata
cdef void *londata
cdef void *latdata
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(lons, &londata, &buflenlons) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0:
raise GeodError
cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(lons)
cdef PyBuffWriteManager latbuff = PyBuffWriteManager(lats)
# process data in buffer
if buflenlons != buflenlats:
raise GeodError("Buffer lengths not the same")
ndim = buflenlons//_DOUBLESIZE
lonsdata = <double *>londata
latsdata = <double *>latdata
if ndim == 1:
lonsdata[0] = 0
if lonbuff.len != latbuff.len:
raise GeodError("Array lengths are not the same.")
if lonbuff.len == 1:
lonbuff.data[0] = 0
return 0.0
cdef double lat1, lon1, lat2, lon2, pazi1, pazi2, ps12
cdef double total_distance = 0.0
cdef Py_ssize_t iii
with nogil:
for iii in range(ndim - 1):
for iii in range(lonbuff.len - 1):
if radians:
lon1 = _RAD2DG * lonsdata[iii]
lat1 = _RAD2DG * latsdata[iii]
lon2 = _RAD2DG * lonsdata[iii + 1]
lat2 = _RAD2DG * latsdata[iii + 1]
lon1 = _RAD2DG * lonbuff.data[iii]
lat1 = _RAD2DG * latbuff.data[iii]
lon2 = _RAD2DG * lonbuff.data[iii + 1]
lat2 = _RAD2DG * latbuff.data[iii + 1]
else:
lon1 = lonsdata[iii]
lat1 = latsdata[iii]
lon2 = lonsdata[iii + 1]
lat2 = latsdata[iii + 1]
lon1 = lonbuff.data[iii]
lat1 = latbuff.data[iii]
lon2 = lonbuff.data[iii + 1]
lat2 = latbuff.data[iii + 1]
geod_inverse(
&self._geod_geodesic,
lat1, lon1, lat2, lon2,
&ps12, &pazi1, &pazi2,
)
lonsdata[iii] = ps12
lonbuff.data[iii] = ps12
total_distance += ps12
return total_distance
......@@ -293,35 +254,26 @@ cdef class Geod:
(float, float): The area (meter^2) and permimeter (meters) of the polygon.
"""
cdef Py_ssize_t buflenlons, buflenlats, ndim, iii
cdef void *londata
cdef void *latdata
cdef double *lonsdata
cdef double *latsdata
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(lons, &londata, &buflenlons) <> 0:
raise GeodError
if PyObject_AsWriteBuffer(lats, &latdata, &buflenlats) <> 0:
raise GeodError
cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(lons)
cdef PyBuffWriteManager latbuff = PyBuffWriteManager(lats)
# process data in buffer
if not buflenlons == buflenlats:
raise GeodError("Buffer lengths not the same")
if not lonbuff.len == latbuff.len:
raise GeodError("Array lengths are not the same.")
cdef double polygon_area
cdef double polygon_perimeter
ndim = buflenlons//_DOUBLESIZE
cdef Py_ssize_t iii
lonsdata = <double *>londata
latsdata = <double *>latdata
with nogil:
if radians:
for iii in range(ndim):
lonsdata[iii] *= _RAD2DG
latsdata[iii] *= _RAD2DG
for iii in range(lonbuff.len):
lonbuff.data[iii] *= _RAD2DG
latbuff.data[iii] *= _RAD2DG
geod_polygonarea(
&self._geod_geodesic,
latsdata, lonsdata, ndim,
latbuff.data, lonbuff.data, lonbuff.len,
&polygon_area, &polygon_perimeter
)
return (polygon_area, polygon_perimeter)
......
......@@ -165,7 +165,7 @@ def get_codes(auth_name, pj_type, allow_deprecated=False):
----------
auth_name: str
The name of the authority.
pj_type: ~pyproj.enums.PJType
pj_type: pyproj.enums.PJType
The type of object to get the authorities.
allow_deprecated: bool, optional
Allow a deprecated code in the return.
......
......@@ -56,42 +56,35 @@ cdef class Proj:
if errcheck=False and the forward transformation is invalid, no exception is
raised and 'inf' is returned.
"""
cdef PyBuffWriteManager lonbuff = PyBuffWriteManager(lons)
cdef PyBuffWriteManager latbuff = PyBuffWriteManager(lats)
# process data in buffer
if lonbuff.len != latbuff.len:
raise ProjError("Buffer lengths not the same")
cdef PJ_COORD projxyout
cdef PJ_COORD projlonlatin = proj_coord(0, 0, 0, HUGE_VAL)
cdef Py_ssize_t buflenx, bufleny, ndim, iii
cdef double *lonsdata
cdef double *latsdata
cdef void *londata
cdef void *latdata
cdef Py_ssize_t iii
cdef int errno
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(lons, &londata, &buflenx) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
if PyObject_AsWriteBuffer(lats, &latdata, &bufleny) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
# process data in buffer
if buflenx != bufleny:
raise ProjError("Buffer lengths not the same")
ndim = buflenx//_DOUBLESIZE
lonsdata = <double *>londata
latsdata = <double *>latdata
with nogil:
proj_errno_reset(self.projobj)
for iii in range(ndim):
for iii in range(latbuff.len):
# if inputs are nan's, return big number.
if lonsdata[iii] != lonsdata[iii] or latsdata[iii] != latsdata[iii]:
lonsdata[iii] = HUGE_VAL
latsdata[iii] = HUGE_VAL
if lonbuff.data[iii] != lonbuff.data[iii] or latbuff.data[iii] != latbuff.data[iii]:
lonbuff.data[iii] = HUGE_VAL
latbuff.data[iii] = HUGE_VAL
if errcheck:
with gil:
raise ProjError("projection_undefined")
continue
if proj_angular_input(self.projobj, PJ_FWD):
projlonlatin.uv.u = _DG2RAD * lonsdata[iii]
projlonlatin.uv.v = _DG2RAD * latsdata[iii]
projlonlatin.uv.u = _DG2RAD * lonbuff.data[iii]
projlonlatin.uv.v = _DG2RAD * latbuff.data[iii]
else:
projlonlatin.uv.u = lonsdata[iii]
projlonlatin.uv.v = latsdata[iii]
projlonlatin.uv.u = lonbuff.data[iii]
projlonlatin.uv.v = latbuff.data[iii]
projxyout = proj_trans(self.projobj, PJ_FWD, projlonlatin)
errno = proj_errno(self.projobj)
if errcheck and errno:
......@@ -111,20 +104,20 @@ cdef class Proj:
if errcheck:
with gil:
raise ProjError("Projection undefined.")
lonsdata[iii] = HUGE_VAL
latsdata[iii] = HUGE_VAL
lonbuff.data[iii] = HUGE_VAL
latbuff.data[iii] = HUGE_VAL
elif proj_angular_output(self.projobj, PJ_FWD):
lonsdata[iii] = _RAD2DG * projxyout.xy.x
latsdata[iii] = _RAD2DG * projxyout.xy.y
lonbuff.data[iii] = _RAD2DG * projxyout.xy.x
latbuff.data[iii] = _RAD2DG * projxyout.xy.y
else:
lonsdata[iii] = projxyout.xy.x
latsdata[iii] = projxyout.xy.y
lonbuff.data[iii] = projxyout.xy.x
latbuff.data[iii] = projxyout.xy.y
ProjError.clear()
@cython.boundscheck(False)
@cython.wraparound(False)
def _inv(self, object x, object y, bint errcheck=False):
def _inv(self, object xx, object yy, bint errcheck=False):
"""
inverse transformation - x,y to lons,lats (done in place).
if errcheck=True, an exception is raised if the inverse transformation is invalid.
......@@ -134,45 +127,36 @@ cdef class Proj:
if not self.has_inverse:
raise ProjError('inverse projection undefined')
cdef PyBuffWriteManager xbuff = PyBuffWriteManager(xx)
cdef PyBuffWriteManager ybuff = PyBuffWriteManager(yy)
# process data in buffer
if xbuff.len != ybuff.len:
raise ProjError("Array lengths not the same.")
cdef PJ_COORD projxyin = proj_coord(0, 0, 0, HUGE_VAL)
cdef PJ_COORD projlonlatout
cdef Py_ssize_t buflenx, bufleny, ndim, iii
cdef void *xdata
cdef void *ydata
cdef double *xdatab
cdef double *ydatab
cdef Py_ssize_t iii
cdef int errno
# if buffer api is supported, get pointer to data buffers.
if PyObject_AsWriteBuffer(x, &xdata, &buflenx) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
if PyObject_AsWriteBuffer(y, &ydata, &bufleny) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
# process data in buffer
# (for numpy/regular python arrays).
if buflenx != bufleny:
raise ProjError("Buffer lengths not the same")
ndim = buflenx//_DOUBLESIZE
xdatab = <double *>xdata
ydatab = <double *>ydata
with nogil:
# reset errors potentially left over
proj_errno_reset(self.projobj)
for iii in range(ndim):
for iii in range(xbuff.len):
# if inputs are nan's, return big number.
if xdatab[iii] != xdatab[iii] or ydatab[iii] != ydatab[iii]:
xdatab[iii] = HUGE_VAL
ydatab[iii] = HUGE_VAL
if xbuff.data[iii] != xbuff.data[iii] or ybuff.data[iii] != ybuff.data[iii]:
xbuff.data[iii] = HUGE_VAL
ybuff.data[iii] = HUGE_VAL
if errcheck:
with gil:
raise ProjError("projection_undefined")
continue
if proj_angular_input(self.projobj, PJ_INV):
projxyin.xy.x = _DG2RAD * xdatab[iii]
projxyin.xy.y = _DG2RAD * ydatab[iii]
projxyin.xy.x = _DG2RAD * xbuff.data[iii]
projxyin.xy.y = _DG2RAD * ybuff.data[iii]
else:
projxyin.xy.x = xdatab[iii]
projxyin.xy.y = ydatab[iii]
projxyin.xy.x = xbuff.data[iii]
projxyin.xy.y = ybuff.data[iii]
projlonlatout = proj_trans(self.projobj, PJ_INV, projxyin)
errno = proj_errno(self.projobj)
if errcheck and errno:
......@@ -193,14 +177,14 @@ cdef class Proj:
if errcheck:
with gil:
raise ProjError("projection_undefined")
xdatab[iii] = HUGE_VAL
ydatab[iii] = HUGE_VAL
xbuff.data[iii] = HUGE_VAL
ybuff.data[iii] = HUGE_VAL
elif proj_angular_output(self.projobj, PJ_INV):
xdatab[iii] = _RAD2DG * projlonlatout.uv.u
ydatab[iii] = _RAD2DG * projlonlatout.uv.v
xbuff.data[iii] = _RAD2DG * projlonlatout.uv.u
ybuff.data[iii] = _RAD2DG * projlonlatout.uv.v
else:
xdatab[iii] = projlonlatout.uv.u
ydatab[iii] = projlonlatout.uv.v
xbuff.data[iii] = projlonlatout.uv.u
ybuff.data[iii] = projlonlatout.uv.v
ProjError.clear()
def __repr__(self):
......
......@@ -404,68 +404,59 @@ cdef class _Transformer(Base):
return
tmp_pj_direction = _PJ_DIRECTION_MAP[TransformDirection.create(direction)]
cdef PJ_DIRECTION pj_direction = <PJ_DIRECTION>tmp_pj_direction
# private function to call pj_transform
cdef void *xdata
cdef void *ydata
cdef void *zdata
cdef void *tdata
cdef double *xx
cdef double *yy
cdef double *zz
cdef double *tt
cdef Py_ssize_t buflenx, bufleny, buflenz, buflent, npts, iii
cdef int err
if PyObject_AsWriteBuffer(inx, &xdata, &buflenx) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
if PyObject_AsWriteBuffer(iny, &ydata, &bufleny) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
if inz is not None and PyObject_AsWriteBuffer(inz, &zdata, &buflenz) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
else:
buflenz = bufleny
if intime is not None and PyObject_AsWriteBuffer(intime, &tdata, &buflent) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
else:
buflent = bufleny
cdef PyBuffWriteManager xbuff = PyBuffWriteManager(inx)
cdef PyBuffWriteManager ybuff = PyBuffWriteManager(iny)
if not buflenx or not (buflenx == bufleny == buflenz == buflent):
raise ProjError('x,y,z, and time must be same size')
xx = <double *>xdata
yy = <double *>ydata
cdef PyBuffWriteManager zbuff
cdef Py_ssize_t buflenz
cdef double* zz
if inz is not None:
zz = <double *>zdata
zbuff = PyBuffWriteManager(inz)
buflenz = zbuff.len
zz = zbuff.data
else:
buflenz = xbuff.len
zz = NULL
cdef PyBuffWriteManager tbuff
cdef Py_ssize_t buflent
cdef double* tt
if intime is not None:
tt = <double *>tdata
tbuff = PyBuffWriteManager(intime)
buflent = tbuff.len
tt = tbuff.data
else:
buflent = xbuff.len
tt = NULL
npts = buflenx//8
if not xbuff.len or not (xbuff.len == ybuff.len == buflenz == buflent):
raise ProjError('x, y, z, and time must be same size')
cdef Py_ssize_t iii
# degrees to radians
if not self.is_pipeline and not radians\
and self._input_radians[pj_direction]:
with nogil:
for iii in range(npts):
xx[iii] = xx[iii]*_DG2RAD
yy[iii] = yy[iii]*_DG2RAD
for iii in range(xbuff.len):
xbuff.data[iii] = xbuff.data[iii]*_DG2RAD
ybuff.data[iii] = ybuff.data[iii]*_DG2RAD
# radians to degrees
elif not self.is_pipeline and radians\
and not self._input_radians[pj_direction]\
and self.input_geographic:
with nogil:
for iii in range(npts):
xx[iii] = xx[iii]*_RAD2DG
yy[iii] = yy[iii]*_RAD2DG
for iii in range(xbuff.len):
xbuff.data[iii] = xbuff.data[iii]*_RAD2DG
ybuff.data[iii] = ybuff.data[iii]*_RAD2DG
with nogil:
proj_errno_reset(self.projobj)
proj_trans_generic(
self.projobj,
pj_direction,
xx, _DOUBLESIZE, npts,
yy, _DOUBLESIZE, npts,
zz, _DOUBLESIZE, npts,
tt, _DOUBLESIZE, npts,
xbuff.data, _DOUBLESIZE, xbuff.len,
ybuff.data, _DOUBLESIZE, ybuff.len,
zz, _DOUBLESIZE, xbuff.len,
tt, _DOUBLESIZE, xbuff.len,
)
cdef int errno = proj_errno(self.projobj)
if errcheck and errno:
......@@ -478,23 +469,23 @@ cdef class _Transformer(Base):
if not self.is_pipeline and not radians\
and self._output_radians[pj_direction]:
with nogil:
for iii in range(npts):
xx[iii] = xx[iii]*_RAD2DG
yy[iii] = yy[iii]*_RAD2DG
for iii in range(xbuff.len):
xbuff.data[iii] = xbuff.data[iii]*_RAD2DG
ybuff.data[iii] = ybuff.data[iii]*_RAD2DG
# degrees to radians
elif not self.is_pipeline and radians\
and not self._output_radians[pj_direction]\
and self.output_geographic:
with nogil:
for iii in range(npts):
xx[iii] = xx[iii]*_DG2RAD
yy[iii] = yy[iii]*_DG2RAD
for iii in range(xbuff.len):
xbuff.data[iii] = xbuff.data[iii]*_DG2RAD
ybuff.data[iii] = ybuff.data[iii]*_DG2RAD
ProjError.clear()
@cython.boundscheck(False)
@cython.wraparound(False)
def _transform_sequence(
self, Py_ssize_t stride, inseq, bint switch,
self, Py_ssize_t stride, object inseq, bint switch,
direction, time_3rd, radians, errcheck
):
if self.projections_exact_same or (self.projections_equivalent and self.skip_equivalent):
......@@ -502,31 +493,25 @@ cdef class _Transformer(Base):
tmp_pj_direction = _PJ_DIRECTION_MAP[TransformDirection.create(direction)]
cdef PJ_DIRECTION pj_direction = <PJ_DIRECTION>tmp_pj_direction
# private function to itransform function
cdef:
void *buffer
double *coords
double *x
double *y
double *z
double *tt
Py_ssize_t buflen, npts, iii, jjj
cdef double *x
cdef double *y
cdef double *z
cdef double *tt
if stride < 2:
raise ProjError("coordinates must contain at least 2 values")
if PyObject_AsWriteBuffer(inseq, &buffer, &buflen) <> 0:
raise ProjError("object does not provide the python buffer writeable interface")
coords = <double*>buffer
npts = buflen // (stride * _DOUBLESIZE)
cdef PyBuffWriteManager coordbuff = PyBuffWriteManager(inseq)
cdef Py_ssize_t npts, iii, jjj
npts = coordbuff.len // stride
# degrees to radians
if not self.is_pipeline and not radians\
and self._input_radians[pj_direction]:
with nogil:
for iii in range(npts):
jjj = stride * iii
coords[jjj] *= _DG2RAD
coords[jjj + 1] *= _DG2RAD
coordbuff.data[jjj] *= _DG2RAD
coordbuff.data[jjj + 1] *= _DG2RAD
# radians to degrees
elif not self.is_pipeline and radians\
and not self._input_radians[pj_direction]\
......@@ -534,26 +519,26 @@ cdef class _Transformer(Base):
with nogil:
for iii in range(npts):
jjj = stride * iii
coords[jjj] *= _RAD2DG
coords[jjj + 1] *= _RAD2DG
coordbuff.data[jjj] *= _RAD2DG
coordbuff.data[jjj + 1] *= _RAD2DG
if not switch:
x = coords
y = coords + 1
x = coordbuff.data
y = coordbuff.data + 1
else:
x = coords + 1
y = coords
x = coordbuff.data + 1
y = coordbuff.data
# z coordinate
if stride == 4 or (stride == 3 and not time_3rd):
z = coords + 2
z = coordbuff.data + 2
else:
z = NULL
# time
if stride == 3 and time_3rd:
tt = coords + 2
tt = coordbuff.data + 2
elif stride == 4:
tt = coords + 3
tt = coordbuff.data + 3
else:
tt = NULL
......@@ -581,8 +566,8 @@ cdef class _Transformer(Base):
with nogil:
for iii in range(npts):
jjj = stride * iii
coords[jjj] *= _RAD2DG
coords[jjj + 1] *= _RAD2DG
coordbuff.data[jjj] *= _RAD2DG
coordbuff.data[jjj + 1] *= _RAD2DG
# degrees to radians
elif not self.is_pipeline and radians\
and not self._output_radians[pj_direction]\
......@@ -590,7 +575,7 @@ cdef class _Transformer(Base):
with nogil:
for iii in range(npts):
jjj = stride * iii
coords[jjj] *= _DG2RAD
coords[jjj + 1] *= _DG2RAD
coordbuff.data[jjj] *= _DG2RAD
coordbuff.data[jjj + 1] *= _DG2RAD
ProjError.clear()
......@@ -9,6 +9,26 @@ cdef extern from "math.h":
HUGE_VAL
cdef extern from "Python.h":
int PyObject_AsWriteBuffer(object, void **rbuf, Py_ssize_t *len)
cdef struct PyObject
cdef int PyBUF_WRITABLE
int PyObject_GetBuffer(PyObject *exporter, Py_buffer *view, int flags)
void PyBuffer_Release(Py_buffer *view)
cdef class PyBuffWriteManager:
cdef Py_buffer buffer
cdef double* data
cdef public Py_ssize_t len
def __cinit__(self):
self.data = NULL
def __init__(self, object data):
if PyObject_GetBuffer(<PyObject *>data, &self.buffer, PyBUF_WRITABLE) <> 0:
raise BufferError("pyproj had a problem getting the buffer from data.")
self.data = <double *>self.buffer.buf
self.len = self.buffer.len // self.buffer.itemsize
def __dealloc__(self):
PyBuffer_Release(&self.buffer)
self.data = NULL
"""
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",
"false_easting": "x_0",
"false_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",
}
METHOD_NAME_TO_CF_MAP = {"Transverse Mercator": "transverse_mercator"}
PARAM_TO_CF_MAP = {
"Latitude of natural origin": "latitude_of_projection_origin",
"Longitude of natural origin": "longitude_of_central_meridian",
"Latitude of false origin": "latitude_of_projection_origin",
"Longitude of false origin": "longitude_of_central_meridian",
"Scale factor at natural origin": "scale_factor_at_central_meridian",
"Easting at projection centre": "false_easting",
"Northing at projection centre": "false_northing",
"Easting at false origin": "false_easting",
"Northing at false origin": "false_northing",
"False easting": "false_easting",
"False northing": "false_northing",
}
# -*- coding: utf-8 -*-
"""
This module interfaces with PROJ to produce a pythonic interface
to the coordinate reference system (CRS) information through the CRS
class.
Original Author: Alan D. Snow [github.com/snowman2] (2019)
"""
from pyproj._crs import ( # noqa: F401
CoordinateOperation,
CoordinateSystem,
Datum,
Ellipsoid,
PrimeMeridian,
is_proj,
is_wkt,
)
from pyproj.crs.crs import ( # noqa: F401
CRS,
BoundCRS,
CompoundCRS,
DerivedGeographicCRS,
GeographicCRS,
ProjectedCRS,
VerticalCRS,
)
from pyproj.exceptions import CRSError # noqa: F401
This diff is collapsed.