Skip to content

Commit

Permalink
Merge pull request #44812 from tomkralidis/metasearch-ogcapi-records
Browse files Browse the repository at this point in the history
[FEATURE][MetaSearch] add support for OGC API - Records
  • Loading branch information
nyalldawson committed Nov 29, 2021
2 parents 7b5cd9b + 5ff73b1 commit d44fa83
Show file tree
Hide file tree
Showing 16 changed files with 637 additions and 234 deletions.
Expand Up @@ -27,10 +27,10 @@

from MetaSearch.util import get_ui_class

BASE_CLASS = get_ui_class('xmldialog.ui')
BASE_CLASS = get_ui_class('apidialog.ui')


class XMLDialog(QDialog, BASE_CLASS):
class APIRequestResponseDialog(QDialog, BASE_CLASS):
"""Raw XML Dialogue"""

def __init__(self):
Expand Down
327 changes: 145 additions & 182 deletions python/plugins/MetaSearch/dialogs/maindialog.py

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions python/plugins/MetaSearch/dialogs/manageconnectionsdialog.py
Expand Up @@ -30,7 +30,7 @@
import xml.etree.ElementTree as etree

from qgis.core import QgsSettings
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, QListWidgetItem, QMessageBox
from qgis.PyQt.QtWidgets import QDialog, QDialogButtonBox, QFileDialog, QListWidgetItem, QMessageBox # noqa

from MetaSearch.util import (get_connections_from_file, get_ui_class,
prettify_xml)
Expand Down Expand Up @@ -76,8 +76,8 @@ def select_file(self):
'.', label)
else:
slabel = self.tr('Load Connections')
self.filename, selected_filter = QFileDialog.getOpenFileName(self, slabel,
'.', label)
self.filename, selected_filter = QFileDialog.getOpenFileName(
self, slabel, '.', label)

if not self.filename:
return
Expand Down Expand Up @@ -154,7 +154,8 @@ def load(self, items):

# check for duplicates
if conn_name in keys:
label = self.tr('File {0} exists. Overwrite?').format(conn_name)
label = self.tr('File {0} exists. Overwrite?').format(
conn_name)
res = QMessageBox.warning(self, self.tr('Loading Connections'),
label,
QMessageBox.Yes | QMessageBox.No)
Expand Down
13 changes: 10 additions & 3 deletions python/plugins/MetaSearch/dialogs/newconnectiondialog.py
Expand Up @@ -31,6 +31,7 @@
from qgis.PyQt.QtWidgets import QDialog, QMessageBox

from MetaSearch.util import get_ui_class
from MetaSearch.search_backend import CATALOG_TYPES

BASE_CLASS = get_ui_class('newconnectiondialog.ui')

Expand All @@ -49,13 +50,16 @@ def __init__(self, conn_name=None):
self.username = None
self.password = None

self.cmbCatalogType.addItems(CATALOG_TYPES)

def accept(self):
"""add CSW entry"""

conn_name = self.leName.text().strip()
conn_url = self.leURL.text().strip()
conn_username = self.leUsername.text().strip()
conn_password = self.lePassword.text().strip()
conn_catalog_type = self.cmbCatalogType.currentText()

