Skip to content

Commit

Permalink
Merge pull request #69 from Septima/MetadataDbLinker-2-to-3
Browse files Browse the repository at this point in the history
Metadata db linker 2 to 3
  • Loading branch information
Nicolai Mogensen authored Jan 13, 2020
2 parents 4cec7e9 + 1fd0746 commit 9f91dd2
Show file tree
Hide file tree
Showing 65 changed files with 3,257 additions and 1,513 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ target/
#
.idea

#.vscode
.vscode

#
.DS_Store

Expand Down
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,36 @@
# qgis-metadatafunctionality
The purpose of this QGIS plugin is to make it possible to enter metadatainformation (name, description, kle-journalnumber, date-of-creation-table) for a table in database through DB Manager.

# Installation and setup
The MetadataDBLinker plugin requires as minimum one table where metadata is stored, and an optional table describing the fields in the graphical user interface. The plugin can be installed using the install plugin from zip option in QGIS. ZIP files can be found and downloaded under `releases` for this Github Repository.

![options](figures/installzip.PNG?raw=true "Installing the Plugin")

## First time setup
First time setting up the plugin the metadata table should be created and settings filled out accordingly. Navigate to the settings window in QGIS `Settings -> Options` and MetadataDBLinker will have its own tab.


![settings](figures/options.PNG?raw=true "MetadataDbLinker Options")

MetadataDBLinker allows a dedicated user to be used with the metadata table. Access rights to this user can be controlled in PostgreSQL. Click the `Metadata Table (SQL)` button for an SQL CREATE statement that will create the table. Create the table in your PostgreSQL Database, make sure your user has approriate access to it then fill out the settings. Finally test the connection by clicking the test button, if OK the plugin should be working.

![options](figures/settings.PNG?raw=true "Settings")

### Gui Table

An extra table can optionally be configured to describe if certain GUI fields in the dialog should be required or enabled. The `Save metadata` button will be greyed out if required fields are not filled. Click the `Gui Table (SQL)` button in the settings for an SQL CREATE statement to set up this table.

Rows in this table refers columns in the `metadata` table by the `metadata_col_name` column. The table contains three boolean columns: `required`, `editable` and `is_shown` which can be set for every entry in the `metadata` table.

## Usage

The plugin can be accessed in two ways. If the plugin is configured and active it can be reached from the toolbar. The plugin will also automatically start after importing layers into DB-manager. Click a layer in the browser within plugin to assign metadata, or if the dialog was started from DB-manager the layer is already selected. Fill out the metadata accordingly and hit `Save metadata` when done. The metadata fields will be enabled when a layer is selected in the browser. If a layer already has metadata assigned these fields will be filled and can be updated.


![dblinker](figures/dblinker.PNG?raw=true "Metadata-DB-linker")

## Locator

As an added feature, layers with added metadata can be searched using the QGIS Locator by their metadata fields under the category "Metadata-DB-Linker". Clicking the entries will add to them to the current active project.

![dblinker](figures/locator.PNG?raw=true "Metadata-DB-linker")
Binary file added figures/dblinker.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/installzip.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/locator.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/options.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added figures/settings.PNG
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
30 changes: 30 additions & 0 deletions sql/gui_table.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
-- These statements create a table and some nescessary data
-- 1: Replace ALL occurrences of [schema] to the schema
-- 2: Replace [owner] to the owner of the metadatatabel
-- 3: Execute these statements in the postgresdatabase

-- Table: metadata.gui_table
CREATE TABLE [schema].gui_table
(
id SERIAL,
metadata_col_name character varying,
type character varying,
required boolean,
editable boolean,
is_shown boolean,
CONSTRAINT gui_table_pkey PRIMARY KEY (metadata_col_name)
)
WITH (
OIDS = FALSE
)
TABLESPACE pg_default;

ALTER TABLE [schema].gui_table OWNER to [owner];

