Skip to content

Commit

Permalink
Rip off a band aid, and deprecate all "proj4" calls from the API
Browse files Browse the repository at this point in the history
Alias these across to new "proj" methods, which don't include the
version number.
  • Loading branch information
nyalldawson committed Dec 20, 2019
1 parent 6654870 commit b37dd09
Show file tree
Hide file tree
Showing 36 changed files with 506 additions and 341 deletions.
172 changes: 132 additions & 40 deletions python/core/auto_generated/qgscoordinatereferencesystem.sip.in
Expand Up @@ -34,12 +34,12 @@ latitude/longitude in degrees. The most common one is World Geodetic System 84 (
typically using meters or feet as units. Common projected coordinate systems are Universal
Transverse Mercator or Albers Equal Area.

Internally QGIS uses proj4 library for all the math behind coordinate transformations, so in case
Internally QGIS uses proj library for all the math behind coordinate transformations, so in case
of any troubles with projections it is best to examine the PROJ representation within the object,
as that is the representation that will be ultimately used.

Methods that allow inspection of CRS instances include isValid(), authid(), description(),
toWkt(), toProj4(), mapUnits() and others.
toWkt(), toProj(), mapUnits() and others.
Creation of CRS instances is further described in \ref crs_construct_and_copy section below.
Transformations between coordinate reference systems are done using QgsCoordinateTransform class.

Expand All @@ -50,7 +50,7 @@ For example, the following code will create and inspect "British national grid"
crs = QgsCoordinateReferenceSystem("EPSG:27700")
if crs.isValid():
print("CRS Description: {}".format(crs.description()))
print("CRS PROJ text: {}".format(crs.toProj4()))
print("CRS PROJ text: {}".format(crs.toProj()))
else:
print("Invalid CRS!")

Expand Down Expand Up @@ -83,11 +83,11 @@ See authid() and createFromOgcWmsCrs() methods.

2. **PROJ string.** This is a string consisting of a series of key/value pairs in the following
format: `+param1=value1 +param2=value2 [...]`. This is the format natively used by the
underlying proj4 library. For example, the definition of WGS84 looks like this:
underlying proj library. For example, the definition of WGS84 looks like this:

+proj=longlat +datum=WGS84 +no_defs

See toProj4() and createFromProj4() methods.
See toProj() and createFromProj() methods.

3. **Well-known text (WKT).** Defined by Open Geospatial Consortium (OGC), this is another common
format to define CRS. For WGS84 the OGC WKT definition is the following:
Expand Down Expand Up @@ -169,6 +169,12 @@ both flavors.
EpsgCrsId
};

enum Format
{
FormatWkt,
FormatProj,
};

QgsCoordinateReferenceSystem();
%Docstring
Constructs an invalid CRS object
Expand All @@ -185,7 +191,7 @@ It supports the following formats:
- "EPSG:<code>" - handled with createFromOgcWms()
- "POSTGIS:<srid>" - handled with createFromSrid()
- "INTERNAL:<srsid>" - handled with createFromSrsId()
- "PROJ4:<proj4>" - handled with createFromProj4()
- "PROJ4:<proj4>" - handled with createFromProj()
- "WKT:<wkt>" - handled with createFromWkt()

If no prefix is specified, WKT definition is assumed.
Expand All @@ -202,8 +208,9 @@ Constructor a CRS object using a PostGIS SRID, an EPSG code or an internal QGIS

.. note::

We encourage you to use EPSG code, WKT or Proj4 to describe CRS's in your code
wherever possible. Internal QGIS CRS IDs are not guaranteed to be permanent / involatile.
We encourage you to use EPSG code or WKT to describe CRSes in your code
wherever possible. Internal QGIS CRS IDs are not guaranteed to be permanent / involatile,
and proj strings are a lossy format.

:param id: The ID valid for the chosen CRS ID type
:param type: One of the types described in CrsType
Expand Down Expand Up @@ -253,17 +260,31 @@ Creates a CRS from a given EPSG ID.
.. versionadded:: 3.0
%End

