Skip to content

Commit

Permalink
Merge 8b20d64 into 9e4e720
Browse files Browse the repository at this point in the history
  • Loading branch information
snowman2 committed Jan 23, 2020
2 parents 9e4e720 + 8b20d64 commit bbd4181
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 31 deletions.
151 changes: 127 additions & 24 deletions pyproj/_crs.pyx
Expand Up @@ -5,9 +5,18 @@ from collections import OrderedDict

from pyproj._datadir cimport pyproj_context_initialize
from pyproj.compat import cstrencode, pystrdecode
from pyproj.crs.ellipsoid import CustomEllipsoid
from pyproj.crs.enums import CoordinateOperationType, DatumType
from pyproj.enums import ProjVersion, WktVersion
from pyproj.exceptions import CRSError
from pyproj.geod import pj_ellps


# This is for looking up the ellipsoid parameters
# based on the long name
_PJ_ELLPS_NAME_MAP = {
ellps["description"]: ellps_id for ellps_id, ellps in pj_ellps.items()
}


cdef cstrdecode(const char *instring):
Expand Down Expand Up @@ -911,25 +920,22 @@ cdef class Ellipsoid(_CRSParts):
return Ellipsoid.from_json_dict(_load_proj_json(ellipsoid_json_str))

@staticmethod
def from_name(
def _from_name(
ellipsoid_name,
auth_name=None,
auth_name,
):
"""
.. versionadded:: 2.5.0
Create a Ellipsoid from a name.
Examples:
- WGS 84
Parameters
----------
ellipsoid_name: str
Ellipsoid name.
auth_name: str, optional
auth_name: str
The authority name to refine search (e.g. 'EPSG').
If None, will search all authorities. Default is None.
If None, will search all authorities.
Returns
-------
Expand All @@ -954,6 +960,56 @@ cdef class Ellipsoid(_CRSParts):
return Ellipsoid.create(context, ellipsoid_pj)


@staticmethod
def from_name(
ellipsoid_name,
auth_name=None,
):
"""
.. versionadded:: 2.5.0
Create a Ellipsoid from a name.
Examples:
- WGS 84
Parameters
----------
ellipsoid_name: str
Ellipsoid name.
auth_name: str, optional
The authority name to refine search (e.g. 'EPSG').
If None, will search all authorities. Default is None.
Returns
-------
Ellipsoid
"""
try:
return Ellipsoid._from_name(
ellipsoid_name=ellipsoid_name,
auth_name=auth_name,
)
except CRSError:
if auth_name not in ("PROJ", None):
raise
pass

# add support for past names for PROJ ellipsoids
try:
ellipsoid_params = pj_ellps[
_PJ_ELLPS_NAME_MAP.get(ellipsoid_name, ellipsoid_name)
]
except KeyError:
raise CRSError("Invalid ellipsoid name: {}".format(ellipsoid_name))
return CustomEllipsoid(
name=ellipsoid_params["description"],
semi_major_axis=ellipsoid_params["a"],
semi_minor_axis=ellipsoid_params.get("b"),
inverse_flattening=ellipsoid_params.get("rf"),
)


cdef class PrimeMeridian(_CRSParts):
"""
.. versionadded:: 2.0.0
Expand Down Expand Up @@ -1386,43 +1442,33 @@ cdef class Datum(_CRSParts):
return Datum.from_name(datum_string)

@staticmethod
def from_name(
def _from_name(
datum_name,
auth_name=None,
datum_type=DatumType.GEODETIC_REFERENCE_FRAME,
auth_name,
datum_type,
):
"""
.. versionadded:: 2.5.0
Create a Datum from a name.
Examples:
- WGS 84
- World Geodetic System 1984
Parameters
----------
datum_name: str
Datum name.
auth_name: str, optional
auth_name: str
The authority name to refine search (e.g. 'EPSG').
If None, will search all authorities. Default is None.
If None, will search all authorities.
datum_type: DatumType, optional
The datum type to create. Default is DatumType.GEODETIC_REFERENCE_FRAME.
The datum type to create.
Returns
-------
Datum
"""
pj_datum_type = _PJ_DATUM_TYPE_MAP[DatumType.create(datum_type)]
pj_datum_type = _PJ_DATUM_TYPE_MAP[datum_type]
cdef PJ_CONTEXT* context = proj_context_create()
pyproj_context_initialize(context, True)
# ensure the PROJ string name matches properly
# https://github.com/OSGeo/PROJ/issues/1823
datum_name = _DATUM_NAME_MAP.get(
datum_name.upper().replace(" ", ""),
datum_name,
)
cdef PJ* datum_pj = _from_name(
context,
datum_name,
Expand All @@ -1439,6 +1485,63 @@ cdef class Datum(_CRSParts):
CRSError.clear()
return Datum.create(context, datum_pj)

@staticmethod
def from_name(
datum_name,
auth_name=None,
datum_type=DatumType.GEODETIC_REFERENCE_FRAME,
):
"""
.. versionadded:: 2.5.0
Create a Datum from a name.
Examples:
- WGS 84
- World Geodetic System 1984
Parameters
----------
datum_name: str
Datum name.
auth_name: str, optional
The authority name to refine search (e.g. 'EPSG').
If None, will search all authorities. Default is None.
datum_type: DatumType, optional
The datum type to create. Default is DatumType.GEODETIC_REFERENCE_FRAME.
Returns
-------
Datum
"""
datum_type = DatumType.create(datum_type)
try:
return Datum._from_name(
datum_name=datum_name,
auth_name=auth_name,
datum_type=datum_type,
)
except CRSError:
if (
auth_name not in ("PROJ", None)
or datum_type!=DatumType.GEODETIC_REFERENCE_FRAME
):
raise
pass
# add support for PROJ datum aliases
# https://github.com/OSGeo/PROJ/issues/1823
try:
datum_name=_DATUM_NAME_MAP[datum_name.upper().replace(" ", "")]
except KeyError:
raise CRSError(
"Invalid datum name: {}".format(datum_name)
)
return Datum.from_name(
datum_name=datum_name,
auth_name=auth_name,
datum_type=datum_type,
)

@staticmethod
def from_json_dict(datum_dict):
"""
Expand Down
5 changes: 4 additions & 1 deletion pyproj/crs/ellipsoid.py
Expand Up @@ -10,6 +10,7 @@ class CustomEllipsoid(Ellipsoid):

def __new__(
cls,
name="undefined",
semi_major_axis=None,
inverse_flattening=None,
semi_minor_axis=None,
Expand All @@ -18,6 +19,8 @@ def __new__(
"""
Parameters
----------
name: str, optional
Name of the ellipsoid. Default is 'undefined'.
semi_major_axis: float, optional
The semi major axis in meters. Required if missing radius.
inverse_flattening: float, optional
Expand All @@ -33,7 +36,7 @@ def __new__(
ellipsoid_json = {
"$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
"type": "Ellipsoid",
"name": "undefined",
"name": name,
}
if semi_major_axis is not None:
ellipsoid_json["semi_major_axis"] = semi_major_axis
Expand Down
26 changes: 22 additions & 4 deletions test/crs/test_crs.py
Expand Up @@ -848,10 +848,15 @@ def test_datum_from_name__auth_type(auth_name):
"invalid_str", ["3-598y5-98y", "urn:ogc:def:ellipsoid:EPSG::7001"]
)
def test_datum__from_name__invalid(invalid_str):
with pytest.raises(CRSError, match="Invalid datum"):
with pytest.raises(CRSError, match="Invalid datum name:"):
Datum.from_name(invalid_str)


def test_datum__from_name__invalid_type():
with pytest.raises(CRSError, match="Invalid datum name: WGS84"):
Datum.from_name("WGS84", datum_type="VERTICAL_REFERENCE_FRAME")


@pytest.mark.parametrize(
"invalid_str", ["3-598y5-98y", "urn:ogc:def:ellipsoid:EPSG::7001"]
)
Expand All @@ -866,9 +871,17 @@ def test_ellipsoid__from_string(input_str):
assert ee.name == "Airy 1830"


def test_ellipsoid__from_name():
ee = Ellipsoid.from_name("Airy 1830")
assert ee.name == "Airy 1830"
@pytest.mark.parametrize(
"input_str,long_name",
[
("Airy 1830", "Airy 1830"),
("intl", "International 1909 (Hayford)"),
("International 1909 (Hayford)", "International 1909 (Hayford)"),
],
)
def test_ellipsoid__from_name(input_str, long_name):
ee = Ellipsoid.from_name(input_str)
assert ee.name == long_name


@pytest.mark.parametrize("invalid_str", ["3-598y5-98y", "urn:ogc:def:datum:EPSG::6326"])
Expand All @@ -877,6 +890,11 @@ def test_ellipsoid__from_name__invalid(invalid_str):
Ellipsoid.from_name(invalid_str)


def test_ellipsoid__from_name__invalid__auth():
with pytest.raises(CRSError, match="Invalid ellipsoid"):
Ellipsoid.from_name("intl", auth_name="ESRI")


@pytest.mark.parametrize("invalid_str", ["3-598y5-98y", "urn:ogc:def:datum:EPSG::6326"])
def test_ellipsoid__from_string__invalid(invalid_str):
with pytest.raises(CRSError, match="Invalid ellipsoid"):
Expand Down
6 changes: 4 additions & 2 deletions test/crs/test_crs_ellipsoid.py
Expand Up @@ -19,8 +19,10 @@ def test_custom_ellipsoid():


def test_custom_ellipsoid__minor():
ce = CustomEllipsoid(semi_major_axis=6378137, semi_minor_axis=6356752.314)
assert ce.name == "undefined"
ce = CustomEllipsoid(
name="test", semi_major_axis=6378137, semi_minor_axis=6356752.314
)
assert ce.name == "test"
assert ce.semi_major_metre == 6378137
assert ce.semi_minor_metre == 6356752.314
assert_almost_equal(ce.inverse_flattening, 298.25722014)
Expand Down

0 comments on commit bbd4181

Please sign in to comment.