117 lines
3.6 KiB
Python
117 lines
3.6 KiB
Python
|
"""
|
||
|
This module is for building datums to be used when
|
||
|
building a CRS.
|
||
|
"""
|
||
|
from typing import Any, Dict, Optional, Union
|
||
|
|
||
|
from pyproj._crs import Datum, Ellipsoid, PrimeMeridian
|
||
|
|
||
|
|
||
|
class CustomDatum(Datum):
|
||
|
"""
|
||
|
.. versionadded:: 2.5.0
|
||
|
|
||
|
Class to build a datum based on an ellipsoid and prime meridian.
|
||
|
"""
|
||
|
|
||
|
def __new__(
|
||
|
cls,
|
||
|
name: str = "undefined",
|
||
|
ellipsoid: Any = "WGS 84",
|
||
|
prime_meridian: Any = "Greenwich",
|
||
|
):
|
||
|
"""
|
||
|
Parameters
|
||
|
----------
|
||
|
name: str, optional
|
||
|
Name of the datum. Default is 'undefined'.
|
||
|
ellipsoid: Any, optional
|
||
|
Anything accepted by :meth:`pyproj.crs.Ellipsoid.from_user_input`
|
||
|
or a :class:`pyproj.crs.datum.CustomEllipsoid`.
|
||
|
prime_meridian: Any, optional
|
||
|
Anything accepted by :meth:`pyproj.crs.PrimeMeridian.from_user_input`.
|
||
|
"""
|
||
|
datum_json = {
|
||
|
"$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
|
||
|
"type": "GeodeticReferenceFrame",
|
||
|
"name": name,
|
||
|
"ellipsoid": Ellipsoid.from_user_input(ellipsoid).to_json_dict(),
|
||
|
"prime_meridian": PrimeMeridian.from_user_input(
|
||
|
prime_meridian
|
||
|
).to_json_dict(),
|
||
|
}
|
||
|
return cls.from_json_dict(datum_json)
|
||
|
|
||
|
|
||
|
class CustomEllipsoid(Ellipsoid):
|
||
|
"""
|
||
|
.. versionadded:: 2.5.0
|
||
|
|
||
|
Class to build a custom ellipsoid.
|
||
|
"""
|
||
|
|
||
|
def __new__(
|
||
|
cls,
|
||
|
name: str = "undefined",
|
||
|
semi_major_axis: Optional[float] = None,
|
||
|
inverse_flattening: Optional[float] = None,
|
||
|
semi_minor_axis: Optional[float] = None,
|
||
|
radius: Optional[float] = None,
|
||
|
):
|
||
|
"""
|
||
|
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
|
||
|
The inverse flattening in meters.
|
||
|
Required if missing semi_minor_axis and radius.
|
||
|
semi_minor_axis: float, optional
|
||
|
The semi minor axis in meters.
|
||
|
Required if missing inverse_flattening and radius.
|
||
|
radius: float, optional
|
||
|
The radius in meters. Can only be used alone.
|
||
|
Cannot be mixed with other parameters.
|
||
|
"""
|
||
|
ellipsoid_json = {
|
||
|
"$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
|
||
|
"type": "Ellipsoid",
|
||
|
"name": name,
|
||
|
} # type: Dict[str, Union[float, str]]
|
||
|
if semi_major_axis is not None:
|
||
|
ellipsoid_json["semi_major_axis"] = semi_major_axis
|
||
|
if inverse_flattening is not None:
|
||
|
ellipsoid_json["inverse_flattening"] = inverse_flattening
|
||
|
if semi_minor_axis is not None:
|
||
|
ellipsoid_json["semi_minor_axis"] = semi_minor_axis
|
||
|
if radius is not None:
|
||
|
ellipsoid_json["radius"] = radius
|
||
|
return cls.from_json_dict(ellipsoid_json)
|
||
|
|
||
|
|
||
|
class CustomPrimeMeridian(PrimeMeridian):
|
||
|
"""
|
||
|
.. versionadded:: 2.5.0
|
||
|
|
||
|
Class to build a prime meridian based on a longitude.
|
||
|
"""
|
||
|
|
||
|
def __new__(cls, longitude: float, name: str = "undefined"):
|
||
|
"""
|
||
|
Parameters
|
||
|
----------
|
||
|
longitude: float
|
||
|
Longitude of prime meridian.
|
||
|
name: str, optional
|
||
|
Name of the prime meridian.
|
||
|
"""
|
||
|
datum_json = {
|
||
|
"$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
|
||
|
"type": "PrimeMeridian",
|
||
|
"name": name,
|
||
|
"longitude": longitude,
|
||
|
}
|
||
|
return cls.from_json_dict(datum_json)
|