|
|
@@ -0,0 +1,2252 @@
|
|
|
+ # -*- coding: utf-8 -*-
|
|
|
+"""
|
|
|
+/***************************************************************************
|
|
|
+ Atlas
|
|
|
+ A QGIS plugin
|
|
|
+ Atlas
|
|
|
+ Generated by Plugin Builder: http://g-sherman.github.io/Qgis-Plugin-Builder/
|
|
|
+ -------------------
|
|
|
+ begin : 2019-02-15
|
|
|
+ git sha : $Format:%H$
|
|
|
+ copyright : (C) 2019 by jan vrobel
|
|
|
+ email : vrobel.jan@seznam.cz
|
|
|
+ ***************************************************************************/
|
|
|
+
|
|
|
+/***************************************************************************
|
|
|
+ * *
|
|
|
+ * 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. *
|
|
|
+ * *
|
|
|
+ ***************************************************************************/
|
|
|
+"""
|
|
|
+from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt, QFileSystemWatcher, QRegExp,QDir
|
|
|
+from PyQt5.QtGui import QIcon, QPixmap, QRegExpValidator, QDoubleValidator
|
|
|
+from PyQt5.QtWidgets import QAction, QTreeWidget, QTreeWidgetItem, QMessageBox, QLabel, QProgressDialog, QDialog, QProgressBar,QListWidgetItem
|
|
|
+# Initialize Qt resources from file resources.py
|
|
|
+from .resources import *
|
|
|
+import re
|
|
|
+#from .flaskServer import *
|
|
|
+from multiprocessing import Process
|
|
|
+from pathlib import Path
|
|
|
+# Import the code for the DockWidget
|
|
|
+from builtins import str
|
|
|
+from builtins import range
|
|
|
+from builtins import object
|
|
|
+import json
|
|
|
+import zipfile
|
|
|
+import tempfile
|
|
|
+import configparser
|
|
|
+import shutil
|
|
|
+import uuid
|
|
|
+import copy
|
|
|
+import webbrowser
|
|
|
+from .Atlas_dockwidget import AtlasDockWidget
|
|
|
+import os.path
|
|
|
+import tempfile
|
|
|
+import qgis.core
|
|
|
+from qgis.core import *
|
|
|
+import platform
|
|
|
+import os
|
|
|
+import qgis.utils
|
|
|
+import qgis.gui
|
|
|
+from qgis.gui import QgsMapCanvas
|
|
|
+from qgis.core import QgsApplication
|
|
|
+from qgis.utils import iface
|
|
|
+from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMessageBox, QWidget, QInputDialog, QLineEdit, QFileDialog
|
|
|
+import requests
|
|
|
+import tempfile
|
|
|
+import time
|
|
|
+from urllib.request import urlopen
|
|
|
+import subprocess
|
|
|
+import threading
|
|
|
+#from flask import Flask, request, jsonify
|
|
|
+import base64
|
|
|
+import hashlib
|
|
|
+import html
|
|
|
+import re
|
|
|
+import urllib.parse
|
|
|
+from .ogr2ogr import main
|
|
|
+## forms
|
|
|
+from .dlg_GetLayers import GetLayersDialog
|
|
|
+from .dlg_importMap import ImportMapDialog
|
|
|
+from .dlg_deleteMap import DeleteMapDialog
|
|
|
+from .dlg_importLayer import ImportLayerDialog
|
|
|
+from .dlg_addLayer import AddLayerDialog
|
|
|
+from .dlg_addMap import AddMapDialog
|
|
|
+from .dlg_createComposite import CreateCompositeDialog
|
|
|
+from .dlg_deleteLayerFromMap import DeleteLayerFromMapDialog
|
|
|
+from .dlg_editMap import EditMapDialog
|
|
|
+from .dlg_ConnectionManager import ConnectionManagerDialog
|
|
|
+from .dlg_userInfo import UserInfoDialog
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+class Atlas:
|
|
|
+ """QGIS Plugin Implementation."""
|
|
|
+
|
|
|
+ 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__)
|
|
|
+
|
|
|
+ ## init global variables
|
|
|
+ # global filename
|
|
|
+ self.client_id = None
|
|
|
+ self.filename = None
|
|
|
+ self.layerName = None
|
|
|
+ self.username = 'browser'
|
|
|
+ self.EPSG = 'EPSG:3857'
|
|
|
+ self.composite = None
|
|
|
+ self.thread1 = None
|
|
|
+ self.compositeList = []
|
|
|
+ self.compositeListOld = []
|
|
|
+ self.CHUNK_SIZE = 1048576 ## s touto hodnotou pracuje layman klient (cca 1MB soubor)
|
|
|
+ self.URI = "http://layman.lesprojekt.cz"
|
|
|
+ self.access_token = None
|
|
|
+ self.expires_in = None
|
|
|
+ self.refresh_token = None
|
|
|
+ self.laymanUsername = ""
|
|
|
+ self.authHeader = None
|
|
|
+ self.code_verifier = None
|
|
|
+ self.code_challenge = None
|
|
|
+ self.Agrimail = None
|
|
|
+ self.loadedInMemory = False
|
|
|
+ self.uri = 'http://layman.lesprojekt.cz/rest/'
|
|
|
+ # global dlgGetLayers
|
|
|
+ self.dlgGetLayers= GetLayersDialog()
|
|
|
+ # initialize locale
|
|
|
+ locale = QSettings().value('locale/userLocale')[0:2]
|
|
|
+ locale_path = os.path.join(
|
|
|
+ self.plugin_dir,
|
|
|
+ 'i18n',
|
|
|
+ 'Atlas_{}.qm'.format(locale))
|
|
|
+
|
|
|
+ if os.path.exists(locale_path):
|
|
|
+ self.translator = QTranslator()
|
|
|
+ self.translator.load(locale_path)
|
|
|
+
|
|
|
+ if qVersion() > '4.3.3':
|
|
|
+ QCoreApplication.installTranslator(self.translator)
|
|
|
+
|
|
|
+ # Declare instance attributes
|
|
|
+ self.actions = []
|
|
|
+ self.menu = self.tr(u'&Layman')
|
|
|
+ # TODO: We are going to let the user set this up in a future iteration
|
|
|
+ self.toolbar = self.iface.addToolBar(u'Layman')
|
|
|
+ self.toolbar.setObjectName(u'Layman')
|
|
|
+
|
|
|
+ #print "** INITIALIZING Atlas"
|
|
|
+
|
|
|
+ self.pluginIsActive = False
|
|
|
+ self.dockwidget = None
|
|
|
+ ## prepare temp dir
|
|
|
+ tempDir = tempfile.gettempdir() + os.sep + "atlas"
|
|
|
+ try:
|
|
|
+ os.mkdir(tempDir)
|
|
|
+ print("Directory " , tempDir , " Created ")
|
|
|
+ except FileExistsError:
|
|
|
+ print("Directory " , tempDir , " already exists")
|
|
|
+
|
|
|
+
|
|
|
+ # 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('Layman', message)
|
|
|
+
|
|
|
+
|
|
|
+ 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:
|
|
|
+ self.toolbar.addAction(action)
|
|
|
+
|
|
|
+ if add_to_menu:
|
|
|
+ self.iface.addPluginToMenu(
|
|
|
+ self.menu,
|
|
|
+ action)
|
|
|
+
|
|
|
+ self.actions.append(action)
|
|
|
+
|
|
|
+ return action
|
|
|
+
|
|
|
+
|
|
|
+ def initGui(self):
|
|
|
+ """Create the menu entries and toolbar icons inside the QGIS GUI."""
|
|
|
+
|
|
|
+ #icon_path = ':/plugins/Atlas/icon.png'
|
|
|
+ #self.add_action(
|
|
|
+ # icon_path,
|
|
|
+ # text=self.tr(u''),
|
|
|
+ # callback=self.run,
|
|
|
+ # parent=self.iface.mainWindow())
|
|
|
+ #self.first_start = True
|
|
|
+
|
|
|
+ ################## user
|
|
|
+ self.textbox = QLabel(self.iface.mainWindow())
|
|
|
+ # Set width
|
|
|
+ self.textbox.setFixedWidth(140)
|
|
|
+ # Add textbox to toolbar
|
|
|
+ self.txtAction = self.toolbar.addWidget(self.textbox)
|
|
|
+ # Set tooltip
|
|
|
+ self.txtAction.setToolTip(self.tr(u'Current Row Number'))
|
|
|
+ # Set callback
|
|
|
+ self.textbox.setText("Layman")
|
|
|
+
|
|
|
+ ################ end usericon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'login.png'
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'login.png'
|
|
|
+ self.menu_Connection = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Login'),
|
|
|
+ callback=self.run_login,
|
|
|
+ enabled_flag=True,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+
|
|
|
+
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'save.png'
|
|
|
+ self.menu_saveLocalFile = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Save as to JSON and SLD'),
|
|
|
+ callback=self.saveLocalFile,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+
|
|
|
+ self.first_start = True
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'file.png'
|
|
|
+ self.menu_loadJson = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Load from JSON'),
|
|
|
+ callback=self.loadLocalFile,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+ self.first_start = True
|
|
|
+
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'layers-up.png'
|
|
|
+ self.menu_ImportLayerDialog = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Export layer to server'),
|
|
|
+ callback=self.run_ImportLayerDialog,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'layers-down.png'
|
|
|
+ self.menu_AddLayerDialog = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Load layer from server'),
|
|
|
+ callback=self.run_AddLayerDialog,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'upload-map.png'
|
|
|
+ self.menu_ImportMapDialog = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Manage maps'),
|
|
|
+ callback=self.run_ImportMapDialog,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'download_map.png'
|
|
|
+ self.menu_AddMapDialog = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'Load map from server'),
|
|
|
+ callback=self.run_AddMapDialog,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+
|
|
|
+ #icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'delete.png'
|
|
|
+ #self.menu_DeleteMapDialog = self.add_action(
|
|
|
+ # icon_path,
|
|
|
+ # text=self.tr(u'Delete map'),
|
|
|
+ # callback=self.run_DeleteMapDialog,
|
|
|
+ # enabled_flag=False,
|
|
|
+ # parent=self.iface.mainWindow())
|
|
|
+ #icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'globus.png'
|
|
|
+ #self.menu_CreateCompositeDialog = self.add_action(
|
|
|
+ # icon_path,
|
|
|
+ # text=self.tr(u'Create map'),
|
|
|
+ # callback=self.run_CreateCompositeDialog,
|
|
|
+ # enabled_flag=False,
|
|
|
+ # parent=self.iface.mainWindow())
|
|
|
+ icon_path = self.plugin_dir + os.sep + 'icons' + os.sep + 'account.svg'
|
|
|
+ self.menu_UserInfoDialog = self.add_action(
|
|
|
+ icon_path,
|
|
|
+ text=self.tr(u'User info'),
|
|
|
+ callback=self.run_UserInfoDialog,
|
|
|
+ enabled_flag=False,
|
|
|
+ parent=self.iface.mainWindow())
|
|
|
+ #--------------------------------------------------------------------------
|
|
|
+ def run_UserInfoDialog(self):
|
|
|
+ self.dlg = UserInfoDialog()
|
|
|
+ self.dlg.show()
|
|
|
+ userEndpoint = "http://layman.lesprojekt.cz/rest/current-user"
|
|
|
+ r = requests.get(url = userEndpoint, headers = self.authHeader)
|
|
|
+ res = r.text
|
|
|
+ res = self.fromByteToJson(r.content)
|
|
|
+ print(res['claims'])
|
|
|
+ self.dlg.label_layman.setText(res['claims']['preferred_username'])
|
|
|
+ self.dlg.label_agrihub.setText(res['claims']['email'])
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+ def run_EditMap(self, x):
|
|
|
+ self.dlg = EditMapDialog()
|
|
|
+ self.dlg.pushButton_save.setStyleSheet("#pushButton_save {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_save:hover{background: #66ab27 ;}#pushButton_save:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.lineEdit_name.hide()
|
|
|
+ self.dlg.label_2.hide()
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ self.dlg.lineEdit_name.setText(self.compositeList[x]['name'])
|
|
|
+ self.dlg.lineEdit_abstract.setText(self.compositeList[x]['abstract'])
|
|
|
+ self.dlg.lineEdit_title.setText(self.compositeList[x]['title'])
|
|
|
+ self.dlg.lineEdit_units.setText(self.compositeList[x]['units'])
|
|
|
+ self.dlg.lineEdit_scale.setText(str(self.compositeList[x]['scale']))
|
|
|
+ self.dlg.lineEdit_user.setText(self.compositeList[x]['user']['name'])
|
|
|
+ self.dlg.rejected.connect(lambda: self.afterCloseEditMapDialog())
|
|
|
+ self.dlg.pushButton_save.clicked.connect(lambda: self.modifyMap(x))
|
|
|
+ self.dlg.rejected.connect(lambda: self.afterCloseCompositeDialog())
|
|
|
+ self.dlg.show()
|
|
|
+ result = self.dlg.exec_()
|
|
|
+
|
|
|
+ def run_DeleteLayerFromMap(self):
|
|
|
+ self.dlg = DeleteLayerFromMapDialog()
|
|
|
+ self.dlg.pushButton.clicked.connect(lambda: self.deteteLayerFromComposite(self.dlg.listWidget.currentRow(),self.compositeList[self.dlg.listWidget.currentRow()]['layers'][self.dlg.listWidget_listLayers2.currentRow()]['params']['LAYERS']))
|
|
|
+ #self.dlg.pushButton.clicked.connect(lambda: print(self.dlg.listWidget_2.currentRow()))
|
|
|
+
|
|
|
+ layers = QgsProject.instance().mapLayers().values()
|
|
|
+
|
|
|
+ for i in range (0, len(self.compositeList)):
|
|
|
+ self.dlg.listWidget.addItem(self.compositeList[i]['name'])
|
|
|
+ # self.dlg.pushButton.setEnabled(False)
|
|
|
+ self.dlg.listWidget.itemClicked.connect(self.listCompositeLayers)
|
|
|
+ self.dlg.listWidget_listLayers2.itemClicked.connect(self.showThumbnail)
|
|
|
+
|
|
|
+
|
|
|
+ # self.dlg.listWidget_listMaps.itemClicked.connect(self.enableButton)
|
|
|
+ self.dlg.show()
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ result = self.dlg.exec_()
|
|
|
+
|
|
|
+ def run_CreateCompositeDialog(self, fromImport = False):
|
|
|
+ self.dlg = CreateCompositeDialog()
|
|
|
+ self.dlg.label_info.hide()
|
|
|
+ self.dlg.label_2.hide()
|
|
|
+ self.dlg.lineEdit.hide()
|
|
|
+ self.dlg.pushButton_CreateComposition.clicked.connect(lambda: self.createComposite(self.dlg.lineEdit.text(),self.dlg.lineEdit_2.text()))
|
|
|
+ layers = QgsProject.instance().mapLayers().values()
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.setExtent)
|
|
|
+ for layer in layers:
|
|
|
+ # self.dlg.listWidget_listLayers.addItem(layer.name())
|
|
|
+ if (layer.type() == QgsMapLayer.VectorLayer):
|
|
|
+ item = QTreeWidgetItem([layer.name()])
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.treeWidget.addTopLevelItem(item)
|
|
|
+ ext = iface.mapCanvas().extent()
|
|
|
+ self.dlg.lineEdit.setValidator(QRegExpValidator(QRegExp("[a-z]{1}[a-z0-9]{1,30}")))
|
|
|
+ self.dlg.lineEdit_2.editingFinished.connect(self.checkNameCreateMap)
|
|
|
+ self.dlg.lineEdit_3.setText(str(ext.xMinimum()))
|
|
|
+ self.dlg.lineEdit_4.setText(str(ext.xMaximum()))
|
|
|
+ self.dlg.lineEdit_5.setText(str(ext.yMinimum()))
|
|
|
+ self.dlg.lineEdit_6.setText(str(ext.yMaximum()))
|
|
|
+ self.dlg.pushButton_defaultExtent.clicked.connect(lambda: self.setDefaultExtent(ext))
|
|
|
+ self.dlg.pushButton_defaultExtent.setStyleSheet("#pushButton_defaultExtent {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_defaultExtent:hover{background: #66ab27 ;}#pushButton_defaultExtent:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_CreateComposition.setStyleSheet("#pushButton_CreateComposition {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_CreateComposition:hover{background: #66ab27 ;}#pushButton_CreateComposition:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+ self.dlg.show()
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ if (fromImport):
|
|
|
+ self.dlg.rejected.connect(lambda: self.afterCloseCompositeDialog())
|
|
|
+ result = self.dlg.exec_()
|
|
|
+
|
|
|
+
|
|
|
+ def run_ImportMapDialog(self):
|
|
|
+ self.dlg = ImportMapDialog()
|
|
|
+ self.dlg.label_import.hide()
|
|
|
+ #self.dlg.listWidget_listLayers2.hide()
|
|
|
+ self.dlg.pushButton_deleteMap.setEnabled(False)
|
|
|
+ self.dlg.pushButton_editMeta.setEnabled(False)
|
|
|
+ self.dlg.pushButton_addRaster.setEnabled(False)
|
|
|
+ self.dlg.mMapLayerComboBox.setFilters(QgsMapLayerProxyModel.VectorLayer)
|
|
|
+ self.dlg.pushButton.clicked.connect(lambda: self.addLayerToComposite(self.dlg.listWidget.currentRow()))
|
|
|
+ self.dlg.pushButton_deleteMap.clicked.connect(lambda: self.deleteMap(self.dlg.listWidget.currentItem().text(),self.dlg.listWidget.currentRow()))
|
|
|
+ # self.dlg.pushButton_deleteMap.clicked.connect(lambda: self.deleteMapFromCanvas(self.dlg.listWidget.currentRow()))
|
|
|
+ self.dlg.pushButton_up.clicked.connect(lambda: self.reorderLayers(self.dlg.listWidget_listLayers.currentRow(), 1, self.dlg.listWidget.currentRow()))
|
|
|
+ self.dlg.pushButton_down.clicked.connect(lambda: self.reorderLayers(self.dlg.listWidget_listLayers.currentRow(), -1, self.dlg.listWidget.currentRow()))
|
|
|
+
|
|
|
+
|
|
|
+ if not self.loadedInMemory:
|
|
|
+ self.loadAllComposites()
|
|
|
+ self.dlg.pushButton_addMap.clicked.connect(lambda: self.showAddMapDialog())
|
|
|
+ layers = QgsProject.instance().mapLayers().values()
|
|
|
+ for i in range (0, len(self.compositeList)):
|
|
|
+ print(self.compositeList[i])
|
|
|
+ #self.dlg.listWidget.addItem(self.compositeList[i]['name'])
|
|
|
+ self.dlg.listWidget.addItem(self.compositeList[i]['title'])
|
|
|
+ self.dlg.progressBar.hide()
|
|
|
+ self.dlg.pushButton.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
|
|
|
+ self.dlg.pushButton_addMap.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
|
|
|
+ self.dlg.pushButton_addRaster.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'plus.png'))
|
|
|
+ self.dlg.pushButton_deleteLayers.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'minus.png'))
|
|
|
+ self.dlg.pushButton_deleteMap.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'minus.png'))
|
|
|
+ self.dlg.pushButton_editMeta.setIcon(QIcon(self.plugin_dir + os.sep + 'icons' + os.sep + 'edit.png'))
|
|
|
+ self.dlg.listWidget.itemClicked.connect(self.refreshLayerList)
|
|
|
+ self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_deleteMap.setEnabled(True))
|
|
|
+ self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_editMeta.setEnabled(True))
|
|
|
+ self.dlg.listWidget.itemClicked.connect(lambda: self.dlg.pushButton_addRaster.setEnabled(True))
|
|
|
+ self.dlg.listWidget_listLayers.itemClicked.connect(lambda: self.dlg.pushButton_down.setEnabled(True))
|
|
|
+ self.dlg.listWidget_listLayers.itemClicked.connect(lambda: self.dlg.pushButton_up.setEnabled(True))
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton_editMeta.clicked.connect(lambda: self.showEditMapDialog(self.dlg.listWidget.currentRow()))
|
|
|
+ ###########nacitam vrstvy z laymana do comboboxu
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ # print(r.content())
|
|
|
+ data = r.json()
|
|
|
+ for row in range(0, len(data)):
|
|
|
+ self.dlg.comboBox_raster.addItem(data[row]['name'])
|
|
|
+
|
|
|
+ self.dlg.pushButton_addRaster.clicked.connect(lambda: self.addExistingLayerToComposite(self.dlg.comboBox_raster.currentText()))
|
|
|
+ #### nahrát mapy ze serveru do comboboxu
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ for row in range(0, len(data)):
|
|
|
+ self.dlg.comboBox_loadMap.addItem(data[row]['name'])
|
|
|
+
|
|
|
+ self.dlg.pushButton_loadMap.clicked.connect(lambda: self.readMapJson(self.dlg.comboBox_loadMap.currentText(), 'WMS'))
|
|
|
+ self.dlg.pushButton_loadMapWFS.clicked.connect(lambda: self.readMapJson(self.dlg.comboBox_loadMap.currentText(), 'WFS'))
|
|
|
+ self.dlg.pushButton_loadMapWFS.hide()
|
|
|
+ self.dlg.pushButton_loadMap.hide()
|
|
|
+ self.dlg.comboBox_loadMap.hide()
|
|
|
+ #############
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ self.dlg.pushButton_deleteLayers.setEnabled(False)
|
|
|
+ self.dlg.listWidget_listLayers.itemClicked.connect(self.showSmallThumbnail)
|
|
|
+ # self.dlg.listWidget_listLayers.itemClicked.connect(self.showThumbnail)
|
|
|
+ self.dlg.listWidget.itemClicked.connect(self.enableButton)
|
|
|
+ self.dlg.pushButton_deleteLayers.clicked.connect(lambda: self.deteteLayerFromComposite(self.dlg.listWidget.currentRow(),self.dlg.listWidget_listLayers.currentRow(), self.dlg.listWidget_listLayers.currentItem().text()))
|
|
|
+ self.dlg.show()
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+
|
|
|
+ self.dlg.pushButton_down.setStyleSheet("#pushButton_down {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_down:hover{background: #66ab27 ;}#pushButton_down:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_up.setStyleSheet("#pushButton_up {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_up:hover{background: #66ab27 ;}#pushButton_up:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}#pushButton_close:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_deleteLayers.setStyleSheet("#pushButton_deleteLayers {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_deleteLayers:hover{background: #66ab27 ;}#pushButton_deleteLayers:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_deleteMap.setStyleSheet("#pushButton_deleteMap {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_deleteMap:hover{background: #66ab27 ;}#pushButton_deleteMap:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_addRaster.setStyleSheet("#pushButton_addRaster {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_addRaster:hover{background: #66ab27 ;}#pushButton_addRaster:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_addMap.setStyleSheet("#pushButton_addMap {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_addMap:hover{background: #66ab27 ;}#pushButton_addMap:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_editMeta.setStyleSheet("#pushButton_editMeta {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_editMeta:hover{background: #66ab27 ;}#pushButton_editMeta:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_loadMapWFS.setStyleSheet("#pushButton_loadMapWFS {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_loadMapWFS:hover{background: #66ab27 ;}#pushButton_loadMapWFS:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_loadMap.setStyleSheet("#pushButton_loadMap {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_loadMap:hover{background: #66ab27 ;}#pushButton_loadMap:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ result = self.dlg.exec_()
|
|
|
+ def run_DeleteMapDialog(self):
|
|
|
+ self.dlg = DeleteMapDialog()
|
|
|
+ self.refreshListWidgetMaps()
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.enableButton)
|
|
|
+ self.dlg.pushButton.clicked.connect(lambda: self.deleteMapFromServer(self.dlg.treeWidget.selectedItems()[0].text(0)))
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ self.dlg.show()
|
|
|
+ result = self.dlg.exec_()
|
|
|
+ def run_ImportLayerDialog(self):
|
|
|
+ self.dlg = ImportLayerDialog()
|
|
|
+
|
|
|
+ # self.dlg.pushButton.clicked.connect(lambda: self.postRequest(self.dlg.treeWidget.currentItem().text(0)))
|
|
|
+
|
|
|
+ self.dlg.pushButton.clicked.connect(lambda: self.callPostRequest(self.dlg.treeWidget.selectedItems()))
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ # self.dlg.treeWidget.itemClicked.connect(self.enableButton)
|
|
|
+ self.dlg.treeWidget.itemPressed.connect(self.enableButtonImport)
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.onItemClicked)
|
|
|
+ layers = QgsProject.instance().mapLayers().values()
|
|
|
+
|
|
|
+ for layer in layers:
|
|
|
+ if (layer.type() == QgsMapLayer.VectorLayer):
|
|
|
+ layerType = 'vector layer'
|
|
|
+ else:
|
|
|
+ layerType = 'raster layer'
|
|
|
+ item = QTreeWidgetItem([layer.name(), layerType])
|
|
|
+ self.dlg.treeWidget.addTopLevelItem(item)
|
|
|
+ self.dlg.setWindowModality(Qt.ApplicationModal)
|
|
|
+
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
|
|
|
+ self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+ self.dlg.show()
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ result = self.dlg.exec_()
|
|
|
+ def run_login(self):
|
|
|
+ self.dlg = ConnectionManagerDialog()
|
|
|
+ self.dlg.show()
|
|
|
+ self.dlg.pushButton_Connect.setEnabled(False)
|
|
|
+ if (os.path.isfile(os.getenv("HOME") + os.sep + ".layman" + os.sep +'layman_user.INI')):
|
|
|
+ config = self.loadIni()
|
|
|
+ if len(config['DEFAULT']['login']) > 0:
|
|
|
+ self.Agrimail = config['DEFAULT']['login']
|
|
|
+ self.dlg.pushButton_Connect.setEnabled(True)
|
|
|
+ self.dlg.lineEdit_userName.setText(config['DEFAULT']['login'] + "@lesprojekt.cz")
|
|
|
+ self.dlg.lineEdit_AgriID.setText(config['DEFAULT']['id'])
|
|
|
+ else:
|
|
|
+ try:
|
|
|
+ os.makedirs(os.getenv("HOME") + os.sep + ".layman")
|
|
|
+ except:
|
|
|
+ print("layman directory already exists")
|
|
|
+ self.dlg.lineEdit_userName.setText("@lesprojekt.cz")
|
|
|
+ self.dlg.pushButton_Connect.setEnabled(True)
|
|
|
+ self.dlg.pushButton_ttt.hide()
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.lineEdit_userName.textChanged.connect(self.checkUsername)
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ self.dlg.pushButton_Connect.clicked.connect(lambda: self.openAuthLiferayUrl())
|
|
|
+ self.dlg.pushButton_Continue.clicked.connect(lambda: self.getToken())
|
|
|
+ self.dlg.pushButton_Continue.setEnabled(False)
|
|
|
+ self.dlg.pushButton_ttt.clicked.connect(lambda: self.printVariables())
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}")
|
|
|
+ self.dlg.pushButton_Connect.setStyleSheet("#pushButton_Connect {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_Connect:hover{background: #66ab27 ;}")
|
|
|
+ self.dlg.pushButton_Continue.setStyleSheet("#pushButton_Continue {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_Continue:hover{background: #66ab27 ;} #pushButton_Continue:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+ result = self.dlg.exec_()
|
|
|
+ def run_AddMapDialog(self):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps'
|
|
|
+ print(url)
|
|
|
+ r = requests.get(url = url)
|
|
|
+ print(r.content)
|
|
|
+ data = r.json()
|
|
|
+ self.dlg = AddMapDialog()
|
|
|
+
|
|
|
+ for row in range(0, len(data)):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+data[row]['name']+'/file'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ # print(r.content)
|
|
|
+ d = r.json()
|
|
|
+ print(d['title'])
|
|
|
+ # item = QTreeWidgetItem([data[row]['name'], data[row]['url'], data[row]['uuid']])
|
|
|
+ item = QTreeWidgetItem([d['title']])
|
|
|
+ self.dlg.treeWidget.addTopLevelItem(item)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ self.dlg.pushButton_mapWFS.setEnabled(False)
|
|
|
+ self.dlg.label_info.hide()
|
|
|
+
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.showThumbnailMap)
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.enableButton)
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.enableLoadMapButtons)
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton.clicked.connect(lambda: self.readMapJson(self.dlg.treeWidget.selectedItems()[0].text(0), 'WMS'))
|
|
|
+ self.dlg.pushButton_mapWFS.clicked.connect(lambda: self.readMapJson(self.dlg.treeWidget.selectedItems()[0].text(0), 'WFS'))
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+
|
|
|
+ self.dlg.pushButton_mapWFS.setStyleSheet("#pushButton_mapWFS {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_mapWFS:hover{background: #66ab27 ;}#pushButton_mapWFS:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}#pushButton_close:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+ self.dlg.show()
|
|
|
+ result = self.dlg.exec_()
|
|
|
+ def run_AddLayerDialog(self):
|
|
|
+ if not self.loadedInMemory:
|
|
|
+ self.loadAllComposites()
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ self.dlg = AddLayerDialog()
|
|
|
+ self.dlg.pushButton_layerRedirect.hide()
|
|
|
+ self.dlg.pushButton_layerRedirect.setEnabled(False)
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ self.dlg.pushButton_wfs.setEnabled(False)
|
|
|
+ self.dlg.pushButton_delete.setEnabled(False)
|
|
|
+
|
|
|
+ for row in range(0, len(data)):
|
|
|
+ item = QTreeWidgetItem([data[row]['name']])
|
|
|
+ self.dlg.treeWidget.addTopLevelItem(item)
|
|
|
+ self.dlg.pushButton_delete.clicked.connect(lambda: self.layerDelete(self.dlg.treeWidget.selectedItems()[0].text(0)))
|
|
|
+ self.dlg.pushButton_layerRedirect.clicked.connect(lambda: self.layerInfoRedirect(self.dlg.treeWidget.selectedItems()[0].text(0)))
|
|
|
+ self.dlg.pushButton.clicked.connect(lambda: self.readLayerJson(self.dlg.treeWidget.selectedItems()[0].text(0), "WMS"))
|
|
|
+ self.dlg.pushButton_wfs.clicked.connect(lambda: self.readLayerJson(self.dlg.treeWidget.selectedItems()[0].text(0), "WFS"))
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.showThumbnail)
|
|
|
+ self.dlg.treeWidget.itemClicked.connect(self.enableDeleteButton)
|
|
|
+ self.dlg.pushButton_close.clicked.connect(lambda: self.dlg.close())
|
|
|
+ self.dlg.setWindowModality(Qt.ApplicationModal)
|
|
|
+
|
|
|
+ self.dlg.pushButton_delete.setStyleSheet("#pushButton_delete {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_delete:hover{background: #66ab27 ;}#pushButton_delete:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_close.setStyleSheet("#pushButton_close {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_close:hover{background: #66ab27 ;}#pushButton_close:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_delete.setStyleSheet("#pushButton_delete {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_delete:hover{background: #66ab27 ;}#pushButton_delete:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton.setStyleSheet("#pushButton {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton:hover{background: #66ab27 ;}#pushButton:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.pushButton_wfs.setStyleSheet("#pushButton_wfs {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} #pushButton_wfs:hover{background: #66ab27 ;}#pushButton_wfs:disabled{background: #64818b ;}")
|
|
|
+ self.dlg.setStyleSheet("#DialogBase {background: #f0f0f0 ;}")
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.show()
|
|
|
+ result = self.dlg.exec_()
|
|
|
+ def showExistingLayers(self,x):
|
|
|
+
|
|
|
+ self.dlg.listWidget_listLayers.clear()
|
|
|
+ for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
|
|
|
+
|
|
|
+ self.dlg.listWidget_listLayers.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
|
|
|
+ #--------------------------- slots---------------------
|
|
|
+ # @QtCore.pyqtSlot(QtWidgets.QTreeWidgetItem, int)
|
|
|
+ def onItemClicked(self, it, col):
|
|
|
+ if (it.text(1) == 'raster layer'):
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ else:
|
|
|
+ self.dlg.pushButton.setEnabled(True)
|
|
|
+ def setExtent(self, it, col):
|
|
|
+ layer = QgsProject.instance().mapLayersByName(it.text(0))
|
|
|
+ ext = layer[0].extent()
|
|
|
+ xmin = ext.xMinimum()
|
|
|
+ xmax = ext.xMaximum()
|
|
|
+ ymin = ext.yMinimum()
|
|
|
+ ymax = ext.yMaximum()
|
|
|
+ self.dlg.lineEdit_3.setText(str(xmin))
|
|
|
+ self.dlg.lineEdit_4.setText(str(xmax))
|
|
|
+ self.dlg.lineEdit_5.setText(str(ymin))
|
|
|
+ self.dlg.lineEdit_6.setText(str(ymax))
|
|
|
+ self.dlg.label_4.setText("Extent of canvas: " + it.text(0))
|
|
|
+
|
|
|
+ def enableDeleteButton(self, item, col):
|
|
|
+ self.dlg.pushButton.setEnabled(True)
|
|
|
+ self.dlg.pushButton_wfs.setEnabled(True)
|
|
|
+ self.dlg.pushButton_layerRedirect.setEnabled(True)
|
|
|
+ self.dlg.pushButton_delete.setEnabled(True)
|
|
|
+
|
|
|
+ def enableButton(self, item, col):
|
|
|
+
|
|
|
+
|
|
|
+ self.dlg.pushButton.setEnabled(True)
|
|
|
+ self.dlg.pushButton_mapWFS.setEnabled(True)
|
|
|
+ self.dlg.pushButton_deleteLayers.setEnabled(True)
|
|
|
+ self.dlg.pushButton_editMeta.setEnabled(True)
|
|
|
+ self.dlg.pushButton_addRaster.setEnabled(True)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def checkUsername(self, name):
|
|
|
+ n = name.split("@")
|
|
|
+ if(len(n[0]) > 0):
|
|
|
+ self.dlg.pushButton_Connect.setEnabled(True)
|
|
|
+ self.Agrimail = n[0]
|
|
|
+ else:
|
|
|
+ self.dlg.pushButton_Connect.setEnabled(False)
|
|
|
+
|
|
|
+
|
|
|
+ def checkLoadedMap(self, name):
|
|
|
+ print(self.compositeList)
|
|
|
+ loaded = False
|
|
|
+ for i in range (0, len(self.compositeList)):
|
|
|
+ if self.compositeList[i]['name'] == name:
|
|
|
+ loaded = True
|
|
|
+
|
|
|
+ return loaded
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def enableLoadMapButtons(self, item):
|
|
|
+ self.dlg.pushButton_mapWFS.setEnabled(True)
|
|
|
+ def enableButtonImport(self, item, column):
|
|
|
+ if (len(self.dlg.treeWidget.selectedItems()) > 0):
|
|
|
+ self.dlg.pushButton.setEnabled(True)
|
|
|
+ else:
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+
|
|
|
+
|
|
|
+ def enableButton(self, item):
|
|
|
+ try: ## addMap nemá combobox
|
|
|
+ if (self.dlg.mMapLayerComboBox.count() > 0):
|
|
|
+ self.dlg.pushButton.setEnabled(True)
|
|
|
+ self.dlg.pushButton_mapWFS.setEnabled(True)
|
|
|
+ else:
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ except:
|
|
|
+ self.dlg.pushButton.setEnabled(True) ## addMap nemá combobox nastavujeme funkční tlačítko
|
|
|
+
|
|
|
+ try:
|
|
|
+ self.dlg.pushButton_deleteLayers.setEnabled(True) # pro formulář importMap
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+ def listCompositeLayers(self, it):
|
|
|
+ self.dlg.listWidget_listLayers2.clear()
|
|
|
+ for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
|
|
|
+
|
|
|
+ self.dlg.listWidget_listLayers2.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
|
|
|
+ def deleteLayerThrowCompositions(self, name):
|
|
|
+ for x in range (0,len(self.compositeList)):
|
|
|
+
|
|
|
+ for i in range (0,len(self.compositeList[x]['layers'])):
|
|
|
+ if (name == self.compositeList[x]['layers'][i]['params']['LAYERS']):
|
|
|
+ inComposite = True
|
|
|
+ print(self.compositeList[x]['layers'][i]['params']['LAYERS'])
|
|
|
+ self.deteteLayerFromComposite(x, i, name)
|
|
|
+ def checkLayersInComopsitions(self, name):
|
|
|
+ inComposite = False
|
|
|
+ for x in range (0,len(self.compositeList)):
|
|
|
+
|
|
|
+ for i in range (0,len(self.compositeList[x]['layers'])):
|
|
|
+ if (name == self.compositeList[x]['layers'][i]['params']['LAYERS']):
|
|
|
+ inComposite = True
|
|
|
+ print(self.compositeList[x]['layers'][i]['params']['LAYERS'])
|
|
|
+ return inComposite
|
|
|
+
|
|
|
+
|
|
|
+ def refreshCompositeList(self):
|
|
|
+ self.dlg.listWidget.clear()
|
|
|
+ print (len(self.compositeList))
|
|
|
+
|
|
|
+ for i in range (0, len(self.compositeList)):
|
|
|
+ # self.dlg.listWidget.addItem(self.compositeList[i]['name'])
|
|
|
+ self.dlg.listWidget.addItem(self.compositeList[i]['title'])
|
|
|
+
|
|
|
+
|
|
|
+ def refreshLayerList(self):
|
|
|
+ self.dlg.listWidget_listLayers.clear()
|
|
|
+ for i in range (0,len(self.compositeList[self.dlg.listWidget.currentRow()]['layers'])):
|
|
|
+ self.dlg.listWidget_listLayers.addItem(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
|
|
|
+ print(self.compositeList[self.dlg.listWidget.currentRow()]['layers'][i]['params']['LAYERS'])
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def refreshListWidgetMaps(self):
|
|
|
+ self.dlg.treeWidget.clear()
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps'
|
|
|
+ print(url)
|
|
|
+ r = requests.get(url = url)
|
|
|
+ #print(r.content())
|
|
|
+ data = r.json()
|
|
|
+
|
|
|
+ for row in range(0, len(data)):
|
|
|
+ item = QTreeWidgetItem([data[row]['name']])
|
|
|
+ self.dlg.treeWidget.addTopLevelItem(item)
|
|
|
+
|
|
|
+ def showAddMapDialog(self):
|
|
|
+ self.old_dlg = self.dlg
|
|
|
+ self.run_CreateCompositeDialog(True)
|
|
|
+
|
|
|
+
|
|
|
+ ### connect
|
|
|
+ def afterCloseCompositeDialog(self):
|
|
|
+ self.dlg = self.old_dlg
|
|
|
+ self.refreshCompositeList()
|
|
|
+
|
|
|
+ def afterCloseEditMapDialog(self):
|
|
|
+ self.dlg = self.old_dlg
|
|
|
+
|
|
|
+ def showEditMapDialog(self, x):
|
|
|
+ self.old_dlg = self.dlg
|
|
|
+ self.run_EditMap(x)
|
|
|
+ ############### pravdepodobne půjde smazat
|
|
|
+ def refreshItems(self):
|
|
|
+
|
|
|
+ self.dlg.listWidget_listLayers.clear()
|
|
|
+ for i in range (0,len(self.compositeList)):
|
|
|
+ # self.dlg.listWidget_listLayers.addItem(self.compositeList[i]['name'])
|
|
|
+ self.dlg.listWidget_listLayers.addItem(self.compositeList[i]['title'])
|
|
|
+
|
|
|
+ def saveEditedToComposite(self,x):
|
|
|
+ self.compositeList[x]['abstract'] = self.dlg.lineEdit_abstract.text()
|
|
|
+ self.compositeList[x]['title'] = self.dlg.lineEdit_title.text()
|
|
|
+
|
|
|
+ def layerDelete(self, name):
|
|
|
+ if (self.checkLayersInComopsitions(name) == True):
|
|
|
+ msgbox = QMessageBox(QMessageBox.Question, "Delete layer", "This layers is included in other compositions. It will be delete from every composition.")
|
|
|
+ msgbox.addButton(QMessageBox.Yes)
|
|
|
+ msgbox.addButton(QMessageBox.No)
|
|
|
+ msgbox.setDefaultButton(QMessageBox.No)
|
|
|
+ reply = msgbox.exec()
|
|
|
+ if (reply == QMessageBox.Yes):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+name
|
|
|
+ response = requests.delete(url, headers = self.authHeader)
|
|
|
+ print(response.content)
|
|
|
+ print(response)
|
|
|
+ self.addLayerRefresh()
|
|
|
+ self.deleteLayerThrowCompositions(name)
|
|
|
+
|
|
|
+ else:
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+name
|
|
|
+ response = requests.delete(url, headers = self.authHeader)
|
|
|
+ print(response.content)
|
|
|
+ print(response)
|
|
|
+ self.addLayerRefresh()
|
|
|
+ def addLayerRefresh(self):
|
|
|
+ self.dlg.treeWidget.clear()
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ for row in range(0, len(data)):
|
|
|
+ item = QTreeWidgetItem([data[row]['name']])
|
|
|
+ self.dlg.treeWidget.addTopLevelItem(item)
|
|
|
+ def checkIfMapExist(self, name):
|
|
|
+ url = "http://layman.lesprojekt.cz/rest/"+self.laymanUsername+"/maps/"+str(name)+"/file"
|
|
|
+ r = requests.get(url)
|
|
|
+ print(r.content)
|
|
|
+ if (r.status_code == 404):
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ return True
|
|
|
+
|
|
|
+ def reorderLayers(self, pos, order, x):
|
|
|
+ self.compositeList[x]['layers']
|
|
|
+ i = 0
|
|
|
+
|
|
|
+ for lay in self.compositeList[x]['layers']:
|
|
|
+ #print (lay)
|
|
|
+ if i == pos:
|
|
|
+
|
|
|
+ pom = self.compositeList[x]['layers'][i]
|
|
|
+ self.compositeList[x]['layers'][i] = self.compositeList[x]['layers'][i + order]
|
|
|
+ self.compositeList[x]['layers'][i + order] = pom
|
|
|
+
|
|
|
+ i = i + 1
|
|
|
+ print(self.compositeList[x]['layers'])
|
|
|
+ self.importMap(x, 'mod')
|
|
|
+ self.refreshLayerList()
|
|
|
+ self.dlg.listWidget_listLayers.setCurrentRow(pos + order)
|
|
|
+
|
|
|
+ def showThumbnail(self, it):
|
|
|
+ try:
|
|
|
+ layer = it.text(0) ##pro QTreeWidget
|
|
|
+ except:
|
|
|
+ layer = it.text()##pro listWidget
|
|
|
+ try:
|
|
|
+ url = self.URI+'/rest/' +self.laymanUsername+'/layers/'+str(layer)+'/thumbnail'
|
|
|
+ data = urlopen(url).read()
|
|
|
+ pixmap = QPixmap(200, 200)
|
|
|
+ pixmap.loadFromData(data)
|
|
|
+ smaller_pixmap = pixmap.scaled(200, 200, Qt.KeepAspectRatio, Qt.FastTransformation)
|
|
|
+ self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
|
|
|
+ self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
|
|
|
+ except:
|
|
|
+ self.dlg.label_thumbnail.setText(' Unable to load thumbnail.')
|
|
|
+ def showSmallThumbnail(self, it):
|
|
|
+ try:
|
|
|
+ layer = it.text(0) ##pro QTreeWidget
|
|
|
+ except:
|
|
|
+ layer = it.text()##pro listWidget
|
|
|
+ try:
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layer)+'/thumbnail'
|
|
|
+ data = urlopen(url).read()
|
|
|
+ pixmap = QPixmap(170, 170)
|
|
|
+ pixmap.loadFromData(data)
|
|
|
+ smaller_pixmap = pixmap.scaled(170, 170, Qt.KeepAspectRatio, Qt.FastTransformation)
|
|
|
+ self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
|
|
|
+ self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
|
|
|
+ except:
|
|
|
+ self.dlg.label_thumbnail.setText(' Unable to load thumbnail.')
|
|
|
+
|
|
|
+ def showThumbnailMap(self, it):
|
|
|
+ try:
|
|
|
+ map = it.text(0) ##pro QTreeWidget
|
|
|
+ except:
|
|
|
+ map = it.text()##pro listWidget
|
|
|
+
|
|
|
+ try:
|
|
|
+ map = self.removeUnacceptableChars(str(map))
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+str(map)+'/thumbnail'
|
|
|
+ print(url)
|
|
|
+ data = urlopen(url).read()
|
|
|
+ pixmap = QPixmap(100, 100)
|
|
|
+ pixmap.loadFromData(data)
|
|
|
+ smaller_pixmap = pixmap.scaled(100, 100, Qt.KeepAspectRatio, Qt.FastTransformation)
|
|
|
+ self.dlg.label_thumbnail.setPixmap(smaller_pixmap)
|
|
|
+ # self.dlg.label_thumbnail.setAlignment(Qt.AlignCenter)
|
|
|
+ except:
|
|
|
+ self.dlg.label_thumbnail.setText(' Unable to load thumbnail.')
|
|
|
+
|
|
|
+ def checkNameCreateMap(self):
|
|
|
+ text = self.dlg.lineEdit_2.text()
|
|
|
+ text = self.removeUnacceptableChars(text)
|
|
|
+ print(text)
|
|
|
+ if (self.checkIfMapExist(text)):
|
|
|
+ self.dlg.pushButton_CreateComposition.setEnabled(False)
|
|
|
+ self.dlg.label_info.show()
|
|
|
+
|
|
|
+ else:
|
|
|
+ self.dlg.pushButton_CreateComposition.setEnabled(True)
|
|
|
+ self.dlg.label_info.hide()
|
|
|
+ #----------------------------------------------------------
|
|
|
+ def readLayerJson(self,layerName, service):
|
|
|
+ if self.checkLayerOnLayman(layerName):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layerName
|
|
|
+ print (url)
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ if (service == "WMS"):
|
|
|
+ print("loading WMS")
|
|
|
+ print (data['wms']['url'])
|
|
|
+ wmsUrl = data['wms']['url']
|
|
|
+ format = 'png'
|
|
|
+ epsg = 'EPSG:4326'
|
|
|
+ self.loadWms(wmsUrl, layerName, format, epsg)
|
|
|
+ if (service == "WFS"):
|
|
|
+ wfsUrl = data['wfs']['url']
|
|
|
+ print("loading WFS")
|
|
|
+ self.loadWfs(wfsUrl, layerName)
|
|
|
+ else:
|
|
|
+ QMessageBox.information(None, "Layman", "Something went wrong with this layer: "+layerName)
|
|
|
+ def loadAllComposites(self):
|
|
|
+ url = self.URI+'/rest/' + self.laymanUsername + '/maps'
|
|
|
+ try:
|
|
|
+ r = requests.get(url = url)
|
|
|
+ except:
|
|
|
+ QMessageBox.information(None, "Error", "Connection with server failed!.")
|
|
|
+ data = r.json()
|
|
|
+ print(data)
|
|
|
+ for i in data:
|
|
|
+ print(i['name'])
|
|
|
+ url = self.URI+'/rest/' + self.laymanUsername + '/maps/'+i['name']+'/file'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ map = r.json()
|
|
|
+ self.compositeList.append (map)
|
|
|
+ self.loadedInMemory = True
|
|
|
+
|
|
|
+ def readMapJson(self,name, service):
|
|
|
+ nameWithDiacritics = name
|
|
|
+ name = self.removeUnacceptableChars(name)
|
|
|
+ print(name)
|
|
|
+ print("readMapJson " + name)
|
|
|
+ if not self.checkLoadedMap(name): ## je nactena mapa?
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name +'/file'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ print(data)
|
|
|
+
|
|
|
+ self.addComposite(data,service, name)
|
|
|
+ try:
|
|
|
+ self.refreshCompositeList() ## pouze pro import Form
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name +'/file'
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ self.loadService(data,service, name)
|
|
|
+
|
|
|
+ # QMessageBox.information(None, "Message", "This map is already loaded in memory. Loading only layers to canvas")
|
|
|
+
|
|
|
+
|
|
|
+ def deleteMapFromServer(self,name):
|
|
|
+
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name
|
|
|
+ response = requests.delete(url, headers = self.authHeader)
|
|
|
+ print(response)
|
|
|
+ QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
|
|
|
+ # self.refreshMapList()
|
|
|
+ self.refreshListWidgetMaps() ## pro treewidget
|
|
|
+
|
|
|
+
|
|
|
+ def deleteMap(self,name, x):
|
|
|
+ name = self.removeUnacceptableChars(name)
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name
|
|
|
+ response = requests.delete(url, headers = self.authHeader)
|
|
|
+ print(response)
|
|
|
+ print(response.content)
|
|
|
+ QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
|
|
|
+ del (self.compositeList[x])
|
|
|
+ self.refreshCompositeList()## pro import map form
|
|
|
+ self.dlg.listWidget_listLayers.clear()
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def deleteMapandLayers(self,name, x):
|
|
|
+ try:
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/maps/'+name
|
|
|
+ response = requests.delete(url, headers = self.authHeader)
|
|
|
+ QMessageBox.information(None, "Message", "Composition deleted sucessfully.")
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ except:
|
|
|
+ QMessageBox.information(None, "Warning", "Deleting composition failed.")
|
|
|
+ #self.refreshItems()
|
|
|
+ self.deleteMapFromCanvas(x)
|
|
|
+ self.dlg.listWidget_listLayers.clear()
|
|
|
+ self.dlg.pushButton_deleteLayers.setEnabled(False)
|
|
|
+ self.dlg.pushButton.setEnabled(False)
|
|
|
+ self.dlg.pushButton_deleteMap.setEnabled(False)
|
|
|
+ self.refreshCompositeList()
|
|
|
+
|
|
|
+ def deleteMapFromCanvas(self, x):
|
|
|
+ for i in range (0,len(self.compositeList[x]['layers'])): #[0]['params']['LAYERS']:
|
|
|
+ name = self.compositeList[x]['layers'][i]['params']['LAYERS']
|
|
|
+ lay = QgsProject.instance().mapLayersByName(name)[0]
|
|
|
+ if (lay != None and lay.type() != QgsMapLayer.VectorLayer):
|
|
|
+ QgsProject.instance().removeMapLayer(lay.id())
|
|
|
+ del (self.compositeList[x])
|
|
|
+
|
|
|
+ def deleteLayerFromCanvas(self, name):
|
|
|
+ lay = QgsProject.instance().mapLayersByName(name)[0]
|
|
|
+ if (lay != None and lay.type() != QgsMapLayer.VectorLayer):
|
|
|
+ QgsProject.instance().removeMapLayer(lay.id())
|
|
|
+
|
|
|
+
|
|
|
+ def getSelectedLayers(self):
|
|
|
+ arr = self.dlg.listWidget_listLayers2.selectedItems()
|
|
|
+ layers = []
|
|
|
+ for a in arr:
|
|
|
+ layer = QgsProject.instance().mapLayersByName(a.text())
|
|
|
+ for lay in layer:
|
|
|
+
|
|
|
+ if (lay.type() == QgsMapLayer.VectorLayer):
|
|
|
+ layers.append(lay)
|
|
|
+
|
|
|
+ return layers
|
|
|
+ def run_getLayer(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:
|
|
|
+ self.first_start = False
|
|
|
+
|
|
|
+
|
|
|
+ self.dlgGetLayers.items.clear()
|
|
|
+ # show the dialog
|
|
|
+ self.dlgGetLayers.show()
|
|
|
+ data= self.getExistingLayers()
|
|
|
+ for x in range(len(data)):
|
|
|
+ print(data[x]['name'])
|
|
|
+ self.dlgGetLayers.items.addItem(data[x]['name'])
|
|
|
+ # Run the dialog event loop
|
|
|
+ print (self.dlgGetLayers)
|
|
|
+ result = self.dlgGetLayers.exec_()
|
|
|
+
|
|
|
+
|
|
|
+ # See if OK was pressed
|
|
|
+ if result:
|
|
|
+ # Do something useful here - delete the line containing pass and
|
|
|
+ # substitute with your code.
|
|
|
+
|
|
|
+ print ("test tlacitka")
|
|
|
+
|
|
|
+ def onClosePlugin(self):
|
|
|
+ """Cleanup necessary items here when plugin dockwidget is closed"""
|
|
|
+
|
|
|
+ #print "** CLOSING Atlas"
|
|
|
+
|
|
|
+ # disconnects
|
|
|
+ self.dockwidget.closingPlugin.disconnect(self.onClosePlugin)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ self.pluginIsActive = False
|
|
|
+
|
|
|
+
|
|
|
+ def unload(self):
|
|
|
+ """Removes the plugin menu item and icon from QGIS GUI."""
|
|
|
+
|
|
|
+ #print "** UNLOAD Atlas"
|
|
|
+
|
|
|
+ for action in self.actions:
|
|
|
+ self.iface.removePluginMenu(
|
|
|
+ self.tr(u'&Atlas'),
|
|
|
+ action)
|
|
|
+ self.iface.removeToolBarIcon(action)
|
|
|
+ # remove the toolbar
|
|
|
+ del self.toolbar
|
|
|
+
|
|
|
+ #--------------------------------------------------------------------------
|
|
|
+ def bounds(self, layers):
|
|
|
+
|
|
|
+ extent = None
|
|
|
+ for layer in layers:
|
|
|
+ if layer.type() == 0:
|
|
|
+ transform = QgsCoordinateTransform(layer.crs(), QgsCoordinateReferenceSystem('EPSG:4326'), QgsProject.instance()) # WGS 84 / UTM zone 33N
|
|
|
+ try:
|
|
|
+ layerExtent = transform.transform(layer.extent())
|
|
|
+ except QgsCsException:
|
|
|
+ print("exception in transform layer srs")
|
|
|
+ layerExtent = QgsRectangle(-180, -90, 180, 90)
|
|
|
+ if extent is None:
|
|
|
+ extent = layerExtent
|
|
|
+ else:
|
|
|
+ extent.combineExtentWith(layerExtent)
|
|
|
+
|
|
|
+ return (extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum())
|
|
|
+ def copySymbols(self,symbol, tempPath, fileNames):
|
|
|
+ for i in range(symbol.symbolLayerCount()):
|
|
|
+ sl = symbol.symbolLayer(i)
|
|
|
+ if isinstance(sl, QgsSvgMarkerSymbolLayer):
|
|
|
+ symbolPath = sl.path();
|
|
|
+ shutil.copy(symbolPath, tempPath)
|
|
|
+ print("Copying " + str(sl.path()))
|
|
|
+ fileNames.append(tempPath + os.sep + os.path.basename(symbolPath))
|
|
|
+ else:
|
|
|
+ print("Ignoring " + str(sl))
|
|
|
+
|
|
|
+ def setDefaultExtent (self, ext):
|
|
|
+ self.dlg.lineEdit_3.setText(str(ext.xMinimum()))
|
|
|
+ self.dlg.lineEdit_4.setText(str(ext.xMaximum()))
|
|
|
+ self.dlg.lineEdit_5.setText(str(ext.yMinimum()))
|
|
|
+ self.dlg.lineEdit_6.setText(str(ext.yMaximum()))
|
|
|
+
|
|
|
+
|
|
|
+ def loadJsonLayer(self, fileName):
|
|
|
+ name = (os.path.splitext(os.path.basename(fileName))[0])
|
|
|
+ vlayer = QgsVectorLayer(fileName, name,"ogr")
|
|
|
+ sldPath = os.path.splitext(fileName[:-4])[0] + ".sld"
|
|
|
+ print (sldPath)
|
|
|
+ exists = os.path.isfile(sldPath)
|
|
|
+ if (exists):
|
|
|
+ vlayer.loadSldStyle(os.path.splitext(fileName)[0]+ ".sld")
|
|
|
+ print("sld loaded")
|
|
|
+ QgsProject.instance().addMapLayer(vlayer)
|
|
|
+ vlayer.triggerRepaint()
|
|
|
+ def checkLoadedLayer(self):
|
|
|
+ layers = iface.layerTreeView().selectedLayers()
|
|
|
+ if (len(layers) > 0):
|
|
|
+ self.json_export()
|
|
|
+ else:
|
|
|
+ QMessageBox.information(None, "Message", "You must load layer first!")
|
|
|
+ def getEmptyComposite(self, compositeName, compositeTitle):
|
|
|
+ compositeEPSG = "epsg:4326"
|
|
|
+ if (self.dlg.lineEdit_3.text() == "" or self.dlg.lineEdit_4.text() == "" or self.dlg.lineEdit_5.text() == "" or self.dlg.lineEdit_6.text() == ""):
|
|
|
+ ext = iface.mapCanvas().extent()
|
|
|
+ xmin = ext.xMinimum()
|
|
|
+ xmax = ext.xMaximum()
|
|
|
+ ymin = ext.yMinimum()
|
|
|
+ ymax = ext.yMaximum()
|
|
|
+ else:
|
|
|
+ xmin = self.dlg.lineEdit_3.text()
|
|
|
+ xmax = self.dlg.lineEdit_4.text()
|
|
|
+ ymin = self.dlg.lineEdit_5.text()
|
|
|
+ ymax = self.dlg.lineEdit_6.text()
|
|
|
+
|
|
|
+
|
|
|
+ abstract = self.dlg.lineEdit_7.text()
|
|
|
+ comp = {"abstract":abstract,"center":[1672068,6568819],"current_base_layer":{"title":"Composite_base_layer"},"extent":[str(xmin),str(ymin),str(xmax),str(ymax)],"groups":{"guest":"w"},"layers":[],"name":compositeName,"projection":compositeEPSG,"scale":1,"title":compositeTitle,"units":"m","user":{"email":"","name":self.laymanUsername}}
|
|
|
+ self.dlg.close()
|
|
|
+ iface.messageBar().pushWidget(iface.messageBar().createMessage("Atlas:", " Kompozice " + compositeName + " byla úspešně vytvořena."), Qgis.Success, duration=3)
|
|
|
+ return comp
|
|
|
+ def loadLocalFile(self):
|
|
|
+ options = QFileDialog.Options()
|
|
|
+ dialog = QFileDialog()
|
|
|
+ dialog.setStyleSheet("QPushButton {color: #fff !important;text-transform: uppercase; text-decoration: none; background: #72c02c; padding: 20px; border-radius: 50px; display: inline-block; border: none;transition: all 0.4s ease 0s;} QPushButton:hover{background: #66ab27 ;}QPushButton:disabled{background: #64818b ;}");
|
|
|
+ fileName = dialog.getOpenFileName(None,"Load file", "","GeoJson Files (*.geojson);;Json Files (*.json)", options=options)
|
|
|
+ print ("načítám json ze souboru:" + fileName[0])
|
|
|
+ self.loadJsonLayer(fileName[0])
|
|
|
+ def modifyMap(self, x):
|
|
|
+ name = self.removeUnacceptableChars(self.dlg.lineEdit_title.text())
|
|
|
+ #self.compositeList[x]['name'] = self.dlg.lineEdit_name.text()
|
|
|
+ self.compositeList[x]['name'] = name
|
|
|
+ self.compositeList[x]['abstract'] = self.dlg.lineEdit_abstract.text()
|
|
|
+ self.compositeList[x]['title'] = self.dlg.lineEdit_title.text()
|
|
|
+
|
|
|
+
|
|
|
+ print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
|
|
|
+ oldName = self.dlg.lineEdit_name.text()
|
|
|
+ response = requests.delete(self.URI+'/rest/'+self.laymanUsername+'/maps/'+oldName,headers = self.authHeader)
|
|
|
+ print(response.content)
|
|
|
+ self.dlg.close()
|
|
|
+ self.afterCloseEditMapDialog()
|
|
|
+ self.importMap(x, 'mod')
|
|
|
+
|
|
|
+ try:
|
|
|
+ self.refreshCompositeList()
|
|
|
+ iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Map metadata was saved successfully."), Qgis.Success, duration=3)
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ def saveLocalFile(self):
|
|
|
+
|
|
|
+ layer = self.iface.activeLayer()
|
|
|
+ path = iface.activeLayer().dataProvider().dataSourceUri()
|
|
|
+ path = path.split("|")[0].replace("'","")
|
|
|
+ if (layer == None):
|
|
|
+ QMessageBox.information(None, "Message", "You must load layer first!")
|
|
|
+ else:
|
|
|
+ # defaultDir = QDir().home()
|
|
|
+ defaultDir = os.path.dirname(path)
|
|
|
+ print(defaultDir)
|
|
|
+ print(defaultDir +os.sep+ str(layer.name()) + ".geojson")
|
|
|
+ print(QDir().homePath() +os.sep+ str(layer.name()) + ".geojson")
|
|
|
+ dialog = QFileDialog()
|
|
|
+ dialog.setFileMode(1)
|
|
|
+ dialog.setDirectory(defaultDir)
|
|
|
+ print(dialog.directory().path())
|
|
|
+ # layer_name = dialog.getSaveFileName(None, "Save file", QDir().homePath() +os.sep+ str(layer.name()) + ".geojson", "*.geojson")
|
|
|
+ layer_name = dialog.getSaveFileName(None, "Save file", defaultDir +os.sep+ str(layer.name()) + ".geojson", "*.geojson")
|
|
|
+ self.json_export_local(layer_name[0], layer)
|
|
|
+
|
|
|
+ def json_export_local(self, layer_name, lay):
|
|
|
+ import shutil
|
|
|
+ filePath = self.getTempPath(layer_name)
|
|
|
+ ogr_driver_name = "GeoJSON"
|
|
|
+ project = QgsProject.instance()
|
|
|
+ fileNames = []
|
|
|
+ ## zde musí být zajištěna vektorová vrstva
|
|
|
+ layer = lay
|
|
|
+ layerType = layer.type()
|
|
|
+ if layerType == QgsMapLayer.VectorLayer:
|
|
|
+
|
|
|
+ renderer = layer.renderer()
|
|
|
+ hasIcon = False
|
|
|
+ if isinstance(renderer, QgsSingleSymbolRenderer):
|
|
|
+
|
|
|
+ self.copySymbols(renderer.symbol(), tempfile.gettempdir(), fileNames)
|
|
|
+ hasIcon = True
|
|
|
+
|
|
|
+
|
|
|
+ layerCrs = qgis.utils.iface.activeLayer().crs().authid()
|
|
|
+ crs = QgsCoordinateReferenceSystem(layerCrs)
|
|
|
+ result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, layer_name, "utf-8", crs, ogr_driver_name) # export jsonu do souboru
|
|
|
+ print(result2)
|
|
|
+ if(result2[0] == 2): ## testujeme zda není soubor otevřený v jiném procesu / návratový kod 2
|
|
|
+
|
|
|
+ tempFile = self.getTempPath(os.path.basename(layer_name.replace(".geojson", "") ))
|
|
|
+ print(tempFile)
|
|
|
+ #QMessageBox.information(None, "Layman", "It is not possible overwrite this file. File is already open in other process.")
|
|
|
+ sld_temp_filename = tempFile.replace("geojson", "sld")
|
|
|
+ layer.saveSldStyle(sld_temp_filename)
|
|
|
+ result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, tempFile, "utf-8", crs, ogr_driver_name)
|
|
|
+ print(result2)
|
|
|
+ if(result2[0] == 2):
|
|
|
+ QMessageBox.information(None, "Layman", "It is not possible overwrite this file. File is already open in other process.")
|
|
|
+ return
|
|
|
+ if os.path.basename(layer_name.replace(".geojson", "")) != '':
|
|
|
+ QgsProject.instance().removeMapLayer(layer.id())
|
|
|
+ print(tempFile, layer_name)
|
|
|
+ shutil.copy(tempFile, layer_name)
|
|
|
+ shutil.copy(sld_temp_filename, layer_name.replace(".geojson", ".sld"))
|
|
|
+ self.loadJsonLayer(layer_name)
|
|
|
+
|
|
|
+ else:
|
|
|
+ sld_filename = layer_name.replace("geojson", "sld")
|
|
|
+ result3 = False
|
|
|
+ layer.saveSldStyle(sld_filename)
|
|
|
+
|
|
|
+ def json_export(self, layer_name):
|
|
|
+
|
|
|
+ filePath = self.getTempPath(layer_name)
|
|
|
+ ogr_driver_name = "GeoJSON"
|
|
|
+ project = QgsProject.instance()
|
|
|
+ fileNames = []
|
|
|
+ layer = QgsProject.instance().mapLayersByName(layer_name)[0]
|
|
|
+
|
|
|
+ layerType = layer.type()
|
|
|
+ if layerType == QgsMapLayer.VectorLayer:
|
|
|
+
|
|
|
+ renderer = layer.renderer()
|
|
|
+ hasIcon = False
|
|
|
+ if isinstance(renderer, QgsSingleSymbolRenderer):
|
|
|
+
|
|
|
+ self.copySymbols(renderer.symbol(), tempfile.gettempdir(), fileNames)
|
|
|
+ hasIcon = True
|
|
|
+
|
|
|
+
|
|
|
+ #layerCrs = qgis.utils.iface.activeLayer().crs().authid()
|
|
|
+ layerCrs = layer.crs().authid()
|
|
|
+ crs = QgsCoordinateReferenceSystem(layerCrs)# původně bylo
|
|
|
+ layer_filename = filePath
|
|
|
+ # crs = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
|
|
|
+ ##crs = layer.crs().authid()
|
|
|
+ # tempOut = layer_filename.replace(".geojson", "_2.geojson")
|
|
|
+ result2 = qgis.core.QgsVectorFileWriter.writeAsVectorFormat(layer, layer_filename, "utf-8", crs, ogr_driver_name) # export jsonu do souboru
|
|
|
+ ##transformace
|
|
|
+ # input = tempOut
|
|
|
+ # out = layer_filename
|
|
|
+ # try:
|
|
|
+ # os.remove(layer_filename)
|
|
|
+ # except:
|
|
|
+ # pass
|
|
|
+ ## print("","-f", "Geojson", "-s_srs", layerCrs, "-t_srs", "epsg:4326", out, input)
|
|
|
+ # print("convert")
|
|
|
+ # print(main(["","-f", ogr_driver_name, "-s_srs", "EPSG:5514", "-t_srs", "EPSG:4326", out, input])) ## ogr2ogr
|
|
|
+ ##
|
|
|
+ sld_filename = filePath.replace("geojson", "sld")
|
|
|
+ result3 = False
|
|
|
+ layer.saveSldStyle(sld_filename)
|
|
|
+
|
|
|
+
|
|
|
+ def checkValidAttributes(self, layer_name):
|
|
|
+ layers = QgsProject.instance().mapLayersByName(layer_name)
|
|
|
+ if len(layers) > 1:
|
|
|
+ for l in layers:
|
|
|
+ if (isinstance(l, QgsVectorLayer)):
|
|
|
+ print("xxx")
|
|
|
+ layers.clear()
|
|
|
+ layers.append(l)
|
|
|
+ break
|
|
|
+ isValid = True
|
|
|
+ pom =layers[0].getFeature(1)
|
|
|
+ for nam in pom.fields().names():
|
|
|
+ if (nam == ''):
|
|
|
+ isValid = False
|
|
|
+ return isValid
|
|
|
+
|
|
|
+
|
|
|
+ def checkWgsExtent(self, layer):
|
|
|
+ WgsXmax = 180
|
|
|
+ WgsXmin = -180
|
|
|
+ WgsYmax = 90
|
|
|
+ WgsYmin = -90
|
|
|
+ extent = layer.extent()
|
|
|
+ if (extent.xMaximum() > WgsXmax or extent.xMinimum() < WgsXmin or extent.yMaximum() > WgsYmax or extent.yMinimum() < WgsYmin ):
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ return True
|
|
|
+
|
|
|
+
|
|
|
+ def callPostRequest(self, layers):
|
|
|
+
|
|
|
+ for item in layers:
|
|
|
+ print (item.text(0))
|
|
|
+ self.postRequest(item.text(0))
|
|
|
+ #def transformLayer2(self, layer):
|
|
|
+ # pass
|
|
|
+ def transformLayer(self, layer):
|
|
|
+ layer = iface.activeLayer()
|
|
|
+ crsSrc = layer.crs()
|
|
|
+ print(crsSrc.authid())
|
|
|
+ crsDest = QgsCoordinateReferenceSystem(4326, QgsCoordinateReferenceSystem.EpsgCrsId)
|
|
|
+ print(crsSrc, crsDest)
|
|
|
+ xform = QgsCoordinateTransform(crsSrc, crsDest, 5514, 4326)
|
|
|
+ feats=[]
|
|
|
+
|
|
|
+ if (layer.geometryType() == 0):
|
|
|
+ destLayer = QgsVectorLayer("Point?crs=EPSG:4326","lay","memory")
|
|
|
+ if (layer.geometryType() == 1):
|
|
|
+ destLayer = QgsVectorLayer("Linestring?crs=EPSG:4326","lay","memory")
|
|
|
+ if (layer.geometryType() == 2):
|
|
|
+ destLayer = QgsVectorLayer("Polygon?crs=EPSG:4326","lay","memory")
|
|
|
+
|
|
|
+ for f in layer.getFeatures():
|
|
|
+ g = f.geometry()
|
|
|
+
|
|
|
+ g.transform(xform)
|
|
|
+ print(g)
|
|
|
+ f.setGeometry(g)
|
|
|
+ feats.append(f)
|
|
|
+
|
|
|
+ destLayer.dataProvider().addFeatures(feats)
|
|
|
+ return destLayer
|
|
|
+ def postRequest(self, layer_name):
|
|
|
+ nameCheck = True
|
|
|
+ validExtent = True
|
|
|
+ layers = QgsProject.instance().mapLayersByName(layer_name)
|
|
|
+ layer_name = self.removeUnacceptableChars(layer_name)
|
|
|
+ layers[0].setName(layer_name)
|
|
|
+ if len(layers) > 1:
|
|
|
+ for l in layers:
|
|
|
+ if (isinstance(l, QgsVectorLayer)):
|
|
|
+ layers.clear()
|
|
|
+ layers.append(l)
|
|
|
+ break
|
|
|
+
|
|
|
+ if not (re.match('[a-zA-Z_]{1}', layer_name)): ## nesmí být nesmysl v názvu na prvním místě
|
|
|
+ QMessageBox.information(None, "Layman", "Diacritics or number in first character is not allowed.")
|
|
|
+ nameCheck = False
|
|
|
+ if not (re.match('[a-zA-Z0-9]', layer_name)): ## není povolena diakritika
|
|
|
+ QMessageBox.information(None, "Layman", "Diacritics is not allowed.")
|
|
|
+ nameCheck = False
|
|
|
+
|
|
|
+ print(layer_name)
|
|
|
+ #if (layers[0].crs().authid() != 'EPSG:4323'):
|
|
|
+ # layers[0] = self.transformLayer(layers[0])
|
|
|
+
|
|
|
+ if not self.checkWgsExtent(layers[0]):
|
|
|
+ QMessageBox.information(None, "Layman", "Extent of layer is out of WGS 84 range. (EPSG: 4326)")
|
|
|
+ validExtent = False
|
|
|
+
|
|
|
+ if (nameCheck and validExtent):
|
|
|
+
|
|
|
+ crs = layers[0].crs().authid()
|
|
|
+ crs = "EPSG:4326"
|
|
|
+ data = { 'name' : str(layer_name), 'title' : str(layer_name), 'crs' : str(crs) }
|
|
|
+
|
|
|
+ if (self.checkValidAttributes(layer_name)):
|
|
|
+ if (self.checkExistingLayer(layer_name)):
|
|
|
+ print("vrstva již existuje")
|
|
|
+ msgbox = QMessageBox(QMessageBox.Question, "Layman", "Layer "+layer_name+" already exists in server. Do you want overwrite it´s geometry?")
|
|
|
+ msgbox.addButton(QMessageBox.Yes)
|
|
|
+ msgbox.addButton(QMessageBox.No)
|
|
|
+ msgbox.setDefaultButton(QMessageBox.No)
|
|
|
+ reply = msgbox.exec()
|
|
|
+ if (reply == QMessageBox.Yes):
|
|
|
+ print("vrstva již existuje")
|
|
|
+ self.json_export(layer_name)
|
|
|
+ geoPath = self.getTempPath(layer_name)
|
|
|
+ #try:
|
|
|
+ if (os.path.getsize(geoPath) > self.CHUNK_SIZE):
|
|
|
+ self.postInChunks(layer_name, "patch")
|
|
|
+ else:
|
|
|
+ self.patchLayer(layer_name, data)
|
|
|
+ iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
|
|
|
+ #except:
|
|
|
+ # iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was not imported successfully."), Qgis.Warning, duration=3)
|
|
|
+ else:
|
|
|
+ pass
|
|
|
+ else:
|
|
|
+
|
|
|
+ self.layerName = layer_name
|
|
|
+ # if (self.checkEpsg(layer_name)):
|
|
|
+ if(True): ##Pravděpodobně nebude třeba testovat EPSG, pokud se detekuje, je vrstva transformována.
|
|
|
+ # print (layer_name)
|
|
|
+ self.json_export(layer_name)
|
|
|
+ sldPath = self.getTempPath(self.layerName).replace("geojson", "sld")
|
|
|
+ geoPath = self.getTempPath(self.layerName)
|
|
|
+ if (os.path.getsize(geoPath) > self.CHUNK_SIZE):
|
|
|
+ self.postInChunks(layer_name, "post")
|
|
|
+ else:
|
|
|
+ if(os.path.isfile(sldPath)): ## existuje sld?
|
|
|
+ files = [('file', open(geoPath, 'rb')), ('sld', open(sldPath, 'rb'))]
|
|
|
+ else:
|
|
|
+ files = {'file': (geoPath, open(geoPath, 'rb')),}
|
|
|
+
|
|
|
+ print(files)
|
|
|
+ response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/layers', files=files, data = data, headers = self.authHeader)
|
|
|
+ print(response.content)
|
|
|
+ print(response.status_code)
|
|
|
+ if response.status_code == 200:
|
|
|
+ iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was imported successfully."), Qgis.Success, duration=3)
|
|
|
+ else:
|
|
|
+ iface.messageBar().pushWidget(iface.messageBar().createMessage("Import:", " Layer " + layer_name + " was not imported."), Qgis.Warning, duration=3)
|
|
|
+ else:
|
|
|
+ # QMessageBox.information(None, "Atlas", "Vrstva "+layer_name+" nelze nahrát. Použíjte EPSG:4326 nebo EPSG:3857")
|
|
|
+ QMessageBox.information(None, "Layman", "Use EPSG:4326")
|
|
|
+ else:
|
|
|
+ QMessageBox.information(None, "Layman", "Layer "+layer_name+" does not have attributes!")
|
|
|
+
|
|
|
+ def addExistingLayerToComposite(self, name):
|
|
|
+ x = self.dlg.listWidget.currentRow()
|
|
|
+ if self.checkLayerOnLayman(name):
|
|
|
+ inComposite = name in self.isRasterLayerInComposite(x, name)
|
|
|
+ if not(inComposite):
|
|
|
+ response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(name), verify=False)
|
|
|
+ res = self.fromByteToJson(response.content)
|
|
|
+ print(res)
|
|
|
+ wmsUrl = res['wms']['url']
|
|
|
+
|
|
|
+
|
|
|
+ self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(name),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(name),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
|
|
|
+ self.importMap(x, 'add', 1)
|
|
|
+ self.refreshLayerList()
|
|
|
+ else:
|
|
|
+ QMessageBox.information(None, "Message", "Composition already include layer "+name+"!")
|
|
|
+ else:
|
|
|
+ QMessageBox.information(None, "Layman", "Something went wrong with this layer: "+name)
|
|
|
+
|
|
|
+ def addExistingMapToMemory(self, name):
|
|
|
+ response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/maps/'+str(name), verify=False)
|
|
|
+ res = self.fromByteToJson(response.content)
|
|
|
+ print(res)
|
|
|
+ wmsUrl = res['wms']['url']
|
|
|
+
|
|
|
+ x = self.dlg.listWidget.currentRow()
|
|
|
+
|
|
|
+
|
|
|
+ self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(name),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(name),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
|
|
|
+ self.importMap(x, 'add', 1)
|
|
|
+ self.refreshLayerList()
|
|
|
+
|
|
|
+ def layerInfoRedirect(self, name):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + name
|
|
|
+ print(url)
|
|
|
+ response = requests.get(url)
|
|
|
+ r = self.fromByteToJson(response.content)
|
|
|
+ try:
|
|
|
+ url = r['metadata']['record_url']
|
|
|
+ webbrowser.open(url, new=2) ## redirect na micku pro více info
|
|
|
+ except:
|
|
|
+ QMessageBox.information(None, "Layman", "Link is unavailable.")
|
|
|
+ def checkLayerOnLayman(self, layer_name):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+"/layers/"+layer_name
|
|
|
+ r = requests.get(url = url, verify=False)
|
|
|
+ #print(r.content)
|
|
|
+ data = r.json()
|
|
|
+ try:
|
|
|
+ if data['wms']['status'] == 'NOT_AVAILABLE' or data['wms']['status'] == 'PENDING':
|
|
|
+ return False
|
|
|
+ else:
|
|
|
+ return True
|
|
|
+ except:
|
|
|
+ return True # validní vrstva nemá status
|
|
|
+
|
|
|
+
|
|
|
+ def addLayerToComposite(self,x):
|
|
|
+
|
|
|
+ self.compositeListOld = copy.deepcopy(self.compositeList) ## list pred upravou pro vraceni zmen
|
|
|
+ #layers = self.getSelectedLayers() #odkomentovat pro zapnuti nacitani vrstev z listwidgetu
|
|
|
+ layers = []
|
|
|
+ layers.append(self.dlg.mMapLayerComboBox.currentLayer())
|
|
|
+ successful = 0
|
|
|
+ print (len(layers))
|
|
|
+ try:
|
|
|
+ step = self.getProgressBarStep(len(layers))
|
|
|
+ except:
|
|
|
+ QMessageBox.information(None, "Layman", "No layer selected!")
|
|
|
+
|
|
|
+ for i in range (0, len(layers)):
|
|
|
+ print(type(layers[i]))
|
|
|
+ print("tst")
|
|
|
+ print (self.isLayerInComposite(x))
|
|
|
+ print (layers[i].name() in self.isLayerInComposite(x))
|
|
|
+ inComposite = layers[i].name() in self.isLayerInComposite(x)
|
|
|
+ if (self.checkExistingLayer(layers[i].name()) and inComposite):
|
|
|
+ QMessageBox.information(None, "Message", "Composition already include layer "+layers[i].name()+"!")
|
|
|
+
|
|
|
+ # self.postRequest(layers[i].name())
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ else:
|
|
|
+ self.postRequest(layers[i].name())
|
|
|
+ wmsStatus = 'PENDING'
|
|
|
+ j = 0
|
|
|
+ while ((wmsStatus == 'PENDING') and (j < 10)):
|
|
|
+ print (self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layers[i].name()))
|
|
|
+ response = requests.get(self.URI+'/rest/'+self.laymanUsername+'/layers/'+str(layers[i].name()), verify=False)
|
|
|
+ res = self.fromByteToJson(response.content)
|
|
|
+ try:
|
|
|
+ wmsStatus = res['wms']['status']
|
|
|
+ except:
|
|
|
+ wmsStatus = "done"
|
|
|
+ time.sleep(1)
|
|
|
+ j = j + 1
|
|
|
+
|
|
|
+
|
|
|
+ print(res)
|
|
|
+ try:
|
|
|
+ wmsUrl = res['wms']['url']
|
|
|
+ except:
|
|
|
+ wmsUrl = self.URI+'/geoserver/'+layers[i].name()+'/ows'
|
|
|
+ self.compositeList[x]['layers'].append({"metadata":{},"visibility":True,"opacity":1,"title":str(layers[i].name()),"className":"HSLayers.Layer.WMS","singleTile":True,"wmsMaxScale":0,"legends":[""],"maxResolution":None,"minResolution":0,"url": wmsUrl ,"params":{"LAYERS": str(layers[i].name()),"INFO_FORMAT":"application/vnd.ogc.gml","FORMAT":"image/png","FROMCRS":"EPSG:3857","VERSION":"1.3.0"},"ratio":1.5,"dimensions":{}})
|
|
|
+ successful = successful + 1
|
|
|
+ self.dlg.progressBar.setValue(self.dlg.progressBar.value()+step)
|
|
|
+
|
|
|
+ self.importMap(x, "add", successful)
|
|
|
+ def getProgressBarStep(self, count):
|
|
|
+ return (100/count)
|
|
|
+
|
|
|
+ def deteteLayerFromComposite(self, x, position, name): ## pro verzi s komboboxem
|
|
|
+
|
|
|
+ previousLayers = self.compositeList[x]['layers']
|
|
|
+ self.compositeList[x]['layers'] = []
|
|
|
+ for i in range (0,len(previousLayers)):
|
|
|
+ if (i != position):
|
|
|
+ self.compositeList[x]['layers'].append(previousLayers[i])
|
|
|
+ self.importMap(x, "del")
|
|
|
+ done = True
|
|
|
+ if (len(self.compositeList[x]['layers']) != 0 and len(self.compositeList[x]['layers']) != None):
|
|
|
+ for i in range (0, len(self.compositeList[x]['layers'])):
|
|
|
+ if (self.compositeList[x]['layers'][i]['params']['LAYERS'] == name):
|
|
|
+ done = False
|
|
|
+ if (done and QgsProject.instance().mapLayersByName(name)): ## kompozice může mít načtené vrstvy, které nejsou v canvasu
|
|
|
+ self.deleteLayerFromCanvas(name)
|
|
|
+
|
|
|
+ def importCleanComposite(self,x):
|
|
|
+ tempFile = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
|
|
|
+ with open(tempFile, 'w') as outfile:
|
|
|
+ json.dump(self.compositeList[x], outfile)
|
|
|
+ with open(tempFile, 'rb') as f:
|
|
|
+ d = json.load(f)
|
|
|
+ files = {'file': (tempFile, open(tempFile, 'rb')),}
|
|
|
+ data = { 'name' : self.compositeList[x]['name'], 'title' : self.compositeList[x]['title'], 'description' : self.compositeList[x]['abstract']}
|
|
|
+ print(self.URI+'/rest/'+self.laymanUsername+'/maps/')
|
|
|
+ #response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps/', data = data, files=files, headers = self.authHeader, verify=False)
|
|
|
+ print(self.authHeader)
|
|
|
+ response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader, verify=False)
|
|
|
+
|
|
|
+ print(response.content)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def showProgressBar(self, bar):
|
|
|
+ bar = QProgressBar()
|
|
|
+ bar.setRange(0,0) ## range 0,0 je nekonečný
|
|
|
+ self.showProgressBar(bar)
|
|
|
+ bar.show()
|
|
|
+ iface.mainWindow().statusBar().addWidget(bar)
|
|
|
+ def fromByteToJson(self, res):
|
|
|
+ pom = res
|
|
|
+ pom = pom.decode('utf_8')
|
|
|
+ pom = json.loads(pom)
|
|
|
+ return pom
|
|
|
+
|
|
|
+ def importMap(self, x, operation, s = 0): ##s je počet vrstev úspěšně nahraných na server
|
|
|
+ if (s != 0):
|
|
|
+ self.dlg.progressBar.show()
|
|
|
+ self.dlg.label_import.show()
|
|
|
+ tempFile = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
|
|
|
+
|
|
|
+ try:
|
|
|
+ existingLayers = self.isLayerInComposite(x)
|
|
|
+ except:
|
|
|
+ existingLayers = []
|
|
|
+ successful = s
|
|
|
+ with open(tempFile, 'w') as outfile:
|
|
|
+ json.dump(self.compositeList[x], outfile)
|
|
|
+ jsonPath = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "compsite.json"
|
|
|
+ with open(jsonPath, 'rb') as f:
|
|
|
+ d = json.load(f)
|
|
|
+
|
|
|
+ files = {'file': (jsonPath, open(jsonPath, 'rb')),}
|
|
|
+ data = { 'name' : self.compositeList[x]['name'], 'title' : self.compositeList[x]['title'], 'description' : self.compositeList[x]['abstract']}
|
|
|
+ req = requests.get(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
|
|
|
+ mapCode = req.status_code ## test jestli vrstva na serveru existuje. Pokud ne = error 404
|
|
|
+ if (mapCode == 404):
|
|
|
+ if (operation == "add"):
|
|
|
+ msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete přidat do kompozice "+str(successful)+" vrstev?")
|
|
|
+ if (operation == "mod"):
|
|
|
+ msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete opravdu provést změny v této kompozici?")
|
|
|
+ self.dlg.close()
|
|
|
+ self.afterCloseEditMapDialog()
|
|
|
+ print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
|
|
|
+
|
|
|
+ response = requests.delete(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'],headers = self.authHeader, verify=False)
|
|
|
+ print(response.content)
|
|
|
+ self.dlg.show()
|
|
|
+ if (operation == "del"):
|
|
|
+ msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete smazat vybranou vrstvu?")
|
|
|
+ msgbox.addButton(QMessageBox.Yes)
|
|
|
+ msgbox.addButton(QMessageBox.No)
|
|
|
+ msgbox.setDefaultButton(QMessageBox.No)
|
|
|
+ reply = msgbox.exec()
|
|
|
+ if (reply == QMessageBox.Yes):
|
|
|
+ response = requests.post(self.URI+'/rest/'+self.laymanUsername+'/maps', files=files, data = data, headers = self.authHeader, verify=False)
|
|
|
+ print(response.content)
|
|
|
+ data = response.content
|
|
|
+ self.dlg.progressBar.hide()
|
|
|
+ # self.refreshItems()## refresh formuláře
|
|
|
+ if (operation != "mod"):
|
|
|
+ self.refreshLayerList()
|
|
|
+
|
|
|
+ else:
|
|
|
+ if (operation == "add"):
|
|
|
+ self.dlg.progressBar.setValue(0)
|
|
|
+
|
|
|
+ else:
|
|
|
+ print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
|
|
|
+ files = {'file': (jsonPath, open(jsonPath, 'rb')),}
|
|
|
+ response = requests.patch(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'], data = data, files=files, headers = self.authHeader, verify=False)
|
|
|
+ try:
|
|
|
+ self.refreshLayerList()
|
|
|
+ except:
|
|
|
+ ## nacházíme se v jiném formuláři, není co refreshovat
|
|
|
+ pass
|
|
|
+ #if (operation == "add"):
|
|
|
+ # print(len(existingLayers))
|
|
|
+ # msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
|
|
|
+ # #if(len(existingLayers) == 0):
|
|
|
+
|
|
|
+ # # #if (successful != 0):
|
|
|
+ # # msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
|
|
|
+ # #else:
|
|
|
+ # # # msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Kompozice již obsauje vrstvy: "+(', '.join(existingLayers))+". Chcete vybrané vrstvy opravdu znovu přidat?.")
|
|
|
+ # # msgbox = QMessageBox(QMessageBox.Question, "Layman", "Vybraná vrstva bude přidána do kompozice.")
|
|
|
+ #if (operation == "del"):
|
|
|
+ # msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete smazat vybranou vrstvu?")
|
|
|
+ #if (operation == "mod"):
|
|
|
+ # msgbox = QMessageBox(QMessageBox.Question, "Import Map", "Chcete uložit upravenou mapu?")
|
|
|
+ #msgbox.addButton(QMessageBox.Yes)
|
|
|
+ #msgbox.addButton(QMessageBox.No)
|
|
|
+ #msgbox.setDefaultButton(QMessageBox.No)
|
|
|
+ #reply = msgbox.exec()
|
|
|
+ #if (reply == QMessageBox.Yes):
|
|
|
+ # print(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'])
|
|
|
+ # files = {'file': (jsonPath, open(jsonPath, 'rb')),}
|
|
|
+ # response = requests.patch(self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name'], data = data, files=files, headers = self.authHeader, verify=False)
|
|
|
+
|
|
|
+ # try:
|
|
|
+ # self.refreshLayerList()
|
|
|
+ # except:
|
|
|
+ # ## nacházíme se v jiném formuláři, není co refreshovat
|
|
|
+ # pass
|
|
|
+ #if (reply == QMessageBox.No):
|
|
|
+
|
|
|
+ # self.compositeList = copy.deepcopy(self.compositeListOld)
|
|
|
+ # #self.refreshItems()##refresh formulare
|
|
|
+ # self.refreshLayerList()
|
|
|
+ try: ## některé formuláře nemají progress bar
|
|
|
+ self.dlg.progressBar.hide()
|
|
|
+ self.dlg.label_import.hide()
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+ def deleteLayer(self, layerName):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + layerName
|
|
|
+ r = requests.delete(url)
|
|
|
+ print (r.content)
|
|
|
+ def getActiveLayer(self):
|
|
|
+ layer = self.iface.activeLayer()
|
|
|
+ return layer
|
|
|
+
|
|
|
+ def createComposite(self, name, title):
|
|
|
+ # if (name == "" or title == ""):
|
|
|
+ if (title == ""):
|
|
|
+ QMessageBox.information(None, "Message", "Není vyplněn titulek!")
|
|
|
+ else:
|
|
|
+ name = self.removeUnacceptableChars(title)
|
|
|
+ data = self.getEmptyComposite(name,title)
|
|
|
+ print (data)
|
|
|
+ self.compositeList.append(data)
|
|
|
+ x = len(self.compositeList) - 1
|
|
|
+ self.importCleanComposite(x)
|
|
|
+ try:
|
|
|
+ self.refreshCompositeList()
|
|
|
+ except:
|
|
|
+ pass
|
|
|
+
|
|
|
+
|
|
|
+ def patchLayer(self, layer_name, data):
|
|
|
+ self.layerName = layer_name
|
|
|
+ self.json_export(layer_name)
|
|
|
+ sldPath = self.getTempPath(self.layerName).replace("geojson", "sld")
|
|
|
+ geoPath = self.getTempPath(self.layerName)
|
|
|
+ print(sldPath)
|
|
|
+ if(os.path.isfile(sldPath)): ## existuje sld?
|
|
|
+ files = [('file', open(geoPath, 'rb')), ('sld', open(sldPath, 'rb'))]
|
|
|
+ print("sld")
|
|
|
+ else:
|
|
|
+ files = {'file': (geoPath, open(geoPath, 'rb')),}
|
|
|
+ print("ne sld")
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+"/layers/" + layer_name
|
|
|
+ print(url)
|
|
|
+ r = requests.patch(url, files=files, data = data, headers = self.authHeader, verify=False)
|
|
|
+ print(r.content)
|
|
|
+
|
|
|
+ def getTempPath(self, name):
|
|
|
+
|
|
|
+ print (name)
|
|
|
+ if type(name) is tuple:
|
|
|
+ return (name[0] + name[1])
|
|
|
+ else:
|
|
|
+ tempFile = tempfile.gettempdir() + os.sep + name +'.geojson'
|
|
|
+
|
|
|
+ return tempFile
|
|
|
+ def sendLayer(self):
|
|
|
+ layer = self.getActiveLayer()
|
|
|
+ if (layer == None):
|
|
|
+ QMessageBox.information(None, "Message", "Neexistuje žádná vrstva k uložení")
|
|
|
+ else:
|
|
|
+ self.json_export()
|
|
|
+ self.postRequest()
|
|
|
+ def getExistingLayers(self):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+"/layers"
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+ for x in range(len(data)):
|
|
|
+ print(data[x]['name'])
|
|
|
+ return data
|
|
|
+ def checkExistingLayer(self, layerName):
|
|
|
+ layerName = self.removeUnacceptableChars(layerName)
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+"/layers"
|
|
|
+ r = requests.get(url = url)
|
|
|
+ data = r.json()
|
|
|
+
|
|
|
+ pom = set()
|
|
|
+ for x in range(len(data)):
|
|
|
+ pom.add((data[x]['name']))
|
|
|
+ layerName = layerName.replace(" ", "_").lower()
|
|
|
+ print(layerName)
|
|
|
+ print(pom)
|
|
|
+ if (layerName in pom):
|
|
|
+ return True
|
|
|
+ else:
|
|
|
+ return False
|
|
|
+
|
|
|
+ def removeUnacceptableChars(self, input):
|
|
|
+ input = input.replace("ř","r")
|
|
|
+ input = input.replace("š","s")
|
|
|
+ input = input.replace("ž","z")
|
|
|
+ input = input.replace("ů","u")
|
|
|
+ input = input.replace("ú","u")
|
|
|
+ input = input.replace(" ","_")
|
|
|
+ input = input.replace("é","e")
|
|
|
+ input = input.replace("í","i")
|
|
|
+ input = input.replace("á","a")
|
|
|
+ input = input.replace("ó","o")
|
|
|
+ input = input.replace("č","c")
|
|
|
+ input = input.replace("ď","d")
|
|
|
+ input = input.replace("ě","e")
|
|
|
+ input = input.replace("ť","t")
|
|
|
+ input = re.sub(r'[?|$|.|!]',r'',input)
|
|
|
+ input = input.lower()
|
|
|
+ # iface.messageBar().pushWidget(iface.messageBar().createMessage("Layman:", "Diacritics in name of layer was replaced."), Qgis.Success, duration=3)
|
|
|
+ return input
|
|
|
+
|
|
|
+ def test (self):
|
|
|
+ item = self.dlgGetLayers.items.currentItem().text()
|
|
|
+ print( item)
|
|
|
+
|
|
|
+ def isLayerInComposite(self, x):
|
|
|
+ layers =[]
|
|
|
+ layers.append(self.dlg.mMapLayerComboBox.currentLayer())
|
|
|
+ print (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
|
|
|
+ req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
|
|
|
+ data = req.json()
|
|
|
+
|
|
|
+ print (data['abstract'])
|
|
|
+ print (len(self.compositeList[x]['layers']))
|
|
|
+ existingLayers = []
|
|
|
+ for i in range (0, len(data['layers'])):
|
|
|
+ for j in range (0, len(layers)):
|
|
|
+ if (data['layers'][i]['params']['LAYERS'] in layers[j].name() ):
|
|
|
+ existingLayers.append(data['layers'][i]['params']['LAYERS'])
|
|
|
+
|
|
|
+ return existingLayers
|
|
|
+
|
|
|
+ def isRasterLayerInComposite(self, x, name):
|
|
|
+ req = requests.get (self.URI+'/rest/'+self.laymanUsername+'/maps/'+self.compositeList[x]['name']+'/file')
|
|
|
+ data = req.json()
|
|
|
+ existingLayers = []
|
|
|
+ for i in range (0, len(data['layers'])):
|
|
|
+ if (data['layers'][i]['params']['LAYERS'] == name ):
|
|
|
+ existingLayers.append(data['layers'][i]['params']['LAYERS'])
|
|
|
+ return existingLayers
|
|
|
+
|
|
|
+ def addComposite(self, data, service, groupName = ''):
|
|
|
+ #self.compositeList.append (data)
|
|
|
+ print(len(data['layers']))
|
|
|
+ for x in range(0, len(data['layers'])):
|
|
|
+ # repairUrl = self.convertUrlFromHex(data['layers'][x]['url'])
|
|
|
+ repairUrl = self.URI+"/geoserver/"+self.laymanUsername+"/ows"
|
|
|
+ layerName = data['layers'][x]['params']['LAYERS']
|
|
|
+ format = data['layers'][x]['params']['FORMAT']
|
|
|
+ # epsg = str(data['groups']['projection']).upper()
|
|
|
+ epsg = 'EPSG:4326'
|
|
|
+ #abstract = data['data']['layers'][x]['params']['ABSTRACT']
|
|
|
+ wmsName = data['layers'][x]['params']['LAYERS']
|
|
|
+ if service == 'WMS':
|
|
|
+ self.loadWms(repairUrl, layerName, format,epsg, groupName)
|
|
|
+
|
|
|
+ if service == 'WFS':
|
|
|
+ self.loadWfs(repairUrl, layerName, groupName)
|
|
|
+ def loadService(self, data, service, groupName = ''):
|
|
|
+
|
|
|
+ print(len(data['layers']))
|
|
|
+ for x in range(0, len(data['layers'])):
|
|
|
+ #repairUrl = self.convertUrlFromHex(data['layers'][x]['url'])
|
|
|
+ repairUrl = "http://layman.lesprojekt.cz/geoserver/"+self.laymanUsername+"/ows"
|
|
|
+ layerName = data['layers'][x]['params']['LAYERS']
|
|
|
+ format = data['layers'][x]['params']['FORMAT']
|
|
|
+ # epsg = str(data['groups']['projection']).upper()
|
|
|
+ epsg = 'EPSG:4326'
|
|
|
+ #abstract = data['data']['layers'][x]['params']['ABSTRACT']
|
|
|
+ wmsName = data['layers'][x]['params']['LAYERS']
|
|
|
+ if self.checkLayerOnLayman(layerName):
|
|
|
+ if service == 'WMS':
|
|
|
+ self.loadWms(repairUrl, layerName, format,epsg, groupName)
|
|
|
+
|
|
|
+ if service == 'WFS':
|
|
|
+ self.loadWfs(repairUrl, layerName, groupName)
|
|
|
+ else:
|
|
|
+ QMessageBox.information(None, "Layman", "Layer: "+layerName + " is corrupted and will not be loaded.")
|
|
|
+
|
|
|
+ def loadWms(self, url, layerName, format, epsg, groupName = ''):
|
|
|
+ print(url)
|
|
|
+ urlWithParams = 'contextualWMSLegend=0&crs='+epsg+'&dpiMode=7&featureCount=10&format=image/png&layers='+layerName+'&styles=&url=' + url
|
|
|
+ print(urlWithParams)
|
|
|
+ rlayer = QgsRasterLayer(urlWithParams, layerName, 'wms')
|
|
|
+ if (groupName != ''):
|
|
|
+ self.addWmsToGroup(groupName,rlayer)
|
|
|
+ else:
|
|
|
+ QgsProject.instance().addMapLayer(rlayer)
|
|
|
+
|
|
|
+ def loadWfs(self, url, layerName, groupName = ''):
|
|
|
+ epsg = 'EPSG:4326'
|
|
|
+ uri = "http://layman.lesprojekt.cz/geoserver/"+self.laymanUsername+"/ows?srsname="+epsg+"&typename="+self.laymanUsername+":"+layerName+"&restrictToRequestBBOX=1&pagingEnabled=True &version=auto&request=GetFeature&service=WFS"
|
|
|
+
|
|
|
+ print(uri)
|
|
|
+ vlayer = QgsVectorLayer(uri, layerName, "WFS")
|
|
|
+ print(vlayer.isValid())
|
|
|
+ if (groupName != ''):
|
|
|
+ self.addWmsToGroup(groupName,vlayer)
|
|
|
+ else:
|
|
|
+ QgsProject.instance().addMapLayer(vlayer)
|
|
|
+ def addWmsToGroup(self, groupName, layer):
|
|
|
+ root = QgsProject.instance().layerTreeRoot()
|
|
|
+ group = root.findGroup(groupName)
|
|
|
+ if not(group):
|
|
|
+ group = root.addGroup(groupName)
|
|
|
+ QgsProject.instance().addMapLayer(layer,False)
|
|
|
+ group.insertChildNode(1,QgsLayerTreeLayer(layer))
|
|
|
+
|
|
|
+ def convertUrlFromHex(self, url):
|
|
|
+ url = url.replace('%3A',':')
|
|
|
+ url = url.replace('%2F','/')
|
|
|
+ url = url.replace('%3F','?')
|
|
|
+ url = url.replace('%3D','=')
|
|
|
+ url = url.replace('%26','&')
|
|
|
+ return url
|
|
|
+
|
|
|
+ def checkEpsg(self, name):
|
|
|
+ ret = False
|
|
|
+ layer = QgsProject.instance().mapLayersByName(name)
|
|
|
+ layerCRS = layer[0].crs().authid()
|
|
|
+ if ((layerCRS == 'EPSG:4326') or (layerCRS == 'EPSG:3857')):
|
|
|
+ ret = True
|
|
|
+ return ret
|
|
|
+
|
|
|
+ def registerLayer(self, name):
|
|
|
+ sldPath = self.getTempPath(name).replace("geojson", "sld")
|
|
|
+ geoPath = self.getTempPath(name)
|
|
|
+
|
|
|
+ url = "http://layman.lesprojekt.cz/rest/"+self.laymanUsername+"/layers"
|
|
|
+
|
|
|
+ files = {'sld': (sldPath, open(sldPath, 'rb')),} # nahrávám sld
|
|
|
+ payload = {
|
|
|
+ 'file': name+".geojson"
|
|
|
+ }
|
|
|
+ response = requests.request("POST", url, files = files, data=payload, headers = self.authHeader)
|
|
|
+ # print(response.text)
|
|
|
+
|
|
|
+ def read_in_chunks(self, file_object): ## cca 1MB chunk převzato z laymana test klienta
|
|
|
+ chunk_size=self.CHUNK_SIZE
|
|
|
+ while True:
|
|
|
+ data = file_object.read(chunk_size)
|
|
|
+ if not data:
|
|
|
+ break
|
|
|
+ yield data
|
|
|
+
|
|
|
+ def postInChunks(self, layer_name, reqType):
|
|
|
+ print(reqType)
|
|
|
+ if (reqType == "patch"):
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layer_name
|
|
|
+ r = requests.delete(url,headers = self.authHeader)
|
|
|
+ # print(r.content)
|
|
|
+
|
|
|
+ self.registerLayer(layer_name)
|
|
|
+
|
|
|
+ filePath = os.path.join(tempfile.gettempdir(), "atlas_chunks" ) ## chunky se ukládají do adresáře v tempu
|
|
|
+
|
|
|
+ if not (os.path.exists(filePath)):
|
|
|
+ os.mkdir(filePath)
|
|
|
+ file = self.getTempPath(layer_name)
|
|
|
+ f = open(file, 'rb')
|
|
|
+ arr = []
|
|
|
+ for piece in self.read_in_chunks(f):
|
|
|
+ arr.append(piece)
|
|
|
+
|
|
|
+ url = self.URI+'/rest/'+self.laymanUsername+'/layers/'+layer_name+'/chunk'
|
|
|
+ resumableFilename = layer_name+'.geojson'
|
|
|
+ layman_original_parameter = "file"
|
|
|
+ resumableTotalChunks = len(arr)
|
|
|
+
|
|
|
+ for i in range (1, len(arr)+1): ##chunky jsou počítané od 1 proto +1
|
|
|
+ print("chunk" + str(i))
|
|
|
+ file = arr[i-1] # rozsekaná část souboru
|
|
|
+ resumableChunkNumber = i # cislo casti
|
|
|
+ payload = {
|
|
|
+ 'file' : "chunk"+str(i)+".geojson",
|
|
|
+ 'resumableFilename': resumableFilename,
|
|
|
+ 'layman_original_parameter': layman_original_parameter,
|
|
|
+ 'resumableChunkNumber': i,
|
|
|
+ 'resumableTotalChunks': resumableTotalChunks
|
|
|
+ }
|
|
|
+
|
|
|
+ f = open(filePath + os.sep+"chunk"+str(i)+".geojson", "wb")
|
|
|
+ f.write(bytearray(arr[i-1]))
|
|
|
+ f.close()
|
|
|
+ files = {'file': (layer_name+".geojson", open(filePath +os.sep+ "chunk"+str(i)+".geojson", 'rb')),}
|
|
|
+ response = requests.post(url, files = files, data=payload, headers = self.authHeader)
|
|
|
+
|
|
|
+ print(response.content)
|
|
|
+
|
|
|
+
|
|
|
+############################################# auth part############################
|
|
|
+
|
|
|
+ def startThread(self):
|
|
|
+ self.thread1 = threading.Thread(target=self.refreshToken)
|
|
|
+ self.thread1.start()
|
|
|
+
|
|
|
+ def refreshToken(self):
|
|
|
+ #self.expires_in = 60
|
|
|
+ path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "tsts.txt"
|
|
|
+ i = 0
|
|
|
+ tokenEndpoint = "https://www.agrihub.cz/o/oauth2/token"
|
|
|
+ while (i < self.expires_in):
|
|
|
+ f = open(path, "a")
|
|
|
+ f.write(str(i))
|
|
|
+
|
|
|
+ f.close()
|
|
|
+ time.sleep(1)
|
|
|
+ if i == self.expires_in - 4:
|
|
|
+
|
|
|
+
|
|
|
+ data = {'grant_type':'refresh_token',
|
|
|
+ 'refresh_token': self.refresh_token,
|
|
|
+ 'client_id':'id-3462f94b-875c-9185-4ced-b69841f24b3',
|
|
|
+ 'redirect_uri':'http://localhost:3000/client/authn/oauth2-liferay/callback',
|
|
|
+ 'code_verifier':'test'
|
|
|
+ }
|
|
|
+
|
|
|
+ r = requests.post(url = tokenEndpoint, data = data, headers = self.authHeader)
|
|
|
+ res = self.fromByteToJson(r.content)
|
|
|
+ self.access_token = res['access_token']
|
|
|
+ self.refresh_token = res['refresh_token']
|
|
|
+ self.expires_in = res['expires_in']
|
|
|
+ print(self.access_token)
|
|
|
+ self.setAuthHeader()
|
|
|
+ i = 0
|
|
|
+ else:
|
|
|
+ i += 1
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ def authOptained (self):
|
|
|
+ self.dlg.pushButton_Continue.setEnabled(True)
|
|
|
+
|
|
|
+ self.menu_Connection.setEnabled(True)
|
|
|
+ self.menu_saveLocalFile.setEnabled(True)
|
|
|
+ self.menu_loadJson.setEnabled(True)
|
|
|
+ self.menu_ImportLayerDialog.setEnabled(True)
|
|
|
+ self.menu_AddLayerDialog.setEnabled(True)
|
|
|
+ self.menu_AddMapDialog.setEnabled(True)
|
|
|
+ self.menu_ImportLayerDialog.setEnabled(True)
|
|
|
+ self.menu_ImportMapDialog.setEnabled(True)
|
|
|
+ # self.menu_DeleteMapDialog.setEnabled(True)
|
|
|
+ # self.menu_CreateCompositeDialog.setEnabled(True)
|
|
|
+ self.menu_UserInfoDialog.setEnabled(True)
|
|
|
+ self.textbox.setText("Layman: Logged user")
|
|
|
+
|
|
|
+ def getCodeVerifier(self):
|
|
|
+ code_verifier = base64.urlsafe_b64encode(os.urandom(40)).decode('utf-8')
|
|
|
+ code_verifier = re.sub('[^a-zA-Z0-9]+', '', code_verifier)
|
|
|
+ self.code_verifier = code_verifier
|
|
|
+ return (code_verifier)
|
|
|
+
|
|
|
+ def getCodeChallenge(self, code_verifier):
|
|
|
+ code_challenge = hashlib.sha256(code_verifier.encode('utf-8')).digest()
|
|
|
+ code_challenge = base64.urlsafe_b64encode(code_challenge).decode('utf-8')
|
|
|
+ code_challenge = code_challenge.replace('=', '')
|
|
|
+ self.code_challenge = code_challenge
|
|
|
+ return (code_challenge)
|
|
|
+
|
|
|
+ def printVariables(self):
|
|
|
+ print (self.access_token)
|
|
|
+ print(self.refresh_token)
|
|
|
+ print(self.authHeader)
|
|
|
+ print(self.laymanUsername)
|
|
|
+
|
|
|
+ def getAuthCode(self):
|
|
|
+ path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "auth.txt"
|
|
|
+ f = open(path, "r")
|
|
|
+ ret = f.read()
|
|
|
+ f.close()
|
|
|
+ return ret
|
|
|
+
|
|
|
+ def getToken(self):
|
|
|
+ self.saveIni()
|
|
|
+
|
|
|
+ tokenEndpoint = "https://www.agrihub.cz/o/oauth2/token"
|
|
|
+ # data to be sent to api
|
|
|
+ data = {'grant_type':'authorization_code',
|
|
|
+ 'client_id': self.client_id,
|
|
|
+ 'redirect_uri':'http://localhost:3000/client/authn/oauth2-liferay/callback',
|
|
|
+ 'code_verifier': self.code_verifier,
|
|
|
+ 'code': self.getAuthCode()}
|
|
|
+
|
|
|
+ # sending post request and saving response as response object
|
|
|
+ r = requests.post(url = tokenEndpoint, data = data, headers = self.authHeader)
|
|
|
+ res = self.fromByteToJson(r.content)
|
|
|
+ print (res)
|
|
|
+ try:
|
|
|
+ print(res['access_token'])
|
|
|
+ print(res['expires_in'])
|
|
|
+ print(res['refresh_token'])
|
|
|
+ except:
|
|
|
+ QMessageBox.information(None, "Message", "Autorization was not sucessfull! Please try it again.")
|
|
|
+ return
|
|
|
+ self.access_token = res['access_token']
|
|
|
+ self.refresh_token = res['refresh_token']
|
|
|
+ self.expires_in = res['expires_in']
|
|
|
+ self.setAuthHeader()
|
|
|
+ data ={
|
|
|
+ 'access_token': res['access_token'],
|
|
|
+ 'refresh_token': res['refresh_token'],
|
|
|
+ 'expires_in':res['expires_in']
|
|
|
+ }
|
|
|
+ path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "tokens.json"
|
|
|
+ with open(path, 'w') as outfile:
|
|
|
+ json.dump(data, outfile)
|
|
|
+ self.startThread()
|
|
|
+ self.registerUserIfNotExists()
|
|
|
+ self.dlg.close()
|
|
|
+
|
|
|
+ def setAuthHeader(self):
|
|
|
+ self.authHeader ={
|
|
|
+ "Authorization": "Bearer " + self.access_token,
|
|
|
+ "AuthorizationIssUrl" : 'https://www.agrihub.cz/o/oauth2/authorize'
|
|
|
+ }
|
|
|
+
|
|
|
+ def registerUserIfNotExists(self):
|
|
|
+ userEndpoint = "http://layman.lesprojekt.cz/rest/current-user"
|
|
|
+ #self.laymanUsername = self.dlg.lineEdit_userName.text()
|
|
|
+ id = self.client_id.replace('-', '')
|
|
|
+ user = {'username':self.Agrimail}
|
|
|
+ #user = self.Agrimail
|
|
|
+ print("authheader: "+ str(self.authHeader))
|
|
|
+ r = requests.patch(url = userEndpoint, data = user, headers = self.authHeader)
|
|
|
+ res = r.text
|
|
|
+ res = self.fromByteToJson(r.content)
|
|
|
+ print (res)
|
|
|
+ print(user)
|
|
|
+ print(res)
|
|
|
+ try:
|
|
|
+ # if res['message'] == 'User already reserved username.': # res['code'] == 34, code 35 je pokud již jiný uživatel má účet, který chceme registrovat
|
|
|
+ if res['code'] == 34: # res['code'] == 34, code 35 je pokud již jiný uživatel má účet, který chceme registrovat (code 35 pravděpodobně nemůže nastat)
|
|
|
+
|
|
|
+ print("user exists")
|
|
|
+ self.laymanUsername = res['detail']['username']
|
|
|
+ #self.laymanUsername = res['username']
|
|
|
+ #else:
|
|
|
+ # self.laymanUsername = user['username']
|
|
|
+ except:
|
|
|
+
|
|
|
+ print("creating new user: " + res['username'])
|
|
|
+ self.laymanUsername = res['username']
|
|
|
+ #API_ENDPOINT = "http://layman.lesprojekt.cz/rest/current-user"
|
|
|
+ #headers ={
|
|
|
+ # "Authorization": "Bearer "+ self.access_token,
|
|
|
+ # "AuthorizationIssUrl" : 'https://www.agrihub.cz/o/oauth2/authorize'
|
|
|
+ #}
|
|
|
+
|
|
|
+
|
|
|
+ def openAuthLiferayUrl(self):
|
|
|
+
|
|
|
+ self.getCodeChallenge(self.getCodeVerifier()) ##generování kódů
|
|
|
+ self.client_id = self.dlg.lineEdit_AgriID.text()
|
|
|
+ path = tempfile.gettempdir() + os.sep + "atlas" + os.sep + "auth.txt"
|
|
|
+ self.watcher = QFileSystemWatcher()
|
|
|
+ self.watcher.addPath(path)
|
|
|
+ self.watcher.fileChanged.connect(self.authOptained)
|
|
|
+
|
|
|
+
|
|
|
+ #################
|
|
|
+
|
|
|
+ print ("##### flask server is starting #####")
|
|
|
+ thread = StartFlaskDaemon()
|
|
|
+ thread.daemon = True
|
|
|
+ thread.start()
|
|
|
+ url = 'https://www.agrihub.cz/o/oauth2/authorize?response_type=code&client_id='+self.client_id+'&redirect_uri=http%3A%2F%2Flocalhost:3000%2Fclient%2Fauthn%2Foauth2-liferay%2Fcallback&code_challenge='+self.code_challenge ##n4bQgYhMfWWaL-qgxVrQFaO_TxsrC4Is0V1sFbDwCgg'
|
|
|
+ webbrowser.open(url, new=2)
|
|
|
+
|
|
|
+ def saveIni(self):
|
|
|
+ file = os.getenv("HOME") + os.sep + ".layman" + os.sep + 'layman_user.INI'
|
|
|
+ dir = os.getenv("HOME") + os.sep + ".layman"
|
|
|
+ if not (os.path.isdir(dir)):
|
|
|
+ try:
|
|
|
+ os.mkdir(dir)
|
|
|
+ except OSError:
|
|
|
+ print ("vytváření adresáře selhalo")
|
|
|
+ config = configparser.ConfigParser()
|
|
|
+ config['DEFAULT']['login'] = self.Agrimail
|
|
|
+ config['DEFAULT']['id'] = self.client_id
|
|
|
+
|
|
|
+
|
|
|
+ with open(file, 'w') as configfile:
|
|
|
+ config.write(configfile)
|
|
|
+ def loadIni(self):
|
|
|
+ file = os.getenv("HOME") + os.sep + ".layman" + os.sep +'layman_user.INI'
|
|
|
+ config = configparser.ConfigParser()
|
|
|
+ config.read(file)
|
|
|
+ return config
|
|
|
+ def run(self):
|
|
|
+ """Run method that loads and starts the plugin"""
|
|
|
+
|
|
|
+ if not self.pluginIsActive:
|
|
|
+ self.pluginIsActive = True
|
|
|
+
|
|
|
+ #print "** STARTING Atlas"
|
|
|
+
|
|
|
+ # dockwidget may not exist if:
|
|
|
+ # first run of plugin
|
|
|
+ # removed on close (see self.onClosePlugin method)
|
|
|
+ if self.dockwidget == None:
|
|
|
+ # Create the dockwidget (after translation) and keep reference
|
|
|
+ self.dockwidget = AtlasDockWidget()
|
|
|
+
|
|
|
+
|
|
|
+ # connect to provide cleanup on closing of dockwidget
|
|
|
+ self.dockwidget.closingPlugin.connect(self.onClosePlugin)
|
|
|
+ self.dockwidget.pushButton.clicked.connect(self.sendLayer)
|
|
|
+ self.dockwidget.pushButton_2.clicked.connect(self.loadLocalFile)
|
|
|
+ self.dockwidget.pushButton_3.clicked.connect(self.saveLocalFile)
|
|
|
+ self.dockwidget.pushButton_getLayers.clicked.connect(self.run_getLayer)
|
|
|
+ self.dlgGetLayers.pushButtonxx.clicked.connect(lambda: print(self.dlgGetLayers.items.currentItem().text()))
|
|
|
+
|
|
|
+ # show the dockwidget
|
|
|
+ # TODO: fix to allow choice of dock location
|
|
|
+ self.iface.addDockWidget(Qt.TopDockWidgetArea, self.dockwidget)
|
|
|
+ self.dockwidget.show()
|
|
|
+
|
|
|
+class StartFlaskDaemon(threading.Thread):
|
|
|
+ def run(self):
|
|
|
+ from subprocess import Popen, PIPE
|
|
|
+ import platform
|
|
|
+ import sys
|
|
|
+ from pathlib import Path
|
|
|
+ d= os.path.dirname(Path(__file__).absolute()) + os.sep+"flask_listener" + os.sep + "flask_listener.py"
|
|
|
+
|
|
|
+ if platform.system() == 'Windows':
|
|
|
+ process = subprocess.Popen(["python", d],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
|
+ else:
|
|
|
+ process = subprocess.Popen(["python " + d],stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
|
|
|
+ stdout, stderr = process.communicate()
|
|
|
+ print (stdout, stderr)
|
|
|
+ '''Start your thread here'''
|
|
|
+
|