static QgsCoordinateReferenceSystem fromProj4( const QString &proj4 );
static QgsCoordinateReferenceSystem fromProj4( const QString &proj4 ) /Deprecated/;
%Docstring
Creates a CRS from a proj4 style formatted string.
Creates a CRS from a proj style formatted string.

:param proj4: proj4 format string
:param proj: proj format string

:return: matching CRS, or an invalid CRS if string could not be matched

.. seealso:: :py:func:`createFromProj4`
.. seealso:: :py:func:`createFromProj`

.. versionadded:: 3.0
.. deprecated::
Use fromProj() instead.
%End

static QgsCoordinateReferenceSystem fromProj( const QString &proj );
%Docstring
Creates a CRS from a proj style formatted string.

:param proj: proj format string

:return: matching CRS, or an invalid CRS if string could not be matched

.. seealso:: :py:func:`createFromProj`

.. versionadded:: 3.10.3
%End

static QgsCoordinateReferenceSystem fromWkt( const QString &wkt );
Expand Down Expand Up @@ -304,8 +325,9 @@ Sets this CRS by lookup of the given ID in the CRS database.

.. note::

We encourage you to use EPSG code, WKT or Proj4 to describe CRS's in your code
wherever possible. Internal QGIS CRS IDs are not guaranteed to be permanent / involatile.
We encourage you to use EPSG code or WKT to describe CRSes in your code
wherever possible. Internal QGIS CRS IDs are not guaranteed to be permanent / involatile,
and Proj strings are a lossy format.
%End


Expand Down Expand Up @@ -342,8 +364,6 @@ Sets this CRS using a WKT definition.

If EPSG code of the WKT definition can be determined, it is extracted
and createFromOgcWmsCrs() is used to initialize the object.
Otherwise the WKT will be converted to a proj4 string and createFromProj4()
set up the object.

:param wkt: The WKT for the desired spatial reference system.

Expand Down Expand Up @@ -378,25 +398,63 @@ user's local CRS database from home directory is used.
.. seealso:: :py:func:`fromSrsId`
%End

bool createFromProj4( const QString &projString );
bool createFromProj4( const QString &projString ) /Deprecated/;
%Docstring
Sets this CRS by passing it a PROJ style formatted string.

The string will be parsed and the projection and ellipsoid
members set and the remainder of the Proj string will be stored
in the parameters member. The reason for this is so that we
can easily present the user with 'natural language' representation
of the projection and ellipsoid by looking them up in the srs.db sqlite
database.

We try to match the Proj string to internal QGIS CRS ID using the following logic:

- ask the Proj library to identify the CRS to a standard registered CRS (e.g. EPSG codes)
- if no match is found, compare the CRS to all user CRSes, using the Proj library
to determine CRS equivalence (hence making the match parameter order insensitive)
- if none of the above match, use the Proj string to create the CRS and do not
associated an internal CRS ID to it.

:param projString: A Proj format string

:return: ``True`` on success else ``False``

.. note::

Some members may be left blank if no match can be found in CRS database.

.. note::

this method uses an internal cache. Call invalidateCache() to clear the cache.

.. seealso:: :py:func:`fromProj`

.. deprecated::
Use createFromProj() instead
%End

bool createFromProj( const QString &projString );
%Docstring
Sets this CRS by passing it a PROJ style formatted string.

The string will be parsed and the projection and ellipsoid
members set and the remainder of the proj4 string will be stored
members set and the remainder of the Proj string will be stored
in the parameters member. The reason for this is so that we
can easily present the user with 'natural language' representation
of the projection and ellipsoid by looking them up in the srs.db sqlite
database.

We try to match the proj4 string to internal QGIS CRS ID using the following logic:
We try to match the Proj string to internal QGIS CRS ID using the following logic:

