Skip to content

Commit dc15c53

Browse files
committed
suggestion for implementing wms/wmts/wfs/... links in record.geojson
1 parent d207854 commit dc15c53

File tree

3 files changed

+78
-14
lines changed

3 files changed

+78
-14
lines changed

pycsw/ogc/api/records.py

Lines changed: 54 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
from pycsw.core.pygeofilter_evaluate import to_filter
4646
from pycsw.core.util import bind_url, get_today_and_now, jsonify_links, load_custom_repo_mappings, wkt2geom
4747
from pycsw.ogc.api.oapi import gen_oapi
48-
from pycsw.ogc.api.util import match_env_var, render_j2_template, to_json
48+
from pycsw.ogc.api.util import match_env_var, render_j2_template, to_json, merge_qs
4949

5050
LOGGER = logging.getLogger(__name__)
5151

@@ -1000,20 +1000,61 @@ def record2json(record, url, collection, stac_item=False):
10001000

10011001
if record.links:
10021002
rdl = record_dict['links']
1003-
10041003
for link in jsonify_links(record.links):
1005-
link2 = {
1006-
'href': link['url'],
1007-
'name': link['name'],
1004+
link2 = {
1005+
'type': link['protocol'],
10081006
'description': link['description'],
1009-
'type': link['protocol']
1010-
}
1011-
if 'rel' in link:
1012-
link2['rel'] = link['rel']
1013-
elif 'function' in link:
1014-
link2['rel'] = link['function']
1015-
1016-
rdl.append(link2)
1007+
'title': link['name'],
1008+
'href': link['url']
1009+
}
1010+
if link['protocol']:
1011+
if 'OGC:WMS' in link['protocol'].upper():
1012+
link2['rel'] = 'map'
1013+
link2['templated'] = 'true'
1014+
# assumes link['href'] includes '&layers=...', else link['name'] contains layername(s)
1015+
link2['href'] = merge_qs(link['url'], {
1016+
'request': 'GetMap', 'service': 'WMS',
1017+
'width': '{width}', 'height': '{height}', 'bbox': '{bbox}'}, {
1018+
'version': '1.3.0', 'crs': 'epsg:4326',
1019+
'layers': link['name'], 'format': 'image/png'})
1020+
link2['variables'] = {
1021+
'bbox': {
1022+
'type': 'array',
1023+
'items': {'type': 'number', 'format': 'double'},
1024+
'minItems': 4, 'maxItems': 4
1025+
},
1026+
'width': {'type': 'number', 'format': 'integer'},
1027+
'height': {'type': 'number', 'format': 'integer'}
1028+
}
1029+
link2['type'] = 'image/png'
1030+
1031+
elif 'OGC:WMTS' in link['protocol'].upper():
1032+
link2['rel'] = 'map'
1033+
link2['templated'] = 'true'
1034+
link2['href'] = merge_qs(link['url'], {
1035+
'service': 'WMTS', 'request': 'GetTile', 'version': '1.0.0',
1036+
'TileMatrix': '{TileMatrix}', 'TileRow': '{TileRow}', 'TileCol': '{TileCol}'}, {
1037+
'TileMatrixSet': 'default', 'Layer': link['name'],
1038+
'Style': 'default', 'Format': 'image/png'})
1039+
link2['variables'] = {
1040+
'TileMatrix': {'type': 'number', 'format': 'integer'},
1041+
'TileRow': {'type': 'number', 'format': 'integer'},
1042+
'TileCol': {'type': 'number', 'format': 'integer'}
1043+
}
1044+
link2['type'] = 'image/png'
1045+
1046+
#elif 'OSGEO:TMS' in link['protocol'].upper():
1047+
#elif 'OGC:WFS' in link['protocol'].upper():
1048+
#elif 'OGC:WMTS' in link['protocol'].upper():
1049+
#elif 'OGC:CSW' in link['protocol'].upper():
1050+
#elif 'OGC:WCS' in link['protocol'].upper():
1051+
1052+
elif 'rel' in link:
1053+
link2['rel'] = link['rel']
1054+
elif 'function' in link:
1055+
link2['rel'] = link['function']
1056+
1057+
rdl.append(link2)
10171058

10181059
record_dict['links'].append({
10191060
'rel': 'collection',

pycsw/ogc/api/templates/item.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ <h2>{{ data['id'] }}</h2>
7171
<td>
7272
<ul>
7373
{% for link in data['links'] %}
74-
<li><a href="{{ link['href'] }}" title="{{ link['description'] }}">{{ link['name'] }}</a></li>
74+
<li><a href="{{ link['href'] }}" title="{{ link['description'] }}">{{ link['title'] or link['href'] }}</a></li>
7575
{% endfor %}
7676
</ul>
7777
</tr>

pycsw/ogc/api/util.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import mimetypes
3939
import os
4040
import re
41+
from urllib.parse import urlparse, parse_qsl, urlencode
4142

4243
from jinja2 import Environment, FileSystemLoader
4344
from jinja2.exceptions import TemplateNotFound
@@ -139,6 +140,28 @@ class EnvVarLoader(yaml.SafeLoader):
139140

140141
return yaml.load(fh, Loader=EnvVarLoader)
141142

143+
def merge_qs(url, req, opt):
144+
"""
145+
Merge required and optional parameters into a querystring.
146+
Typically replaces https://example.com/mapserver?map=foo.map&servic=wms&request=GetCapabilities&layers=trees for
147+
https://example.com/mapserver?map=foo.map?servic=wms&request=GetMap&version=1.3.0&layers=trees&bbox={bbox}&format=...
148+
149+
:param url: The original url to be substituted
150+
:param req: These arguments will be sustituted
151+
:param opt: These arguments are substituted if they don't exist
152+
153+
:returns: url
154+
"""
155+
156+
parsed_url = urlparse(url)
157+
args = dict(parse_qsl(parsed_url.query))
158+
for k,v in req.items():
159+
args[k] = v
160+
for k,v in opt.items():
161+
if k not in args.keys() or args[k] == '':
162+
args[k] = v
163+
164+
return url.split('?')[0] + '?' + urlencode(args)
142165

143166
def to_json(dict_, pretty=False):
144167
"""

0 commit comments

Comments
 (0)