Skip to content
Draft
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
3 changes: 3 additions & 0 deletions docs/source/publishing/ogcapi-maps.rst
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,9 @@ required. An optional style name can be defined via `options.style`.
- `4326`
- `3857`

If `crs` is not provided, the server will default `4326`. If `crs-bbox` and `bbox` are not provided,
the server will default to the crs and bounding box defined in the configuration of the spatial extent.

Data visualization examples
---------------------------

Expand Down
23 changes: 16 additions & 7 deletions pygeoapi/api/maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,19 @@ def get_collection_map(api: API, request: APIRequest,

query_args['format_'] = request.params.get('f', 'png')
query_args['style'] = style
query_args['crs'] = CRS_CODES[request.params.get(
'crs', collection_def.get('crs', DEFAULT_CRS))]
query_args['bbox_crs'] = CRS_CODES[request.params.get(
'bbox-crs', collection_def.get('crs', DEFAULT_CRS))]
query_args['transparent'] = request.params.get('transparent', True)

query_args['crs'] = CRS_CODES.get(request.params.get(
'crs', DEFAULT_CRS))
query_args['bbox_crs'] = CRS_CODES.get(request.params.get(
'bbox-crs',
api.config['resources'][dataset]['extents']['spatial'].get(
'crs', DEFAULT_CRS))
)

if query_args['crs'] is None:
query_args['crs'] = DEFAULT_CRS
if query_args['bbox_crs'] is None:
query_args['bbox_crs'] = DEFAULT_CRS

try:
query_args['width'] = int(request.params.get('width', 500))
Expand All @@ -135,7 +143,8 @@ def get_collection_map(api: API, request: APIRequest,

LOGGER.debug('Processing bbox parameter')
try:
bbox = request.params.get('bbox').split(',')
bbox = request.params.get(
'bbox').split(',')
if len(bbox) != 4:
exception = {
'code': 'InvalidParameterValue',
Expand All @@ -145,6 +154,7 @@ def get_collection_map(api: API, request: APIRequest,
LOGGER.error(exception)
return headers, HTTPStatus.BAD_REQUEST, to_json(
exception, api.pretty_print)

except AttributeError:
bbox = api.config['resources'][dataset]['extents']['spatial']['bbox'] # noqa
try:
Expand All @@ -163,7 +173,6 @@ def get_collection_map(api: API, request: APIRequest,
if query_args['bbox_crs'] != query_args['crs']:
LOGGER.debug(f'Reprojecting bbox CRS: {query_args["crs"]}')
bbox = transform_bbox(bbox, query_args['bbox_crs'], query_args['crs'])

query_args['bbox'] = bbox

LOGGER.debug('Processing datetime parameter')
Expand Down
13 changes: 12 additions & 1 deletion pygeoapi/crs.py
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,19 @@ def transform_bbox(bbox: list, from_crs: Union[str, pyproj.CRS],

from_crs_obj = get_crs(from_crs)
to_crs_obj = get_crs(to_crs)

transform_func = pyproj.Transformer.from_crs(
from_crs_obj, to_crs_obj).transform
from_crs_obj, to_crs_obj, always_xy=True).transform

# Clip values to max and min lat of WebMercator,
# to avoid infinte pole distortion
if to_crs_obj.to_epsg() == 3857:
bbox = [
bbox[0],
max(-85.0511, bbox[1]),
bbox[2],
min(85.0511, bbox[3])
]

n_dims = len(bbox) // 2
return list(transform_func(*bbox[:n_dims]) + transform_func(
Expand Down
4 changes: 2 additions & 2 deletions pygeoapi/provider/wms_facade.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def __init__(self, provider_def):

def query(self, style=None, bbox=[-180, -90, 180, 90], width=500,
height=300, crs=DEFAULT_CRS, datetime_=None, transparent=True,
bbox_crs=DEFAULT_CRS, format_='png', **kwargs):
format_='png', **kwargs):
"""
Generate map

Expand All @@ -88,7 +88,7 @@ def query(self, style=None, bbox=[-180, -90, 180, 90], width=500,

version = self.options.get('version', '1.3.0')

if version == '1.3.0' and CRS_CODES.get(bbox_crs) == 'EPSG:4326':
if version == '1.3.0' and CRS_CODES.get(crs) == 'EPSG:4326':
bbox = [bbox[1], bbox[0], bbox[3], bbox[2]]
bbox2 = ','.join(map(str, bbox))

Expand Down
48 changes: 38 additions & 10 deletions pygeoapi/templates/collections/collection.html
Original file line number Diff line number Diff line change
Expand Up @@ -154,18 +154,46 @@ <h3>{% trans %}Storage CRS{% endtrans %}</h3>
['{{ data['extent']['spatial']['bbox'][0][1] }}', '{{ data['extent']['spatial']['bbox'][0][2] }}']
]);

{# if this collection has a map representation, add it to the map #}
{% for link in data['links'] %}
{% if link['rel'] == 'http://www.opengis.net/def/rel/ogc/1.0/map' and link['href'] %}
L.imageOverlay.ogcapi("{{ data['base_url'] }}", {collection: "{{ data['id'] }}", "opacity": .7, "transparent": true}).addTo(map);
bbox_layer.setStyle({
fillOpacity: 0
});
{% endif %}
{% endfor %}
var lbounds = bbox_layer.getBounds();

function clampLat(lat) {
return Math.max(-85.0511, Math.min(lat, 85.0511));
}

var sw = lbounds.getSouthWest();
var ne = lbounds.getNorthEast();
var clampedSw = L.latLng(clampLat(sw.lat), sw.lng);
var clampedNe = L.latLng(clampLat(ne.lat), ne.lng);
var clampedBounds = L.latLngBounds(clampedSw, clampedNe);

// Set the bounds to the limits of WebMercator
var crsBounds = L.latLngBounds(
L.latLng(-85.0511, -180), // SouthWest
L.latLng(85.0511, 180) // NorthEast
);
map.setMaxBounds(crsBounds);

{# if this collection has a map representation, add it to the map #}
{% for link in data['links'] %}
{% if link['rel'] == 'http://www.opengis.net/def/rel/ogc/1.0/map' and link['href'] %}
L.imageOverlay.ogcapi("{{ data['base_url'] }}", {collection: "{{ data['id'] }}", "opacity": .7, "transparent": true, "bounds": clampedBounds }).addTo(map);
bbox_layer.setStyle({
fillOpacity: 0
});
{% endif %}
{% endfor %}

map.addLayer(bbox_layer);
map.fitBounds(bbox_layer.getBounds(), {maxZoom: 10});
map.fitBounds(clampedBounds, {maxZoom: 10,});

// Make sure we stay within the bounds
map.on('moveend', function() {
if (!crsBounds.contains(map.getBounds())) {
map.fitBounds(clampedBounds);
}
});

map.setMinZoom(2);

// Allow to get bbox query parameter of a rectangular area specified by
// dragging the mouse while pressing the Ctrl key
Expand Down
7 changes: 0 additions & 7 deletions tests/provider/test_wms_facade_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,3 @@ def test_query(config):

results = p.query()
assert len(results) > 0

# an invalid CRS should return the default bbox (4326)
results2 = p.query(crs='http://www.opengis.net/def/crs/EPSG/0/1111')
assert len(results2) == len(results)

results3 = p.query(crs='http://www.opengis.net/def/crs/EPSG/0/3857')
assert len(results3) != len(results)
Loading