-- Insert descriptive fields for the Metadata Model
INSERT INTO [schema].gui_table(metadata_col_name, type, required, editable) VALUES ('name', 'text', true, true);
INSERT INTO [schema].gui_table(metadata_col_name, type, required, editable) VALUES ('description', 'text', false, true);
INSERT INTO [schema].gui_table(metadata_col_name, type, required, editable) VALUES ('geodatainfo_uuid', 'text', false, true);
INSERT INTO [schema].gui_table(metadata_col_name, type, required, editable) VALUES ('kle_no', 'text', false, true);
INSERT INTO [schema].gui_table(metadata_col_name, type, required, editable) VALUES ('responsible', 'text', false, true);
INSERT INTO [schema].gui_table(metadata_col_name, type, required, editable) VALUES ('project', 'text', false, true);
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@ CREATE TABLE [schema].[table] (
sourcetable varchar,
guid varchar,
ts_timezone varchar,
geodatainfo_uuid uuid,
CONSTRAINT pk_metadata PRIMARY KEY (guid)
)
WITH (OIDS=FALSE);
ALTER TABLE [schema].[table] OWNER TO [owner];

-- QGIS Locator function
create or replace function [schema]._getMetaDataMatches(varchar, int default 1000)
returns table (name varchar, description varchar, host varchar, db varchar, port integer, schema varchar, sourcetable varchar)
as $$
Expand Down
13 changes: 7 additions & 6 deletions src/MetadataDbLinker/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ LRELEASE = lrelease
SOURCES = \
__init__.py \
metadata_db_linker.py \
ui/dialog_metadata.py \
./ui/dialog_metadata.py \
ui/dialog_settings.py \
ui/dialog_settings_db_def.py

Expand All @@ -48,13 +48,14 @@ PY_FILES = \
__init__.py \
metadata_db_linker.py \
ui/dialog_metadata.py \
ui/dialog_settings.py \
ui/dialog_settings_db_def.py
config/dialog_settings_db_def.py \
config/settings.py \
config/settings_dialog.py

UI_FILES = \
ui/dialog_metadata.ui \
ui/dialog_settings.ui \
ui/dialog_settings_db_def.ui
config/dialog_settings.ui \
config/dialog_settings_db_def.ui

EXTRAS = metadata.txt icon.png

Expand All @@ -80,7 +81,7 @@ default: compile
compile: $(COMPILED_RESOURCE_FILES)

%.py : %.qrc $(RESOURCES_SRC)
pyrcc4 -o $*.py $<
pyrcc5 -o $*.py $<

