diff --git a/dialogs/dataview/clusterviewdialog.py b/dialogs/dataview/graphrelationviewdialog.py similarity index 98% rename from dialogs/dataview/clusterviewdialog.py rename to dialogs/dataview/graphrelationviewdialog.py index 8eec9183..3c1aff18 100644 --- a/dialogs/dataview/clusterviewdialog.py +++ b/dialogs/dataview/graphrelationviewdialog.py @@ -14,11 +14,11 @@ from ...tasks.query.discovery.findrelatedconceptquerytask import FindRelatedConceptQueryTask FORM_CLASS, _ = uic.loadUiType(os.path.join( - os.path.dirname(__file__), '../ui/clusterviewdialog.ui')) + os.path.dirname(__file__), '../ui/graphrelationviewdialog.ui')) MESSAGE_CATEGORY = 'ClusterviewDialog' -class ClusterViewDialog(QWidget, FORM_CLASS): +class GraphRelationViewDialog(QWidget, FORM_CLASS): def __init__(self,triplestoreconf,concept,label=""): super(QWidget, self).__init__() diff --git a/dialogs/menu/conceptcontextmenu.py b/dialogs/menu/conceptcontextmenu.py index 4f20b527..e1ff4ecb 100644 --- a/dialogs/menu/conceptcontextmenu.py +++ b/dialogs/menu/conceptcontextmenu.py @@ -5,7 +5,8 @@ ) from qgis.PyQt.QtCore import QUrl -from ..dataview.clusterviewdialog import ClusterViewDialog +from ..dataview.graphrelationviewdialog import GraphRelationViewDialog +from ..tool.advancedquerydialog import AdvancedQueryDialog from ...dialogs.util.bboxdialog import BBOXDialog from ...util.ui.uiutils import UIUtils from ...tasks.query.data.querylayertask import QueryLayerTask @@ -75,6 +76,10 @@ def __init__(self,dlg,triplestoreconf,prefixes,position,context,item,preferredla actionrelgeo = QAction("Check related concepts") actionrelgeo.setIcon(UIUtils.countinstancesicon) menu.addAction(actionrelgeo) + actionAdvancedQuery = QAction("Advanced Query") + actionAdvancedQuery.setIcon(UIUtils.addfeaturecollectionicon) + actionAdvancedQuery.triggered.connect(self.advancedQueryDialog) + menu.addAction(actionAdvancedQuery) actionrelgeo.triggered.connect(self.relatedGeoConcepts) actionqueryinstances = QAction("Query all instances") actionqueryinstances.setIcon(UIUtils.queryinstancesicon) @@ -222,10 +227,15 @@ def queryLinkedGeoInstance(self): self.triplestoreconf, True, SPARQLUtils.labelFromURI(concept), None,0,True,None) QgsApplication.taskManager().addTask(self.qlayerinstance) + def advancedQueryDialog(self): + concept = self.item.data(UIUtils.dataslot_conceptURI) + label = self.item.text() + AdvancedQueryDialog(self.triplestoreconf,concept,label) + def relatedGeoConcepts(self): concept = self.item.data(UIUtils.dataslot_conceptURI) label = self.item.text() - ClusterViewDialog(self.triplestoreconf,concept,label) + GraphRelationViewDialog(self.triplestoreconf,concept,label) #if not label.endswith("]"): # self.qtaskinstance = FindRelatedConceptQueryTask( # "Getting related geo concepts for " + str(concept), diff --git a/dialogs/menu/tabcontextmenu.py b/dialogs/menu/tabcontextmenu.py index 50085d3b..0f4b0d22 100644 --- a/dialogs/menu/tabcontextmenu.py +++ b/dialogs/menu/tabcontextmenu.py @@ -26,7 +26,7 @@ def __init__(self,name,parent,position,triplestoreconf): def saveClassesTreeToRDF(self, context): filename, _filter = QFileDialog.getSaveFileName( - self, "Select output file ", "", "Linked Data (*.ttl *.n3 *.nt *.graphml)", ) + self, "Select output file ", "", "Linked Data (*.ttl *.n3 *.nt *.graphml)", ) if filename == "": return result=set() @@ -38,7 +38,7 @@ def saveClassesTreeToRDF(self, context): def saveVisibleTreeToRDF(self, context): filename, _filter = QFileDialog.getSaveFileName( - self, "Select output file ", "", "Linked Data (*.ttl *.n3 *.nt *.graphml)", ) + self, "Select output file ", "", "Linked Data (*.ttl *.n3 *.nt *.graphml)", ) if filename == "": return result=set() @@ -50,7 +50,7 @@ def saveVisibleTreeToRDF(self, context): def saveTreeToRDF(self, context): filename, _filter = QFileDialog.getSaveFileName( - self, "Select output file ", "", "Linked Data (*.ttl *.n3 *.nt *.graphml)", ) + self, "Select output file ", "", "Linked Data (*.ttl *.n3 *.nt *.graphml)", ) if filename == "": return result=set() diff --git a/dialogs/sparql_unicorn_dialog.py b/dialogs/sparql_unicorn_dialog.py index 9c24853e..b19681c7 100644 --- a/dialogs/sparql_unicorn_dialog.py +++ b/dialogs/sparql_unicorn_dialog.py @@ -610,14 +610,14 @@ def conceptSelectAction(self): querytext = "" if concept is not None and concept.startswith("http"): querytext = \ - self.queryTemplates.itemData(self.queryTemplates.currentIndex())#.replace("wd:Q%%concept%% .", "wd:" + concept[concept.rfind('/') + 1:] + " .") + self.queryTemplates.itemData(self.queryTemplates.currentIndex()).replace("wd:Q%%concept%% .", "wd:" + concept[concept.rfind('/') + 1:] + " .") elif concept is not None: querytext = \ - self.queryTemplates.itemData(self.queryTemplates.currentIndex())#.replace("wd:Q%%concept%% .", "wd:" + concept + " .") + self.queryTemplates.itemData(self.queryTemplates.currentIndex()).replace("wd:Q%%concept%% .", "wd:" + concept + " .") else: querytext = self.queryTemplates.itemData(self.queryTemplates.currentIndex())#.replace("%%concept%%", concept) - #QgsMessageLog.logMessage('Started task "{}"'.format("Concept: " + str(concept)), MESSAGE_CATEGORY, - # Qgis.Info) + QgsMessageLog.logMessage('Started task "{}"'.format("Concept: " + str(concept)), MESSAGE_CATEGORY, + Qgis.Info) querytext=SPARQLUtils.queryPreProcessing(querytext,self.triplestoreconf[endpointIndex],concept) self.inp_sparql2.setPlainText(querytext) self.inp_sparql2.columnvars = {} diff --git a/dialogs/tool/advancedquerydialog.py b/dialogs/tool/advancedquerydialog.py new file mode 100644 index 00000000..ddc2aa83 --- /dev/null +++ b/dialogs/tool/advancedquerydialog.py @@ -0,0 +1,69 @@ +from qgis.PyQt import uic +from qgis.PyQt import QtWidgets +from qgis.PyQt.QtWidgets import QStyle,QWidget,QMenu,QAction +from qgis.core import QgsApplication, QgsCoordinateReferenceSystem +from qgis.PyQt.QtCore import Qt +from qgis.PyQt.QtGui import QStandardItemModel +from qgis.PyQt.QtCore import QSortFilterProxyModel + +from ...util.sparqlutils import SPARQLUtils +from ...util.ui.uiutils import UIUtils +from ...tasks.query.discovery.findrelatedconceptquerytask import FindRelatedConceptQueryTask +import os.path + +# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer +FORM_CLASS, _ = uic.loadUiType(os.path.join( + os.path.dirname(__file__), '../ui/advancedquerydialog.ui')) + +## +# @brief The main dialog window of the SPARQLUnicorn QGIS Plugin. +class AdvancedQueryDialog(QtWidgets.QDialog, FORM_CLASS): + ## The triple store configuration file + triplestoreconf = None + ## Prefix map + prefixes = None + ## LoadGraphTask for loading a graph from a file or uri + qtask = None + + def __init__(self, triplestoreconf={}, concept="",title="Convert CRS"): + """Constructor.""" + super(QWidget, self).__init__() + self.setupUi(self) + self.setWindowTitle(title) + self.setWindowIcon(UIUtils.rdffileicon) + self.triplestoreconf = triplestoreconf + self.tablemodel = QStandardItemModel() + self.tablemodel.setHeaderData(0, Qt.Horizontal, "Ingoing Concept") + self.tablemodel.setHeaderData(1, Qt.Horizontal, "Ingoing Relation") + self.tablemodel.setHeaderData(2, Qt.Horizontal, "Outgoing Relation") + self.tablemodel.setHeaderData(3, Qt.Horizontal, "Target Concept") + self.tablemodel.insertRow(0) + self.nodetype = SPARQLUtils.classnode + self.filter_proxy_model = QSortFilterProxyModel() + self.filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive) + self.filter_proxy_model.setSourceModel(self.tablemodel) + self.filter_proxy_model.setFilterKeyColumn(3) + self.tableView.setModel(self.filter_proxy_model) + self.tableView.setContextMenuPolicy(Qt.CustomContextMenu) + self.tableView.entered.connect(lambda modelindex: UIUtils.showTableURI(modelindex, self.tableView, self.statusBarLabel)) + #self.tableView.doubleClicked.connect(self.showRelatedFromIndex) + #self.tableView.customContextMenuRequested.connect(self.onContext) + #self.filterTableEdit.textChanged.connect(self.filter_proxy_model.setFilterRegExp) + #self.filterTableComboBox.currentIndexChanged.connect(lambda: self.filter_proxy_model.setFilterKeyColumn(self.filterTableComboBox.currentIndex())) + self.show() + + + def getRelatedClassStatistics(self): + if self.concept == "" or self.concept is None: + return + self.qtask = FindRelatedConceptQueryTask("Querying related classes.... (" + str(self.concept) + ")", + self.triplestoreconf["resource"], + self.tablemodel, + self.concept, + self.label, + self.nodetype, + self.triplestoreconf,self.tableView) + QgsApplication.taskManager().addTask(self.qtask) + + + diff --git a/dialogs/ui/advancedquerydialog.ui b/dialogs/ui/advancedquerydialog.ui new file mode 100644 index 00000000..1b119d11 --- /dev/null +++ b/dialogs/ui/advancedquerydialog.ui @@ -0,0 +1,55 @@ + + + AdvancedQueryDialog + + + + 0 + 0 + 740 + 431 + + + + Advanced Query Dialog + + + + + 9 + 9 + 711 + 411 + + + + + + + Query Selection + + + + + + + + + + Cancel + + + + + + + Query Single Layer + + + + + + + + + diff --git a/dialogs/ui/clusterviewdialog.ui b/dialogs/ui/graphrelationviewdialog.ui similarity index 100% rename from dialogs/ui/clusterviewdialog.ui rename to dialogs/ui/graphrelationviewdialog.ui diff --git a/util/sparqlutils.py b/util/sparqlutils.py index 52820a82..6bb8e649 100644 --- a/util/sparqlutils.py +++ b/util/sparqlutils.py @@ -325,7 +325,7 @@ def queryPreProcessing(query,triplestoreconf,concept=None,convertToCollectionFor query=query.replace("?con %%typeproperty%% %%concept%% .","%%concept%% %%collectionmemberproperty%% ?con .") if concept is not None: if "resource" in triplestoreconf and "url" in triplestoreconf["resource"] and ("wikidata" in triplestoreconf["resource"]["url"] or "factgrid" in triplestoreconf["resource"]["url"]) and concept[concept.find('(')+1:-1].startswith("Q"): - query=query.replace("%%concept%%",str("wd:" + concept[concept.find('(')+1:-1])) + query=query.replace("%%concept%%",str("wd:" + concept[concept.find('(')+1:])) else: query = query.replace("%%concept%%", "<" + str(concept) + ">") typeproperty = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type"