2

I have this text information regarding a CRS: "WGS 84 / UTM zone 31N".

I need to get the corresponding EPSG code or create the corresponding CRS object with PyQGIS.

I could use the QgsCoordinateReferenceSystem class, but I cannot find a method.

Can anyone help me with this?

1

4 Answers 4

4

A follow-up to @user30184's answer that addresses accessing the database using PyQGIS (adapted from this post)

# imports
from os import environ
from os.path import join
from qgis.core import QgsProviderRegistry


def find_crs_auth_id(crs_description: str) -> int:
    """
    Gets the auth_id from a CRS description.
    Based on proj.db
    Parameters:
    ==========
    :param crs_description: the CRS description to check
    Returns:
    ==========
    auth_id, -1 if not found
    """
    db = join(environ['PROJ_LIB'], 'proj.db') # referring to C:/OSGeo4W/share/proj/proj.db

    # set the ogr driver for an sqlite database
    pmd = QgsProviderRegistry.instance().providerMetadata("ogr")

    con = pmd.createConnection(db, {})
    query = f"SELECT code FROM projected_crs WHERE name = '{crs_description}'"
    result = con.executeSql(query)

    return int(result[0]) if len(result) else -1
    
auth_id = find_crs_auth_id("WGS 84 / UTM zone 31N")
print(auth_id) #32631
3

QGIS is using Proj and Proj has the coordinate system parameters stored into a SQLite database named "proj.db". So one alternative could be to query the code directly from that database. Direct string comparison as in the example below might not be very reliable because all the spaces etc. in the string should match. Maybe a fuzzy full text search https://www.sqlite.org/fts3.html would be better.

enter image description here

2
  • Thank you for your answer. Would you know how to make call the database with PyQgis ? I have actually never tried using sql with python Apr 13, 2023 at 12:51
  • 1
    Sorry, I don't. But because you can insert WGS 84 / UTM zone 31N into a search box for selecting the CRS of the project and QGIS finds the right CRS then I suppose that QGIS has the routines that you would need. It is just about where to find them.
    – user30184
    Apr 13, 2023 at 13:21
3

A follow-up to @Matt's answer with a function and QGIS database path that works on every platforms. It utilizes the sqlite3 library.

# imports
import sqlite3
from qgis.core import QgsApplication


def find_crs_auth_id(crs_description: str) -> int:
    """
    Gets the auth_id from a CRS description.
    Based on srs.db
    Parameters:
    ==========
    :param crs_description: the CRS description to check
    Returns:
    ==========
    auth_id if crs was found by the description, else -1
    """
    db = QgsApplication.srsDatabaseFilePath() # referring to .../resources/srs.db
    con = sqlite3.connect(db)
    cur = con.cursor()

    query = f"SELECT auth_id FROM tbl_srs WHERE description = '{crs_description}'"
    result = cur.execute(query)
    row = result.fetchone()
    con.close()

    return row[0] if row is not None else -1


auth_id = find_crs_auth_id("WGS 84 / UTM zone 31N")
print(auth_id) #32631
3

I managed to find the corresponding EPSG CRS code with the pyproj library and the query_utm_crs_info() method.

It returns a complete list of available projections in QGIS, with their name and EPSG.

# imports
from pyproj.database import query_utm_crs_info

def find_crs_auth_id(crs_description: str) -> int:
    """
    Gets the auth_id from a CRS description.
    Based on pyproj.db
    Parameters:
    ==========
    :param crs_description: the CRS description to check
    Returns:
    ==========
    auth_id, -1 if not found
    """

    list_of_crs = query_utm_crs_info()
    result = [c[1] for c in list_of_crs if c[0] == "EPSG" and c[2] == f'{crs_description}']
    
    return int(result[0]) if len(result) else -1
    
auth_id = find_crs_auth_id("WGS 84 / UTM zone 31N")
print(auth_id) #32631
1
  • [c[1] for c in query_utm_crs_info() if c[0] == "EPSG" and c[2] == "WGS 84 / UTM zone 31N"] Apr 14, 2023 at 15:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.