# -*- coding: utf-8 -*-
"""
/***************************************************************************
 SPAQLunicorn
                                 A QGIS plugin
 This plugin adds a GeoJSON layer from a Wikidata SPARQL query.
 Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
                              -------------------
        begin                : 2019-10-28
        git sha              : $Format:%H$
        copyright            : (C) 2019 by SPARQL Unicorn
        email                : rse@fthiery.de
        developer(s)         : Florian Thiery,  Timo Homburg
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/
"""

#import sys
#import pip
from qgis.utils import iface
from qgis.core import Qgis

from qgis.PyQt.QtCore import QSettings,QCoreApplication,QRegExp,QVariant
from qgis.PyQt.QtGui import QIcon,QRegExpValidator,QBrush,QColor
from qgis.core import QgsTask, QgsTaskManager
from qgis.PyQt.QtWidgets import QAction,QComboBox,QCompleter,QFileDialog,QTableWidgetItem,QHBoxLayout,QPushButton,QWidget,QMessageBox
from qgis.core import QgsProject,QgsGeometry,QgsVectorLayer,QgsExpression,QgsFeatureRequest,QgsCoordinateReferenceSystem,QgsCoordinateTransform,QgsApplication,QgsWkbTypes,QgsField
from qgis.utils import iface
import os.path
import sys
import xml.etree.ElementTree as ET
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "dependencies")))
import requests
import uuid
import json
import urllib.parse
from rdflib import *
from rdflib.plugins.sparql import prepareQuery
from SPARQLWrapper import SPARQLWrapper, JSON, POST, GET
# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from .sparql_unicorn_dialog import SPAQLunicornDialog
from .sparqlhighlighter import SPARQLHighlighter
from .tooltipplaintext import ToolTipPlainText
from .triplestoredialog import TripleStoreDialog
from .searchdialog import SearchDialog
from .varinput import VarInputDialog
from .whattoenrich import EnrichmentDialog
from .valuemapping import ValueMappingDialog
from .bboxdialog import BBOXDialog
from .uploadrdfdialog import UploadRDFDialog

import re

geoconcepts=""