if any([conn_name == '', conn_url == '']):
QMessageBox.warning(self, self.tr('Save Connection'),
Expand All @@ -75,9 +79,10 @@ def accept(self):
# warn if entry was renamed to an existing connection
if all([self.conn_name_orig != conn_name,
self.settings.contains(keyurl)]):
res = QMessageBox.warning(self, self.tr('Save Connection'),
self.tr('Overwrite {0}?').format(conn_name),
QMessageBox.Ok | QMessageBox.Cancel)
res = QMessageBox.warning(
self, self.tr('Save Connection'),
self.tr('Overwrite {0}?').format(conn_name),
QMessageBox.Ok | QMessageBox.Cancel)
if res == QMessageBox.Cancel:
return

Expand All @@ -92,6 +97,8 @@ def accept(self):
self.settings.setValue('%s/username' % key, conn_username)
self.settings.setValue('%s/password' % key, conn_password)

self.settings.setValue('%s/catalog-type' % key, conn_catalog_type)

QDialog.accept(self)

def reject(self):
Expand Down
7 changes: 6 additions & 1 deletion python/plugins/MetaSearch/link_types.py
Expand Up @@ -22,6 +22,8 @@
###############################################################################

WMSWMST_LINK_TYPES = [
'WMS',
'WMTS',
'OGC:WMS',
'OGC:WMTS',
'OGC:WMS-1.1.1-http-get-map',
Expand All @@ -33,6 +35,7 @@
]

WFS_LINK_TYPES = [
'WFS',
'OGC:WFS',
'OGC:WFS-1.0.0-http-get-capabilities',
'OGC:WFS-1.1.0-http-get-capabilities',
Expand All @@ -41,6 +44,7 @@
]

WCS_LINK_TYPES = [
'WCS',
'OGC:WCS',
'OGC:WCS-1.1.0-http-get-capabilities',
'urn:x-esri:specification:ServiceType:wcs:url',
Expand All @@ -49,7 +53,8 @@

AMS_LINK_TYPES = [
'ESRI:ArcGIS:MapServer',
'Esri REST: Map Service'
'Esri REST: Map Service',
'ESRI REST'
]

AFS_LINK_TYPES = [
Expand Down
16 changes: 8 additions & 8 deletions python/plugins/MetaSearch/plugin.py
Expand Up @@ -58,10 +58,10 @@ def initGui(self):
'images/MetaSearch.svg'))
self.action_run = QAction(run_icon, 'MetaSearch',
self.iface.mainWindow())
self.action_run.setWhatsThis(QCoreApplication.translate('MetaSearch',
'MetaSearch plugin'))
self.action_run.setStatusTip(QCoreApplication.translate('MetaSearch',
'Search Metadata Catalogs'))
self.action_run.setWhatsThis(
QCoreApplication.translate('MetaSearch', 'MetaSearch plugin'))
self.action_run.setStatusTip(QCoreApplication.translate(
'MetaSearch', 'Search Metadata Catalogs'))

self.action_run.triggered.connect(self.run)

Expand All @@ -71,10 +71,10 @@ def initGui(self):
# help
help_icon = QgsApplication.getThemeIcon('/mActionHelpContents.svg')
self.action_help = QAction(help_icon, 'Help', self.iface.mainWindow())
self.action_help.setWhatsThis(QCoreApplication.translate('MetaSearch',
'MetaSearch plugin help'))
self.action_help.setStatusTip(QCoreApplication.translate('MetaSearch',
'Get Help on MetaSearch'))
self.action_help.setWhatsThis(
QCoreApplication.translate('MetaSearch', 'MetaSearch plugin help'))
self.action_help.setStatusTip(QCoreApplication.translate(
'MetaSearch', 'Get Help on MetaSearch'))
self.action_help.triggered.connect(self.help)

self.iface.addPluginToWebMenu(self.web_menu, self.action_help)
Expand Down
Expand Up @@ -16,4 +16,4 @@
<csw name="Portugal: Sistema Nacional de Informação Geográfica (SNIG)" url="https://snig.dgterritorio.gov.pt/rndg/srv/eng/csw"/>
<csw name="Spain: Centro Nacional de Información Geográfica (CNIG)" url="http://www.ign.es/csw-inspire/srv/spa/csw"/>
<csw name="Germany: GDI-DE Geodatenkatalog.de" url="https://gdk.gdi-de.org/gdi-de/srv/ger/csw"/>
</qgsCSWConnections>
</qgsCSWConnections>
@@ -0,0 +1,67 @@
<!DOCTYPE html>
<html lang="{{ language }}">
<head>
<meta charset="utf-8"/>
<title>{{ gettext('Service Metadata') }}</title>
<style type="text/css">
body,h3, h4 {
background-color: #ffffff;
font-family: arial, verdana, sans-serif;
text-align: left;
float: left;
}
header {
display: inline-block;
}
</style>
</head>
<body>
<header>
<h3>{{ gettext('Service Metadata') }}</h3>
</header>
<section id="service-metadata">
<h4>{{ gettext('Service Identification') }}</h4>
<table>
<tr>
<td>{{ gettext('Title') }}</td>
<td>{{ obj.title }}</td>
</tr>
<tr>
<td>{{ gettext('Abstract') }}</td>
<td>{{ obj.description or obj['title'] }}</td>
</tr>
<tr>
<td>{{ gettext('Service URL') }}</td>
<td><a href="{{ obj.url }}">{{ obj.url}}</a></td>
</tr>
</table>
</section>

<section id="collections">
<h4>{{ gettext('Collections') }}</h4>
{% for j in obj.collections()['collections'] %}
{% if j.id in obj.records() %}
<p><b>{{ j.title }}</b><br/>{{ j.description }}</p>
{% endif %}
{% endfor %}
</section>

<section id="conformance">
<h4>{{ gettext('Conformance') }}</h4>
<ul>
{% for i in obj.conformance()['conformsTo'] %}
<li><a href="{{ i }}">{{ i }}</a></li>
{% endfor %}
</ul>
</section>

<section id="links">
<h4>{{ gettext('Links') }}</h4>
<ul>
{% for link in obj.links %}
<li><a href="{{ link['href'] }}">{{ link['title'] }}</a></li>
{% endfor %}
</ul>
</section>
</body>
</html>
Expand Up @@ -17,7 +17,7 @@
</head>
<body>
<header>
<h3>{{ gettext('Record Metadata') }} (<a href="{{ obj.xml_url }}">{{ gettext('View XML') }}</a>)</h3>
<h3>{{ gettext('Record Metadata') }} (<a href="{{ obj.url }}">{{ gettext('View XML') }}</a>)</h3>
</header>
<section id="record-metadata">
<table>
Expand Down
@@ -0,0 +1,63 @@
<!DOCTYPE html>
{% macro render_item_value(v, width) -%}
{% set val = v | string | trim %}
{% if val|length and val.lower().endswith(('.jpg', '.jpeg', '.png', '.gif', '.bmp')) %}
{# Ends with image extension: render img element with link to image #}
<a href="{{ val }}"><img src="{{ val }}" alt="{{ val.split('/') | last }}" width="{{ width }}"/></a>
{% elif v is string or v is number %}
{{ val | urlize() }}
{% elif v is mapping %}
<ul>
{% for i,j in v.items() %}
<li><i>{{ gettext(i) }}:</i> {{ render_item_value(j, 60) }}</li>
{% endfor %}</ul>
{% elif v is iterable %}
<ul>
{% for i in v %}
<li>{{ render_item_value(i, 60) }}</li>
{% endfor %}
</ul>
{% else %}
{{ val | urlize() }}
{% endif %}
{%- endmacro %}
<html lang="{{ language }}">
<head>
<meta charset="utf-8"/>
<title>{{ gettext('Record Metadata') }}</title>
<style type="text/css">
body, h3 {
background-color: #ffffff;
font-family: arial, verdana, sans-serif;
text-align: left;
float: left;
}
header {
display: inline-block;
}
</style>
</head>
<body>
<header>
<h3>{{ gettext('Record Metadata') }} (<a href="{{ obj.url }}">{{ gettext('View JSON') }}</a>)</h3>
</header>
<section id="record-metadata">
<table>
<tr>
<td>{{ gettext('Identifier') }}</td>
<td>{{ obj['id'] }}</td>
</tr>
{% if (obj['properties']) %}
{% for a,b in obj['properties'].items() %}
{% if a not in ['extent'] %}
<tr>
<td>{{ gettext(a) }}</td>
<td>{{ render_item_value( b, 120 ) }}</td>
</tr>
{% endif %}
{% endfor %}
{% endif %}
</table>
</section>
</body>
</html>

0 comments on commit d44fa83

Please sign in to comment.