Skip to content

Improve CRS support in OAMaps#2358

Open
doublebyte1 wants to merge 11 commits into
geopython:masterfrom
doublebyte1:crs-parse
Open

Improve CRS support in OAMaps#2358
doublebyte1 wants to merge 11 commits into
geopython:masterfrom
doublebyte1:crs-parse

Conversation

@doublebyte1

@doublebyte1 doublebyte1 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

Overview

This PR enables accepting uris and (safe/unsafe) curies in the crs and bbox-crs parameters of OAM.

Examples of requests:

Related Issue / discussion

#2366

Additional information

In addition, this PR also enable support to all EPSG codes supported by pyproj and the provider.

Examples:

http://localhost:5000/collections/mapserver_world_map/map?f=png&crs=http://www.opengis.net/def/crs/EPSG/0/4269

4269

http://localhost:5000/collections/mapserver_world_map/map?f=png&crs=EPSG:3978&bbox-crs=http://www.opengis.net/def/crs/EPSG/0/4326&bbox=-79.6,43.5,-79.1,43.9

3978

http://localhost:5000/collections/mapserver_world_map/map?f=png&crs=[EPSG:3857]

3857

http://localhost:5000/collections/mapserver_world_map/map?f=png&crs=OGC:CRS84

crs84

Dependency policy (RFC2)

  • I have ensured that this PR meets RFC2 requirements

Updates to public demo

Contributions and licensing

(as per https://github.com/geopython/pygeoapi/blob/master/CONTRIBUTING.md#contributions-and-licensing)

  • I'd like to contribute [feature X|bugfix Y|docs|something else] to pygeoapi. I confirm that my contributions to pygeoapi will be compatible with the pygeoapi license guidelines at the time of contribution
  • I have already previously agreed to the pygeoapi Contributions and Licensing Guidelines

@doublebyte1 doublebyte1 marked this pull request as ready for review June 20, 2026 19:38
Comment thread docs/source/publishing/ogcapi-maps.rst Outdated
- `4326`
- `3857`,
- `CRS84`
supports a `crs` and `bbox-crs` parameters, expressed as an uri or a curie. Currently, this provider supports CRS84 and various crs from the EPSG namespace; for a matter of convenience, they can be expressed

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • s/curie/CURIE/g
  • s/various crs/various CRS/g

Comment thread docs/source/publishing/ogcapi-maps.rst Outdated
- `3857`,
- `CRS84`
supports a `crs` and `bbox-crs` parameters, expressed as an uri or a curie. Currently, this provider supports CRS84 and various crs from the EPSG namespace; for a matter of convenience, they can be expressed
also as unsafe curies.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • s/curies/CURIEs/g

from urllib.parse import urlencode

from pygeoapi.crs import get_crs_curie
from pyproj.exceptions import CRSError

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

import logging
from urllib.parse import urlencode

from pyproj.exceptions import CRSError

from pygeoapi.crs import get_crs_curie

(ordering by standard packages, 3rd party, local).

Comment thread pygeoapi/crs.py Outdated
"""

try:
str = str.lower()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

str is a Python keyword, suggest str_.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will actually replace it with crs, which makes even more sense.

Comment thread pygeoapi/crs.py Outdated
if not str.startswith(("http://", "https://")):
raise CRSError('Not an uri')

str = str.lower()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/str/str_/g

Comment thread pygeoapi/crs.py Outdated
if path_el[4] == 'epsg':
return f'EPSG:{path_el[6]}'
elif path_el[6] != 'crs84':
raise CRSError('Unsupported crs')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/crs/CRS/g

@doublebyte1 doublebyte1 requested a review from tomkralidis June 21, 2026 16:22
Comment thread pygeoapi/crs.py
curie = crs.strip('[]')
LOGGER.debug(f'Attempt to parse a curie: {curie}')

curie_el = curie.split(':')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could do [curie_auth, curie_code] = curie.split(':') if we aren't using the fully qualified array anywhere.

Comment thread pygeoapi/crs.py
return supported_crs_list


def get_crs_uri(crs) -> str:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be worth trying to keep function naming conventions in this file. Because it's in pygeoapi.crs I had omitted the _crs component for get_crs (previous named get_crs_from_uri) and get_srid. Could this be:

def get_uri(crs: CRS) -> str:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could also do the opposite where get_srid becomes get_crs_srid

Comment thread pygeoapi/crs.py
return e


def get_crs_curie(crs) -> str:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above,

def get_curie(crs: CRS | str) -> str:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants