Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions pygeoapi/api/tiles.py
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,8 @@ def tilematrixsets(api: API,
}]

if request.format == F_HTML: # render
content = render_j2_template(api.tpl_config, api.tpl_config,
content = render_j2_template(api.tpl_config,
api.config['server']['templates'],
'tilematrixsets/index.html',
tms, request.locale)
return headers, HTTPStatus.OK, content
Expand Down Expand Up @@ -436,7 +437,8 @@ def tilematrixset(api: API,
}

if request.format == F_HTML: # render
content = render_j2_template(api.tpl_config, api.tpl_config,
content = render_j2_template(api.tpl_config,
api.config['server']['templates'],
'tilematrixsets/tilematrixset.html',
tms, request.locale)
return headers, HTTPStatus.OK, content
Expand Down
23 changes: 23 additions & 0 deletions pygeoapi/crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,25 @@ def _inplace_replace_geometry_filter_name(
sub_node, geometry_column_name)


def normalize_crs_uri(crs: str) -> str:
"""Normalize a CRS identifier to the canonical URL form.

Accepts the shorthand "EPSG:xxxx" and returns the corresponding
http://www.opengis.net/def/crs/EPSG/0/xxxx URI, so that a query
parameter can be matched against the supported-CRS list which uses
URL form. Non-EPSG inputs are returned unchanged.

:param crs: CRS identifier (URL, URN, or "AUTHORITY:CODE").
:returns: Canonical URL-form URI when the input is an EPSG shorthand,
else the input unchanged.
"""
if ':' in crs and '/' not in crs:
authority, _, code = crs.partition(':')
if authority.upper() == 'EPSG' and code.isdigit():
return f'http://www.opengis.net/def/crs/EPSG/0/{code}'
return crs


def create_crs_transform_spec(
provider_def: dict, query_crs_uri: Optional[str] = None
) -> Union[None, CrsTransformSpec]:
Expand Down Expand Up @@ -565,6 +584,10 @@ def create_crs_transform_spec(
else:
query_crs_uri = DEFAULT_CRS
LOGGER.debug(f'no crs parameter, using default: {query_crs_uri}')
else:
# Allow the common shorthand "EPSG:xxxx" in addition to the full
# URI form; both denote the same CRS.
query_crs_uri = normalize_crs_uri(query_crs_uri)

supported_crs_list = get_supported_crs_list(provider_def)
# Check that the crs specified by the query parameter is supported.
Expand Down
10 changes: 8 additions & 2 deletions pygeoapi/process/manager/mongodb_.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,15 @@ def get_jobs(self, status=None, limit=None, offset=None):
database = self.db.job_manager_pygeoapi
collection = database.jobs
if status is not None:
jobs = list(collection.find({}, {"status": status}))
query = {"status": status}
else:
jobs = list(collection.find({}))
query = {}
cursor = collection.find(query)
if offset:
cursor = cursor.skip(offset)
if limit:
cursor = cursor.limit(limit)
jobs = list(cursor)
LOGGER.info("JOBMANAGER - MongoDB jobs queried")
return {
'jobs': jobs,
Expand Down
5 changes: 5 additions & 0 deletions pygeoapi/process/manager/postgresql.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@ def get_jobs(
if status is not None:
results = results.filter(self.c.status == status.value)

if offset:
results = results.offset(offset)
if limit:
results = results.limit(limit)

jobs = [r._asdict() for r in results.all()]
return {'jobs': jobs, 'numberMatched': len(jobs)}

Expand Down
10 changes: 8 additions & 2 deletions pygeoapi/provider/mapscript_.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,16 @@ def __init__(self, provider_def):

self._layer.type = getattr(mapscript, self.options['type'])

# The documented configuration surface is storage_crs (a URI
# such as "http://www.opengis.net/def/crs/EPSG/0/2169").
# options.projection is the legacy integer override kept for
# backward compatibility: when it is present it still wins,
# so existing deployments that rely on it keep working.
try:
self.crs = int(self.options['projection'])
except KeyError:
self.crs = 4326
except (KeyError, ValueError):
crs_epsg = self.storage_crs.to_epsg()
self.crs = crs_epsg if crs_epsg is not None else 4326

self._layer.setProjection(self._epsg2projstring(self.crs))

Expand Down
18 changes: 15 additions & 3 deletions pygeoapi/provider/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
from decimal import Decimal
import functools
import logging
from typing import Optional, Any
from typing import Optional, Any, Union

from geoalchemy2 import Geometry # noqa - this isn't used explicitly but is needed to process Geometry columns
from geoalchemy2.functions import ST_MakeEnvelope, ST_Intersects
Expand All @@ -60,7 +60,7 @@
desc,
delete
)
from sqlalchemy.engine import URL, Engine
from sqlalchemy.engine import URL, Engine, make_url
from sqlalchemy.exc import (
ConstraintColumnNotFoundError,
InvalidRequestError,
Expand Down Expand Up @@ -649,7 +649,7 @@ def get_engine(
database: str,
user: str,
password: str,
conn_str: Optional[str] = None,
conn_str: Optional[Union[str, URL]] = None,
**connect_args
) -> Engine:
"""
Expand Down Expand Up @@ -679,6 +679,18 @@ def get_engine(
port=int(port),
database=database
)
else:
# A caller-provided URL with a bare driver name (e.g. "postgresql://")
# resolves to SQLAlchemy's default DBAPI for that backend (psycopg v3
# for PostgreSQL), which may not be installed. Honour the provider's
# driver_name when the URL does not already pin one.
parsed = make_url(conn_str)
if '+' not in parsed.drivername and '+' in driver_name:
backend = driver_name.split('+', 1)[0]
if parsed.drivername == backend:
conn_str = parsed.set(
drivername=driver_name
)

# Separate connection-pool tuning from DBAPI connect args. Pool keys are
# applied to create_engine() directly; everything left in connect_args is
Expand Down
Loading