- perform a whole text search on proj4 string (if not null)
- if not match is found, split proj4 into individual parameters and try to find
a match where the parameters are in a different order
- if none of the above match, use findMatchingProj()
- ask the Proj library to identify the CRS to a standard registered CRS (e.g. EPSG codes)
- if no match is found, compare the CRS to all user CRSes, using the Proj library
to determine CRS equivalence (hence making the match parameter order insensitive)
- if none of the above match, use the Proj string to create the CRS and do not
associated an internal CRS ID to it.

:param projString: A proj4 format string
:param projString: A Proj format string

:return: ``True`` on success else ``False``

Expand All @@ -408,7 +466,9 @@ a match where the parameters are in a different order

this method uses an internal cache. Call invalidateCache() to clear the cache.

.. seealso:: :py:func:`fromProj4`
.. seealso:: :py:func:`fromProj`

.. versionadded:: 3.10.3
%End

bool createFromString( const QString &definition );
Expand All @@ -419,7 +479,7 @@ It supports the following formats:
- "EPSG:<code>" - handled with createFromOgcWms()
- "POSTGIS:<srid>" - handled with createFromSrid()
- "INTERNAL:<srsid>" - handled with createFromSrsId()
- "PROJ4:<proj4>" - handled with createFromProj4()
- "PROJ4:<proj4>" - handled with createFromProj()
- "WKT:<wkt>" - handled with createFromWkt()

If no prefix is specified, WKT definition is assumed.
Expand Down Expand Up @@ -491,17 +551,20 @@ if that involves resorting to a hard coded default of geocs:wgs84.
%End


long findMatchingProj();
long findMatchingProj() /Deprecated/;
%Docstring
Walks the CRS databases (both system and user database) trying to match
stored PROJ string to a database entry in order to fill in further
pieces of information about CRS.

.. note::

The ellipsoid and projection acronyms must be set as well as the proj4string!
The ellipsoid and projection acronyms must be set as well as the proj string!

:return: long the SrsId of the matched CRS, zero if no match was found

.. deprecated::
Not used in Proj >= 6 based builds
%End

bool operator==( const QgsCoordinateReferenceSystem &srs ) const;
Expand Down Expand Up @@ -582,7 +645,7 @@ user.
%Docstring
Returns the projection acronym for the projection used by the CRS.

:return: the official proj4 acronym for the projection family
:return: the official Proj acronym for the projection family

.. note::

Expand All @@ -595,7 +658,7 @@ Returns the projection acronym for the projection used by the CRS.
%Docstring
Returns the ellipsoid acronym for the ellipsoid used by the CRS.

:return: the official proj4 acronym for the ellipoid
:return: the official authority:code identifier for the ellipoid, or PARAMETER:MAJOR:MINOR for custom ellipsoids

.. note::

Expand Down Expand Up @@ -624,24 +687,48 @@ only used on builds based on Proj >= 6, with earlier versions always using WKT1_
If ``multiline`` is ``True`` then a formatted multiline string will be returned, using the specified ``indentationWidth``.
This is only used on builds based on Proj >= 6.

.. seealso:: :py:func:`toProj4`
.. seealso:: :py:func:`toProj`
%End

QString toProj4() const;
QString toProj4() const /Deprecated/;
%Docstring
Returns a Proj4 string representation of this CRS.
Returns a Proj string representation of this CRS.

If proj and ellps keys are found in the parameters,
they will be stripped out and the projection and ellipsoid acronyms will be
overridden with these.

:return: Proj4 format string that defines this CRS.
:return: Proj format string that defines this CRS.

.. note::
.. warning::

Not all CRS definitions can be represented by Proj strings. An empty
string will be returned if the CRS could not be represented by a Proj string.

.. seealso:: :py:func:`toWkt`

.. deprecated::
use toProj() instead.
%End

QString toProj() const;
%Docstring
Returns a Proj string representation of this CRS.

If proj and ellps keys are found in the parameters,
they will be stripped out and the projection and ellipsoid acronyms will be
overridden with these.

:return: Proj format string that defines this CRS.

.. warning::