class SPAQLunicorn:
    """QGIS Plugin Implementation."""
    loadedfromfile=False
	
    enrichedExport=False
	
    exportNameSpace=None

    exportIdCol=None
	
    exportSetClass=None

    triplestoreconf=None
    
    enrichLayer=None
	
    originalRowCount=0
	
    enrichLayerCounter=0
	
    addVocabConf=None
	
    exportColConfig={}

    valueconcept={}
	
    columnvars={}
	
    prefixes=[]
   
    def __init__(self, iface):
        """Constructor.

        :param iface: An interface instance that will be passed to this class
            which provides the hook by which you can manipulate the QGIS
            application at run time.
        :type iface: QgsInterface
        """
        # Save reference to the QGIS interface
        self.iface = iface
        # initialize plugin directory
        self.plugin_dir = os.path.dirname(__file__)
        # initialize locale
        locale = QSettings().value('locale/userLocale')[0:2]
        locale_path = os.path.join(
            self.plugin_dir,
            'i18n',
            'SPAQLunicorn_{}.qm'.format(locale))

        if os.path.exists(locale_path):
            self.translator = QTranslator()
            self.translator.load(locale_path)
            QCoreApplication.installTranslator(self.translator)

        # Declare instance attributes
        self.actions = []
        self.menu = self.tr(u'&SPARQL Unicorn Wikidata Plugin')

        # Check if plugin was started the first time in current QGIS session
        # Must be set in initGui() to survive plugin reloads
        self.first_start = None

    # noinspection PyMethodMayBeStatic
    def tr(self, message):
        """Get the translation for a string using Qt translation API.

        We implement this ourselves since we do not inherit QObject.

        :param message: String for translation.
        :type message: str, QString

        :returns: Translated version of message.
        :rtype: QString
        """
        # noinspection PyTypeChecker,PyArgumentList,PyCallByClass
        return QCoreApplication.translate('SPAQLunicorn', message)


    def validateSPARQL(self):
        try:
            prepareQuery("".join(self.prefixes[self.dlg.comboBox.currentIndex()])+"\n"+self.dlg.inp_sparql2.toPlainText())
            self.dlg.errorLabel.setText("Valid Query")
            self.errorline=-1
            self.sparqlhighlight.errorhighlightline=self.errorline
            self.sparqlhighlight.currentline=0
        except Exception as e:
            self.dlg.errorLabel.setText(str(e))
            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
                #msgBox=QMessageBox()
                #msgBox.setText(str(self.errorline)+" "+str(self.sparqlhighlight.errorhighlightline)+" "+str(self.sparqlhighlight.errorhighlightcol))
                #msgBox.exec()

    def add_action(
        self,
        icon_path,
        text,
        callback,
        enabled_flag=True,
        add_to_menu=True,
        add_to_toolbar=True,
        status_tip=None,
        whats_this=None,
        parent=None):
        icon = QIcon(icon_path)
        action = QAction(icon, text, parent)
        action.triggered.connect(callback)
        action.setEnabled(enabled_flag)

        if status_tip is not None:
            action.setStatusTip(status_tip)

        if whats_this is not None:
            action.setWhatsThis(whats_this)

        if add_to_toolbar:
            # Adds plugin icon to Plugins toolbar
            self.iface.addToolBarIcon(action)

        if add_to_menu:
            self.iface.addPluginToVectorMenu(
                self.menu,
                action)

        self.actions.append(action)

        return action

    def initGui(self):
        """Create the menu entries and toolbar icons inside the QGIS GUI."""
        #a = str('numpy' in sys.modules)
        #iface.messageBar().pushMessage("load libs", a, level=Qgis.Success)

        icon_path = ':/plugins/sparql_unicorn/icon.png'
        self.add_action(
            icon_path,
            text=self.tr(u'Adds GeoJSON layer from a Wikidata'),
            callback=self.run,
            parent=self.iface.mainWindow())

        # will be set False in run()
        self.first_start = True


    def unload(self):
        """Removes the plugin menu item and icon from QGIS GUI."""
        for action in self.actions:
            self.iface.removePluginVectorMenu(
                self.tr(u'&SPARQL Unicorn Wikidata Plugin'),
                action)
            self.iface.removeToolBarIcon(action)

    def processResults(self,results,reproject,mandatoryvars,geooptional):
        latval=mandatoryvars[0]
        lonval=""
        if len(mandatoryvars)>1:
            lonval=mandatoryvars[1]
        features = []
        first=True
        newobject=True
        item=""
        for result in results["results"]["bindings"]:
            if "item" in result and "rel" in result and "val" in result and (item=="" or result["item"]["value"]!=item) and "geo" in mandatoryvars:
                if item!="":
                    myGeometryInstance=QgsGeometry.fromWkt(result["geo"]["value"])
                    if reproject!="":
                        sourceCrs = QgsCoordinateReferenceSystem(reproject)
                        destCrs = QgsCoordinateReferenceSystem(4326)
                        tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                        myGeometryInstance.transform(tr)
                    #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
                    feature = { 'type': 'Feature', 'properties': properties, 'geometry':  json.loads(myGeometryInstance.asJson()) }
                    features.append(feature)
                properties = {}
                item=result["item"]["value"]
            if "item" in result and "rel" in result and "val" in result and "lat" in result and "lon" in result and (item=="" or result["item"]["value"]!=item) and "lat" in mandatoryvars and "lon" in mandatoryvars:
                if item!="":
                    myGeometryInstance = QgsGeometry.fromWkt("POINT("+str(float(result[lonval]["value"]))+" "+str(float(result[latval]["value"]))+")")
                    if reproject!="":
                        sourceCrs = QgsCoordinateReferenceSystem(reproject)
                        destCrs = QgsCoordinateReferenceSystem(4326)
                        tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                        myGeometryInstance.transform(tr)
                    #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
                    feature = { 'type': 'Feature', 'properties': properties, 'geometry':  json.loads(myGeometryInstance.asJson()) }
                    features.append(feature)
                properties = {}
                item=result["item"]["value"]
            #if not "rel" in result and not "val" in result:
            properties = {}
            for var in results["head"]["vars"]:
                if var in result:
                    if var=="rel" and "val" in result:
                        properties[result[var]["value"]] = result["val"]["value"]
                    elif var!="val":
                        properties[var] = result[var]["value"]
            if not "rel" in result and not "val" in result and "geo" in result:
                myGeometryInstance=QgsGeometry.fromWkt(result["geo"]["value"].replace("<http://www.opengis.net/def/crs/EPSG/0/"+str(reproject)+"> ",""))
                if reproject!="":
                    sourceCrs = QgsCoordinateReferenceSystem(reproject)
                    destCrs = QgsCoordinateReferenceSystem(4326)
                    tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                    myGeometryInstance.transform(tr)
                #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
                feature = { 'type': 'Feature', 'properties': properties, 'geometry':  json.loads(myGeometryInstance.asJson()) }
                features.append(feature)
            if not "rel" in result and not "val" in result and latval in result and lonval in result and reproject==27700:
                myGeometryInstance = QgsGeometry.fromWkt("POINT("+str(float(result[latval]["value"]))+" "+str(float(result[lonval]["value"]))+")")
                if reproject!="":
                    sourceCrs = QgsCoordinateReferenceSystem(reproject)
                    destCrs = QgsCoordinateReferenceSystem(4326)
                    tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                    myGeometryInstance.transform(tr)
                #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
                feature = { 'type': 'Feature', 'properties': properties, 'geometry':  json.loads(myGeometryInstance.asJson()) }
                features.append(feature)
            if not "rel" in result and not "val" in result and latval in result and lonval in result and reproject!=27700:
                myGeometryInstance = QgsGeometry.fromWkt("POINT("+str(float(result[lonval]["value"]))+" "+str(float(result[latval]["value"]))+")")
                if reproject!="":
                    sourceCrs = QgsCoordinateReferenceSystem(reproject)
                    destCrs = QgsCoordinateReferenceSystem(4326)
                    tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                    myGeometryInstance.transform(tr)
                #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
                feature = { 'type': 'Feature', 'properties': properties, 'geometry':  json.loads(myGeometryInstance.asJson()) }
                features.append(feature)
            if not "rel" in result and not "val" in result and not "geo" in result and geooptional:
                #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
                feature = { 'type': 'Feature', 'properties': properties, 'geometry':  {} }
                features.append(feature)
            #print(properties)
        if "rel" in results["results"]["bindings"] and "val" in results["results"]["bindings"]:
            myGeometryInstance = QgsGeometry.fromWkt(result["geo"]["value"])
            if reproject!="":
                sourceCrs = QgsCoordinateReferenceSystem(reproject)
                destCrs = QgsCoordinateReferenceSystem(4326)
                tr = QgsCoordinateTransform(sourceCrs, destCrs, QgsProject.instance())
                myGeometryInstance.transform(tr)
            #feature = { 'type': 'Feature', 'properties': { 'label': result["label"]["value"], 'item': result["item"]["value"] }, 'geometry': wkt.loads(result["geo"]["value"].replace("Point", "POINT")) }
            feature = { 'type': 'Feature', 'properties': properties, 'geometry':  json.loads(myGeometryInstance.asJson()) }
            features.append(feature)		
        if features==[] and len(results["results"]["bindings"])==0:
            return None
        if features==[] and len(results["results"]["bindings"])>0:
            return len(results["results"]["bindings"])
        geojson = {'type': 'FeatureCollection', 'features': features }
        return geojson

    def create_unicorn_layer(self):
        endpointIndex = self.dlg.comboBox.currentIndex()
        # SPARQL query
        #print(self.loadedfromfile)
		# query
        query = self.dlg.inp_sparql2.toPlainText()
        if self.loadedfromfile:
            concept = self.dlg.layerconcepts.currentText()
            geojson=self.getGeoJSONFromGeoConcept(self.currentgraph,concept)
            vlayer = QgsVectorLayer(json.dumps(geojson, sort_keys=True, indent=4),"unicorn_"+self.dlg.inp_label.text(),"ogr")
            print(vlayer.isValid())
            QgsProject.instance().addMapLayer(vlayer)
            canvas = iface.mapCanvas()
            canvas.setExtent(vlayer.extent())
            iface.messageBar().pushMessage("Add layer", "OK", level=Qgis.Success)
            #iface.messageBar().pushMessage("Error", "An error occured", level=Qgis.Critical)
            self.dlg.close()
            return
        else:
            endpoint_url=self.triplestoreconf[endpointIndex]["endpoint"]
        missingmandvars=[]
        for mandvar in self.triplestoreconf[endpointIndex]["mandatoryvariables"]:
            if mandvar not in query:
                  missingmandvars.append("?"+mandvar)
        if missingmandvars!=[] and not self.dlg.allownongeo.isChecked():
            msgBox=QMessageBox()
            msgBox.setText("The SPARQL query is missing the following mandatory variables: "+str(missingmandvars))
            msgBox.exec()
        #msgBox=QMessageBox()
        #msgBox.setText(str(self.dlg.inp_sparql2.columnvars))
        #msgBox.exec()
        #msgBox=QMessageBox()
        #msgBox.setText(query)
        #msgBox.exec()
        if self.dlg.inp_sparql2.columnvars!={}:
            for lay in self.dlg.inp_sparql2.columnvars:
                if lay in query:
                    query=query.replace("WHERE {","WHERE {\n"+self.dlg.inp_sparql2.columnvars[lay]+"\n")
            msgBox=QMessageBox()
            msgBox.setText(query)
            msgBox.exec()
        sparql = SPARQLWrapper(endpoint_url, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
        sparql.setQuery("".join(self.prefixes[endpointIndex]) + query)
        sparql.setMethod(POST)
        sparql.setReturnFormat(JSON)
        try:
            results = sparql.query().convert()
        except Exception as e: 
            try:
                sparql = SPARQLWrapper(endpoint_url, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
                sparql.setQuery("".join(self.prefixes[endpointIndex]) + query)
                sparql.setMethod(GET)
                sparql.setReturnFormat(JSON)
                results = sparql.query().convert()
            except Exception as e:
                msgBox=QMessageBox()
                msgBox.setText("The following exception occurred: "+str(e))
                msgBox.exec()
                return            
        #print(results)
        # geojson stuff
        geojson=self.processResults(results,(self.triplestoreconf[endpointIndex]["crs"] if "crs" in self.triplestoreconf[endpointIndex] else ""),self.triplestoreconf[endpointIndex]["mandatoryvariables"][1:],self.dlg.allownongeo.isChecked())
        if geojson==None:
            msgBox=QMessageBox()
            msgBox.setText("The query yielded no results. Therefore no layer will be created!")
            msgBox.exec()
            return
        if isinstance(geojson, int) and not self.dlg.allownongeo.isChecked():
            msgBox=QMessageBox()
            msgBox.setText("The query did not retrieve a geometry result. However, there were "+str(geojson)+" non-geometry query results. You can retrieve them by allowing non-geometry queries!")
            msgBox.exec()
            return
        # add layer
        vlayer = QgsVectorLayer(json.dumps(geojson, sort_keys=True, indent=4),"unicorn_"+self.dlg.inp_label.text(),"ogr")
        print(vlayer.isValid())
        QgsProject.instance().addMapLayer(vlayer)
        canvas = iface.mapCanvas()
        canvas.setExtent(vlayer.extent())
        iface.messageBar().pushMessage("Add layer", "OK", level=Qgis.Success)
        #iface.messageBar().pushMessage("Error", "An error occured", level=Qgis.Critical)
        self.dlg.close()

    def getGeoConcepts(self,triplestoreurl,query,queryvar,graph,getlabels):
        viewlist=[]
        resultlist=[]
        if graph!=None:
            results = graph.query(query)
            for row in results:
                viewlist.append(str(row[0]))
        else:
            sparql = SPARQLWrapper(triplestoreurl, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
            sparql.setQuery(query)
            print("now sending query")
            sparql.setReturnFormat(JSON)
            results = sparql.query().convert()
            for result in results["results"]["bindings"]:
                viewlist.append(str(result[queryvar]["value"]))
        print(viewlist)
        self.dlg.layercount.setText("["+str(len(viewlist))+"]")
        if getlabels and "classlabelquery" in self.triplestoreconf[self.dlg.comboBox.currentIndex()] and self.triplestoreconf[self.dlg.comboBox.currentIndex()]["classlabelquery"]!="":
            labels=self.getLabelsForClasses(viewlist,self.triplestoreconf[self.dlg.comboBox.currentIndex()]["classlabelquery"],self.dlg.comboBox.currentIndex())
            print(labels)
            self.dlg.layercount.setText("["+str(len(labels))+"]")
            i=0
            sorted_labels=sorted(labels.items(),key=lambda x:x[1])
            for lab in sorted_labels:
                resultlist.append(labels[lab[0]]+"("+lab[0]+")")
                i=i+1	
            return resultlist
        return viewlist

    def getLabelsForClasses(self,classes,query,endpointIndex):
        result={}
        query=self.triplestoreconf[endpointIndex]["classlabelquery"]
        #url="https://www.wikidata.org/w/api.php?action=wbgetentities&props=labels&ids="
        if "SELECT" in query:
            vals="VALUES ?class { "
            for qid in classes:
                vals+=qid+" "
            vals+="}\n"
            query=query.replace("%%concepts%%",vals)
            sparql = SPARQLWrapper(triplestoreurl, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
            sparql.setQuery(query)
            sparql.setReturnFormat(JSON)
            results = sparql.query().convert()
            for res in results["results"]["bindings"]:
                result[res["class"]["value"]]=res["label"]["value"]
        else:
            url=self.triplestoreconf[self.dlg.comboBox.currentIndex()]["classlabelquery"]
            i=0
            qidquery=""
            for qid in classes:
                if "Q" in qid:
                    qidquery+="Q"+qid.split("Q")[1]
                if (i%50)==0:
                    print(url.replace("%%concepts%%",qidquery))
                    myResponse = json.loads(requests.get(url.replace("%%concepts%%",qidquery)).text)
                    print(myResponse)
                    for ent in myResponse["entities"]:
                        print(ent)
                        if "en" in myResponse["entities"][ent]["labels"]:
                            result[ent]=myResponse["entities"][ent]["labels"]["en"]["value"]                
                    qidquery=""
                else:
                    qidquery+="|"
                i=i+1
        return result

    def getGeoJSONFromGeoConcept(self,graph,concept):
        print(concept)
        qres = graph.query(
        """SELECT DISTINCT ?a ?rel ?val ?wkt
        WHERE {
          ?a rdf:type <"""+concept+"""> .
          ?a ?rel ?val .
          OPTIONAL { ?val <http://www.opengis.net/ont/geosparql#asWKT> ?wkt}
        }""")
        geos=[]
        geometries = {
            'type': 'FeatureCollection',
            'features': geos,
            }
        newfeature=False
        lastfeature=""
        currentgeo={}
        for row in qres:
            print(lastfeature+" - "+row[0]+" - "+str(len(row)))
            print(row)
            if(lastfeature=="" or lastfeature!=row[0]):
                if(lastfeature!=""):
                    geos.append(currentgeo)
                lastfeature=row[0]
                currentgeo={'id':row[0],'geometry':{},'properties':{}}
            if(row[3]!=None):
                print(row[3])
                if("<" in row[3]):
                    currentgeo['geometry']=json.loads(QgsGeometry.fromWkt(row[3].split(">")[1].strip()).asJson())
                else:
                    currentgeo['geometry']=json.loads(QgsGeometry.fromWkt(row[3]).asJson())
            else:
                currentgeo['properties'][str(row[1])]=str(row[2])
        return geometries

    def createEnrichSearchDialog(self,row=-1,column=-1):
        if column==1:
            self.buildSearchDialog(row,column,False,self.dlg.enrichTable,False,False,None,self.addVocabConf)
        if column==6:
            self.buildSearchDialog(row,column,False,self.dlg.enrichTable,False,False,None,self.addVocabConf)

    def createEnrichSearchDialogProp(self,row=-1,column=-1):
        self.buildSearchDialog(row,column,False,self.dlg.findIDPropertyEdit,True,False,None,self.addVocabConf)

    def createInterlinkSearchDialog(self, row=-1, column=-1):
        if column>3 and column<7:
            self.buildSearchDialog(row,column,True,self.dlg.interlinkTable,True,False,None,self.addVocabConf)
        elif column>=7:
            layers = QgsProject.instance().layerTreeRoot().children()
            selectedLayerIndex = self.dlg.chooseLayerInterlink.currentIndex()
            layer = layers[selectedLayerIndex].layer()
            self.buildValueMappingDialog(row,column,True,self.dlg.interlinkTable,layer)
        elif column==-1:
            self.buildSearchDialog(row,column,-1,self.dlg.interlinkOwlClassInput,False,False,None,self.addVocabConf)

    def buildSearchDialog(self,row,column,interlinkOrEnrich,table,propOrClass,bothOptions=False,currentprefixes=None,addVocabConf=None):
        self.dlg.currentcol=column
        self.dlg.currentrow=row
        self.dlg.interlinkdialog = SearchDialog(column,row,self.triplestoreconf,self.prefixes,interlinkOrEnrich,table,propOrClass,bothOptions,currentprefixes,addVocabConf)
        self.dlg.interlinkdialog.setMinimumSize(650, 400)
        self.dlg.interlinkdialog.setWindowTitle("Search Interlink Concept")
        self.dlg.interlinkdialog.exec_()
        
    def buildValueMappingDialog(self,row,column,interlinkOrEnrich,table,layer):
        self.dlg.currentcol=column
        self.dlg.currentrow=row
        valuemap=None
        if table.item(row, column)!=None and table.item(row, column).text()!="":
           valuemap=table.item(row, column).data(1)
        self.dlg.interlinkdialog =ValueMappingDialog(column,row,self.triplestoreconf,interlinkOrEnrich,table,table.item(row, 3).text(),layer,valuemap)
        self.dlg.interlinkdialog.setMinimumSize(650, 400)
        self.dlg.interlinkdialog.setWindowTitle("Get Value Mappings for column "+table.item(row, 3).text())
        self.dlg.interlinkdialog.exec_()

    def addnewEnrichRow(self):
        currentRowCount = self.dlg.enrichTable.rowCount() 
        self.dlg.enrichTable.insertRow(currentRowCount)
        
    def moveRow(self,upOrDown):
        if self.dlg.enrichTable.selectionModel().hasSelected():
            currentRowCount = self.dlg.enrichTable.selectedRows() 

    def loadLayerForEnrichment(self):
        layers = QgsProject.instance().layerTreeRoot().children()
        selectedLayerIndex = self.dlg.chooseLayerEnrich.currentIndex()
        #if len(layers)>0:
        #   return
        layer = layers[selectedLayerIndex].layer()
        self.dlg.enrichTableResult.hide()
        while self.dlg.enrichTableResult.rowCount() > 0:
            self.dlg.enrichTableResult.removeRow(0);
        self.dlg.enrichTable.show()
        self.dlg.addEnrichedLayerRowButton.setEnabled(True)
        fieldnames = [field.name() for field in layer.fields()]
        while self.dlg.enrichTable.rowCount() > 0:
            self.dlg.enrichTable.removeRow(0);
        row=0
        self.dlg.enrichTable.setColumnCount(9)
        self.dlg.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.dlg.enrichTable.rowCount() 
            self.dlg.enrichTable.insertRow(row)
            self.dlg.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.dlg.enrichTable.setCellWidget(row,3,cbox)
            cbox=QComboBox()	
            cbox.addItem("Enrich Value")	
            cbox.addItem("Enrich URI")	
            cbox.addItem("Enrich Both")	
            self.dlg.enrichTable.setCellWidget(row,4,cbox)
            cbox=QComboBox()
            for fieldd in fieldnames:
                cbox.addItem(fieldd)	
            self.dlg.enrichTable.setCellWidget(row,5,cbox)
            itemm=QTableWidgetItem("http://www.w3.org/2000/01/rdf-schema#label")
            self.dlg.enrichTable.setItem(row,6,itemm)
            itemm=QTableWidgetItem("")
            self.dlg.enrichTable.setItem(row,7,itemm)
            itemm=QTableWidgetItem("")
            self.dlg.enrichTable.setItem(row,8,itemm)
            celllayout= QHBoxLayout()
            upbutton=QPushButton("Up")
            removebutton=QPushButton("Remove",self.dlg)
            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.dlg.enrichTable.setCellWidget(row,4,w)
            #self.dlg.enrichTable.setItem(row,3,cbox)
            row+=1
        self.originalRowCount=row

    def deleteEnrichRow(send):
        w = send.sender().parent()
        row = self.dlg.enrichTable.indexAt(w.pos()).row()
        self.dlg.enrichTable.removeRow(row);
        self.dlg.enrichTable.setCurrentCell(0, 0)
		
    def useDefaultIDPropProcess(self):
        self.dlg.findIDPropertyEdit.setText("http://www.w3.org/2000/01/rdf-schema#label")
        
    def addEnrichRow(self):
        layers = QgsProject.instance().layerTreeRoot().children()
        selectedLayerIndex = self.dlg.chooseLayerEnrich.currentIndex()
        layer = layers[selectedLayerIndex].layer()
        self.dlg.enrichTableResult.hide()
        fieldnames = [field.name() for field in layer.fields()]
        item=QTableWidgetItem("new_column")
        #item.setFlags(QtCore.Qt.ItemIsEnabled)
        row = self.dlg.enrichTable.rowCount() 
        self.dlg.enrichTable.insertRow(row)
        self.dlg.enrichTable.setItem(row,0,item)
        cbox=QComboBox()
        cbox.addItem("Get Remote")
        cbox.addItem("No Enrichment")
        cbox.addItem("Exclude")
        self.dlg.enrichTable.setCellWidget(row,3,cbox)
        cbox=QComboBox()	
        cbox.addItem("Enrich Value")	
        cbox.addItem("Enrich URI")	
        cbox.addItem("Enrich Both")	
        self.dlg.enrichTable.setCellWidget(row,4,cbox)
        cbox=QComboBox()
        for fieldd in fieldnames:
            cbox.addItem(fieldd)	
        self.dlg.enrichTable.setCellWidget(row,5,cbox)
        itemm=QTableWidgetItem("http://www.w3.org/2000/01/rdf-schema#label")
        self.dlg.enrichTable.setItem(row,6,itemm) 
        itemm=QTableWidgetItem("")
        self.dlg.enrichTable.setItem(row,7,itemm)
        itemm=QTableWidgetItem("")
        self.dlg.enrichTable.setItem(row,8,itemm)
        

    def enrichLayerProcess(self):
        layers = QgsProject.instance().layerTreeRoot().children()
        selectedLayerIndex = self.dlg.chooseLayerEnrich.currentIndex()
        self.enrichLayer = layers[selectedLayerIndex].layer().clone()
        attlist={}
        itemlist=[]
        propertylist=[]
        excludelist=[]
        resultmap={}
        self.dlg.enrichTableResult.clear()
        self.dlg.enrichTableResult.setRowCount(0)		
        self.dlg.enrichTableResult.setColumnCount(self.dlg.enrichTable.rowCount())
        fieldnames=[]
        for row in range(self.dlg.enrichTable.rowCount()):
            fieldnames.append(self.dlg.enrichTable.item(row, 0).text())
        self.dlg.enrichTableResult.setHorizontalHeaderLabels(fieldnames)
        for row in range(self.dlg.enrichTable.rowCount()):
            idfield=self.dlg.enrichTable.cellWidget(row, 5).currentText()
            idprop=self.dlg.enrichTable.item(row, 6).text()
            if idprop==None or idprop=="":
                msgBox=QMessageBox()
                msgBox.setText("ID Property has not been specified for column "+str(self.dlg.enrichTable.item(row, 0).text()))
                msgBox.exec()
                return
            item = self.dlg.enrichTable.item(row, 0).text()
            propertyy=self.dlg.enrichTable.item(row, 1)
            triplestoreurl=""
            if self.dlg.enrichTable.item(row, 2)!=None:
                triplestoreurl=self.dlg.enrichTable.item(row, 2).text()
                print(self.dlg.enrichTable.item(row, 2).text())
            strategy = self.dlg.enrichTable.cellWidget(row, 3).currentText()
            content=""
            if self.dlg.enrichTable.cellWidget(row, 4)!=None:
                content = self.dlg.enrichTable.cellWidget(row, 4).currentText()
            if item!=idfield:
                propertylist.append(self.dlg.enrichTable.item(row, 1)) 
            if strategy=="Exclude":
                excludelist.append(row)
            if strategy!="No Enrichment" and propertyy!=None:
                if row>=self.originalRowCount:
                    self.enrichLayer.dataProvider().addAttributes([QgsField(item,QVariant.String)])
                    self.enrichLayer.updateFields()
                fieldnames = [field.name() for field in self.enrichLayer.fields()]
                self.enrichLayer.startEditing()
                print(str(self.enrichLayer.dataProvider().capabilitiesString()))
                print(str(fieldnames))
                print("Enrichment for "+propertyy.text())
                print("Item: "+idfield)
                itemlist.append(item)
                attlist[item]=[]
                attlist[idfield]=[]
                for f in self.enrichLayer.getFeatures():
                    if item in f:
                        attlist[item].append(f[item])
                    attlist[idfield].append(f[idfield])
                query=""
                if content=="Enrich URI": 
                    query+="SELECT ?item WHERE {\n"
                elif content=="Enrich Value" or content=="Enrich Both":
                    query+="SELECT ?item ?val ?valLabel ?vals WHERE {\n"
                query+="VALUES ?vals { "
                print(attlist)
                for it in attlist[idfield]:
                    if str(it).startswith("http"):
                        query+="<"+str(it)+"> "
                    elif idprop=="http://www.w3.org/2000/01/rdf-schema#label" and self.dlg.enrichTable.item(row, 8).text()!="":
                        query+="\""+str(it)+"\"@"+self.dlg.enrichTable.item(row, 8).text()+" "
                    else:
                        query+="\""+str(it)+"\" "
                query+=" } . \n"
                proppp=propertyy.data(1)
                if propertyy.data(1).startswith("//"):
                    proppp="http:"+proppp
                if self.dlg.enrichTable.item(row, 7).text()!="" and "wikidata" in triplestoreurl:
                    query+="?item wdt:P31 <"+self.dlg.enrichTable.item(row, 7).text()+"> .\n"
                else:
                    query+="?item rdf:type <"+self.dlg.enrichTable.item(row, 7).text()+"> .\n"
                query+="?item <"+idprop+"> ?vals .\n"
                query+="?item <"+proppp+"> ?val . \n"
                if (content=="Enrich Value" or content=="Enrich Both") and not "wikidata" in triplestoreurl:
                    query+="OPTIONAL{ ?val rdfs:label ?valLabel }"
                elif (content=="Enrich Value" or content=="Enrich Both") and "wikidata" in triplestoreurl:
                    query+="SERVICE wikibase:label { bd:serviceParam wikibase:language \"[AUTO_LANGUAGE],en\". }\n"
                query+="} ORDER BY ?item "
                print(query)
                print(triplestoreurl)
                try:
                    sparql = SPARQLWrapper(triplestoreurl, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
                    sparql.setQuery(query)
                    sparql.setMethod(POST)
                    print("now sending query")
                    sparql.setReturnFormat(JSON)
                    results = sparql.query().convert()
                except Exception as e: 
                    try:
                        sparql = SPARQLWrapper(triplestoreurl, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
                        sparql.setQuery(query)
                        sparql.setMethod(GET)
                        sparql.setReturnFormat(JSON)
                        results = sparql.query().convert()
                    except Exception as e:
                        msgBox=QMessageBox()
                        msgBox.setText("The following exception occurred: "+str(e))
                        msgBox.exec()
                        return    
                print(str(results))
                #resultcounter=0
                for resultcounter in results["results"]["bindings"]:
                    if content=="Enrich Value":
                        resultmap[resultcounter["vals"]["value"]]=resultcounter["valLabel"]["value"]
                    elif content=="Enrich URI":
                        resultmap[resultcounter["vals"]["value"]]=resultcounter["val"]["value"]
                    else:
                        resultmap[resultcounter["vals"]["value"]]=resultcounter["valLabel"]["value"]+";"+resultcounter["val"]["value"]
                print(str(resultmap))
                rowww=0            
                for f in self.enrichLayer.getFeatures():
                    if rowww>=self.dlg.enrichTableResult.rowCount():
                        self.dlg.enrichTableResult.insertRow(rowww)
                    if f[idfield] in resultmap:
                        if strategy=="Merge":
                            newitem=QTableWidgetItem(str(f[item])+str(resultmap[f[idfield]]))
                        elif strategy=="Keep Local":
                            if f[item]==None:
                                newitem=QTableWidgetItem(str(resultmap[f[idfield]]))
                            else:
                                newitem=QTableWidgetItem(str(f[item]))
                        elif strategy=="Ask User":
                            newitem=QTableWidgetItem(str(f[item])+";"+str(resultmap[f[idfield]]))
                        elif strategy=="Keep Remote":
                            if not f[idfield] in resultmap or resultmap[f[idfield]]==None:
                                newitem=QTableWidgetItem(str(f[item]))
                            else:
                                newitem=QTableWidgetItem(str(resultmap[f[idfield]]))
                        else:
                            newitem=QTableWidgetItem(str(resultmap[f[idfield]]))
                        self.dlg.enrichTableResult.setItem(rowww,row,newitem)
                        #if ";" in str(newitem):
                        #    newitem.setBackground(QColor.red)
                        print(str(newitem))
                    rowww+=1  
            else:
                rowww=0            
                for f in self.enrichLayer.getFeatures():
                    if rowww>=self.dlg.enrichTableResult.rowCount():
                        self.dlg.enrichTableResult.insertRow(rowww)
                    #if item in f:
                    newitem=QTableWidgetItem(str(f[item]))
                    self.dlg.enrichTableResult.setItem(rowww,row,newitem)
                    #if ";" in str(newitem):
                    #    newitem.setBackground(QColor.red)
                    print(str(newitem))
                    rowww+=1
            self.enrichLayer.commitChanges()
            row+=1
        iface.vectorLayerTools().stopEditing(self.enrichLayer)
        self.enrichLayer.dataProvider().deleteAttributes(excludelist)
        self.enrichLayer.updateFields()
        self.dlg.enrichTable.hide()
        self.dlg.enrichTableResult.show()
        self.dlg.startEnrichment.setText("Enrichment Configuration")
        self.dlg.startEnrichment.clicked.disconnect()
        self.dlg.startEnrichment.clicked.connect(self.showConfigTable)
        self.dlg.addEnrichedLayerRowButton.setEnabled(False)
        return self.enrichLayer
    
    def showConfigTable(self):
        self.dlg.enrichTableResult.hide()
        self.dlg.enrichTable.show()
        self.dlg.startEnrichment.setText("Start Enrichment")
        self.dlg.startEnrichment.clicked.disconnect()
        self.dlg.startEnrichment.clicked.connect(self.enrichLayerProcess)

    def addEnrichedLayer(self):
        self.enrichLayerCounter+=1
        self.enrichLayer.setName(self.enrichLayer.name()+"_enrich"+str(self.enrichLayerCounter))
        self.enrichLayer.startEditing()
        row=0
        fieldnames = [field.name() for field in self.enrichLayer.fields()]
        for f in self.enrichLayer.getFeatures():
            fieldcounter=0
            for field in fieldnames:
                if self.dlg.enrichTableResult.item(row,fieldcounter)!=None:
                    f[field]=self.dlg.enrichTableResult.item(row,fieldcounter).text()
                else:
                    f[field]=""
                fieldcounter+=1
            self.enrichLayer.updateFeature(f)
            row+=1
        self.enrichLayer.commitChanges()
        iface.vectorLayerTools().stopEditing(self.enrichLayer)
        QgsProject.instance().addMapLayer(self.enrichLayer,True)
        canvas = iface.mapCanvas()
        canvas.setExtent(self.enrichLayer.extent())
        iface.messageBar().pushMessage("Add layer", "OK", level=Qgis.Success)
        self.dlg.close()

    def loadMapping(self):
        dialog = QFileDialog(self.dlg)
        dialog.setFileMode(QFileDialog.AnyFile)
        if dialog.exec_():
            fileNames = dialog.selectedFiles()
            filepath=fileNames[0].split(".")
            self.readMapping(fileNames[0])

    def readMapping(self,filename):
        if self.dlg.interlinkTable.rowCount()!=0:
            tree = ET.parse(filename)
            root = tree.getroot()
            filedata=root.find('file')[0]
            self.dlg.interlinkNameSpace.setText(filedata.get("namespace"))
            self.dlg.interlinkOwlClassInput.setText(filedata.get("class"))  
            for neighbor in root.iter('column'):
                name=neighbor.get("name")
                proptype=neighbor.get("prop")
                propiri=neighbor.get("propiri")
                concept=neighbor.get("concept")
                query=neighbor.get("query")
                triplestoreurl=neighbor.get("triplestoreurl")
                valuemappings={}
                for vmap in neighbor.findall("valuemapping"):
                    valuemappings[vmap.get("from")]=vmap.get("to")
                for row in range(self.dlg.interlinkTable.rowCount()):
                    columnname=self.dlg.interlinkTable.item(row,3).text()
                    if columnname==name:
                        if propiri!=None:
                            item=QTableWidgetItem(propiri)
                            item.setText(propiri)
                            item.setData(1,propiri)
                            self.dlg.interlinkTable.setItem(row,4,item)
                        if proptype!=None:
                            comboboxx=self.dlg.interlinkTable.cellWidget(row,5)
                            if proptype=="annotation":
                                comboboxx.setCurrentIndex(comboboxx.findText("AnnotationProperty", QtCore.Qt.MatchFixedString))
                            elif proptype=="obj":
                                comboboxx.setCurrentIndex(comboboxx.findText("ObjectProperty", QtCore.Qt.MatchFixedString))
                            elif proptype=="data":
                                comboboxx.setCurrentIndex(comboboxx.findText("DataProperty", QtCore.Qt.MatchFixedString))
                            elif proptype=="subclass":
                                comboboxx.setCurrentIndex(comboboxx.findText("SubClass", QtCore.Qt.MatchFixedString))
                            else:
                                comboboxx.setCurrentIndex(comboboxx.findText("Automatic", QtCore.Qt.MatchFixedString))
                        if concept!=None:
                            item=QTableWidgetItem(concept)
                            item.setText(concept)
                            item.setData(1,concept)
                            self.dlg.interlinkTable.setItem(row,6,item)
                        if valuemappings!={} and valuemappings!=None:
                            item=QTableWidgetItem("ValueMap{}")
                            item.setText("ValueMap{}")
                            item.setData(1,valuemappings)
                            if query!=None:
                                item.setData(2,query)
                                item.setData(3,triplestoreurl)                                
                            self.dlg.interlinkTable.setItem(row,7,item)
                        elif query!=None:
                            item=QTableWidgetItem("ValueMap{}")
                            item.setText("ValueMap{}")
                            item.setData(2,query)
                            item.setData(3,triplestoreurl)
                            if valuemappings!={} and valuemappings!=None:
                                item.setData(1,valuemappings)                                
                            self.dlg.interlinkTable.setItem(row,7,item)                            
        else:
            msgBox=QMessageBox()
            msgBox.setText("Please first load a dataset to enrich before loading a mapping file")
            msgBox.exec()

    def exportMapping(self):
        filename, _filter = QFileDialog.getSaveFileName(
            self.dlg, "Select   output file ","", "XML (.xml)",)
        if filename=="":
             return
        layers = QgsProject.instance().layerTreeRoot().children()
        ttlstring=self.exportMappingProcess()
        splitted=filename.split(".")
        exportNameSpace=""
        exportSetClass=""
        with open(filename, 'w') as output_file:
            output_file.write(ttlstring)
            iface.messageBar().pushMessage("export mapping successfully!", "OK", level=Qgis.Success)

    def exportMappingProcess(self):
        xmlmappingheader="<?xml version=\"1.0\" ?>\n<data>\n<file "
        xmlmapping=""
        self.exportIdCol=""
        self.exportNameSpace=self.dlg.interlinkNameSpace.text()
        self.exportSetClass=self.dlg.interlinkOwlClassInput.text()
        xmlmappingheader+="class=\""+self.dlg.interlinkOwlClassInput.text()+"\" "
        xmlmappingheader+="namespace=\""+self.dlg.interlinkNameSpace.text()+"\" "
        propurilist=[]
        classurilist=[]
        includelist=[]
        for row in range(self.dlg.interlinkTable.rowCount()):
            item = self.dlg.interlinkTable.item(row, 0)
            if item.checkState():
                includelist.append(True)
                if self.dlg.interlinkTable.item(row, 1).checkState():
                    self.exportIdCol=self.dlg.interlinkTable.item(row, 3).text()
                    xmlmappingheader+=" indid=\""+self.exportIdCol+"\" "
                    propurilist.append("")
                    classurilist.append("")
                else:
                    xmlmapping+="<column name=\""+self.dlg.interlinkTable.item(row, 3).text()+"\" "
                    column = self.dlg.interlinkTable.item(row, 3).text()
                    if self.dlg.interlinkTable.item(row,4)!=None:
                        column=self.dlg.interlinkTable.item(row,4).data(0)
                        propurilist.append(self.dlg.interlinkTable.item(row,4).data(1))
                        xmlmapping+="propiri=\""+self.dlg.interlinkTable.item(row,4).data(1)+"\" "
                    else:
                         propurilist.append("")
                    if self.dlg.interlinkTable.cellWidget(row, 5)!=None and self.dlg.interlinkTable.cellWidget(row, 5).currentText()!="Automatic":
                        if self.dlg.interlinkTable.cellWidget(row, 5).currentText()=="AnnotationProperty":
                            xmlmapping+="prop=\"annotation\" "
                        elif self.dlg.interlinkTable.cellWidget(row, 5).currentText()=="DataProperty":
                            xmlmapping+="prop=\"data\" "
                        elif self.dlg.interlinkTable.cellWidget(row, 5).currentText()=="ObjectProperty":
                            xmlmapping+="prop=\"obj\" "
                        elif self.dlg.interlinkTable.cellWidget(row, 5).currentText()=="SubClass":
                            xmlmapping+="prop=\"subclass\" "
                    if self.dlg.interlinkTable.item(row, 6)!=None:
                        concept = self.dlg.interlinkTable.item(row, 6).data(0)
                        self.exportColConfig[column]=concept
                        classurilist.append(concept)
                        xmlmapping+="concept=\""+self.dlg.interlinkTable.item(row,6).data(1)+"\" "
                    else:
                        classurilist.append("")
                    if self.dlg.interlinkTable.item(row, 7)!=None:
                        self.valueconcept = self.dlg.interlinkTable.item(row, 7).data(1)
                        if self.dlg.interlinkTable.item(row, 7).data(2)!=None and self.dlg.interlinkTable.item(row, 7).data(3)!=None:
                            xmlmapping+="query=\""+self.dlg.interlinkTable.item(row, 7).data(2).replace("\n"," ")+"\" triplestoreurl=\""+self.dlg.interlinkTable.item(row, 7).data(3)+"\" "
                        xmlmapping+=">\n"
                        if self.valueconcept!=None:
                            for key in self.valueconcept:
                                xmlmapping+="<valuemapping from=\""+key+"\" to=\""+self.valueconcept[key]+"\"/>\n"
                    else:
                        xmlmapping+=">\n"
                    xmlmapping+="</column>\n"
            else:
                includelist.append(False)
                propurilist.append("")
                classurilist.append("")
        xmlmapping+="</file>\n</data>"
        return xmlmappingheader+">\n"+xmlmapping

    def loadLayerForInterlink(self):
        layers = QgsProject.instance().layerTreeRoot().children()
        selectedLayerIndex = self.dlg.chooseLayerInterlink.currentIndex()
        #if len(layers)>0:
        #   return
        layer = layers[selectedLayerIndex].layer()
        fieldnames = [field.name() for field in layer.fields()]
        while self.dlg.interlinkTable.rowCount() > 0:
            self.dlg.interlinkTable.removeRow(0);
        row=0
        self.dlg.interlinkTable.setHorizontalHeaderLabels(["Export?","IDColumn?","GeoColumn?","Column","ColumnProperty","PropertyType","ColumnConcept","ValueConcepts"])
        self.dlg.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.dlg.interlinkTable.insertRow(row)
            self.dlg.interlinkTable.setItem(row,3,item)
            self.dlg.interlinkTable.setItem(row,0,item2)
            self.dlg.interlinkTable.setItem(row,1,item3)
            self.dlg.interlinkTable.setItem(row,2,item4)
            cbox=QComboBox()
            cbox.addItem("Automatic")
            cbox.addItem("AnnotationProperty")
            cbox.addItem("DataProperty")
            cbox.addItem("ObjectProperty")
            cbox.addItem("SubClass")
            self.dlg.interlinkTable.setCellWidget(row,5,cbox)
            currentRowCount = self.dlg.interlinkTable.rowCount() 
            row+=1

    def exportEnrichedLayer(self):
        self.exportIdCol=""
        self.exportNameSpace=self.dlg.interlinkNameSpace.text()
        self.exportSetClass=self.dlg.interlinkOwlClassInput.text()
        propurilist=[]
        classurilist=[]
        includelist=[]
        proptypelist=[]
        valuemappings={}
        valuequeries=[]
        for row in range(self.dlg.interlinkTable.rowCount()):
            item = self.dlg.interlinkTable.item(row, 0)
            if item.checkState():
                includelist.append(True)
                if self.dlg.interlinkTable.item(row, 1).checkState():
                    self.exportIdCol=self.dlg.interlinkTable.item(row, 3).text()
                    propurilist.append("")
                    classurilist.append("")
                    proptypelist.append("")
                else:
                    column = self.dlg.interlinkTable.item(row, 3).text()
                    if self.dlg.interlinkTable.item(row,4)!=None:
                        column=self.dlg.interlinkTable.item(row,3).data(0)
                        propurilist.append(self.dlg.interlinkTable.item(row,4).data(1))
                    else:
                        propurilist.append("")
                    if self.dlg.interlinkTable.item(row,5)!=None:
                        proptypelist.append(self.dlg.interlinkTable.item(row,5).text())
                    else:
                        proptypelist.append("")
                    if self.dlg.interlinkTable.item(row, 6)!=None:
                        concept = self.dlg.interlinkTable.item(row, 6).data(0)
                        self.exportColConfig[column]=concept
                        classurilist.append(concept)
                    else:
                        classurilist.append("")
                    if self.dlg.interlinkTable.item(row, 7)!=None:
                        self.valueconcept = self.dlg.interlinkTable.item(row, 7).data(0)
                        valuemappings[item.text()]=self.dlg.interlinkTable.item(row,7).data(1)
                        valuequeries.append({self.dlg.interlinkTable.item(row,7).data(2),self.dlg.interlinkTable.item(row,7).data(3)})
            else:
                includelist.append(False)
                propurilist.append("")
                classurilist.append("")
                proptypelist.append("")
        self.enrichedExport=True
        self.exportLayer(propurilist,classurilist,includelist,proptypelist,valuemappings,valuequeries,self.dlg.exportTripleStore.isChecked())
        
    def addNewLayerToTripleStore(self,triplestoreaddress,layer):
        ttlstring=self.layerToTTLString(layer)
        queryString = "INSERT DATA { GRAPH <http://example.com/> { "+ttlstring+" } }" 
        sparql = SPARQLWrapper(triplestoreaddress)
        sparql.setQuery(queryString) 
        sparql.method = 'POST'
        sparql.query()
		
    def compareLayers(layer1,layer2,idcolumn):
        changedTriples=""
        fieldnames = [field.name() for field in layer.fields()]
        for f in layer1.getFeatures():
            geom = f.geometry()
            id=f[idcolumn]
            expr = QgsExpression( "\""+idcolumn+"\"="+id )
            it = cLayer.getFeatures( QgsFeatureRequest( expr ) )
            #if len(it)==0:
                #Add new line
            #elif len(it)>0:
                #Compare
		
    def matchColumnValueFromTripleStore(self,toquery):
        values="VALUES ?vals { "
        for queryval in toquery:
            values+="\""+queryval+"\""
        values+="}"
        sparql = SPARQLWrapper("https://query.wikidata.org/sparql", agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
        sparql.setQuery(
        """SELECT DISTINCT ?a
        WHERE {
          ?a wdt:P31 ?class .
          ?a ?label ?vals .
        } """)
        sparql.setReturnFormat(JSON)
        results = sparql.query().convert()
        for result in results["results"]["bindings"]:
            viewlist.append(str(result["a"]["value"]))
        return viewlist

    def layerToTTLString(self,layer,urilist=None,classurilist=None,includelist=None,proptypelist=None,valuemappings=None,valuequeries=None):
        fieldnames = [field.name() for field in layer.fields()]
        ttlstring="<http://www.opengis.net/ont/geosparql#Feature> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n"
        ttlstring+="<http://www.opengis.net/ont/geosparql#SpatialObject> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n"
        ttlstring+="<http://www.opengis.net/ont/geosparql#Geometry> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n"
        ttlstring+="<http://www.opengis.net/ont/geosparql#hasGeometry> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .\n"
        ttlstring+="<http://www.opengis.net/ont/geosparql#asWKT> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .\n"
        ttlstring+="<http://www.opengis.net/ont/geosparql#Feature> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.opengis.net/ont/geosparql#SpatialObject> .\n"
        ttlstring+="<http://www.opengis.net/ont/geosparql#Geometry> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.opengis.net/ont/geosparql#SpatialObject> .\n"
        first=0
        if self.exportNameSpace==None or self.exportNameSpace=="":
            namespace="http://www.github.com/sparqlunicorn#"
        else:
            namespace=self.exportNameSpace
        if self.exportIdCol=="":
            idcol="id"
        else:
            idcol=self.exportIdCol
        classcol="http://www.w3.org/1999/02/22-rdf-syntax-ns#type"
        curid=""
        if self.exportSetClass==None or self.exportSetClass=="":
            curclassid=namespace+str(uuid.uuid4())
        elif self.exportSetClass.startswith("http"):
            curclassid=self.exportSetClass
        else:
            curclassid=urllib.parse.quote(self.exportSetClass)
        for f in layer.getFeatures():
            geom = f.geometry()
            if not idcol in fieldnames:
                curid=namespace+str(uuid.uuid4())
            elif not str(f[idcol]).startswith("http"):
                curid=namespace+str(f[idcol])
            else:
                curid=f[idcol]
            if not classcol in fieldnames:
                ttlstring+="<"+str(curid)+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <"+curclassid+"> .\n"
                if first==0:
                    ttlstring+="<"+str(curclassid)+"> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.opengis.net/ont/geosparql#Feature> .\n"
                    ttlstring+="<"+str(curclassid)+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n"
            ttlstring+="<"+str(curid)+"> <http://www.opengis.net/ont/geosparql#hasGeometry> <"+curid+"_geom> .\n"
            ttlstring+="<"+str(curid)+"_geom> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.opengis.net/ont/geosparql#"+QgsWkbTypes.displayString(geom.wkbType())+"> .\n"
            ttlstring+="<http://www.opengis.net/ont/geosparql#"+QgsWkbTypes.displayString(geom.wkbType())+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n"
            ttlstring+="<http://www.opengis.net/ont/geosparql#"+QgsWkbTypes.displayString(geom.wkbType())+"> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.opengis.net/ont/geosparql#Geometry> .\n"
            ttlstring+="<"+str(curid)+"_geom> <http://www.opengis.net/ont/geosparql#asWKT> \""+geom.asWkt()+"\"^^<http://www.opengis.net/ont/geosparql#wktLiteral> .\n"
            fieldcounter=-1
            for propp in fieldnames:
                fieldcounter+=1
                #if fieldcounter>=len(fieldnames):
                #    fieldcounter=0
                if includelist!=None and fieldcounter<len(includelist) and includelist[fieldcounter]==False:
                    continue
                prop=propp    
                print(str(fieldcounter))
                print(str(urilist)+"\n")
                print(str(classurilist)+"\n")
                print(str(includelist)+"\n")
                if urilist!=None and urilist[fieldcounter]!="":
                    print(urilist)
                    if not urilist[fieldcounter].startswith("http"):
                        print("Does not start with http")
                        prop=urllib.parse.quote(urilist[fieldcounter])
                    else:
                        prop=urilist[fieldcounter]
                    print("New Prop from list: "+str(prop))
                if prop=="http://www.w3.org/1999/02/22-rdf-syntax-ns#type" and "http" in str(f[propp]):
                    ttlstring+="<"+str(f[propp])+"> <"+str(prop)+"> <http://www.w3.org/2002/07/owl#Class> .\n"
                    ttlstring+="<"+str(f[propp])+"> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <http://www.opengis.net/ont/geosparql#Feature> .\n"
                if prop=="id":
                    continue
                #elif urilist!=None and fieldcounter<len(urilist) and urilist[fieldcounter]!="":
                 #   ttlstring+="<"+curid+"> <"+prop+"> <"+str(f[propp])+"> .\n"
                #    if first<10:
                 #       ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .\n"
                 #       ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n"  
                  #      if classurilist[fieldcounter]!="":
                  #           ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <"+classurilist[fieldcounter]+"> .\n"
                elif prop=="http://www.w3.org/2000/01/rdf-schema#label" or prop=="http://www.w3.org/2000/01/rdf-schema#comment" or (proptypelist!=None and proptypelist[fieldcounter]=="AnnotationProperty"):
                    ttlstring+="<"+curid+"> <"+prop+"> \""+str(f[propp]).replace('"','\\"')+"\"^^<http://www.w3.org/2001/XMLSchema#string> .\n"
                    if first<10:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#AnnotationProperty> .\n" 
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n"  						
                elif not f[propp] or f[propp]==None or f[propp]=="":
                    continue
                elif proptypelist!=None and proptypelist[fieldcounter]=="SubClass":
                    ttlstring+="<"+curid+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <"+str(f[propp])+"> .\n"
                    ttlstring+="<"+curid+"> <http://www.w3.org/2000/01/rdf-schema#subClassOf> <"+curclassid+"> .\n"
                    if first<10:
                        ttlstring+="<"+str(f[propp])+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#Class> .\n" 
                elif valuequeries!=None and propp in valuequeries:
                    ttlstring+=""
                    sparql = SPARQLWrapper(valuequeries[propp][1], agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
                    sparql.setQuery("".join(self.prefixes[endpointIndex]) + valuequeries[propp][0].replace("%%"+propp+"%%","\""+str(f[propp])+"\""))
                    sparql.setMethod(POST)
                    sparql.setReturnFormat(JSON)
                    results = sparql.query().convert()
                    ttlstring+="<"+curid+"> <"+prop+"> <"+results["results"]["bindings"][0]["item"]["value"]+"> ."
                    if first<10:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .\n"
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n"  
                        if classurilist[fieldcounter]!="":
                             ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <"+classurilist[fieldcounter]+"> .\n"
                elif valuemappings!=None and propp in valuemappings and f[propp] in self.valuemappings[propp]:
                    ttlstring+="<"+curid+"> <"+prop+"> <"+str(self.valuemappings[propp][f[propp]])+"> .\n"
                    if first<10:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .\n"
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n"  
                        if classurilist[fieldcounter]!="":
                             ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <"+classurilist[fieldcounter]+"> .\n"
                elif "http" in str(f[propp]) or (proptypelist!=None and proptypelist[fieldcounter]=="ObjectProperty"):
                    ttlstring+="<"+curid+"> <"+prop+"> <"+str(f[propp])+"> .\n"
                    if first<10:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#ObjectProperty> .\n"
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n"  
                        if classurilist[fieldcounter]!="":
                             ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <"+classurilist[fieldcounter]+"> .\n"
                elif re.match(r'^-?\d+$', str(f[propp])):
                    ttlstring+="<"+curid+"> <"+prop+"> \""+str(f[propp])+"\"^^<http://www.w3.org/2001/XMLSchema#integer> .\n"
                    if first<10:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .\n"
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n" 
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <http://www.w3.org/2001/XMLSchema#integer> .\n" 
                elif re.match(r'^-?\d+(?:\.\d+)?$', str(f[propp])):
                    ttlstring+="<"+curid+"> <"+prop+"> \""+str(f[propp])+"\"^^<http://www.w3.org/2001/XMLSchema#double> .\n"
                    if first:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .\n"
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n" 
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <http://www.w3.org/2001/XMLSchema#double> .\n" 
                else:
                    ttlstring+="<"+curid+"> <"+prop+"> \""+str(f[propp]).replace('"','\\"')+"\"^^<http://www.w3.org/2001/XMLSchema#string> .\n"
                    if first<10:
                        ttlstring+="<"+prop+"> <http://www.w3.org/1999/02/22-rdf-syntax-ns#type> <http://www.w3.org/2002/07/owl#DatatypeProperty> .\n"
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#domain> <"+curclassid+"> .\n" 
                        ttlstring+="<"+prop+"> <http://www.w3.org/2000/01/rdf-schema#range> <http://www.w3.org/2001/XMLSchema#string> .\n" 
            if first<10:
                first=first+1
        return ttlstring

    def exportLayer2(self):
        self.exportLayer(None,None,None,None,None,None,self.dlg.exportTripleStore_2.isChecked())


    def exportLayer(self,urilist=None,classurilist=None,includelist=None,proptypelist=None,valuemappings=None,valuequeries=None,exportToTripleStore=False):
        layers = QgsProject.instance().layerTreeRoot().children()
        if self.enrichedExport:
            selectedLayerIndex = self.dlg.chooseLayerInterlink.currentIndex()
        else:
            selectedLayerIndex = self.dlg.loadedLayers.currentIndex()
        layer = layers[selectedLayerIndex].layer()
        if exportToTripleStore:
            ttlstring=self.layerToTTLString(layer,urilist,classurilist,includelist,proptypelist,valuemappings,valuequeries)
            uploaddialog=UploadRDFDialog(ttlstring)
            uploaddialog.setMinimumSize(450, 250)
            uploaddialog.setWindowTitle("Upload interlinked dataset to triple store ")
            uploaddialog.exec_()
        else:
            filename, _filter = QFileDialog.getSaveFileName(
                self.dlg, "Select   output file ","", "Linked Data (*.ttl *.n3 *.nt)",)
            if filename=="":
                return
            ttlstring=self.layerToTTLString(layer,urilist,classurilist,includelist,proptypelist,valuemappings,valuequeries)
            g=Graph()
            g.parse(data=ttlstring, format="ttl")
            splitted=filename.split(".")
            exportNameSpace=""
            exportSetClass=""
            with open(filename, 'w') as output_file:
                output_file.write(g.serialize(format=splitted[len(splitted)-1]).decode("utf-8"))
                iface.messageBar().pushMessage("export layer successfully!", "OK", level=Qgis.Success)

    def exportLayerAsGeoJSONLD(self):
        context={
    "geojson": "https://purl.org/geojson/vocab#",
    "Feature": "geojson:Feature",
    "FeatureCollection": "geojson:FeatureCollection",
    "GeometryCollection": "geojson:GeometryCollection",
    "LineString": "geojson:LineString",
    "MultiLineString": "geojson:MultiLineString",
    "MultiPoint": "geojson:MultiPoint",
    "MultiPolygon": "geojson:MultiPolygon",
    "Point": "geojson:Point",
    "Polygon": "geojson:Polygon",
    "bbox": {
      "@container": "@list",
      "@id": "geojson:bbox"
    },
    "coordinates": {
      "@container": "@list",
      "@id": "geojson:coordinates"
    },
    "features": {
      "@container": "@set",
      "@id": "geojson:features"
    },
    "geometry": "geojson:geometry",
    "id": "@id",
    "properties": "geojson:properties",
    "type": "@type",
    "description": "http://purl.org/dc/terms/description",
    "title": "http://purl.org/dc/terms/title"
  }
        layer = layers[selectedLayerIndex].layer()
        fieldnames = [field.name() for field in layer.fields()]
        currentgeo={}
        geos=[]
        for f in layer.getFeatures():
            geom = f.geometry()
            currentgeo={'id':row[0],'geometry':json.loads(geom.asJson()),'properties':{}}
            for prop in fieldnames:
                if prop=="id":
                    currentgeo["id"]=f[prop]
                else:
                    currentgeo["properties"][prop]=f[prop]
            geos.append(currentgeo)
        featurecollection={"@context":context, "type":"FeatureCollection", "@id":"http://example.com/collections/1", "features": geos }
        return featurecollection	
    """
    def loadGraph(self):
        dialog = QFileDialog(self.dlg)
        dialog.setFileMode(QFileDialog.AnyFile)
        self.justloadingfromfile=True
        if dialog.exec_():
            fileNames = dialog.selectedFiles()
            g = Graph()
            filepath=fileNames[0].split(".")
            result = g.parse(fileNames[0], format=filepath[len(filepath)-1])
            print(g)
            self.currentgraph=g
            geoconcepts=self.getGeoConcepts("",self.triplestoreconf[0]["geoconceptquery"],"class",g,False)
            self.dlg.layerconcepts.clear()
            for geo in geoconcepts:
                self.dlg.layerconcepts.addItem(geo)
            comp=QCompleter(self.dlg.layerconcepts)
            comp.setCompletionMode(QCompleter.PopupCompletion)
            comp.setModel(self.dlg.layerconcepts.model())
            self.dlg.layerconcepts.setCompleter(comp)
            self.dlg.inp_sparql.setPlainText(self.triplestoreconf[0]["querytemplate"][0]["query"].replace("%%concept%%",geoconcepts[0]))
            self.loadedfromfile=True
            self.justloadingfromfile=False
            self.dlg.comboBox.setCurrentIndex(0)
            return result
        return None
    """ 
    def loadGraphProcess(task, wait_time,query,triplestoreurl,graph):
        print("THREADSTART")
        viewlist=[]
        #print(query)
        #print(triplestoreurl)
        print(graph)
        if graph!=None:
            print("WE HAVE A GRAPH")
            results = graph.query(query)
            #for row in results:
                #viewlist.append(str(row[0]))
        """
        else:
            sparql = SPARQLWrapper(triplestoreurl, agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.64 Safari/537.11")
            sparql.setQuery(query)
            print("now sending query")
            sparql.setReturnFormat(JSON)
            results = sparql.query().convert()
            for result in results["results"]["bindings"]:
                viewlist.append(str(result[queryvar]["value"]))
        """
        print(viewlist)
        return viewlist

    def loadGraphGUI(exception, result=None):
        print("Loading graph gui")
        self.dlg.layercount.setText("["+str(len(result))+"]")		
        for geo in geoconcepts:
            self.dlg.layerconcepts.addItem(geo)
        comp=QCompleter(self.dlg.layerconcepts)
        comp.setCompletionMode(QCompleter.PopupCompletion)
        comp.setModel(self.dlg.layerconcepts.model())
        self.dlg.layerconcepts.setCompleter(comp)
        self.dlg.inp_sparql2.setPlainText(self.triplestore[0]["querytemplate"][0]["query"].replace("%%concept%%",geoconcepts[0]))
        self.dlg.inp_sparql2.columnvars={}
        self.loadedfromfile=True
        self.justloadingfromfile=False
        return result
    
    def loadGraph(self):
        dialog = QFileDialog(self.dlg)
        dialog.setFileMode(QFileDialog.AnyFile)
        self.justloadingfromfile=True
        if dialog.exec_():
            fileNames = dialog.selectedFiles()
            g = Graph()
            filepath=fileNames[0].split(".")
            result = g.parse(fileNames[0], format=filepath[len(filepath)-1])
            print(g)
            self.currentgraph=g
            self.dlg.layerconcepts.clear()
            print(self.triplestoreconf[0]["geoconceptquery"])
            task1=QgsTask.fromFunction('loadGraphProcess', self.loadGraphProcess,onfinished=self.loadGraphGUI,wait_time=100,query=self.triplestoreconf[0]["geoconceptquery"],triplestoreurl="",graph=g)
            QgsApplication.taskManager().addTask(task1)
            #worker = GeoConceptsWorker(self.triplestoreconf[0]["geoconceptquery"],"",g)
            #runworker=RunWorker()
            #runworker.start_worker(worker, self.iface, 'testing the worker')

            #worker = GeoConceptsWorker(self.triplestoreconf[0]["geoconceptquery"],"",g)
            #worker_thread = QThread()
            #worker.moveToThread(worker_thread)
            #worker_thread.finished.connect(self.loadGraphGUI)
            #worker_thread.start()
            #geoconcepts=self.getGeoConcepts("",self.triplestoreconf[0]["geoconceptquery"],"class",g)
        return None
        
    def loadUnicornLayers(self):
        # Fetch the currently loaded layers
        layers = QgsProject.instance().layerTreeRoot().children()
        # Populate the comboBox with names of all the loaded unicorn layers
        self.dlg.loadedLayers.clear()
        self.dlg.chooseLayerInterlink.clear()
        self.dlg.chooseLayerEnrich.clear()
        for layer in layers:
            ucl = layer.name()
            #if type(layer) == QgsMapLayer.VectorLayer:
            self.dlg.loadedLayers.addItem(layer.name())
            self.dlg.chooseLayerInterlink.addItem(layer.name())
            self.dlg.chooseLayerEnrich.addItem(layer.name())       

    def endpointselectaction(self):
        endpointIndex = self.dlg.comboBox.currentIndex()
        self.dlg.queryTemplates.clear()
        print("changing endpoint")
        conceptlist=[]
        self.dlg.layerconcepts.clear()
        if "endpoint" in self.triplestoreconf[endpointIndex] and self.triplestoreconf[endpointIndex]["endpoint"]!="" and (not "staticconcepts" in self.triplestoreconf[endpointIndex] or "staticconcepts" in self.triplestoreconf[endpointIndex] and self.triplestoreconf[endpointIndex]["staticconcepts"]==[]) and "geoconceptquery" in self.triplestoreconf[endpointIndex] and self.triplestoreconf[endpointIndex]["geoconceptquery"]!="":
            conceptlist=self.getGeoConcepts(self.triplestoreconf[endpointIndex]["endpoint"],self.triplestoreconf[endpointIndex]["geoconceptquery"],"class",None,True)
        elif "staticconcepts" in self.triplestoreconf[endpointIndex] and self.triplestoreconf[endpointIndex]["staticconcepts"]!=[]:
            conceptlist=self.triplestoreconf[endpointIndex]["staticconcepts"]
        for concept in conceptlist:
            self.dlg.layerconcepts.addItem(concept)
        comp=QCompleter(self.dlg.layerconcepts)
        comp.setCompletionMode(QCompleter.PopupCompletion)
        comp.setModel(self.dlg.layerconcepts.model())
        self.dlg.layerconcepts.setCompleter(comp)
        if "areaconcepts" in self.triplestoreconf[endpointIndex] and self.triplestoreconf[endpointIndex]["areaconcepts"]:
            conceptlist2=self.triplestoreconf[endpointIndex]["areaconcepts"]
            for concept in conceptlist2:
                 self.dlg.areaconcepts.addItem(concept["concept"])
        if "querytemplate" in self.triplestoreconf[endpointIndex]:
            for concept in self.triplestoreconf[endpointIndex]["querytemplate"]:
                 self.dlg.queryTemplates.addItem(concept["label"])
        if "examplequery" in self.triplestoreconf[endpointIndex]:
            self.dlg.inp_sparql2.setPlainText(self.triplestoreconf[endpointIndex]["examplequery"]) 
            self.dlg.inp_sparql2.columnvars={}


    def getPointFromCanvas(self):
        self.d=BBOXDialog(self.dlg.inp_sparql2,self.triplestoreconf,self.dlg.comboBox.currentIndex())
        self.d.setWindowTitle("Choose BoundingBox")
        self.d.exec_()

    def saveTripleStoreConfig(self):
        __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
        with open(os.path.join(__location__, 'triplestoreconf_personal.json'),'w') as myfile:
            myfile.write(json.dumps(self.triplestoreconf,indent=2))

    def resetTripleStoreConfig(self):
        __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
        with open(os.path.join(__location__, 'triplestoreconf.json'),'r') as myfile:
               data=myfile.read()
        self.triplestoreconf = json.loads(data)
        with open(os.path.join(__location__, 'triplestoreconf_personal.json'),'w') as myfile:
            myfile.write(json.dumps(self.triplestoreconf,indent=2))

    def viewselectaction(self):
        endpointIndex = self.dlg.comboBox.currentIndex()
        if endpointIndex==0:
            self.justloadingfromfile=False
            return
        if self.dlg.layerconcepts.currentText()!=None and "(Q" in self.dlg.layerconcepts.currentText():
            self.dlg.inp_label.setText(self.dlg.layerconcepts.currentText().split("(")[0].lower().replace(" ","_"))
            concept=self.dlg.layerconcepts.currentText().split("Q")[1].replace(")","")
        else:
            concept=self.dlg.layerconcepts.currentText()
        if "querytemplate" in self.triplestoreconf[endpointIndex]:
            self.dlg.inp_sparql2.setPlainText(self.triplestoreconf[endpointIndex]["querytemplate"][self.dlg.queryTemplates.currentIndex()]["query"].replace("%%concept%%",concept))
            self.dlg.inp_sparql2.columnvars={}
            if "wd:Q ." in self.dlg.inp_sparql2.toPlainText():
                self.dlg.inp_sparql2.setPlainText(self.dlg.inp_sparql2.toPlainText().replace("wd:Q .", "wd:Q1248784 ."))
        if "#" in self.dlg.layerconcepts.currentText():
            self.dlg.inp_label.setText(self.dlg.layerconcepts.currentText()[self.dlg.layerconcepts.currentText().rfind('#')+1:].lower().replace(" ","_"))
        else:
            self.dlg.inp_label.setText(self.dlg.layerconcepts.currentText()[self.dlg.layerconcepts.currentText().rfind('/')+1:].lower().replace(" ","_"))

    def check_state3(self):
        self.dlg.searchTripleStoreDialog.check_state(self.dlg.interlinkNameSpace)
		
    def buildCustomTripleStoreDialog(self):	
        self.dlg.searchTripleStoreDialog = TripleStoreDialog(self.triplestoreconf,self.dlg.comboBox)	
        self.dlg.searchTripleStoreDialog.setMinimumSize(700, 500)
        self.dlg.searchTripleStoreDialog.setWindowTitle("Configure Own Triple Store")	
        self.dlg.searchTripleStoreDialog.exec_()
        
    def createWhatToEnrich(self):
        if self.dlg.enrichTable.rowCount()==0:
            return
        layers = QgsProject.instance().layerTreeRoot().children()
        selectedLayerIndex = self.dlg.chooseLayerEnrich.currentIndex()
        layer = layers[selectedLayerIndex].layer()
        self.dlg.searchTripleStoreDialog = EnrichmentDialog(self.triplestoreconf,self.prefixes,self.dlg.enrichTable,layer,None,None)	
        self.dlg.searchTripleStoreDialog.setMinimumSize(700, 500)
        self.dlg.searchTripleStoreDialog.setWindowTitle("Enrichment Search")	
        self.dlg.searchTripleStoreDialog.exec_()

    def run(self):
        """Run method that performs all the real work"""
        # Create the dialog with elements (after translation) and keep reference
        # Only create GUI ONCE in callback, so that it will only load when the plugin is started
        if self.first_start == True:
            __location__ = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
            if os.path.isfile(os.path.join(__location__, 'triplestoreconf_personal.json')):
                with open(os.path.join(__location__, 'triplestoreconf_personal.json'),'r') as myfile:
                    data=myfile.read()
            else:
                with open(os.path.join(__location__, 'triplestoreconf.json'),'r') as myfile:
                    data=myfile.read()
            # parse file 
            with open(os.path.join(__location__, 'addvocabconf.json'),'r') as myfile:
                data2=myfile.read()
            self.triplestoreconf = json.loads(data)
            self.addVocabConf=json.loads(data2)
            #msgBox=QMessageBox()
            #msgBox.setText(str(self.addVocabConf))
            #msgBox.exec()
            counter=0
            for store in self.triplestoreconf:
                self.prefixes.append("")
                for prefix in store["prefixes"]:                 
                    self.prefixes[counter]+="PREFIX "+prefix+":<"+store["prefixes"][prefix]+">\n"
                counter+=1            
            self.addVocabConf = json.loads(data2)
            self.saveTripleStoreConfig()
            self.first_start = False
            self.dlg = SPAQLunicornDialog()
            self.dlg.searchTripleStoreDialog=TripleStoreDialog(self.triplestoreconf,self.dlg.comboBox)
            self.dlg.inp_sparql.hide()
            self.dlg.inp_sparql2=ToolTipPlainText(self.dlg.tab,self.triplestoreconf,self.dlg.comboBox,self.columnvars,self.prefixes)
            self.dlg.inp_sparql2.move(10,130)
            self.dlg.inp_sparql2.setMinimumSize(1071,401)
            self.dlg.inp_sparql2.document().defaultFont().setPointSize(16)
            self.dlg.inp_sparql2.setPlainText("SELECT ?item ?lat ?lon WHERE {\n ?item ?b ?c .\n ?item <http://www.wikidata.org/prop:P123> ?def .\n}")
            self.dlg.inp_sparql2.columnvars={}
            self.sparqlhighlight = SPARQLHighlighter(self.dlg.inp_sparql2)
            self.dlg.comboBox.clear()
            for triplestore in self.triplestoreconf:
                if triplestore["active"]:
                    item=triplestore["name"]
                    if "mandatoryvariables" in triplestore:
                        item+=" --> "
                        for mandvar in triplestore["mandatoryvariables"]:
                            item+="?"+mandvar+" "
                        item+=" required!"
                    self.dlg.comboBox.addItem(item)
            self.dlg.comboBox.setCurrentIndex(1)
            self.viewselectaction()
            self.dlg.areaconcepts.hide()
            self.dlg.areas.hide()
            self.dlg.label_8.hide()
            self.dlg.label_9.hide()
            self.dlg.exportTripleStore.hide()
            self.dlg.exportTripleStore_2.hide()
            #self.dlg.tabWidget.removeTab(2)
           #self.dlg.tabWidget.removeTab(1)
            self.dlg.comboBox.currentIndexChanged.connect(self.endpointselectaction)
            self.dlg.queryTemplates.currentIndexChanged.connect(self.viewselectaction)
            self.dlg.loadedLayers.clear()
            self.dlg.inp_sparql2.textChanged.connect(self.validateSPARQL)
            self.dlg.bboxButton.clicked.connect(self.getPointFromCanvas)
            self.dlg.addEnrichedLayerButton.clicked.connect(self.addEnrichedLayer)
            self.dlg.interlinkTable.cellClicked.connect(self.createInterlinkSearchDialog)
            self.dlg.enrichTable.cellClicked.connect(self.createEnrichSearchDialog)
            self.dlg.chooseLayerInterlink.clear()
            self.dlg.layerconcepts.clear()
            self.dlg.layerconcepts.setEditable(True)
            self.dlg.layerconcepts.setInsertPolicy(QComboBox.NoInsert)
            self.dlg.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.dlg)
            self.dlg.interlinkNameSpace.setValidator(urlvalidator)
            self.dlg.interlinkNameSpace.textChanged.connect(self.check_state3)
            self.dlg.interlinkNameSpace.textChanged.emit(self.dlg.interlinkNameSpace.text())
            #self.dlg.layerconcepts.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            self.dlg.addEnrichedLayerRowButton.clicked.connect(self.addEnrichRow)
            self.dlg.startEnrichment.clicked.connect(self.enrichLayerProcess)
            self.dlg.layerconcepts.currentIndexChanged.connect(self.viewselectaction)
            #self.dlg.layerconcepts.currentIndexChanged.connect(self.loadAreas)
            self.dlg.pushButton.clicked.connect(self.create_unicorn_layer) # load action
            self.dlg.exportLayers.clicked.connect(self.exportLayer2)
            self.dlg.whattoenrich.clicked.connect(self.createWhatToEnrich)
            self.dlg.exportInterlink.clicked.connect(self.exportEnrichedLayer)
            self.dlg.loadLayerInterlink.clicked.connect(self.loadLayerForInterlink)
            self.dlg.enrichTableResult.hide()
            self.dlg.loadTripleStoreButton.clicked.connect(self.buildCustomTripleStoreDialog)
            self.dlg.exportMappingButton.clicked.connect(self.exportMapping)
            self.dlg.importMappingButton.clicked.connect(self.loadMapping)
            #self.dlg.loadLayerInterlink.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            #self.dlg.IDColumnEnrich.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            self.dlg.loadLayerEnrich.clicked.connect(self.loadLayerForEnrichment)
            #self.dlg.loadLayerEnrich.view().setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
            self.dlg.refreshLayersInterlink.clicked.connect(self.loadUnicornLayers)
            self.dlg.loadFileButton.clicked.connect(self.loadGraph) # load action

        if self.first_start == False:
            self.loadUnicornLayers()

        # show the dialog
        self.dlg.show()
        # Run the dialog event loop
        result = self.dlg.exec_()
        # See if OK was pressed
        if result:
            # Do something useful here - delete the line containing pass and
            # substitute with your code.
            pass