%.qm : %.ts
$(LRELEASE) $<
Expand Down
52 changes: 1 addition & 51 deletions src/MetadataDbLinker/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,6 @@
This script initializes the plugin, making it known to QGIS.
"""

from .qgissettingmanager import (
SettingManager,
String,
Scope
)

# HOW WE CAN DEBUG
import sys
# sys.path.append('/Applications/PyCharm.app/Contents/debug-eggs/pycharm-debug.egg')
# import pydevd
# pydevd.settrace('localhost', port=53100, stdoutToServer=True, stderrToServer=True)


# noinspection PyPep8Naming
def classFactory(iface): # pylint: disable=invalid-name
"""Load MetadataDbLinker class from file metadata_db_linker.
Expand All @@ -43,41 +30,4 @@ def classFactory(iface): # pylint: disable=invalid-name
:type iface: QgsInterface
"""
from .metadata_db_linker import MetadataDbLinker
return MetadataDbLinker(iface)


class MetadataDbLinkerSettings(SettingManager):

def __init__(self):
SettingManager.__init__(self, 'Metadata-DB-Linker')
self.add_setting(String('host', Scope.Global, ''))
self.add_setting(String('database', Scope.Global, ''))
self.add_setting(String('port', Scope.Global, ''))
self.add_setting(String('schema', Scope.Global, 'public'))
self.add_setting(String('sourcetable', Scope.Global, ''))
self.add_setting(String('username', Scope.Global, ''))
self.add_setting(String('password', Scope.Global, ''))
self.add_setting(String('taxonUrl', Scope.Global, ''))
self.add_setting(String('taxonTaxonomy', Scope.Global, ''))

def verify_settings_set(self):
errors = ''
if not self.value('host'):
errors += '{}\n'.format('Missing host in settings')
if not self.value('port'):
errors += '{}\n'.format('Missing port in settings')
if not self.value('database'):
errors += '{}\n'.format('Missing database in settings')
if not self.value('schema'):
errors += '{}\n'.format('Missing schema in settings')
if not self.value('sourcetable'):
errors += '{}\n'.format('Missing table in settings')
if not self.value('username'):
errors += '{}\n'.format('Missing username in settings')
if not self.value('password'):
errors += '{}\n'.format('Missing password in settings')

if errors:
return errors

return None
return MetadataDbLinker(iface)
4 changes: 4 additions & 0 deletions src/MetadataDbLinker/config/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from .options_factory import OptionsFactory
from .settings import Settings
from .settings_dialog import ConfigDialog
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@

import os

from PyQt4 import (
QtGui,
from qgis.PyQt import (
uic
)

from qgis.PyQt.QtWidgets import (
QDialog
)
SETTINGS_DB_FORM_CLASS, _ = uic.loadUiType(
os.path.join(
os.path.dirname(__file__),
Expand All @@ -36,7 +37,7 @@
)


class SettingsDbDefDialog(QtGui.QDialog, SETTINGS_DB_FORM_CLASS):
class SettingsDbDefDialog(QDialog, SETTINGS_DB_FORM_CLASS):

def __init__(self, parent=None):
"""Constructor."""
Expand All @@ -54,3 +55,22 @@ def load_db_def(self):
)
with open(nf, 'r') as myfile:
self.textEdit.setText(myfile.read())

class SettingsGuiTableDialog(QDialog, SETTINGS_DB_FORM_CLASS):

def __init__(self, parent=None):
"""Constructor."""
super(SettingsGuiTableDialog, self).__init__(parent)
self.setupUi(self)
self.load_db_def()

def load_db_def(self):
nf = os.path.join(
os.path.dirname(
os.path.realpath(__file__)
),
'sql',
'gui_table.sql'
)
with open(nf, 'r') as myfile:
self.textEdit.setText(myfile.read())
Binary file added src/MetadataDbLinker/config/metadata.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
19 changes: 19 additions & 0 deletions src/MetadataDbLinker/config/options_factory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import os
from qgis.gui import (QgsOptionsWidgetFactory)
from qgis.core import QgsApplication
from qgis.PyQt.QtGui import QIcon
from .settings_dialog import ConfigOptionsPage


class OptionsFactory(QgsOptionsWidgetFactory):

def __init__(self, settings):
super(QgsOptionsWidgetFactory, self).__init__()
self.settings = settings

def icon(self):
icon_path = os.path.join(os.path.dirname(__file__), 'metadata.png')
return QIcon (icon_path)

def createWidget(self, parent):
return ConfigOptionsPage(parent, self.settings)
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import MySettings
self.settings = MySettings()
```

The settings are easily accessed using the `value` and `set_value` methods:
The settings are easily accessed using the `value` and `setValue` methods:

```python
myVariable = self.settings.value("myVariable")
Expand Down Expand Up @@ -126,7 +126,7 @@ The widgets are automatically detected by the manager. If the type of widget is

**Colors**

* Native QGIS widgets (QgsColorButton, QgsColorButtonV2) or any widget (label or pushbutton are recommended). For standard Qt Widgets, QGIS [color button](http://qgis.org/api/classQgsColorButtonV2.html)) will be used. Use options `allowAlpha` (boolean) to allow transparent colors and `dialogTitle` to set the dialog title.
* Native QGIS widgets (QgsColorButton) or any widget (label or pushbutton are recommended). For standard Qt Widgets, QGIS [color button](http://qgis.org/api/classQgsColorButton.html)) will be used. Use options `allowAlpha` (boolean) to allow transparent colors and `dialogTitle` to set the dialog title.

**Integers**

Expand Down
9 changes: 9 additions & 0 deletions src/MetadataDbLinker/config/qgissettingmanager/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@

from .setting_manager import SettingManager
from .setting import Setting, Scope
from .setting_dialog import SettingDialog, UpdateMode

from .types import *



Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
#
#---------------------------------------------------------------------

from PyQt4.QtCore import QObject, pyqtSignal, QSettings
from PyQt5.QtCore import QObject, pyqtSignal, QSettings
from qgis.core import QgsProject


Expand Down
Loading

0 comments on commit 9f91dd2

Please sign in to comment.