class BigList(Ui_BigList, QWidget): itemselected = pyqtSignal(QModelIndex) closewidget = pyqtSignal() savewidget = pyqtSignal() def __init__(self, parent=None, centeronparent=False, showsave=True): super(BigList, self).__init__(parent) self.setupUi(self) self.centeronparent = centeronparent self.listView.clicked.connect(self.selected) self.saveButton.pressed.connect(self.savewidget.emit) self.closebutton.pressed.connect(self.closewidget.emit) self._index = None self.search.textEdited.connect(self.set_filter) self.filtermodel = QSortFilterProxyModel() self.filtermodel.setFilterCaseSensitivity(Qt.CaseInsensitive) self.listView.setModel(self.filtermodel) self.listView.setWordWrap(True) self.saveButton.setVisible(showsave) utils.install_touch_scroll(self.listView) def set_filter(self, text): self.filtermodel.setFilterRegExp(text + ".*") def selected(self, index): self._index = index self._index = self.filtermodel.mapToSource(index) self.itemselected.emit(self._index) def setmodel(self, model): self.filtermodel.setSourceModel(model) def setlabel(self, fieldname): self.fieldnameLabel.setText(fieldname) def currentindex(self): return self._index def setcurrentindex(self, index): if index is None: index = QModelIndex() if isinstance(index, int): index = self.listView.model().index(index, 0) self.listView.setCurrentIndex(index) def show(self): super(BigList, self).show() if self.centeronparent: width = self.parent().width() height = self.parent().height() self.move(width / 4, 0) self.resize(QSize(width / 2, height))
class NafiDockWidget(QtWidgets.QDockWidget, Ui_NafiDockWidgetBase): closingPlugin = pyqtSignal() def __init__(self, parent=None): """Constructor.""" super(NafiDockWidget, self).__init__(parent) self.setupUi(self) # set up QTreeView self.treeView.setHeaderHidden(True) self.treeView.setSortingEnabled(True) self.treeView.setFocusPolicy(Qt.NoFocus) self.treeView.pressed.connect(self.treeViewPressed) # set up search signal self.lineEdit.textChanged.connect(self.searchTextChanged) self.searchText = "" # set up clear search self.clearSearchButton.clicked.connect(self.clearSearch) # set up About … dialog self.aboutButton.clicked.connect(self.showAboutDialog) # set up Download NAFI data … link button self.dataButton.clicked.connect( lambda: webbrowser.open(getNafiDataUrl())) # set up base model self.treeViewModel = NafiTreeViewModel(getNafiUrl()) # set up proxy model for filtering self.proxyModel = QSortFilterProxyModel(self.treeView) self.proxyModel.setSourceModel(self.treeViewModel) self.proxyModel.setRecursiveFilteringEnabled(True) self.treeView.setModel(self.proxyModel) self.reader = NafiCapabilitiesReader() self.reader.capabilitiesDownloaded.connect( lambda xml: self.initModel(xml)) # restore the view from source whenever this dock widget is made visible again self.visibilityChanged.connect( lambda visible: visible and self.loadNafiWms()) # initialise proxied tree view model from WMS contents # self.loadNafiWms() def loadNafiWms(self): """Load the NAFI WMS and additional layers.""" self.wmsUrl = getNafiUrl() self.reader.downloadCapabilities(self.wmsUrl) def initModel(self, wmsXml): """Initialise a QStandardItemModel from the NAFI WMS.""" googSat = GoogleXyzItem() googHyb = GoogleXyzItem("y") googStr = GoogleXyzItem("m") # ibraWms = IbraWmsItem() ozTopoWmts = OzTopoWmtsItem() self.treeViewModel.loadWms( self.wmsUrl, wmsXml, additionalItems=[googSat, googHyb, googStr, ozTopoWmts]) # set default sort and expansion self.proxyModel.sort(0, Qt.AscendingOrder) self.expandTopLevel() def expandTopLevel(self): # expand the top level items for row in range(self.proxyModel.rowCount()): self.treeView.expand(self.proxyModel.index(row, 0)) def treeViewPressed(self, index): """Load a NAFI WMS layer given an index in the tree view.""" assert isinstance( index, QModelIndex), "Supplied parameter is not a QModelIndex" realIndex = self.proxyModel.mapToSource(index) modelNode = self.treeViewModel.itemFromIndex(realIndex) # if we've got a layer and not a layer group, add to map if modelNode is not None: if isinstance( modelNode, (GoogleXyzItem, IbraWmsItem, OzTopoWmtsItem, WmsItem)): modelNode.addLayer() def searchTextChanged(self, text): """Process a change in the search filter text.""" # user adding characters and has exceeded 3 or more, or is removing characters if len(text) >= 3 or len(self.searchText) > len(text): regex = QRegExp(text, Qt.CaseInsensitive, QRegExp.RegExp) self.proxyModel.setFilterRegExp(regex) self.treeView.expandAll() # update last search text state self.searchText = text def clearSearch(self): """Clear search data.""" self.lineEdit.setText(None) self.treeView.collapseAll() def sizeHint(self): return QtCore.QSize(150, 400) def showAboutDialog(self): """Show an About … dialog.""" aboutDialog = NafiAboutDialog() aboutDialog.exec_() def closeEvent(self, event): """Handle plug-in close.""" self.closingPlugin.emit() event.accept()
def refresh_model(self, source_model, db_connector=None, silent=False): filtered_source_model = QSortFilterProxyModel() filtered_source_model.setSourceModel(source_model) filtered_source_model.setFilterRole(int(SourceModel.Roles.TYPE)) self.print_info.emit(self.tr("Refresh available models:")) self.clear() previously_checked_models = self._checked_models self._checked_models = {} # models from db db_modelnames = self._db_modelnames(db_connector) # models from the repos filtered_source_model.setFilterFixedString("model") for r in range(0, filtered_source_model.rowCount()): filtered_source_model_index = filtered_source_model.index( r, SourceModel.Columns.SOURCE) modelname = filtered_source_model_index.data( int(SourceModel.Roles.NAME)) if modelname: enabled = modelname not in db_modelnames self.add_source( modelname, filtered_source_model_index.data( int(SourceModel.Roles.TYPE)), filtered_source_model_index.data( int(SourceModel.Roles.PATH)), filtered_source_model_index.data( int(SourceModel.Roles.ORIGIN_INFO)), previously_checked_models.get( ( modelname, filtered_source_model_index.data( int(SourceModel.Roles.PATH)), ), Qt.Checked, ) if enabled and modelname not in self.checked_models() else Qt.Unchecked, enabled, ) if not silent: self.print_info.emit( self.tr("- Append (repository) model {}{}").format( modelname, " (inactive because it already exists in the database)" if not enabled else "", )) # models from the files filtered_source_model.setFilterFixedString("ili") for r in range(0, filtered_source_model.rowCount()): filtered_source_model_index = filtered_source_model.index( r, SourceModel.Columns.SOURCE) ili_file_path = filtered_source_model_index.data( int(SourceModel.Roles.PATH)) self.ilicache = IliCache(None, ili_file_path) models = self.ilicache.process_ili_file(ili_file_path) for model in models: if model["name"]: enabled = model["name"] not in db_modelnames self.add_source( model["name"], filtered_source_model_index.data( int(SourceModel.Roles.TYPE)), filtered_source_model_index.data( int(SourceModel.Roles.PATH)), filtered_source_model_index.data( int(SourceModel.Roles.ORIGIN_INFO)), previously_checked_models.get( ( model["name"], filtered_source_model_index.data( int(SourceModel.Roles.PATH)), ), Qt.Checked if model is models[-1] and enabled and model["name"] not in self.checked_models() else Qt.Unchecked, ), enabled, ) if not silent: self.print_info.emit( self.tr("- Append (file) model {}{} from {}"). format( model["name"], " (inactive because it already exists in the database)" if not enabled else "", ili_file_path, )) # models from the transfer files filtered_source_model.setFilterRegExp("|".join(TransferExtensions)) for r in range(0, filtered_source_model.rowCount()): filtered_source_model_index = filtered_source_model.index( r, SourceModel.Columns.SOURCE) xtf_file_path = filtered_source_model_index.data( int(SourceModel.Roles.PATH)) models = self._transfer_file_models(xtf_file_path) for model in models: if model["name"]: enabled = model["name"] not in db_modelnames self.add_source( model["name"], filtered_source_model_index.data( int(SourceModel.Roles.TYPE)), filtered_source_model_index.data( int(SourceModel.Roles.PATH)), filtered_source_model_index.data( int(SourceModel.Roles.ORIGIN_INFO)), previously_checked_models.get( ( model["name"], filtered_source_model_index.data( int(SourceModel.Roles.PATH)), ), Qt.Checked if enabled and model["name"] not in self.checked_models() else Qt.Unchecked, ), enabled, ) if not silent: self.print_info.emit( self.tr("- Append (xtf file) model {}{} from {}"). format( model["name"], " (inactive because it already exists in the database)" if not enabled else "", xtf_file_path, )) return self.rowCount()
class SPAQLunicornDialog(QtWidgets.QDialog, FORM_CLASS): ## The triple store configuration file triplestoreconf = None ## Prefix map prefixes = None enrichtab = None interlinktab = None conceptList = None completerClassList = None columnvars = {} def __init__(self, triplestoreconf={}, prefixes=[], addVocabConf={}, autocomplete={}, prefixstore={ "normal": {}, "reversed": {} }, savedQueriesJSON={}, maindlg=None, parent=None): """Constructor.""" super(SPAQLunicornDialog, self).__init__(parent) self.setupUi(self) self.prefixes = prefixes self.maindlg = maindlg self.savedQueriesJSON = savedQueriesJSON self.enrichtab = EnrichmentTab(self) self.interlinktab = InterlinkingTab(self) self.addVocabConf = addVocabConf self.autocomplete = autocomplete self.prefixstore = prefixstore self.triplestoreconf = triplestoreconf self.searchTripleStoreDialog = TripleStoreDialog( self.triplestoreconf, self.prefixes, self.prefixstore, self.comboBox) self.geoClassList.setEditTriggers(QAbstractItemView.NoEditTriggers) self.geoClassList.setAlternatingRowColors(True) self.geoClassList.setViewMode(QListView.ListMode) self.geoClassList.setContextMenuPolicy(Qt.CustomContextMenu) self.geoClassList.customContextMenuRequested.connect(self.onContext) self.geoClassListModel = QStandardItemModel() self.proxyModel = QSortFilterProxyModel(self) self.proxyModel.sort(0) self.proxyModel.setSourceModel(self.geoClassListModel) self.geoClassList.setModel(self.proxyModel) self.geoClassListModel.clear() self.queryLimit.setValidator(QRegExpValidator(QRegExp("[0-9]*"))) self.filterConcepts.textChanged.connect(self.setFilterFromText) self.inp_sparql2 = ToolTipPlainText(self.tab, self.triplestoreconf, self.comboBox, self.columnvars, self.prefixes, self.autocomplete) self.inp_sparql2.move(10, 130) self.inp_sparql2.setMinimumSize(780, 401) self.inp_sparql2.document().defaultFont().setPointSize(16) self.inp_sparql2.setPlainText( "SELECT ?item ?lat ?lon WHERE {\n ?item ?b ?c .\n ?item <http://www.wikidata.org/prop:P123> ?def .\n}" ) self.inp_sparql2.columnvars = {} self.inp_sparql2.textChanged.connect(self.validateSPARQL) self.sparqlhighlight = SPARQLHighlighter(self.inp_sparql2) self.areaconcepts.hide() self.areas.hide() self.label_8.hide() self.label_9.hide() self.savedQueries.hide() self.loadQuery.hide() self.saveQueryButton.hide() self.saveQueryName.hide() self.savedQueryLabel.hide() self.saveQueryName_2.hide() self.enrichTableResult.hide() self.queryTemplates.currentIndexChanged.connect(self.viewselectaction) self.bboxButton.clicked.connect(self.getPointFromCanvas) self.interlinkTable.cellClicked.connect( self.createInterlinkSearchDialog) self.enrichTable.cellClicked.connect(self.createEnrichSearchDialog) self.chooseLayerInterlink.clear() self.searchClass.clicked.connect(self.createInterlinkSearchDialog) urlregex = QRegExp( "http[s]?://(?:[a-zA-Z#]|[0-9]|[$-_@.&+]|[!*\(\),]|(?:%[0-9a-fA-F][0-9a-fA-F]))+" ) urlvalidator = QRegExpValidator(urlregex, self) self.interlinkNameSpace.setValidator(urlvalidator) self.interlinkNameSpace.textChanged.connect(self.check_state3) self.interlinkNameSpace.textChanged.emit( self.interlinkNameSpace.text()) self.addEnrichedLayerButton.clicked.connect( self.enrichtab.addEnrichedLayer) self.startEnrichment.clicked.connect(self.enrichtab.enrichLayerProcess) self.exportInterlink.clicked.connect( self.enrichtab.exportEnrichedLayer) self.loadQuery.clicked.connect(self.loadQueryFunc) self.saveQueryButton.clicked.connect(self.saveQueryFunc) self.exportMappingButton.clicked.connect( self.interlinktab.exportMapping) self.importMappingButton.clicked.connect(self.interlinktab.loadMapping) self.loadLayerInterlink.clicked.connect(self.loadLayerForInterlink) self.loadLayerEnrich.clicked.connect(self.loadLayerForEnrichment) self.addEnrichedLayerRowButton.clicked.connect(self.addEnrichRow) self.geoClassList.selectionModel().selectionChanged.connect( self.viewselectaction) self.loadFileButton.clicked.connect(self.buildLoadGraphDialog) self.refreshLayersInterlink.clicked.connect(self.loadUnicornLayers) self.btn_loadunicornlayers.clicked.connect(self.loadUnicornLayers) self.whattoenrich.clicked.connect(self.createWhatToEnrich) self.quickAddTripleStore.clicked.connect(self.buildQuickAddTripleStore) self.loadTripleStoreButton.clicked.connect( self.buildCustomTripleStoreDialog) self.loadUnicornLayers() def loadQueryFunc(self): if self.triplestoreconf[self.comboBox.currentIndex( )]["endpoint"] in self.savedQueriesJSON: self.inp_sparql2.setPlainText(self.savedQueriesJSON[ self.triplestoreconf[self.comboBox.currentIndex()] ["endpoint"]][self.savedQueries.currentIndex()]["query"]) def saveQueryFunc(self): queryName = self.saveQueryName.text() if queryName != None and queryName != "": __location__ = os.path.realpath( os.path.join(os.getcwd(), os.path.dirname(__file__))) self.savedQueriesJSON[self.triplestoreconf[ self.comboBox.currentIndex()]["endpoint"]].append({ "label": queryName, "query": self.inp_sparql2.toPlainText() }) self.savedQueries.addItem(queryName) f = open(os.path.join(__location__, 'savedqueries.json'), "w") f.write(json.dumps(self.savedQueriesJSON)) f.close() def onContext(self): menu = QMenu("Menu", self.geoClassList) action = QAction("Open in Webbrowser") menu.addAction(action) action.triggered.connect(self.openURL) def openURL(self): curindex = self.proxyModel.mapToSource( self.geoClassList.selectionModel().currentIndex()) concept = self.geoClassListModel.itemFromIndex(curindex).data(1) url = QUrl(concept) QDesktopServices.openUrl(url) def setFilterFromText(self): self.proxyModel.setFilterRegExp(self.filterConcepts.text()) ## # @brief Creates a What To Enrich dialog with parameters given. # # @param self The object pointer def buildLoadGraphDialog(self): self.searchTripleStoreDialog = LoadGraphDialog(self.triplestoreconf, self.maindlg, self) self.searchTripleStoreDialog.setWindowTitle("Load Graph") self.searchTripleStoreDialog.exec_() ## # @brief Creates a What To Enrich dialog with parameters given. # # @param self The object pointer def buildQuickAddTripleStore(self): self.searchTripleStoreDialog = TripleStoreQuickAddDialog( self.triplestoreconf, self.prefixes, self.prefixstore, self.comboBox) self.searchTripleStoreDialog.setMinimumSize(580, 186) self.searchTripleStoreDialog.setWindowTitle( "Configure Own Triple Store") self.searchTripleStoreDialog.exec_() ## # @brief Creates a What To Enrich dialog with parameters given. # # @param self The object pointer def buildCustomTripleStoreDialog(self): self.searchTripleStoreDialog = TripleStoreDialog( self.triplestoreconf, self.prefixes, self.prefixstore, self.comboBox) self.searchTripleStoreDialog.setMinimumSize(700, 500) self.searchTripleStoreDialog.setWindowTitle( "Configure Own Triple Store") self.searchTripleStoreDialog.exec_() ## # @brief Creates a What To Enrich dialog with parameters given. # # @param self The object pointer def createWhatToEnrich(self): if self.enrichTable.rowCount() == 0: return layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.chooseLayerEnrich.currentIndex() layer = layers[selectedLayerIndex].layer() self.searchTripleStoreDialog = EnrichmentDialog( self.triplestoreconf, self.prefixes, self.enrichTable, layer, None, None) self.searchTripleStoreDialog.setMinimumSize(700, 500) self.searchTripleStoreDialog.setWindowTitle("Enrichment Search") self.searchTripleStoreDialog.exec_() def check_state3(self): self.searchTripleStoreDialog.check_state(self.interlinkNameSpace) def createEnrichSearchDialog(self, row=-1, column=-1): if column == 1: self.buildSearchDialog(row, column, False, self.enrichTable, False, False, None, self.addVocabConf) if column == 6: self.buildSearchDialog(row, column, False, self.enrichTable, False, False, None, self.addVocabConf) def createEnrichSearchDialogProp(self, row=-1, column=-1): self.buildSearchDialog(row, column, False, self.findIDPropertyEdit, True, False, None, self.addVocabConf) ## # @brief Creates a search dialog with parameters for interlinking. # # @param self The object pointer # @param row The row of the table for which to map the search result # @param column The column of the table for which to map the search result def createInterlinkSearchDialog(self, row=-1, column=-1): if column > 3 and column < 7: self.buildSearchDialog(row, column, True, self.interlinkTable, True, False, None, self.addVocabConf) elif column >= 7: layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.chooseLayerInterlink.currentIndex() layer = layers[selectedLayerIndex].layer() self.buildValueMappingDialog(row, column, True, self.interlinkTable, layer) elif column == -1: self.buildSearchDialog(row, column, -1, self.interlinkOwlClassInput, False, False, None, self.addVocabConf) ## # @brief Shows the configuration table after creating an enrichment result. # # @param self The object pointer # def showConfigTable(self): self.enrichTableResult.hide() self.enrichTable.show() self.startEnrichment.setText("Start Enrichment") self.startEnrichment.clicked.disconnect() self.startEnrichment.clicked.connect(self.enrichtab.enrichLayerProcess) ## # @brief Executes a GUI event when a new SPARQL endpoint is selected. # Usually loads the list of concepts related to the SPARQL endpoint # @param send The sender of the request # def viewselectaction(self): endpointIndex = self.comboBox.currentIndex() if endpointIndex == 0: self.justloadingfromfile = False return concept = "" curindex = self.proxyModel.mapToSource( self.geoClassList.selectionModel().currentIndex()) if self.geoClassList.selectionModel().currentIndex( ) != None and self.geoClassListModel.itemFromIndex( curindex) != None and re.match( r'.*Q[0-9]+.*', self.geoClassListModel.itemFromIndex(curindex).text() ) and not self.geoClassListModel.itemFromIndex( curindex).text().startswith("http"): self.inp_label.setText( self.geoClassListModel.itemFromIndex(curindex).text().split( "(")[0].lower().replace(" ", "_")) concept = "Q" + self.geoClassListModel.itemFromIndex( curindex).text().split("Q")[1].replace(")", "") elif self.geoClassListModel.itemFromIndex(curindex) != None: concept = self.geoClassListModel.itemFromIndex(curindex).data(1) if "querytemplate" in self.triplestoreconf[endpointIndex]: if "wd:Q%%concept%% ." in self.triplestoreconf[endpointIndex][ "querytemplate"][ self.queryTemplates.currentIndex()]["query"]: querytext = "" if concept != None and concept.startswith("http"): querytext = self.triplestoreconf[endpointIndex][ "querytemplate"][self.queryTemplates.currentIndex( )]["query"].replace( "wd:Q%%concept%% .", "wd:" + concept[concept.rfind('/') + 1:] + " .") elif concept != None: querytext = self.triplestoreconf[endpointIndex][ "querytemplate"][self.queryTemplates.currentIndex( )]["query"].replace("wd:Q%%concept%% .", "wd:" + concept + " .") else: querytext = self.triplestoreconf[endpointIndex][ "querytemplate"][ self.queryTemplates.currentIndex()]["query"].replace( "%%concept%%", concept) if self.queryLimit.text().isnumeric( ) and querytext.rfind("LIMIT") != -1: querytext = querytext[0:querytext.rfind( "LIMIT")] + "LIMIT " + self.queryLimit.text() elif self.queryLimit.text().isnumeric() and querytext.rfind( "LIMIT") == -1: querytext = querytext + " LIMIT " + self.queryLimit.text() self.inp_sparql2.setPlainText(querytext) self.inp_sparql2.columnvars = {} if self.geoClassList.selectionModel().currentIndex( ) != None and self.geoClassListModel.itemFromIndex( curindex ) != None and "#" in self.geoClassListModel.itemFromIndex( curindex).text(): self.inp_label.setText( self.geoClassListModel.itemFromIndex(curindex).text() [self.geoClassListModel.itemFromIndex(curindex).text(). rfind('#') + 1:].lower().replace(" ", "_")) elif self.geoClassList.selectionModel().currentIndex( ) != None and self.geoClassListModel.itemFromIndex(curindex) != None: self.inp_label.setText( self.geoClassListModel.itemFromIndex(curindex).text() [self.geoClassListModel.itemFromIndex(curindex).text(). rfind('/') + 1:].lower().replace(" ", "_")) def itemModelToMap(self, model): resdict = {} for row in range(model.rowCount()): index = model.index(row, 0, self) resdict[model.itemFromIndex(index).text()] = model.itemFromIndex( index).data(1) return resdict ## # @brief Deletes a row from the table in the enrichment dialog. # # @param send The sender of the request # def deleteEnrichRow(send): w = send.sender().parent() row = self.enrichTable.indexAt(w.pos()).row() self.enrichTable.removeRow(row) self.enrichTable.setCurrentCell(0, 0) ## # @brief Adds a new row to the table in the enrichment dialog. # # @param self The object pointer # def addEnrichRow(self): layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.chooseLayerEnrich.currentIndex() layer = layers[selectedLayerIndex].layer() self.enrichTableResult.hide() fieldnames = [field.name() for field in layer.fields()] item = QTableWidgetItem("new_column") #item.setFlags(QtCore.Qt.ItemIsEnabled) row = self.enrichTable.rowCount() self.enrichTable.insertRow(row) self.enrichTable.setItem(row, 0, item) cbox = QComboBox() cbox.addItem("Get Remote") cbox.addItem("No Enrichment") cbox.addItem("Exclude") self.enrichTable.setCellWidget(row, 3, cbox) cbox = QComboBox() cbox.addItem("Enrich Value") cbox.addItem("Enrich URI") cbox.addItem("Enrich Both") self.enrichTable.setCellWidget(row, 4, cbox) cbox = QComboBox() for fieldd in fieldnames: cbox.addItem(fieldd) self.enrichTable.setCellWidget(row, 5, cbox) itemm = QTableWidgetItem("http://www.w3.org/2000/01/rdf-schema#label") self.enrichTable.setItem(row, 6, itemm) itemm = QTableWidgetItem("") self.enrichTable.setItem(row, 7, itemm) itemm = QTableWidgetItem("") self.enrichTable.setItem(row, 8, itemm) ## Validates the SPARQL query in the input field and outputs errors in a label. # @param self The object pointer. def validateSPARQL(self): if self.prefixes != None and self.comboBox != None and self.comboBox.currentIndex( ) != None and self.prefixes[self.comboBox.currentIndex( )] != None and self.inp_sparql2.toPlainText( ) != None and self.inp_sparql2.toPlainText() != "": try: if self.prefixes[self.comboBox.currentIndex()] != "": prepareQuery( "".join(self.prefixes[self.comboBox.currentIndex()]) + "\n" + self.inp_sparql2.toPlainText()) self.errorLabel.setText("Valid Query") self.errorline = -1 self.sparqlhighlight.errorhighlightline = self.errorline self.sparqlhighlight.currentline = 0 self.inp_sparql2.errorline = None except Exception as e: match = re.search(r'line:([0-9]+),', str(e)) match2 = re.search(r'col:([0-9]+),', str(e)) start = int(match.group(1)) - len(self.triplestoreconf[ self.comboBox.currentIndex()]["prefixes"]) - 1 self.errorLabel.setText( re.sub("line:([0-9]+),", "line: " + str(start) + ",", str(e))) self.inp_sparql2.errorline = start - 1 if "line" in str(e): ex = str(e) start = ex.find('line:') + 5 end = ex.find(',', start) start2 = ex.find('col:') + 4 end2 = ex.find(')', start2) self.errorline = ex[start:end] self.sparqlhighlight.errorhighlightcol = ex[start2:end2] self.sparqlhighlight.errorhighlightline = self.errorline self.sparqlhighlight.currentline = 0 ## # @brief Builds the search dialog to search for a concept or class. # @param self The object pointer # @param row the row to insert the result # @param column the column to insert the result # @param interlinkOrEnrich indicates if the dialog is meant for interlinking or enrichment # @param table the GUI element to display the result def buildSearchDialog(self, row, column, interlinkOrEnrich, table, propOrClass, bothOptions=False, currentprefixes=None, addVocabConf=None): self.currentcol = column self.currentrow = row self.interlinkdialog = SearchDialog(column, row, self.triplestoreconf, self.prefixes, interlinkOrEnrich, table, propOrClass, bothOptions, currentprefixes, addVocabConf) self.interlinkdialog.setMinimumSize(650, 400) self.interlinkdialog.setWindowTitle("Search Interlink Concept") self.interlinkdialog.exec_() ## # @brief Builds a boundingbox dialog allows to pick a bounding box for a SPARQL query. # # @param self The object pointer def getPointFromCanvas(self): self.d = BBOXDialog(self.inp_sparql2, self.triplestoreconf, self.comboBox.currentIndex()) self.d.setWindowTitle("Choose BoundingBox") self.d.exec_() ## # @brief Builds a value mapping dialog window for ther interlinking dialog. # # @param self The object pointer # @param row The row of the table for which to map the value # @param column The column of the table for which to map the value # @param table The table in which to save the value mapping result # @param layer The layer which is concerned by the enrichment oder interlinking def buildValueMappingDialog(self, row, column, interlinkOrEnrich, table, layer): self.currentcol = column self.currentrow = row valuemap = None if table.item(row, column) != None and table.item(row, column).text() != "": valuemap = table.item(row, column).data(1) self.interlinkdialog = ValueMappingDialog(column, row, self.triplestoreconf, interlinkOrEnrich, table, table.item(row, 3).text(), layer, valuemap) self.interlinkdialog.setMinimumSize(650, 400) self.interlinkdialog.setWindowTitle("Get Value Mappings for column " + table.item(row, 3).text()) self.interlinkdialog.exec_() ## # @brief Loads a QGIS layer for interlinking into the interlinking dialog. # # @param self The object pointer def loadLayerForInterlink(self): layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.chooseLayerInterlink.currentIndex() if len(layers) == 0: return layer = layers[selectedLayerIndex].layer() fieldnames = [field.name() for field in layer.fields()] while self.interlinkTable.rowCount() > 0: self.interlinkTable.removeRow(0) row = 0 self.interlinkTable.setHorizontalHeaderLabels([ "Export?", "IDColumn?", "GeoColumn?", "Column", "ColumnProperty", "PropertyType", "ColumnConcept", "ValueConcepts" ]) self.interlinkTable.setColumnCount(8) for field in fieldnames: item = QTableWidgetItem(field) item.setFlags(QtCore.Qt.ItemIsEnabled) item2 = QTableWidgetItem() item2.setCheckState(True) item3 = QTableWidgetItem() item3.setCheckState(False) item4 = QTableWidgetItem() item4.setCheckState(False) self.interlinkTable.insertRow(row) self.interlinkTable.setItem(row, 3, item) self.interlinkTable.setItem(row, 0, item2) self.interlinkTable.setItem(row, 1, item3) self.interlinkTable.setItem(row, 2, item4) cbox = QComboBox() cbox.addItem("Automatic") cbox.addItem("AnnotationProperty") cbox.addItem("DataProperty") cbox.addItem("ObjectProperty") cbox.addItem("SubClass") self.interlinkTable.setCellWidget(row, 5, cbox) currentRowCount = self.interlinkTable.rowCount() row += 1 ## # @brief Loads a QGIS layer for enrichment into the enrichment dialog. # # @param self The object pointer def loadLayerForEnrichment(self): layers = QgsProject.instance().layerTreeRoot().children() selectedLayerIndex = self.chooseLayerEnrich.currentIndex() if len(layers) == 0: return layer = layers[selectedLayerIndex].layer() self.enrichTableResult.hide() while self.enrichTableResult.rowCount() > 0: self.enrichTableResult.removeRow(0) self.enrichTable.show() self.addEnrichedLayerRowButton.setEnabled(True) fieldnames = [field.name() for field in layer.fields()] while self.enrichTable.rowCount() > 0: self.enrichTable.removeRow(0) row = 0 self.enrichTable.setColumnCount(9) self.enrichTable.setHorizontalHeaderLabels([ "Column", "EnrichmentConcept", "TripleStore", "Strategy", "content", "ID Column", "ID Property", "ID Domain", "Language" ]) for field in fieldnames: item = QTableWidgetItem(field) item.setFlags(QtCore.Qt.ItemIsEnabled) currentRowCount = self.enrichTable.rowCount() self.enrichTable.insertRow(row) self.enrichTable.setItem(row, 0, item) cbox = QComboBox() cbox.addItem("No Enrichment") cbox.addItem("Keep Local") cbox.addItem("Keep Remote") cbox.addItem("Replace Local") cbox.addItem("Merge") cbox.addItem("Ask User") cbox.addItem("Exclude") self.enrichTable.setCellWidget(row, 3, cbox) cbox = QComboBox() cbox.addItem("Enrich Value") cbox.addItem("Enrich URI") cbox.addItem("Enrich Both") self.enrichTable.setCellWidget(row, 4, cbox) cbox = QComboBox() for fieldd in fieldnames: cbox.addItem(fieldd) self.enrichTable.setCellWidget(row, 5, cbox) itemm = QTableWidgetItem( "http://www.w3.org/2000/01/rdf-schema#label") self.enrichTable.setItem(row, 6, itemm) itemm = QTableWidgetItem("") self.enrichTable.setItem(row, 7, itemm) itemm = QTableWidgetItem("") self.enrichTable.setItem(row, 8, itemm) celllayout = QHBoxLayout() upbutton = QPushButton("Up") removebutton = QPushButton("Remove", self) removebutton.clicked.connect(self.deleteEnrichRow) downbutton = QPushButton("Down") celllayout.addWidget(upbutton) celllayout.addWidget(downbutton) celllayout.addWidget(removebutton) w = QWidget() w.setLayout(celllayout) optitem = QTableWidgetItem() #self.enrichTable.setCellWidget(row,4,w) #self.enrichTable.setItem(row,3,cbox) row += 1 self.originalRowCount = row ## Fetch the currently loaded layers. # @param self The object pointer. def loadUnicornLayers(self): layers = QgsProject.instance().layerTreeRoot().children() # Populate the comboBox with names of all the loaded unicorn layers self.loadedLayers.clear() self.chooseLayerInterlink.clear() self.chooseLayerEnrich.clear() for layer in layers: ucl = layer.name() #if type(layer) == QgsMapLayer.VectorLayer: self.loadedLayers.addItem(layer.name()) self.chooseLayerInterlink.addItem(layer.name()) self.chooseLayerEnrich.addItem(layer.name())
class geopunt4QgisDataCatalog(QDialog): def __init__(self, iface): QDialog.__init__(self, None) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) self.iface = iface # initialize locale locale = QSettings().value("locale/userLocale", "en") if not locale: locale = 'en' else: locale = locale[0:2] localePath = os.path.join(os.path.dirname(__file__), 'i18n', 'geopunt4qgis_{}.qm'.format(locale)) if os.path.exists(localePath): self.translator = QTranslator() self.translator.load(localePath) QCoreApplication.installTranslator(self.translator) self._initGui() def _initGui(self): """setup the user interface""" self.ui = Ui_geopunt4QgisDataCatalogDlg() self.ui.setupUi(self) # get settings self.s = QSettings() self.loadSettings() self.gh = geometryHelper(self.iface) # setup a message bar self.bar = QgsMessageBar() self.bar.setSizePolicy( QSizePolicy.Minimum, QSizePolicy.Fixed) self.ui.verticalLayout.addWidget(self.bar) self.ui.buttonBox.addButton(QPushButton("Sluiten"), QDialogButtonBox.RejectRole) for btn in self.ui.buttonBox.buttons(): btn.setAutoDefault(0) # vars self.firstShow = True self.wms = None self.wfs = None self.dl = None self.zoek = '' self.bronnen = None self.model = QStandardItemModel(self) self.proxyModel = QSortFilterProxyModel(self) self.proxyModel.setSourceModel(self.model) self.ui.resultView.setModel(self.proxyModel) self.completer = QCompleter(self) self.completerModel = QStringListModel(self) self.ui.zoekTxt.setCompleter(self.completer) self.completer.setModel(self.completerModel) # eventhandlers self.ui.zoekBtn.clicked.connect(self.onZoekClicked) self.ui.addWMSbtn.clicked.connect(self.addWMS) self.ui.addWFSbtn.clicked.connect(self.addWFS) self.ui.DLbtn.clicked.connect(lambda: self.openUrl(self.dl)) self.ui.resultView.clicked.connect(self.resultViewClicked) self.ui.modelFilterCbx.currentIndexChanged.connect(self.modelFilterCbxIndexChanged) self.ui.filterWgt.setHidden(1) self.ui.buttonBox.helpRequested.connect(self.openHelp) self.finished.connect(self.clean) def loadSettings(self): self.timeout = int(self.s.value("geopunt4qgis/timeout", 15)) if settings().proxyUrl: self.proxy = settings().proxyUrl else: self.proxy = "" self.md = MDReader(self.timeout, self.proxy) def openHelp(self): webbrowser.open_new_tab("http://www.geopunt.be/voor-experts/geopunt-plug-ins/functionaliteiten/catalogus") def _setModel(self, records): self.model.clear() records = sorted(records, key=lambda k: k['title']) for rec in records: title = QStandardItem(rec['title']) # 0 wms = QStandardItem(rec['wms']) # 1 downloadLink = QStandardItem(rec['download']) # 2 id = QStandardItem(rec['uuid']) # 3 abstract = QStandardItem(rec['abstract']) # 4 wfs = QStandardItem(rec['wfs']) # 5 self.model.appendRow([title, wms, downloadLink, id, abstract, wfs]) # overwrite def show(self): QDialog.show(self) self.setWindowModality(0) metadataUrl = "https://metadata.geopunt.be" inet = internet_on(proxyUrl=self.proxy, timeout=self.timeout, testSite= metadataUrl) if not inet: msg = "Kan geen verbing maken met de metadata van Geopunt: {} \nMogelijke is deze site niet bereikbaar, dan zal deze tool ook niet werken.\nProbeer later opnieuw. Indien dit probleem zich blijft voordoen contacteer informatie Vlaanderen.".format(metadataUrl) QMessageBox.warning(self.iface.mainWindow(), "Waarschuwing: kan geen verbinding maken", msg) self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog","Waarschuwing"), msg, level=Qgis.Warning, duration=3) return if self.firstShow: self.ui.GDIThemaCbx.addItems([''] + self.md.list_GDI_theme()) self.ui.organisatiesCbx.addItems([''] + self.md.list_organisations()) keywords = sorted(self.md.list_suggestionKeyword()) self.completerModel.setStringList(keywords) self.bronnen = self.md.list_bronnen() self.ui.bronCbx.addItems([''] + [n[1] for n in self.bronnen]) self.ui.typeCbx.addItems([''] + [n[0] for n in self.md.dataTypes]) self.ui.INSPIREannexCbx.addItems([''] + self.md.inspireannex) self.ui.INSPIREserviceCbx.addItems([''] + self.md.inspireServiceTypes) self.ui.INSPIREthemaCbx.addItems([''] + self.md.list_inspire_theme()) self.firstShow = False # eventhandlers def resultViewClicked(self): if self.ui.resultView.selectedIndexes(): row = self.ui.resultView.selectedIndexes()[0].row() title = self.proxyModel.data(self.proxyModel.index(row, 0)) self.wms = self.proxyModel.data(self.proxyModel.index(row, 1)) self.dl = self.proxyModel.data(self.proxyModel.index(row, 2)) self.wfs = self.proxyModel.data(self.proxyModel.index(row, 5)) uuid = self.proxyModel.data(self.proxyModel.index(row, 3)) abstract = self.proxyModel.data(self.proxyModel.index(row, 4)) self.ui.descriptionText.setText( """<h3>%s</h3><div>%s</div><br/><div> <a href='https://metadata.geopunt.be/zoekdienst/apps/tabsearch/index.html?uuid=%s'> Ga naar fiche</a></div>""" % (title, abstract, uuid)) if self.wms: self.ui.addWMSbtn.setEnabled(1) else: self.ui.addWMSbtn.setEnabled(0) if self.wfs: self.ui.addWFSbtn.setEnabled(1) else: self.ui.addWFSbtn.setEnabled(0) if self.dl: self.ui.DLbtn.setEnabled(1) else: self.ui.DLbtn.setEnabled(0) def onZoekClicked(self): self.zoek = self.ui.zoekTxt.currentText() self.search() def modelFilterCbxIndexChanged(self): value = self.ui.modelFilterCbx.currentIndex() if value == 1: self.filterModel(1) elif value == 2: self.filterModel(5) elif value == 3: self.filterModel(2) else: self.filterModel() def filterModel(self, col=None): if col != None: self.proxyModel.setFilterKeyColumn(col) expr = QRegExp("?*", Qt.CaseInsensitive, QRegExp.Wildcard) self.proxyModel.setFilterRegExp(expr) else: self.proxyModel.setFilterRegExp(None) def search(self): try: if self.ui.filterBox.isChecked(): themekey = self.ui.GDIThemaCbx.currentText() orgName = self.ui.organisatiesCbx.currentText() dataTypes = [n[1] for n in self.md.dataTypes if n[0] == self.ui.typeCbx.currentText()] if dataTypes != []: dataType = dataTypes[0] else: dataType = '' siteIds = [n[0] for n in self.bronnen if n[1] == self.ui.bronCbx.currentText()] if siteIds != []: siteId = siteIds[0] else: siteId = '' inspiretheme = self.ui.INSPIREthemaCbx.currentText() inspireannex = self.ui.INSPIREannexCbx.currentText() inspireServiceType = self.ui.INSPIREserviceCbx.currentText() searchResult = MDdata(self.md.searchAll( self.zoek, themekey, orgName, dataType, siteId, inspiretheme, inspireannex, inspireServiceType)) else: searchResult = MDdata(self.md.searchAll(self.zoek)) except: self.bar.pushMessage("Error", str(sys.exc_info()[1]), level=Qgis.Critical, duration=3) return self.ui.countLbl.setText("Aantal gevonden: %s" % searchResult.count) self.ui.descriptionText.setText('') self._setModel(searchResult.records) if searchResult.count == 0: self.bar.pushMessage( QCoreApplication.translate("geopunt4QgisPoidialog", "Waarschuwing "), QCoreApplication.translate("geopunt4QgisPoidialog", "Er werden geen resultaten gevonde voor deze zoekopdracht"), duration=5) def openUrl(self, url): if url: webbrowser.open_new_tab(url.encode("utf-8")) def addWMS(self): if self.wms == None: return crs = self.gh.getGetMapCrs(self.iface).authid() if crs != 'EPSG:31370' or crs != 'EPSG:3857' or crs != 'EPSG:3043': crs = 'EPSG:31370' try: lyrs = getWmsLayerNames(self.wms, self.proxy) except: self.bar.pushMessage("Error", str(sys.exc_info()[1]), level=Qgis.Critical, duration=10) return if len(lyrs) == 0: self.bar.pushMessage("WMS", QCoreApplication.translate("geopunt4QgisDataCatalog", "Kan geen lagen vinden in: %s" % self.wms), level=Qgis.Warning, duration=10) return elif len(lyrs) == 1: layerTitle = lyrs[0][1] else: layerTitle, accept = QInputDialog.getItem(self, "WMS toevoegen", "Kies een laag om toe te voegen", [n[1] for n in lyrs], editable=0) if not accept: return layerName = [n[0] for n in lyrs if n[1] == layerTitle][0] style = [n[2] for n in lyrs if n[1] == layerTitle][0] if not style: style = "" url = self.wms.split('?')[0] if crs != 'EPSG:31370' or crs != 'EPSG:3857': crs = 'EPSG:31370' wmsUrl = "contextualWMSLegend=0&dpiMode=7&url=%s&layers=%s&format=image/png&styles=%s&crs=%s" % ( url, layerName, style, crs) try: rlayer = QgsRasterLayer(wmsUrl, layerTitle, 'wms') if rlayer.isValid(): QgsProject.instance().addMapLayer(rlayer) else: self.bar.pushMessage("Error", QCoreApplication.translate("geopunt4QgisDataCatalog", "Kan WMS niet laden"), level=Qgis.Critical, duration=10) except: self.bar.pushMessage("Error", str(sys.exc_info()[1]), level=Qgis.Critical, duration=10) return def addWFS(self): if self.wfs == None: return try: lyrs = getWFSLayerNames(self.wfs, self.proxy) except: self.bar.pushMessage("Error", str(sys.exc_info()[1]), level=Qgis.Critical, duration=10) return if len(lyrs) == 0: self.bar.pushMessage("WFS", QCoreApplication.translate("geopunt4QgisDataCatalog", "Kan geen lagen vinden in: %s" % self.wfs), level=Qgis.Warning, duration=10) return elif len(lyrs) == 1: layerTitle = lyrs[0][1] else: layerTitle, accept = QInputDialog.getItem(self, "WFS toevoegen", "Kies een laag om toe te voegen", [n[1] for n in lyrs], editable=0) if not accept: return layerName = [n[0] for n in lyrs if n[1] == layerTitle][0] crs = [n[2] for n in lyrs if n[1] == layerTitle][0] url = self.wfs.split('?')[0] wfsUri = makeWFSuri(url, layerName, crs ) try: vlayer = QgsVectorLayer(wfsUri, layerTitle, "WFS") QgsProject.instance().addMapLayer(vlayer) except: self.bar.pushMessage("Error", str(sys.exc_info()[1]), level=Qgis.Critical, duration=10) return def clean(self): self.model.clear() self.wms = None self.wfs = None self.dl = None self.ui.zoekTxt.setCurrentIndex(0) self.ui.descriptionText.setText('') self.ui.countLbl.setText("") self.ui.msgLbl.setText("") self.ui.DLbtn.setEnabled(0) self.ui.addWFSbtn.setEnabled(0) self.ui.addWMSbtn.setEnabled(0) self.ui.modelFilterCbx.setCurrentIndex(0)