an empty string will be returned if the CRS could not be represented by a Proj4 string
Not all CRS definitions can be represented by Proj strings. An empty
string will be returned if the CRS could not be represented by a Proj string.

.. seealso:: :py:func:`toWkt`

.. versionadded:: 3.10.3
%End

bool isGeographic() const;
Expand Down Expand Up @@ -696,14 +783,19 @@ Update proj.4 parameters in our database from proj.4
This is used internally and should not be necessary to call in client code
%End

long saveAsUserCrs( const QString &name, bool storeWkt = true );
long saveAsUserCrs( const QString &name, Format nativeFormat = FormatWkt );
%Docstring
Saves the CRS as a custom ("USER") CRS.

Returns the new CRS srsid(), or -1 if the CRS could not be saved.

If ``storeWkt`` is ``True`` then the WKT representation of the CRS will be stored in the database.
If it is ``False``, then only the lossy PROJ string representation of the CRS will be stored (not recommended).
The ``nativeFormat`` argument specifies the format to use when saving the CRS
definition. FormatWkt is recommended as it is a lossless format.

.. warning::

Not all CRS definitions can be represented as a Proj string, so
take care when using the FormatProj option.
%End

QString geographicCrsAuthId() const;
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/db_manager/db_plugins/postgis/connector.py
Expand Up @@ -662,7 +662,7 @@ def getCrs(self, srid):
return QgsCoordinateReferenceSystem()

proj4text = res[0]
crs = QgsCoordinateReferenceSystem.fromProj4(proj4text)
crs = QgsCoordinateReferenceSystem.fromProj(proj4text)
return crs

def getSpatialRefInfo(self, srid):
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/processing/algs/gdal/GdalUtils.py
Expand Up @@ -436,4 +436,4 @@ def gdal_crs_string(crs):
return crs.authid()

# fallback to proj4 string, stripping out newline characters
return crs.toProj4().replace('\n', ' ').replace('\r', ' ')
return crs.toProj().replace('\n', ' ').replace('\r', ' ')
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/grass7/Grass7Algorithm.py
Expand Up @@ -1011,7 +1011,7 @@ def setSessionProjectionFromProject(self):
"""
if not Grass7Utils.projectionSet and iface:
self.destination_crs = iface.mapCanvas().mapSettings().destinationCrs()
proj4 = iface.mapCanvas().mapSettings().destinationCrs().toProj4()
proj4 = iface.mapCanvas().mapSettings().destinationCrs().toProj()
command = 'g.proj -c proj4="{}"'.format(proj4)
self.commands.append(command)
Grass7Utils.projectionSet = True
Expand All @@ -1022,7 +1022,7 @@ def setSessionProjectionFromLayer(self, layer):
We creates a PROJ4 definition which is transmitted to Grass
"""
if not Grass7Utils.projectionSet:
proj4 = str(layer.crs().toProj4())
proj4 = str(layer.crs().toProj())
self.destination_crs = layer.crs()
command = 'g.proj -c proj4="{}"'.format(proj4)
self.commands.append(command)
Expand Down
4 changes: 2 additions & 2 deletions python/plugins/processing/algs/grass7/ext/r_proj.py
Expand Up @@ -28,7 +28,7 @@
def processInputs(alg, parameters, context, feedback):
# Grab the projection from the input vector layer
layer = alg.parameterAsLayer(parameters, 'input', context)
layerCrs = layer.crs().toProj4()
layerCrs = layer.crs().toProj()

# Creates a new location with this Crs
newLocation = 'newProj{}'.format(alg.uniqueSuffix)
Expand All @@ -49,7 +49,7 @@ def processInputs(alg, parameters, context, feedback):
# Grab the projected Crs
crs = alg.parameterAsCrs(parameters, 'crs', context)
alg.commands.append('g.proj -c proj4="{}"'.format(
crs.toProj4(), newLocation))
crs.toProj(), newLocation))

# Remove crs parameter
alg.removeParameter('crs')
Expand Down

0 comments on commit b37dd09

Please sign in to comment.